dns_parser/rdata/
mx.rs

1use {Name, Error};
2use byteorder::{BigEndian, ByteOrder};
3
4#[derive(Debug, Clone, Copy)]
5pub struct Record<'a> {
6    pub preference: u16,
7    pub exchange: Name<'a>,
8}
9
10impl<'a> super::Record<'a> for Record<'a> {
11
12    const TYPE: isize = 15;
13
14    fn parse(rdata: &'a [u8], original: &'a [u8]) -> super::RDataResult<'a> {
15        if rdata.len() < 3 {
16            return Err(Error::WrongRdataLength);
17        }
18        let record = Record {
19            preference: BigEndian::read_u16(&rdata[..2]),
20            exchange: Name::scan(&rdata[2..], original)?,
21        };
22        Ok(super::RData::MX(record))
23    }
24}
25
26#[cfg(test)]
27mod test {
28
29    use {Packet, Header};
30    use Opcode::*;
31    use ResponseCode::NoError;
32    use QueryType as QT;
33    use QueryClass as QC;
34    use Class as C;
35    use RData;
36    use super::*;
37
38    #[test]
39    fn parse_response() {
40        let response = b"\xe3\xe8\x81\x80\x00\x01\x00\x05\x00\x00\x00\x00\
41            \x05gmail\x03com\x00\x00\x0f\x00\x01\xc0\x0c\x00\x0f\x00\x01\
42            \x00\x00\x04|\x00\x1b\x00\x05\rgmail-smtp-in\x01l\x06google\xc0\
43            \x12\xc0\x0c\x00\x0f\x00\x01\x00\x00\x04|\x00\t\x00\
44            \n\x04alt1\xc0)\xc0\x0c\x00\x0f\x00\x01\x00\x00\x04|\
45            \x00\t\x00(\x04alt4\xc0)\xc0\x0c\x00\x0f\x00\x01\x00\
46            \x00\x04|\x00\t\x00\x14\x04alt2\xc0)\xc0\x0c\x00\x0f\
47            \x00\x01\x00\x00\x04|\x00\t\x00\x1e\x04alt3\xc0)";
48        let packet = Packet::parse(response).unwrap();
49        assert_eq!(packet.header, Header {
50            id: 58344,
51            query: false,
52            opcode: StandardQuery,
53            authoritative: false,
54            truncated: false,
55            recursion_desired: true,
56            recursion_available: true,
57            authenticated_data: false,
58            checking_disabled: false,
59            response_code: NoError,
60            questions: 1,
61            answers: 5,
62            nameservers: 0,
63            additional: 0,
64        });
65        assert_eq!(packet.questions.len(), 1);
66        assert_eq!(packet.questions[0].qtype, QT::MX);
67        assert_eq!(packet.questions[0].qclass, QC::IN);
68        assert_eq!(&packet.questions[0].qname.to_string()[..],
69        "gmail.com");
70        assert_eq!(packet.answers.len(), 5);
71        let items = vec![
72            ( 5, "gmail-smtp-in.l.google.com"),
73            (10, "alt1.gmail-smtp-in.l.google.com"),
74            (40, "alt4.gmail-smtp-in.l.google.com"),
75            (20, "alt2.gmail-smtp-in.l.google.com"),
76            (30, "alt3.gmail-smtp-in.l.google.com"),
77        ];
78        for i in 0..5 {
79            assert_eq!(&packet.answers[i].name.to_string()[..],
80            "gmail.com");
81            assert_eq!(packet.answers[i].cls, C::IN);
82            assert_eq!(packet.answers[i].ttl, 1148);
83            match *&packet.answers[i].data {
84                RData::MX( Record { preference, exchange }) => {
85                    assert_eq!(preference, items[i].0);
86                    assert_eq!(exchange.to_string(), (items[i].1).to_string());
87                }
88                ref x => panic!("Wrong rdata {:?}", x),
89            }
90        }
91    }
92}