wire.rs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. //! Parsing the DNS wire protocol.
  2. pub(crate) use std::io::Cursor;
  3. pub(crate) use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
  4. use std::io;
  5. use log::*;
  6. use crate::record::{Record, OPT};
  7. use crate::strings::{ReadLabels, WriteLabels};
  8. use crate::types::*;
  9. impl Request {
  10. /// Converts this request to a vector of bytes.
  11. pub fn to_bytes(&self) -> io::Result<Vec<u8>> {
  12. let mut bytes = Vec::with_capacity(32);
  13. bytes.write_u16::<BigEndian>(self.transaction_id)?;
  14. bytes.write_u16::<BigEndian>(self.flags.to_u16())?;
  15. bytes.write_u16::<BigEndian>(self.queries.len() as u16)?;
  16. bytes.write_u16::<BigEndian>(0)?; // usually answers
  17. bytes.write_u16::<BigEndian>(0)?; // usually authority RRs
  18. bytes.write_u16::<BigEndian>(if self.additional.is_some() { 1 } else { 0 })?; // additional RRs
  19. for query in &self.queries {
  20. bytes.write_labels(&query.qname)?;
  21. bytes.write_u16::<BigEndian>(query.qtype)?;
  22. bytes.write_u16::<BigEndian>(query.qclass.to_u16())?;
  23. }
  24. if let Some(opt) = &self.additional {
  25. bytes.write_u8(0)?; // usually a name
  26. bytes.write_u16::<BigEndian>(OPT::RR_TYPE)?;
  27. bytes.extend(opt.to_bytes()?);
  28. }
  29. Ok(bytes)
  30. }
  31. /// Returns the OPT record to be sent as part of requests.
  32. pub fn additional_record() -> OPT {
  33. OPT {
  34. udp_payload_size: 512,
  35. higher_bits: 0,
  36. edns0_version: 0,
  37. flags: 0,
  38. data: Vec::new(),
  39. }
  40. }
  41. }
  42. impl Response {
  43. /// Reads bytes off of the given slice, parsing them into a response.
  44. #[cfg_attr(all(test, feature = "with_mutagen"), ::mutagen::mutate)]
  45. pub fn from_bytes(bytes: &[u8]) -> Result<Self, WireError> {
  46. info!("Parsing response");
  47. trace!("Bytes -> {:?}", bytes);
  48. let mut c = Cursor::new(bytes);
  49. let transaction_id = c.read_u16::<BigEndian>()?;
  50. trace!("Read txid -> {:?}", transaction_id);
  51. let flags = Flags::from_u16(c.read_u16::<BigEndian>()?);
  52. trace!("Read flags -> {:#?}", flags);
  53. let query_count = c.read_u16::<BigEndian>()?;
  54. let answer_count = c.read_u16::<BigEndian>()?;
  55. let authority_count = c.read_u16::<BigEndian>()?;
  56. let additional_count = c.read_u16::<BigEndian>()?;
  57. let mut queries = Vec::new();
  58. debug!("Reading {}x query from response", query_count);
  59. for _ in 0 .. query_count {
  60. let (qname, _) = c.read_labels()?;
  61. queries.push(Query::from_bytes(qname, &mut c)?);
  62. }
  63. let mut answers = Vec::new();
  64. debug!("Reading {}x answer from response", answer_count);
  65. for _ in 0 .. answer_count {
  66. let (qname, _) = c.read_labels()?;
  67. answers.push(Answer::from_bytes(qname, &mut c)?);
  68. }
  69. let mut authorities = Vec::new();
  70. debug!("Reading {}x authority from response", authority_count);
  71. for _ in 0 .. authority_count {
  72. let (qname, _) = c.read_labels()?;
  73. authorities.push(Answer::from_bytes(qname, &mut c)?);
  74. }
  75. let mut additionals = Vec::new();
  76. debug!("Reading {}x additional answer from response", additional_count);
  77. for _ in 0 .. additional_count {
  78. let (qname, _) = c.read_labels()?;
  79. additionals.push(Answer::from_bytes(qname, &mut c)?);
  80. }
  81. Ok(Self { transaction_id, flags, queries, answers, authorities, additionals })
  82. }
  83. }
  84. impl Query {
  85. /// Reads bytes from the given cursor, and parses them into a query with
  86. /// the given domain name.
  87. #[cfg_attr(all(test, feature = "with_mutagen"), ::mutagen::mutate)]
  88. fn from_bytes(qname: String, c: &mut Cursor<&[u8]>) -> Result<Self, WireError> {
  89. let qtype = c.read_u16::<BigEndian>()?;
  90. trace!("Read qtype -> {:?}", qtype);
  91. let qclass = QClass::from_u16(c.read_u16::<BigEndian>()?);
  92. trace!("Read qclass -> {:?}", qtype);
  93. Ok(Self { qtype, qclass, qname })
  94. }
  95. }
  96. impl Answer {
  97. /// Reads bytes from the given cursor, and parses them into an answer with
  98. /// the given domain name.
  99. #[cfg_attr(all(test, feature = "with_mutagen"), ::mutagen::mutate)]
  100. fn from_bytes(qname: String, c: &mut Cursor<&[u8]>) -> Result<Self, WireError> {
  101. let qtype = c.read_u16::<BigEndian>()?;
  102. trace!("Read qtype -> {:?}", qtype);
  103. if qtype == OPT::RR_TYPE {
  104. let opt = OPT::read(c)?;
  105. Ok(Self::Pseudo { qname, opt })
  106. }
  107. else {
  108. let qclass = QClass::from_u16(c.read_u16::<BigEndian>()?);
  109. trace!("Read qclass -> {:?}", qtype);
  110. let ttl = c.read_u32::<BigEndian>()?;
  111. trace!("Read TTL -> {:?}", ttl);
  112. let record_length = c.read_u16::<BigEndian>()?;
  113. trace!("Read record length -> {:?}", record_length);
  114. let record = Record::from_bytes(qtype, record_length, c)?;
  115. Ok(Self::Standard { qclass, qname, record, ttl })
  116. }
  117. }
  118. }
  119. impl Record {
  120. /// Reads at most `len` bytes from the given curser, and parses them into
  121. /// a record structure depending on the type number, which has already been read.
  122. #[cfg_attr(all(test, feature = "with_mutagen"), ::mutagen::mutate)]
  123. fn from_bytes(qtype: TypeInt, len: u16, c: &mut Cursor<&[u8]>) -> Result<Self, WireError> {
  124. use crate::record::*;
  125. macro_rules! try_record {
  126. ($record:tt) => {
  127. if $record::RR_TYPE == qtype {
  128. info!("Parsing {} record (type {}, len {})", $record::NAME, qtype, len);
  129. return Wire::read(len, c).map(Self::$record)
  130. }
  131. }
  132. }
  133. // Try all the records, one type at a time, returning early if the
  134. // type number matches.
  135. try_record!(A);
  136. try_record!(AAAA);
  137. try_record!(CAA);
  138. try_record!(CNAME);
  139. try_record!(MX);
  140. try_record!(NS);
  141. // OPT is handled separately
  142. try_record!(PTR);
  143. try_record!(SOA);
  144. try_record!(SRV);
  145. try_record!(TXT);
  146. // Otherwise, collect the bytes into a vector and return an unknown
  147. // record type.
  148. let mut bytes = Vec::new();
  149. for _ in 0 .. len {
  150. bytes.push(c.read_u8()?);
  151. }
  152. let type_number = UnknownQtype::from(qtype);
  153. Ok(Self::Other { type_number, bytes })
  154. }
  155. }
  156. impl QClass {
  157. fn from_u16(uu: u16) -> Self {
  158. match uu {
  159. 0x0001 => Self::IN,
  160. 0x0003 => Self::CH,
  161. 0x0004 => Self::HS,
  162. _ => Self::Other(uu),
  163. }
  164. }
  165. fn to_u16(self) -> u16 {
  166. match self {
  167. Self::IN => 0x0001,
  168. Self::CH => 0x0003,
  169. Self::HS => 0x0004,
  170. Self::Other(uu) => uu,
  171. }
  172. }
  173. }
  174. /// Determines the record type number to signify a record with the given name.
  175. pub fn find_qtype_number(record_type: &str) -> Option<TypeInt> {
  176. use crate::record::*;
  177. macro_rules! try_record {
  178. ($record:tt) => {
  179. if $record::NAME == record_type {
  180. return Some($record::RR_TYPE);
  181. }
  182. }
  183. }
  184. try_record!(A);
  185. try_record!(AAAA);
  186. try_record!(CAA);
  187. try_record!(CNAME);
  188. try_record!(MX);
  189. try_record!(NS);
  190. // OPT is elsewhere
  191. try_record!(PTR);
  192. try_record!(SOA);
  193. try_record!(SRV);
  194. try_record!(TXT);
  195. None
  196. }
  197. impl Flags {
  198. /// The set of flags that represents a query packet.
  199. pub fn query() -> Self {
  200. Self::from_u16(0b_0000_0001_0000_0000)
  201. }
  202. /// The set of flags that represents a successful response.
  203. pub fn standard_response() -> Self {
  204. Self::from_u16(0b_1000_0001_1000_0000)
  205. }
  206. /// Converts the flags into a two-byte number.
  207. pub fn to_u16(self) -> u16 { // 0123 4567 89AB CDEF
  208. let mut bits = 0b_0000_0000_0000_0000;
  209. if self.response { bits += 0b_1000_0000_0000_0000; }
  210. match self.opcode {
  211. _ => { bits += 0b_0000_0000_0000_0000; }
  212. }
  213. if self.authoritative { bits += 0b_0000_0100_0000_0000; }
  214. if self.truncated { bits += 0b_0000_0010_0000_0000; }
  215. if self.recursion_desired { bits += 0b_0000_0001_0000_0000; }
  216. if self.recursion_available { bits += 0b_0000_0000_1000_0000; }
  217. // (the Z bit is reserved) 0b_0000_0000_0100_0000
  218. if self.authentic_data { bits += 0b_0000_0000_0010_0000; }
  219. if self.checking_disabled { bits += 0b_0000_0000_0001_0000; }
  220. bits
  221. }
  222. /// Extracts the flags from the given two-byte number.
  223. pub fn from_u16(bits: u16) -> Self {
  224. let has_bit = |bit| { bits & bit == bit };
  225. Self {
  226. response: has_bit(0b_1000_0000_0000_0000),
  227. opcode: 0,
  228. authoritative: has_bit(0b_0000_0100_0000_0000),
  229. truncated: has_bit(0b_0000_0010_0000_0000),
  230. recursion_desired: has_bit(0b_0000_0001_0000_0000),
  231. recursion_available: has_bit(0b_0000_0000_1000_0000),
  232. authentic_data: has_bit(0b_0000_0000_0010_0000),
  233. checking_disabled: has_bit(0b_0000_0000_0001_0000),
  234. error_code: ErrorCode::from_bits(bits & 0b_1111),
  235. }
  236. }
  237. }
  238. impl ErrorCode {
  239. /// Extracts the rcode from the last four bits of the flags field.
  240. fn from_bits(bits: u16) -> Option<Self> {
  241. match bits {
  242. 0 => None,
  243. 1 => Some(Self::FormatError),
  244. 2 => Some(Self::ServerFailure),
  245. 3 => Some(Self::NXDomain),
  246. 4 => Some(Self::NotImplemented),
  247. 5 => Some(Self::QueryRefused),
  248. 16 => Some(Self::BadVersion),
  249. n => Some(Self::Other(n)),
  250. }
  251. }
  252. }
  253. /// Trait for decoding DNS record structures from bytes read over the wire.
  254. pub trait Wire: Sized {
  255. /// This record’s type as a string, such as `"A"` or `"CNAME"`.
  256. const NAME: &'static str;
  257. /// The number signifying that a record is of this type.
  258. /// See <https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4>
  259. const RR_TYPE: u16;
  260. /// Read at most `len` bytes from the given `Cursor`. This cursor travels
  261. /// throughout the complete data — by this point, we have read the entire
  262. /// response into a buffer.
  263. fn read(len: u16, c: &mut Cursor<&[u8]>) -> Result<Self, WireError>;
  264. }
  265. /// Helper macro to get the qtype number of a record type at compile-time.
  266. ///
  267. /// # Examples
  268. ///
  269. /// ```
  270. /// use dns::{qtype, record::MX};
  271. ///
  272. /// assert_eq!(15, qtype!(MX));
  273. /// ```
  274. #[macro_export]
  275. macro_rules! qtype {
  276. ($type:ty) => {
  277. <$type as $crate::Wire>::RR_TYPE
  278. }
  279. }
  280. /// Something that can go wrong deciphering a record.
  281. #[derive(PartialEq, Debug)]
  282. pub enum WireError {
  283. /// There was an IO error reading from the cursor.
  284. /// Almost all the time, this means that the buffer was too short.
  285. IO,
  286. // (io::Error is not PartialEq so we don’t propagate it)
  287. /// When the DNS standard requires records of this type to have a certain
  288. /// fixed length, but the response specified a different length.
  289. ///
  290. /// This error should be returned regardless of the _content_ of the
  291. /// record, whatever it is.
  292. WrongRecordLength {
  293. /// The expected size.
  294. expected: u16,
  295. /// The size that was actually received.
  296. got: u16,
  297. },
  298. /// When the length of this record as specified in the packet differs from
  299. /// the computed length, as determined by reading labels.
  300. ///
  301. /// There are two ways, in general, to read arbitrary-length data from a
  302. /// stream of bytes: length-prefixed (read the length, then read that many
  303. /// bytes) or sentinel-terminated (keep reading bytes until you read a
  304. /// certain value, usually zero). The DNS protocol uses both: each
  305. /// record’s size is specified up-front in the packet, but inside the
  306. /// record, there exist arbitrary-length strings that must be read until a
  307. /// zero is read, indicating there is no more string.
  308. ///
  309. /// Consider the case of a packet, with a specified length, containing a
  310. /// string of arbitrary length (such as the CNAME or TXT records). A DNS
  311. /// client has to deal with this in one of two ways:
  312. ///
  313. /// 1. Read exactly the specified length of bytes from the record, raising
  314. /// an error if the contents are too short or a string keeps going past
  315. /// the length (assume the length is correct but the contents are wrong).
  316. ///
  317. /// 2. Read as many bytes from the record as the string requests, raising
  318. /// an error if the number of bytes read at the end differs from the
  319. /// expected length of the record (assume the length is wrong but the
  320. /// contents are correct).
  321. ///
  322. /// Note that no matter which way is picked, the record will still be
  323. /// incorrect — it only impacts the parsing of records that occur after it
  324. /// in the packet. Knowing which method should be used requires knowing
  325. /// what caused the DNS packet to be erroneous, which we cannot know.
  326. ///
  327. /// dog picks the second way. If a record ends up reading more or fewer
  328. /// bytes than it is ‘supposed’ to, it will raise this error, but _after_
  329. /// having read a different number of bytes than the specified length.
  330. WrongLabelLength {
  331. /// The expected size.
  332. expected: u16,
  333. /// The size that was actually received.
  334. got: u16,
  335. },
  336. /// When the data contained a string containing a cycle of pointers.
  337. /// Contains the vector of indexes that was being checked.
  338. TooMuchRecursion(Vec<u16>),
  339. /// When the data contained a string with a pointer to an index outside of
  340. /// the packet. Contains the invalid index.
  341. OutOfBounds(u16),
  342. }
  343. impl From<io::Error> for WireError {
  344. fn from(ioe: io::Error) -> Self {
  345. error!("IO error -> {:?}", ioe);
  346. Self::IO
  347. }
  348. }
  349. #[cfg(test)]
  350. mod test {
  351. use super::*;
  352. use crate::record::{Record, A, SOA, OPT, UnknownQtype};
  353. use std::net::Ipv4Addr;
  354. #[test]
  355. fn complete_response() {
  356. // This is an artifical amalgam of DNS, not a real-world response!
  357. let buf = &[
  358. 0xce, 0xac, // transaction ID
  359. 0x81, 0x80, // flags (standard query, response, no error)
  360. 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, // counts (1, 1, 1, 2)
  361. // query:
  362. 0x05, 0x62, 0x73, 0x61, 0x67, 0x6f, 0x02, 0x6d, 0x65, 0x00, // name
  363. 0x00, 0x01, // type A
  364. 0x00, 0x01, // class IN
  365. // answer:
  366. 0xc0, 0x0c, // name (backreference)
  367. 0x00, 0x01, // type A
  368. 0x00, 0x01, // class IN
  369. 0x00, 0x00, 0x03, 0x77, // TTL
  370. 0x00, 0x04, // data length 4
  371. 0x8a, 0x44, 0x75, 0x5e, // IP address
  372. // authoritative:
  373. 0x00, // name
  374. 0x00, 0x06, // type SOA
  375. 0x00, 0x01, // class IN
  376. 0xFF, 0xFF, 0xFF, 0xFF, // TTL (maximum possible!)
  377. 0x00, 0x1B, // data length
  378. 0x01, 0x61, 0x00, // primary name server ("a")
  379. 0x02, 0x6d, 0x78, 0x00, // mailbox ("mx")
  380. 0x78, 0x68, 0x52, 0x2c, // serial number
  381. 0x00, 0x00, 0x07, 0x08, // refresh interval
  382. 0x00, 0x00, 0x03, 0x84, // retry interval
  383. 0x00, 0x09, 0x3a, 0x80, // expire limit
  384. 0x00, 0x01, 0x51, 0x80, // minimum TTL
  385. // additional 1:
  386. 0x00, // name
  387. 0x00, 0x99, // unknown type
  388. 0x00, 0x99, // unknown class
  389. 0x12, 0x34, 0x56, 0x78, // TTL
  390. 0x00, 0x04, // data length 4
  391. 0x12, 0x34, 0x56, 0x78, // data
  392. // additional 2:
  393. 0x00, // name
  394. 0x00, 0x29, // type OPT
  395. 0x02, 0x00, // UDP payload size
  396. 0x00, // higher bits
  397. 0x00, // EDNS(0) version
  398. 0x00, 0x00, // more flags
  399. 0x00, 0x00, // no data
  400. ];
  401. let response = Response {
  402. transaction_id: 0xceac,
  403. flags: Flags::standard_response(),
  404. queries: vec![
  405. Query {
  406. qname: "bsago.me.".into(),
  407. qclass: QClass::IN,
  408. qtype: qtype!(A),
  409. },
  410. ],
  411. answers: vec![
  412. Answer::Standard {
  413. qname: "bsago.me.".into(),
  414. qclass: QClass::IN,
  415. ttl: 887,
  416. record: Record::A(A {
  417. address: Ipv4Addr::new(138, 68, 117, 94),
  418. }),
  419. }
  420. ],
  421. authorities: vec![
  422. Answer::Standard {
  423. qname: "".into(),
  424. qclass: QClass::IN,
  425. ttl: 4294967295,
  426. record: Record::SOA(SOA {
  427. mname: "a.".into(),
  428. rname: "mx.".into(),
  429. serial: 2020102700,
  430. refresh_interval: 1800,
  431. retry_interval: 900,
  432. expire_limit: 604800,
  433. minimum_ttl: 86400,
  434. }),
  435. }
  436. ],
  437. additionals: vec![
  438. Answer::Standard {
  439. qname: "".into(),
  440. qclass: QClass::Other(153),
  441. ttl: 305419896,
  442. record: Record::Other {
  443. type_number: UnknownQtype::UnheardOf(153),
  444. bytes: vec![ 0x12, 0x34, 0x56, 0x78 ],
  445. },
  446. },
  447. Answer::Pseudo {
  448. qname: "".into(),
  449. opt: OPT {
  450. udp_payload_size: 512,
  451. higher_bits: 0,
  452. edns0_version: 0,
  453. flags: 0,
  454. data: vec![],
  455. },
  456. },
  457. ],
  458. };
  459. assert_eq!(Response::from_bytes(buf), Ok(response));
  460. }
  461. }