dns.rs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. #![allow(dead_code)]
  2. use bitflags::bitflags;
  3. use byteorder::{ByteOrder, NetworkEndian};
  4. use core::iter;
  5. use core::iter::Iterator;
  6. use super::{Error, Result};
  7. #[cfg(feature = "proto-ipv4")]
  8. use crate::wire::Ipv4Address;
  9. #[cfg(feature = "proto-ipv6")]
  10. use crate::wire::Ipv6Address;
  11. enum_with_unknown! {
  12. /// DNS OpCodes
  13. pub enum Opcode(u8) {
  14. Query = 0x00,
  15. Status = 0x01,
  16. }
  17. }
  18. enum_with_unknown! {
  19. /// DNS OpCodes
  20. pub enum Rcode(u8) {
  21. NoError = 0x00,
  22. FormErr = 0x01,
  23. ServFail = 0x02,
  24. NXDomain = 0x03,
  25. NotImp = 0x04,
  26. Refused = 0x05,
  27. YXDomain = 0x06,
  28. YXRRSet = 0x07,
  29. NXRRSet = 0x08,
  30. NotAuth = 0x09,
  31. NotZone = 0x0a,
  32. }
  33. }
  34. enum_with_unknown! {
  35. /// DNS record types
  36. pub enum Type(u16) {
  37. A = 0x0001,
  38. Ns = 0x0002,
  39. Cname = 0x0005,
  40. Soa = 0x0006,
  41. Aaaa = 0x001c,
  42. }
  43. }
  44. bitflags! {
  45. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  46. pub struct Flags: u16 {
  47. const RESPONSE = 0b1000_0000_0000_0000;
  48. const AUTHORITATIVE = 0b0000_0100_0000_0000;
  49. const TRUNCATED = 0b0000_0010_0000_0000;
  50. const RECURSION_DESIRED = 0b0000_0001_0000_0000;
  51. const RECURSION_AVAILABLE = 0b0000_0000_1000_0000;
  52. const AUTHENTIC_DATA = 0b0000_0000_0010_0000;
  53. const CHECK_DISABLED = 0b0000_0000_0001_0000;
  54. }
  55. }
  56. mod field {
  57. use crate::wire::field::*;
  58. pub const ID: Field = 0..2;
  59. pub const FLAGS: Field = 2..4;
  60. pub const QDCOUNT: Field = 4..6;
  61. pub const ANCOUNT: Field = 6..8;
  62. pub const NSCOUNT: Field = 8..10;
  63. pub const ARCOUNT: Field = 10..12;
  64. pub const HEADER_END: usize = 12;
  65. }
  66. // DNS class IN (Internet)
  67. const CLASS_IN: u16 = 1;
  68. /// A read/write wrapper around a DNS packet buffer.
  69. #[derive(Debug, PartialEq, Eq)]
  70. pub struct Packet<T: AsRef<[u8]>> {
  71. buffer: T,
  72. }
  73. impl<T: AsRef<[u8]>> Packet<T> {
  74. /// Imbue a raw octet buffer with DNS packet structure.
  75. pub const fn new_unchecked(buffer: T) -> Packet<T> {
  76. Packet { buffer }
  77. }
  78. /// Shorthand for a combination of [new_unchecked] and [check_len].
  79. ///
  80. /// [new_unchecked]: #method.new_unchecked
  81. /// [check_len]: #method.check_len
  82. pub fn new_checked(buffer: T) -> Result<Packet<T>> {
  83. let packet = Self::new_unchecked(buffer);
  84. packet.check_len()?;
  85. Ok(packet)
  86. }
  87. /// Ensure that no accessor method will panic if called.
  88. /// Returns `Err(Error)` if the buffer is smaller than
  89. /// the header length.
  90. pub fn check_len(&self) -> Result<()> {
  91. let len = self.buffer.as_ref().len();
  92. if len < field::HEADER_END {
  93. Err(Error)
  94. } else {
  95. Ok(())
  96. }
  97. }
  98. /// Consume the packet, returning the underlying buffer.
  99. pub fn into_inner(self) -> T {
  100. self.buffer
  101. }
  102. pub fn payload(&self) -> &[u8] {
  103. &self.buffer.as_ref()[field::HEADER_END..]
  104. }
  105. pub fn transaction_id(&self) -> u16 {
  106. let field = &self.buffer.as_ref()[field::ID];
  107. NetworkEndian::read_u16(field)
  108. }
  109. pub fn flags(&self) -> Flags {
  110. let field = &self.buffer.as_ref()[field::FLAGS];
  111. Flags::from_bits_truncate(NetworkEndian::read_u16(field))
  112. }
  113. pub fn opcode(&self) -> Opcode {
  114. let field = &self.buffer.as_ref()[field::FLAGS];
  115. let flags = NetworkEndian::read_u16(field);
  116. Opcode::from((flags >> 11 & 0xF) as u8)
  117. }
  118. pub fn rcode(&self) -> Rcode {
  119. let field = &self.buffer.as_ref()[field::FLAGS];
  120. let flags = NetworkEndian::read_u16(field);
  121. Rcode::from((flags & 0xF) as u8)
  122. }
  123. pub fn question_count(&self) -> u16 {
  124. let field = &self.buffer.as_ref()[field::QDCOUNT];
  125. NetworkEndian::read_u16(field)
  126. }
  127. pub fn answer_record_count(&self) -> u16 {
  128. let field = &self.buffer.as_ref()[field::ANCOUNT];
  129. NetworkEndian::read_u16(field)
  130. }
  131. pub fn authority_record_count(&self) -> u16 {
  132. let field = &self.buffer.as_ref()[field::NSCOUNT];
  133. NetworkEndian::read_u16(field)
  134. }
  135. pub fn additional_record_count(&self) -> u16 {
  136. let field = &self.buffer.as_ref()[field::ARCOUNT];
  137. NetworkEndian::read_u16(field)
  138. }
  139. /// Parse part of a name from `bytes`, following pointers if any.
  140. pub fn parse_name<'a>(&'a self, mut bytes: &'a [u8]) -> impl Iterator<Item = Result<&'a [u8]>> {
  141. let mut packet = self.buffer.as_ref();
  142. iter::from_fn(move || loop {
  143. if bytes.is_empty() {
  144. return Some(Err(Error));
  145. }
  146. match bytes[0] {
  147. 0x00 => return None,
  148. x if x & 0xC0 == 0x00 => {
  149. let len = (x & 0x3F) as usize;
  150. if bytes.len() < 1 + len {
  151. return Some(Err(Error));
  152. }
  153. let label = &bytes[1..1 + len];
  154. bytes = &bytes[1 + len..];
  155. return Some(Ok(label));
  156. }
  157. x if x & 0xC0 == 0xC0 => {
  158. if bytes.len() < 2 {
  159. return Some(Err(Error));
  160. }
  161. let y = bytes[1];
  162. let ptr = ((x & 0x3F) as usize) << 8 | (y as usize);
  163. if packet.len() <= ptr {
  164. return Some(Err(Error));
  165. }
  166. // RFC1035 says: "In this scheme, an entire domain name or a list of labels at
  167. // the end of a domain name is replaced with a pointer to a ***prior*** occurrence
  168. // of the same name.
  169. //
  170. // Is it unclear if this means the pointer MUST point backwards in the packet or not. Either way,
  171. // pointers that don't point backwards are never seen in the fields, so use this to check that
  172. // there are no pointer loops.
  173. // Split packet into parts before and after `ptr`.
  174. // parse the part after, keep only the part before in `packet`. This ensure we never
  175. // parse the same byte twice, therefore eliminating pointer loops.
  176. bytes = &packet[ptr..];
  177. packet = &packet[..ptr];
  178. }
  179. _ => return Some(Err(Error)),
  180. }
  181. })
  182. }
  183. }
  184. impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
  185. pub fn payload_mut(&mut self) -> &mut [u8] {
  186. let data = self.buffer.as_mut();
  187. &mut data[field::HEADER_END..]
  188. }
  189. pub fn set_transaction_id(&mut self, val: u16) {
  190. let field = &mut self.buffer.as_mut()[field::ID];
  191. NetworkEndian::write_u16(field, val)
  192. }
  193. pub fn set_flags(&mut self, val: Flags) {
  194. let field = &mut self.buffer.as_mut()[field::FLAGS];
  195. let mask = Flags::all().bits;
  196. let old = NetworkEndian::read_u16(field);
  197. NetworkEndian::write_u16(field, (old & !mask) | val.bits());
  198. }
  199. pub fn set_opcode(&mut self, val: Opcode) {
  200. let field = &mut self.buffer.as_mut()[field::FLAGS];
  201. let mask = 0x3800;
  202. let val: u8 = val.into();
  203. let val = (val as u16) << 11;
  204. let old = NetworkEndian::read_u16(field);
  205. NetworkEndian::write_u16(field, (old & !mask) | val);
  206. }
  207. pub fn set_question_count(&mut self, val: u16) {
  208. let field = &mut self.buffer.as_mut()[field::QDCOUNT];
  209. NetworkEndian::write_u16(field, val)
  210. }
  211. pub fn set_answer_record_count(&mut self, val: u16) {
  212. let field = &mut self.buffer.as_mut()[field::ANCOUNT];
  213. NetworkEndian::write_u16(field, val)
  214. }
  215. pub fn set_authority_record_count(&mut self, val: u16) {
  216. let field = &mut self.buffer.as_mut()[field::NSCOUNT];
  217. NetworkEndian::write_u16(field, val)
  218. }
  219. pub fn set_additional_record_count(&mut self, val: u16) {
  220. let field = &mut self.buffer.as_mut()[field::ARCOUNT];
  221. NetworkEndian::write_u16(field, val)
  222. }
  223. }
  224. /// Parse part of a name from `bytes`, not following pointers.
  225. /// Returns the unused part of `bytes`, and the pointer offset if the sequence ends with a pointer.
  226. fn parse_name_part<'a>(
  227. mut bytes: &'a [u8],
  228. mut f: impl FnMut(&'a [u8]),
  229. ) -> Result<(&'a [u8], Option<usize>)> {
  230. loop {
  231. let x = *bytes.first().ok_or(Error)?;
  232. bytes = &bytes[1..];
  233. match x {
  234. 0x00 => return Ok((bytes, None)),
  235. x if x & 0xC0 == 0x00 => {
  236. let len = (x & 0x3F) as usize;
  237. let label = bytes.get(..len).ok_or(Error)?;
  238. bytes = &bytes[len..];
  239. f(label);
  240. }
  241. x if x & 0xC0 == 0xC0 => {
  242. let y = *bytes.first().ok_or(Error)?;
  243. bytes = &bytes[1..];
  244. let ptr = ((x & 0x3F) as usize) << 8 | (y as usize);
  245. return Ok((bytes, Some(ptr)));
  246. }
  247. _ => return Err(Error),
  248. }
  249. }
  250. }
  251. #[derive(Debug, PartialEq, Eq)]
  252. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  253. pub struct Question<'a> {
  254. pub name: &'a [u8],
  255. pub type_: Type,
  256. }
  257. impl<'a> Question<'a> {
  258. pub fn parse(buffer: &'a [u8]) -> Result<(&'a [u8], Question<'a>)> {
  259. let (rest, _) = parse_name_part(buffer, |_| ())?;
  260. let name = &buffer[..buffer.len() - rest.len()];
  261. if rest.len() < 4 {
  262. return Err(Error);
  263. }
  264. let type_ = NetworkEndian::read_u16(&rest[0..2]).into();
  265. let class = NetworkEndian::read_u16(&rest[2..4]);
  266. let rest = &rest[4..];
  267. if class != CLASS_IN {
  268. return Err(Error);
  269. }
  270. Ok((rest, Question { name, type_ }))
  271. }
  272. /// Return the length of a packet that will be emitted from this high-level representation.
  273. pub const fn buffer_len(&self) -> usize {
  274. self.name.len() + 4
  275. }
  276. /// Emit a high-level representation into a DNS packet.
  277. pub fn emit(&self, packet: &mut [u8]) {
  278. packet[..self.name.len()].copy_from_slice(self.name);
  279. let rest = &mut packet[self.name.len()..];
  280. NetworkEndian::write_u16(&mut rest[0..2], self.type_.into());
  281. NetworkEndian::write_u16(&mut rest[2..4], CLASS_IN);
  282. }
  283. }
  284. #[derive(Debug, PartialEq, Eq)]
  285. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  286. pub struct Record<'a> {
  287. pub name: &'a [u8],
  288. pub ttl: u32,
  289. pub data: RecordData<'a>,
  290. }
  291. impl<'a> RecordData<'a> {
  292. pub fn parse(type_: Type, data: &'a [u8]) -> Result<RecordData<'a>> {
  293. match type_ {
  294. #[cfg(feature = "proto-ipv4")]
  295. Type::A => {
  296. if data.len() != 4 {
  297. return Err(Error);
  298. }
  299. Ok(RecordData::A(Ipv4Address::from_bytes(data)))
  300. }
  301. #[cfg(feature = "proto-ipv6")]
  302. Type::Aaaa => {
  303. if data.len() != 16 {
  304. return Err(Error);
  305. }
  306. Ok(RecordData::Aaaa(Ipv6Address::from_bytes(data)))
  307. }
  308. Type::Cname => Ok(RecordData::Cname(data)),
  309. x => Ok(RecordData::Other(x, data)),
  310. }
  311. }
  312. }
  313. #[derive(Debug, PartialEq, Eq)]
  314. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  315. pub enum RecordData<'a> {
  316. #[cfg(feature = "proto-ipv4")]
  317. A(Ipv4Address),
  318. #[cfg(feature = "proto-ipv6")]
  319. Aaaa(Ipv6Address),
  320. Cname(&'a [u8]),
  321. Other(Type, &'a [u8]),
  322. }
  323. impl<'a> Record<'a> {
  324. pub fn parse(buffer: &'a [u8]) -> Result<(&'a [u8], Record<'a>)> {
  325. let (rest, _) = parse_name_part(buffer, |_| ())?;
  326. let name = &buffer[..buffer.len() - rest.len()];
  327. if rest.len() < 10 {
  328. return Err(Error);
  329. }
  330. let type_ = NetworkEndian::read_u16(&rest[0..2]).into();
  331. let class = NetworkEndian::read_u16(&rest[2..4]);
  332. let ttl = NetworkEndian::read_u32(&rest[4..8]);
  333. let len = NetworkEndian::read_u16(&rest[8..10]) as usize;
  334. let rest = &rest[10..];
  335. if class != CLASS_IN {
  336. return Err(Error);
  337. }
  338. let data = rest.get(..len).ok_or(Error)?;
  339. let rest = &rest[len..];
  340. Ok((
  341. rest,
  342. Record {
  343. name,
  344. ttl,
  345. data: RecordData::parse(type_, data)?,
  346. },
  347. ))
  348. }
  349. }
  350. /// High-level DNS packet representation.
  351. ///
  352. /// Currently only supports query packets.
  353. #[derive(Debug, PartialEq, Eq)]
  354. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  355. pub struct Repr<'a> {
  356. pub transaction_id: u16,
  357. pub opcode: Opcode,
  358. pub flags: Flags,
  359. pub question: Question<'a>,
  360. }
  361. impl<'a> Repr<'a> {
  362. /// Return the length of a packet that will be emitted from this high-level representation.
  363. pub const fn buffer_len(&self) -> usize {
  364. field::HEADER_END + self.question.buffer_len()
  365. }
  366. /// Emit a high-level representation into a DNS packet.
  367. pub fn emit<T: ?Sized>(&self, packet: &mut Packet<&mut T>)
  368. where
  369. T: AsRef<[u8]> + AsMut<[u8]>,
  370. {
  371. packet.set_transaction_id(self.transaction_id);
  372. packet.set_flags(self.flags);
  373. packet.set_opcode(self.opcode);
  374. packet.set_question_count(1);
  375. packet.set_answer_record_count(0);
  376. packet.set_authority_record_count(0);
  377. packet.set_additional_record_count(0);
  378. self.question.emit(packet.payload_mut())
  379. }
  380. }
  381. #[cfg(feature = "proto-ipv4")] // tests assume ipv4
  382. #[cfg(test)]
  383. mod test {
  384. use super::*;
  385. use std::vec::Vec;
  386. #[test]
  387. fn test_parse_name() {
  388. let bytes = &[
  389. 0x78, 0x6c, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77,
  390. 0x77, 0x77, 0x08, 0x66, 0x61, 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x03, 0x63, 0x6f,
  391. 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00,
  392. 0x05, 0xf3, 0x00, 0x11, 0x09, 0x73, 0x74, 0x61, 0x72, 0x2d, 0x6d, 0x69, 0x6e, 0x69,
  393. 0x04, 0x63, 0x31, 0x30, 0x72, 0xc0, 0x10, 0xc0, 0x2e, 0x00, 0x01, 0x00, 0x01, 0x00,
  394. 0x00, 0x00, 0x05, 0x00, 0x04, 0x1f, 0x0d, 0x53, 0x24,
  395. ];
  396. let packet = Packet::new_unchecked(bytes);
  397. let name_vec = |bytes| {
  398. let mut v = Vec::new();
  399. packet
  400. .parse_name(bytes)
  401. .try_for_each(|label| label.map(|label| v.push(label)))
  402. .map(|_| v)
  403. };
  404. //assert_eq!(parse_name_len(bytes, 0x0c), Ok(18));
  405. assert_eq!(
  406. name_vec(&bytes[0x0c..]),
  407. Ok(vec![&b"www"[..], &b"facebook"[..], &b"com"[..]])
  408. );
  409. //assert_eq!(parse_name_len(bytes, 0x22), Ok(2));
  410. assert_eq!(
  411. name_vec(&bytes[0x22..]),
  412. Ok(vec![&b"www"[..], &b"facebook"[..], &b"com"[..]])
  413. );
  414. //assert_eq!(parse_name_len(bytes, 0x2e), Ok(17));
  415. assert_eq!(
  416. name_vec(&bytes[0x2e..]),
  417. Ok(vec![
  418. &b"star-mini"[..],
  419. &b"c10r"[..],
  420. &b"facebook"[..],
  421. &b"com"[..]
  422. ])
  423. );
  424. //assert_eq!(parse_name_len(bytes, 0x3f), Ok(2));
  425. assert_eq!(
  426. name_vec(&bytes[0x3f..]),
  427. Ok(vec![
  428. &b"star-mini"[..],
  429. &b"c10r"[..],
  430. &b"facebook"[..],
  431. &b"com"[..]
  432. ])
  433. );
  434. }
  435. struct Parsed<'a> {
  436. packet: Packet<&'a [u8]>,
  437. questions: Vec<Question<'a>>,
  438. answers: Vec<Record<'a>>,
  439. authorities: Vec<Record<'a>>,
  440. additionals: Vec<Record<'a>>,
  441. }
  442. impl<'a> Parsed<'a> {
  443. fn parse(bytes: &'a [u8]) -> Result<Self> {
  444. let packet = Packet::new_unchecked(bytes);
  445. let mut questions = Vec::new();
  446. let mut answers = Vec::new();
  447. let mut authorities = Vec::new();
  448. let mut additionals = Vec::new();
  449. let mut payload = &bytes[12..];
  450. for _ in 0..packet.question_count() {
  451. let (p, r) = Question::parse(payload)?;
  452. questions.push(r);
  453. payload = p;
  454. }
  455. for _ in 0..packet.answer_record_count() {
  456. let (p, r) = Record::parse(payload)?;
  457. answers.push(r);
  458. payload = p;
  459. }
  460. for _ in 0..packet.authority_record_count() {
  461. let (p, r) = Record::parse(payload)?;
  462. authorities.push(r);
  463. payload = p;
  464. }
  465. for _ in 0..packet.additional_record_count() {
  466. let (p, r) = Record::parse(payload)?;
  467. additionals.push(r);
  468. payload = p;
  469. }
  470. // Check that there are no bytes left
  471. assert_eq!(payload.len(), 0);
  472. Ok(Parsed {
  473. packet,
  474. questions,
  475. answers,
  476. authorities,
  477. additionals,
  478. })
  479. }
  480. }
  481. #[test]
  482. fn test_parse_request() {
  483. let p = Parsed::parse(&[
  484. 0x51, 0x84, 0x01, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67,
  485. 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
  486. ])
  487. .unwrap();
  488. assert_eq!(p.packet.transaction_id(), 0x5184);
  489. assert_eq!(
  490. p.packet.flags(),
  491. Flags::RECURSION_DESIRED | Flags::AUTHENTIC_DATA
  492. );
  493. assert_eq!(p.packet.opcode(), Opcode::Query);
  494. assert_eq!(p.packet.question_count(), 1);
  495. assert_eq!(p.packet.answer_record_count(), 0);
  496. assert_eq!(p.packet.authority_record_count(), 0);
  497. assert_eq!(p.packet.additional_record_count(), 0);
  498. assert_eq!(p.questions.len(), 1);
  499. assert_eq!(
  500. p.questions[0].name,
  501. &[0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00]
  502. );
  503. assert_eq!(p.questions[0].type_, Type::A);
  504. assert_eq!(p.answers.len(), 0);
  505. assert_eq!(p.authorities.len(), 0);
  506. assert_eq!(p.additionals.len(), 0);
  507. }
  508. #[test]
  509. fn test_parse_response() {
  510. let p = Parsed::parse(&[
  511. 0x51, 0x84, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67,
  512. 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
  513. 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xca, 0x00, 0x04, 0xac, 0xd9,
  514. 0xa8, 0xae,
  515. ])
  516. .unwrap();
  517. assert_eq!(p.packet.transaction_id(), 0x5184);
  518. assert_eq!(
  519. p.packet.flags(),
  520. Flags::RESPONSE | Flags::RECURSION_DESIRED | Flags::RECURSION_AVAILABLE
  521. );
  522. assert_eq!(p.packet.opcode(), Opcode::Query);
  523. assert_eq!(p.packet.rcode(), Rcode::NoError);
  524. assert_eq!(p.packet.question_count(), 1);
  525. assert_eq!(p.packet.answer_record_count(), 1);
  526. assert_eq!(p.packet.authority_record_count(), 0);
  527. assert_eq!(p.packet.additional_record_count(), 0);
  528. assert_eq!(
  529. p.questions[0].name,
  530. &[0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00]
  531. );
  532. assert_eq!(p.questions[0].type_, Type::A);
  533. assert_eq!(p.answers[0].name, &[0xc0, 0x0c]);
  534. assert_eq!(p.answers[0].ttl, 202);
  535. assert_eq!(
  536. p.answers[0].data,
  537. RecordData::A(Ipv4Address::new(0xac, 0xd9, 0xa8, 0xae))
  538. );
  539. }
  540. #[test]
  541. fn test_parse_response_multiple_a() {
  542. let p = Parsed::parse(&[
  543. 0x4b, 0x9e, 0x81, 0x80, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x72,
  544. 0x75, 0x73, 0x74, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00,
  545. 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00,
  546. 0x04, 0x0d, 0xe0, 0x77, 0x35, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
  547. 0x09, 0x00, 0x04, 0x0d, 0xe0, 0x77, 0x28, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
  548. 0x00, 0x00, 0x09, 0x00, 0x04, 0x0d, 0xe0, 0x77, 0x43, 0xc0, 0x0c, 0x00, 0x01, 0x00,
  549. 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x04, 0x0d, 0xe0, 0x77, 0x62,
  550. ])
  551. .unwrap();
  552. assert_eq!(p.packet.transaction_id(), 0x4b9e);
  553. assert_eq!(
  554. p.packet.flags(),
  555. Flags::RESPONSE | Flags::RECURSION_DESIRED | Flags::RECURSION_AVAILABLE
  556. );
  557. assert_eq!(p.packet.opcode(), Opcode::Query);
  558. assert_eq!(p.packet.rcode(), Rcode::NoError);
  559. assert_eq!(p.packet.question_count(), 1);
  560. assert_eq!(p.packet.answer_record_count(), 4);
  561. assert_eq!(p.packet.authority_record_count(), 0);
  562. assert_eq!(p.packet.additional_record_count(), 0);
  563. assert_eq!(
  564. p.questions[0].name,
  565. &[
  566. 0x09, 0x72, 0x75, 0x73, 0x74, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x03, 0x6f, 0x72, 0x67,
  567. 0x00
  568. ]
  569. );
  570. assert_eq!(p.questions[0].type_, Type::A);
  571. assert_eq!(p.answers[0].name, &[0xc0, 0x0c]);
  572. assert_eq!(p.answers[0].ttl, 9);
  573. assert_eq!(
  574. p.answers[0].data,
  575. RecordData::A(Ipv4Address::new(0x0d, 0xe0, 0x77, 0x35))
  576. );
  577. assert_eq!(p.answers[1].name, &[0xc0, 0x0c]);
  578. assert_eq!(p.answers[1].ttl, 9);
  579. assert_eq!(
  580. p.answers[1].data,
  581. RecordData::A(Ipv4Address::new(0x0d, 0xe0, 0x77, 0x28))
  582. );
  583. assert_eq!(p.answers[2].name, &[0xc0, 0x0c]);
  584. assert_eq!(p.answers[2].ttl, 9);
  585. assert_eq!(
  586. p.answers[2].data,
  587. RecordData::A(Ipv4Address::new(0x0d, 0xe0, 0x77, 0x43))
  588. );
  589. assert_eq!(p.answers[3].name, &[0xc0, 0x0c]);
  590. assert_eq!(p.answers[3].ttl, 9);
  591. assert_eq!(
  592. p.answers[3].data,
  593. RecordData::A(Ipv4Address::new(0x0d, 0xe0, 0x77, 0x62))
  594. );
  595. }
  596. #[test]
  597. fn test_parse_response_cname() {
  598. let p = Parsed::parse(&[
  599. 0x78, 0x6c, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77,
  600. 0x77, 0x77, 0x08, 0x66, 0x61, 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x03, 0x63, 0x6f,
  601. 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00,
  602. 0x05, 0xf3, 0x00, 0x11, 0x09, 0x73, 0x74, 0x61, 0x72, 0x2d, 0x6d, 0x69, 0x6e, 0x69,
  603. 0x04, 0x63, 0x31, 0x30, 0x72, 0xc0, 0x10, 0xc0, 0x2e, 0x00, 0x01, 0x00, 0x01, 0x00,
  604. 0x00, 0x00, 0x05, 0x00, 0x04, 0x1f, 0x0d, 0x53, 0x24,
  605. ])
  606. .unwrap();
  607. assert_eq!(p.packet.transaction_id(), 0x786c);
  608. assert_eq!(
  609. p.packet.flags(),
  610. Flags::RESPONSE | Flags::RECURSION_DESIRED | Flags::RECURSION_AVAILABLE
  611. );
  612. assert_eq!(p.packet.opcode(), Opcode::Query);
  613. assert_eq!(p.packet.rcode(), Rcode::NoError);
  614. assert_eq!(p.packet.question_count(), 1);
  615. assert_eq!(p.packet.answer_record_count(), 2);
  616. assert_eq!(p.packet.authority_record_count(), 0);
  617. assert_eq!(p.packet.additional_record_count(), 0);
  618. assert_eq!(
  619. p.questions[0].name,
  620. &[
  621. 0x03, 0x77, 0x77, 0x77, 0x08, 0x66, 0x61, 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x03,
  622. 0x63, 0x6f, 0x6d, 0x00
  623. ]
  624. );
  625. assert_eq!(p.questions[0].type_, Type::A);
  626. // cname
  627. assert_eq!(p.answers[0].name, &[0xc0, 0x0c]);
  628. assert_eq!(p.answers[0].ttl, 1523);
  629. assert_eq!(
  630. p.answers[0].data,
  631. RecordData::Cname(&[
  632. 0x09, 0x73, 0x74, 0x61, 0x72, 0x2d, 0x6d, 0x69, 0x6e, 0x69, 0x04, 0x63, 0x31, 0x30,
  633. 0x72, 0xc0, 0x10
  634. ])
  635. );
  636. // a
  637. assert_eq!(p.answers[1].name, &[0xc0, 0x2e]);
  638. assert_eq!(p.answers[1].ttl, 5);
  639. assert_eq!(
  640. p.answers[1].data,
  641. RecordData::A(Ipv4Address::new(0x1f, 0x0d, 0x53, 0x24))
  642. );
  643. }
  644. #[test]
  645. fn test_parse_response_nxdomain() {
  646. let p = Parsed::parse(&[
  647. 0x63, 0xc4, 0x81, 0x83, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x13, 0x61,
  648. 0x68, 0x61, 0x73, 0x64, 0x67, 0x68, 0x6c, 0x61, 0x6b, 0x73, 0x6a, 0x68, 0x62, 0x61,
  649. 0x61, 0x73, 0x6c, 0x64, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
  650. 0x20, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x03, 0x83, 0x00, 0x3d, 0x01, 0x61, 0x0c,
  651. 0x67, 0x74, 0x6c, 0x64, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x03, 0x6e,
  652. 0x65, 0x74, 0x00, 0x05, 0x6e, 0x73, 0x74, 0x6c, 0x64, 0x0c, 0x76, 0x65, 0x72, 0x69,
  653. 0x73, 0x69, 0x67, 0x6e, 0x2d, 0x67, 0x72, 0x73, 0xc0, 0x20, 0x5f, 0xce, 0x8b, 0x85,
  654. 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x03, 0x84, 0x00, 0x09, 0x3a, 0x80, 0x00, 0x01,
  655. 0x51, 0x80,
  656. ])
  657. .unwrap();
  658. assert_eq!(p.packet.transaction_id(), 0x63c4);
  659. assert_eq!(
  660. p.packet.flags(),
  661. Flags::RESPONSE | Flags::RECURSION_DESIRED | Flags::RECURSION_AVAILABLE
  662. );
  663. assert_eq!(p.packet.opcode(), Opcode::Query);
  664. assert_eq!(p.packet.rcode(), Rcode::NXDomain);
  665. assert_eq!(p.packet.question_count(), 1);
  666. assert_eq!(p.packet.answer_record_count(), 0);
  667. assert_eq!(p.packet.authority_record_count(), 1);
  668. assert_eq!(p.packet.additional_record_count(), 0);
  669. assert_eq!(p.questions[0].type_, Type::A);
  670. // SOA authority
  671. assert_eq!(p.authorities[0].name, &[0xc0, 0x20]); // com.
  672. assert_eq!(p.authorities[0].ttl, 899);
  673. assert!(matches!(
  674. p.authorities[0].data,
  675. RecordData::Other(Type::Soa, _)
  676. ));
  677. }
  678. #[test]
  679. fn test_emit() {
  680. let name = &[
  681. 0x09, 0x72, 0x75, 0x73, 0x74, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x03, 0x6f, 0x72, 0x67,
  682. 0x00,
  683. ];
  684. let repr = Repr {
  685. transaction_id: 0x1234,
  686. flags: Flags::RECURSION_DESIRED,
  687. opcode: Opcode::Query,
  688. question: Question {
  689. name,
  690. type_: Type::A,
  691. },
  692. };
  693. let mut buf = Vec::new();
  694. buf.resize(repr.buffer_len(), 0);
  695. repr.emit(&mut Packet::new_unchecked(&mut buf));
  696. let want = &[
  697. 0x12, 0x34, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x72,
  698. 0x75, 0x73, 0x74, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00,
  699. 0x01, 0x00, 0x01,
  700. ];
  701. assert_eq!(&buf, want);
  702. }
  703. }