dns_parser_revived/rdata/
soa.rs

1use crate::{Error, Name};
2use byteorder::{BigEndian, ByteOrder};
3
4/// The SOA (Start of Authority) record
5#[derive(Debug, Clone, Copy)]
6pub struct Record<'a> {
7    pub primary_ns: Name<'a>,
8    pub mailbox: Name<'a>,
9    pub serial: u32,
10    pub refresh: u32,
11    pub retry: u32,
12    pub expire: u32,
13    pub minimum_ttl: u32,
14}
15
16impl<'a> super::Record<'a> for Record<'a> {
17    const TYPE: isize = 6;
18
19    fn parse(rdata: &'a [u8], original: &'a [u8]) -> super::RDataResult<'a> {
20        let mut pos = 0;
21        let primary_name_server = Name::scan(rdata, original)?;
22        pos += primary_name_server.byte_len();
23        let mailbox = Name::scan(&rdata[pos..], original)?;
24        pos += mailbox.byte_len();
25        if rdata[pos..].len() < 20 {
26            return Err(Error::WrongRdataLength);
27        }
28        let record = Record {
29            primary_ns: primary_name_server,
30            mailbox,
31            serial: BigEndian::read_u32(&rdata[pos..(pos + 4)]),
32            refresh: BigEndian::read_u32(&rdata[(pos + 4)..(pos + 8)]),
33            retry: BigEndian::read_u32(&rdata[(pos + 8)..(pos + 12)]),
34            expire: BigEndian::read_u32(&rdata[(pos + 12)..(pos + 16)]),
35            minimum_ttl: BigEndian::read_u32(&rdata[(pos + 16)..(pos + 20)]),
36        };
37        Ok(super::RData::SOA(record))
38    }
39}
40
41#[cfg(test)]
42mod test {
43
44    use crate::Class as C;
45    use crate::Opcode::*;
46    use crate::QueryClass as QC;
47    use crate::QueryType as QT;
48    use crate::RData;
49    use crate::ResponseCode::NameError;
50    use crate::{Header, Packet};
51
52    #[test]
53    fn parse_response() {
54        let response = b"\x9f\xc5\x85\x83\x00\x01\x00\x00\x00\x01\x00\x00\
55                          \x0edlkfjkdjdslfkj\x07youtube\x03com\x00\x00\x01\x00\x01\
56                          \xc0\x1b\x00\x06\x00\x01\x00\x00\x2a\x30\x00\x1e\xc0\x1b\
57                          \x05admin\xc0\x1b\x77\xed\x2a\x73\x00\x00\x51\x80\x00\x00\
58                          \x0e\x10\x00\x00\x3a\x80\x00\x00\x2a\x30";
59        let packet = Packet::parse(response).unwrap();
60        assert_eq!(
61            packet.header,
62            Header {
63                id: 40901,
64                query: false,
65                opcode: StandardQuery,
66                authoritative: true,
67                truncated: false,
68                recursion_desired: true,
69                recursion_available: true,
70                authenticated_data: false,
71                checking_disabled: false,
72                response_code: NameError,
73                questions: 1,
74                answers: 0,
75                nameservers: 1,
76                additional: 0,
77            }
78        );
79        assert_eq!(packet.questions.len(), 1);
80        assert_eq!(packet.questions[0].qtype, QT::A);
81        assert_eq!(packet.questions[0].qclass, QC::IN);
82        assert_eq!(
83            &packet.questions[0].qname.to_string()[..],
84            "dlkfjkdjdslfkj.youtube.com"
85        );
86        assert_eq!(packet.answers.len(), 0);
87
88        assert_eq!(packet.nameservers.len(), 1);
89        assert_eq!(&packet.nameservers[0].name.to_string()[..], "youtube.com");
90        assert_eq!(packet.nameservers[0].cls, C::IN);
91        assert!(!packet.nameservers[0].multicast_unique);
92        assert_eq!(packet.nameservers[0].ttl, 10800);
93        match packet.nameservers[0].data {
94            RData::SOA(ref soa_rec) => {
95                assert_eq!(&soa_rec.primary_ns.to_string()[..], "youtube.com");
96                assert_eq!(&soa_rec.mailbox.to_string()[..], "admin.youtube.com");
97                assert_eq!(soa_rec.serial, 2012031603);
98                assert_eq!(soa_rec.refresh, 20864);
99                assert_eq!(soa_rec.retry, 3600);
100                assert_eq!(soa_rec.expire, 14976);
101                assert_eq!(soa_rec.minimum_ttl, 10800);
102            }
103            ref x => panic!("Wrong rdata {:?}", x),
104        }
105    }
106}