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