dns_parser_revived/
enums.rs

1use crate::rdata::Record;
2use crate::rdata::*;
3use crate::Error;
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 = "serde", derive(serde::Serialize, serde::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/// The CLASS value according to RFC 1035
101#[derive(Debug, PartialEq, Eq, Clone, Copy)]
102pub enum Class {
103    /// the Internet
104    IN = 1,
105    /// the CSNET class (Obsolete - used only for examples in some obsolete
106    /// RFCs)
107    CS = 2,
108    /// the CHAOS class
109    CH = 3,
110    /// Hesiod [Dyer 87]
111    HS = 4,
112}
113
114/// The QCLASS value according to RFC 1035
115#[derive(Debug, PartialEq, Eq, Clone, Copy)]
116pub enum QueryClass {
117    /// the Internet
118    IN = 1,
119    /// the CSNET class (Obsolete - used only for examples in some obsolete
120    /// RFCs)
121    CS = 2,
122    /// the CHAOS class
123    CH = 3,
124    /// Hesiod [Dyer 87]
125    HS = 4,
126    /// Any class
127    Any = 255,
128}
129
130/// The OPCODE value according to RFC 1035
131#[derive(Debug, PartialEq, Eq, Clone, Copy)]
132pub enum Opcode {
133    /// Normal query
134    StandardQuery,
135    /// Inverse query (query a name by IP)
136    InverseQuery,
137    /// Server status request
138    ServerStatusRequest,
139    /// Reserved opcode for future use
140    Reserved(u16),
141}
142
143quick_error! {
144    /// The RCODE value according to RFC 1035
145    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
146    #[allow(missing_docs)] // names are from spec
147    pub enum ResponseCode {
148        NoError
149        FormatError
150        ServerFailure
151        NameError
152        NotImplemented
153        Refused
154        Unknown(code: u8)
155    }
156}
157
158#[cfg(feature = "serde")]
159impl serde::Serialize for ResponseCode {
160    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
161    where
162        S: serde::Serializer,
163    {
164        match self {
165            ResponseCode::NoError => serializer.serialize_str("NoError"),
166            ResponseCode::FormatError => serializer.serialize_str("FormatError"),
167            ResponseCode::ServerFailure => serializer.serialize_str("ServerFailure"),
168            ResponseCode::NameError => serializer.serialize_str("NameError"),
169            ResponseCode::NotImplemented => serializer.serialize_str("NotImplemented"),
170            ResponseCode::Refused => serializer.serialize_str("Refused"),
171            ResponseCode::Unknown(r) => {
172                let mut s = [b'U', b'n', b'k', b'n', b'o', b'w', b'n', 0, 0, 0];
173                s[7] = (*r / 100) + b'0';
174                s[8] = (*r / 10) % 10 + b'0';
175                s[9] = (*r % 10) + b'0';
176                serializer.serialize_str(unsafe { std::str::from_utf8_unchecked(s.as_slice()) })
177            }
178        }
179    }
180}
181
182#[cfg(feature = "serde")]
183impl serde::Serialize for Opcode {
184    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
185    where
186        S: serde::Serializer,
187    {
188        match self {
189            Opcode::StandardQuery => serializer.serialize_str("StandardQuery"),
190            Opcode::InverseQuery => serializer.serialize_str("InverseQuery"),
191            Opcode::ServerStatusRequest => serializer.serialize_str("ServerStatusRequest"),
192            Opcode::Reserved(_) => serializer.serialize_str("Reserved"),
193        }
194    }
195}
196
197impl From<u16> for Opcode {
198    fn from(code: u16) -> Opcode {
199        use self::Opcode::*;
200        match code {
201            0 => StandardQuery,
202            1 => InverseQuery,
203            2 => ServerStatusRequest,
204            x => Reserved(x),
205        }
206    }
207}
208impl From<Opcode> for u16 {
209    fn from(val: Opcode) -> Self {
210        use self::Opcode::*;
211        match val {
212            StandardQuery => 0,
213            InverseQuery => 1,
214            ServerStatusRequest => 2,
215            Reserved(x) => x,
216        }
217    }
218}
219
220impl From<u8> for ResponseCode {
221    fn from(code: u8) -> ResponseCode {
222        use self::ResponseCode::*;
223        match code {
224            0 => NoError,
225            1 => FormatError,
226            2 => ServerFailure,
227            3 => NameError,
228            4 => NotImplemented,
229            5 => Refused,
230            _ => Unknown(code),
231        }
232    }
233}
234impl From<ResponseCode> for u8 {
235    fn from(val: ResponseCode) -> Self {
236        use self::ResponseCode::*;
237        match val {
238            NoError => 0,
239            FormatError => 1,
240            ServerFailure => 2,
241            NameError => 3,
242            NotImplemented => 4,
243            Refused => 5,
244            Unknown(code) => code,
245        }
246    }
247}
248
249impl QueryType {
250    /// Parse a query type code
251    pub fn parse(code: u16) -> Result<QueryType, Error> {
252        use self::QueryType::*;
253        match code as isize {
254            a::Record::TYPE => Ok(A),
255            ns::Record::TYPE => Ok(NS),
256            mf::Record::TYPE => Ok(MF),
257            cname::Record::TYPE => Ok(CNAME),
258            soa::Record::TYPE => Ok(SOA),
259            mb::Record::TYPE => Ok(MB),
260            mg::Record::TYPE => Ok(MG),
261            mr::Record::TYPE => Ok(MR),
262            null::Record::TYPE => Ok(NULL),
263            wks::Record::TYPE => Ok(WKS),
264            ptr::Record::TYPE => Ok(PTR),
265            hinfo::Record::TYPE => Ok(HINFO),
266            minfo::Record::TYPE => Ok(MINFO),
267            mx::Record::TYPE => Ok(MX),
268            txt::Record::TYPE => Ok(TXT),
269            aaaa::Record::TYPE => Ok(AAAA),
270            srv::Record::TYPE => Ok(SRV),
271            axfr::Record::TYPE => Ok(AXFR),
272            mailb::Record::TYPE => Ok(MAILB),
273            maila::Record::TYPE => Ok(MAILA),
274            all::Record::TYPE => Ok(All),
275            x => Err(Error::InvalidQueryType(x as u16)),
276        }
277    }
278}
279
280impl QueryClass {
281    /// Parse a query class code
282    pub fn parse(code: u16) -> Result<QueryClass, Error> {
283        use self::QueryClass::*;
284        match code {
285            1 => Ok(IN),
286            2 => Ok(CS),
287            3 => Ok(CH),
288            4 => Ok(HS),
289            255 => Ok(Any),
290            x => Err(Error::InvalidQueryClass(x)),
291        }
292    }
293}
294
295impl Type {
296    /// Parse a type code
297    pub fn parse(code: u16) -> Result<Type, Error> {
298        use self::Type::*;
299        match code as isize {
300            a::Record::TYPE => Ok(A),
301            ns::Record::TYPE => Ok(NS),
302            mf::Record::TYPE => Ok(MF),
303            cname::Record::TYPE => Ok(CNAME),
304            soa::Record::TYPE => Ok(SOA),
305            mb::Record::TYPE => Ok(MB),
306            mg::Record::TYPE => Ok(MG),
307            mr::Record::TYPE => Ok(MR),
308            null::Record::TYPE => Ok(NULL),
309            wks::Record::TYPE => Ok(WKS),
310            ptr::Record::TYPE => Ok(PTR),
311            hinfo::Record::TYPE => Ok(HINFO),
312            minfo::Record::TYPE => Ok(MINFO),
313            mx::Record::TYPE => Ok(MX),
314            txt::Record::TYPE => Ok(TXT),
315            aaaa::Record::TYPE => Ok(AAAA),
316            srv::Record::TYPE => Ok(SRV),
317            opt::Record::TYPE => Ok(OPT),
318            nsec::Record::TYPE => Ok(NSEC),
319            x => Err(Error::InvalidType(x as u16)),
320        }
321    }
322}
323
324impl Class {
325    /// Parse a class code
326    pub fn parse(code: u16) -> Result<Class, Error> {
327        use self::Class::*;
328        match code {
329            1 => Ok(IN),
330            2 => Ok(CS),
331            3 => Ok(CH),
332            4 => Ok(HS),
333            x => Err(Error::InvalidClass(x)),
334        }
335    }
336}