dns_parser/
enums.rs

1use {Error};
2use rdata::Record;
3use rdata::*;
4
5/// The TYPE value according to RFC 1035
6///
7/// All "EXPERIMENTAL" markers here are from the RFC
8#[derive(Debug, PartialEq, Eq, Clone, Copy)]
9pub enum Type {
10    /// a host addresss
11    A = a::Record::TYPE,
12    /// an authoritative name server
13    NS = ns::Record::TYPE,
14    /// a mail forwarder (Obsolete - use MX)
15    MF = mf::Record::TYPE,
16    /// the canonical name for an alias
17    CNAME = cname::Record::TYPE,
18    /// marks the start of a zone of authority
19    SOA = soa::Record::TYPE,
20    /// a mailbox domain name (EXPERIMENTAL)
21    MB = mb::Record::TYPE,
22    /// a mail group member (EXPERIMENTAL)
23    MG = mg::Record::TYPE,
24    /// a mail rename domain name (EXPERIMENTAL)
25    MR = mr::Record::TYPE,
26    /// a null RR (EXPERIMENTAL)
27    NULL = null::Record::TYPE,
28    /// a well known service description
29    WKS = wks::Record::TYPE,
30    /// a domain name pointer
31    PTR = ptr::Record::TYPE,
32    /// host information
33    HINFO = hinfo::Record::TYPE,
34    /// mailbox or mail list information
35    MINFO = minfo::Record::TYPE,
36    /// mail exchange
37    MX = mx::Record::TYPE,
38    /// text strings
39    TXT = txt::Record::TYPE,
40    /// IPv6 host address (RFC 2782)
41    AAAA = aaaa::Record::TYPE,
42    /// service record (RFC 2782)
43    SRV = srv::Record::TYPE,
44    /// EDNS0 options (RFC 6891)
45    OPT = opt::Record::TYPE,
46    /// next secure record (RFC 4034, RFC 6762)
47    NSEC = nsec::Record::TYPE,
48}
49
50/// The QTYPE value according to RFC 1035
51///
52/// All "EXPERIMENTAL" markers here are from the RFC
53#[derive(Debug, PartialEq, Eq, Clone, Copy)]
54#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
55pub enum QueryType {
56    /// a host addresss
57    A = a::Record::TYPE,
58    /// an authoritative name server
59    NS = ns::Record::TYPE,
60    /// a mail forwarder (Obsolete - use MX)
61    MF = mf::Record::TYPE,
62    /// the canonical name for an alias
63    CNAME = cname::Record::TYPE,
64    /// marks the start of a zone of authority
65    SOA = soa::Record::TYPE,
66    /// a mailbox domain name (EXPERIMENTAL)
67    MB = mb::Record::TYPE,
68    /// a mail group member (EXPERIMENTAL)
69    MG = mg::Record::TYPE,
70    /// a mail rename domain name (EXPERIMENTAL)
71    MR = mr::Record::TYPE,
72    /// a null RR (EXPERIMENTAL)
73    NULL = null::Record::TYPE,
74    /// a well known service description
75    WKS = wks::Record::TYPE,
76    /// a domain name pointer
77    PTR = ptr::Record::TYPE,
78    /// host information
79    HINFO = hinfo::Record::TYPE,
80    /// mailbox or mail list information
81    MINFO = minfo::Record::TYPE,
82    /// mail exchange
83    MX = mx::Record::TYPE,
84    /// text strings
85    TXT = txt::Record::TYPE,
86    /// IPv6 host address (RFC 2782)
87    AAAA = aaaa::Record::TYPE,
88    /// service record (RFC 2782)
89    SRV = srv::Record::TYPE,
90    /// A request for a transfer of an entire zone
91    AXFR = axfr::Record::TYPE,
92    /// A request for mailbox-related records (MB, MG or MR)
93    MAILB = mailb::Record::TYPE,
94    /// A request for mail agent RRs (Obsolete - see MX)
95    MAILA = maila::Record::TYPE,
96    /// A request for all records
97    All = all::Record::TYPE,
98}
99
100
101/// The CLASS value according to RFC 1035
102#[derive(Debug, PartialEq, Eq, Clone, Copy)]
103pub enum Class {
104    /// the Internet
105    IN = 1,
106    /// the CSNET class (Obsolete - used only for examples in some obsolete
107    /// RFCs)
108    CS = 2,
109    /// the CHAOS class
110    CH = 3,
111    /// Hesiod [Dyer 87]
112    HS = 4,
113}
114
115/// The QCLASS value according to RFC 1035
116#[derive(Debug, PartialEq, Eq, Clone, Copy)]
117pub enum QueryClass {
118    /// the Internet
119    IN = 1,
120    /// the CSNET class (Obsolete - used only for examples in some obsolete
121    /// RFCs)
122    CS = 2,
123    /// the CHAOS class
124    CH = 3,
125    /// Hesiod [Dyer 87]
126    HS = 4,
127    /// Any class
128    Any = 255,
129}
130
131/// The OPCODE value according to RFC 1035
132#[derive(Debug, PartialEq, Eq, Clone, Copy)]
133pub enum Opcode {
134    /// Normal query
135    StandardQuery,
136    /// Inverse query (query a name by IP)
137    InverseQuery,
138    /// Server status request
139    ServerStatusRequest,
140    /// Reserved opcode for future use
141    Reserved(u16),
142}
143
144quick_error! {
145    /// The RCODE value according to RFC 1035
146    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
147    #[allow(missing_docs)] // names are from spec
148    pub enum ResponseCode {
149        NoError
150        FormatError
151        ServerFailure
152        NameError
153        NotImplemented
154        Refused
155        Reserved(code: u8)
156    }
157}
158
159impl From<u16> for Opcode {
160    fn from(code: u16) -> Opcode {
161        use self::Opcode::*;
162        match code {
163            0 => StandardQuery,
164            1 => InverseQuery,
165            2 => ServerStatusRequest,
166            x => Reserved(x),
167        }
168    }
169}
170impl Into<u16> for Opcode {
171    fn into(self) -> u16 {
172        use self::Opcode::*;
173        match self {
174            StandardQuery => 0,
175            InverseQuery => 1,
176            ServerStatusRequest => 2,
177            Reserved(x) => x,
178        }
179    }
180}
181
182impl From<u8> for ResponseCode {
183    fn from(code: u8) -> ResponseCode {
184        use self::ResponseCode::*;
185        match code {
186            0       => NoError,
187            1       => FormatError,
188            2       => ServerFailure,
189            3       => NameError,
190            4       => NotImplemented,
191            5       => Refused,
192            6...15  => Reserved(code),
193            x       => panic!("Invalid response code {}", x),
194        }
195    }
196}
197impl Into<u8> for ResponseCode {
198    fn into(self) -> u8 {
199        use self::ResponseCode::*;
200        match self {
201            NoError         => 0,
202            FormatError     => 1,
203            ServerFailure   => 2,
204            NameError       => 3,
205            NotImplemented  => 4,
206            Refused         => 5,
207            Reserved(code)  => code,
208        }
209    }
210}
211
212impl QueryType {
213    /// Parse a query type code
214    pub fn parse(code: u16) -> Result<QueryType, Error> {
215        use self::QueryType::*;
216        match code as isize {
217            a::Record::TYPE         => Ok(A),
218            ns::Record::TYPE        => Ok(NS),
219            mf::Record::TYPE        => Ok(MF),
220            cname::Record::TYPE     => Ok(CNAME),
221            soa::Record::TYPE       => Ok(SOA),
222            mb::Record::TYPE        => Ok(MB),
223            mg::Record::TYPE        => Ok(MG),
224            mr::Record::TYPE        => Ok(MR),
225            null::Record::TYPE      => Ok(NULL),
226            wks::Record::TYPE       => Ok(WKS),
227            ptr::Record::TYPE       => Ok(PTR),
228            hinfo::Record::TYPE     => Ok(HINFO),
229            minfo::Record::TYPE     => Ok(MINFO),
230            mx::Record::TYPE        => Ok(MX),
231            txt::Record::TYPE       => Ok(TXT),
232            aaaa::Record::TYPE      => Ok(AAAA),
233            srv::Record::TYPE       => Ok(SRV),
234            axfr::Record::TYPE      => Ok(AXFR),
235            mailb::Record::TYPE     => Ok(MAILB),
236            maila::Record::TYPE     => Ok(MAILA),
237            all::Record::TYPE       => Ok(All),
238            x               => Err(Error::InvalidQueryType(x as u16)),
239        }
240    }
241}
242
243impl QueryClass {
244    /// Parse a query class code
245    pub fn parse(code: u16) -> Result<QueryClass, Error> {
246        use self::QueryClass::*;
247        match code {
248            1   => Ok(IN),
249            2   => Ok(CS),
250            3   => Ok(CH),
251            4   => Ok(HS),
252            255 => Ok(Any),
253            x   => Err(Error::InvalidQueryClass(x)),
254        }
255    }
256}
257
258impl Type {
259    /// Parse a type code
260    pub fn parse(code: u16) -> Result<Type, Error> {
261        use self::Type::*;
262        match code as isize {
263            a::Record::TYPE         => Ok(A),
264            ns::Record::TYPE        => Ok(NS),
265            mf::Record::TYPE        => Ok(MF),
266            cname::Record::TYPE     => Ok(CNAME),
267            soa::Record::TYPE       => Ok(SOA),
268            mb::Record::TYPE        => Ok(MB),
269            mg::Record::TYPE        => Ok(MG),
270            mr::Record::TYPE        => Ok(MR),
271            null::Record::TYPE      => Ok(NULL),
272            wks::Record::TYPE       => Ok(WKS),
273            ptr::Record::TYPE       => Ok(PTR),
274            hinfo::Record::TYPE     => Ok(HINFO),
275            minfo::Record::TYPE     => Ok(MINFO),
276            mx::Record::TYPE        => Ok(MX),
277            txt::Record::TYPE       => Ok(TXT),
278            aaaa::Record::TYPE      => Ok(AAAA),
279            srv::Record::TYPE       => Ok(SRV),
280            opt::Record::TYPE       => Ok(OPT),
281            nsec::Record::TYPE      => Ok(NSEC),
282            x               => Err(Error::InvalidType(x as u16)),
283        }
284    }
285}
286
287impl Class {
288    /// Parse a class code
289    pub fn parse(code: u16) -> Result<Class, Error> {
290        use self::Class::*;
291        match code {
292            1   => Ok(IN),
293            2   => Ok(CS),
294            3   => Ok(CH),
295            4   => Ok(HS),
296            x   => Err(Error::InvalidClass(x)),
297        }
298    }
299}