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