wez_mdns/dns_parser/
enums.rs

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