domain_core/iana/opcode.rs
1//! DNS OpCodes
2
3use std::cmp;
4use std::convert;
5use std::fmt;
6use std::hash;
7
8
9/// DNS OpCodes.
10///
11/// The opcode specifies the kind of query to be performed.
12///
13/// The opcode is initially defined in RFC 1035. All currently assigned
14/// values can be found in the [IANA registry]. This type is complete as of
15/// 2019-01-28.
16///
17/// [IANA registry]: http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-5
18#[derive(Clone, Copy, Debug)]
19pub enum Opcode {
20 /// A standard query.
21 ///
22 /// This query requests all records matching the name, class, and record
23 /// type given in the query’s question section.
24 ///
25 /// This value is defined in RFC 1035.
26 Query,
27
28 /// An inverse query (IQUERY) (obsolete).
29 ///
30 /// The idea behind inverse queries was to provide a single answer and
31 /// ask the DNS for all the questions that would lead to this answer.
32 /// This kind of query has always been optional, was never widely
33 /// supported, and has therefore been declared obsolete.
34 ///
35 /// This value was defined in RFC 1035 and obsoleted by RFC 3425.
36 IQuery,
37
38 /// A server status request.
39 ///
40 /// This value is defined in RFC 1035. The status request itself was
41 /// defined as experimental and ‘to be defined’ in RFC 1034 and seems
42 /// to never have been mentioned ever again.
43 Status,
44
45 /// A NOTIFY query.
46 ///
47 /// NOTIFY queries allow master servers to inform slave servers when a
48 /// zone has changed.
49 ///
50 /// This value and the NOTIFY query are defined in RFC 1996.
51 Notify,
52
53 /// An UPDATE query.
54 ///
55 /// The UPDATE query can be used to alter zone content managed by a
56 /// master server.
57 ///
58 /// This value and the UPDATE query are defined in RFC 2136.
59 Update,
60
61 /// DNS Stateful operations (DSO).
62 ///
63 /// This value is defined in draft-ietf-dnsop-session-signal.
64 Dso,
65
66 /// A raw integer opcode value.
67 ///
68 /// When converting to an `u8`, only the lower four bits are used.
69 Int(u8)
70}
71
72impl Opcode {
73 /// Creates an Opcode value from an integer value.
74 ///
75 /// Only considers the lower four bits of `value`.
76 pub fn from_int(value: u8) -> Opcode {
77 use self::Opcode::*;
78
79 match value & 0x0F {
80 0 => Query,
81 1 => IQuery,
82 2 => Status,
83 4 => Notify,
84 5 => Update,
85 6 => Dso,
86 value => Int(value)
87 }
88 }
89
90 /// Returns the integer value for this opcode.
91 pub fn to_int(self) -> u8 {
92 use self::Opcode::*;
93
94 match self {
95 Query => 0,
96 IQuery => 1,
97 Status => 2,
98 Notify => 4,
99 Update => 5,
100 Dso => 6,
101 Int(value) => value & 0x0F
102 }
103 }
104}
105
106
107//--- From
108
109impl convert::From<u8> for Opcode {
110 fn from(value: u8) -> Opcode { Opcode::from_int(value) }
111}
112
113impl convert::From<Opcode> for u8 {
114 fn from(value: Opcode) -> u8 { Opcode::to_int(value) }
115}
116
117
118//--- Display
119
120impl fmt::Display for Opcode {
121 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
122 use self::Opcode::*;
123
124 match *self {
125 Query => "QUERY".fmt(f),
126 IQuery => "IQUERY".fmt(f),
127 Status => "STATUS".fmt(f),
128 Notify => "NOTIFY".fmt(f),
129 Update => "UPDATE".fmt(f),
130 Dso => "DSO".fmt(f),
131 Int(value) => {
132 match Opcode::from_int(value) {
133 Int(value) => value.fmt(f),
134 value => value.fmt(f)
135 }
136 }
137 }
138 }
139}
140
141
142//--- PartialEq and Eq
143
144impl cmp::PartialEq for Opcode {
145 fn eq(&self, other: &Opcode) -> bool {
146 self.to_int() == other.to_int()
147 }
148}
149
150impl cmp::PartialEq<u8> for Opcode {
151 fn eq(&self, other: &u8) -> bool {
152 self.to_int() == *other
153 }
154}
155
156impl cmp::PartialEq<Opcode> for u8 {
157 fn eq(&self, other: &Opcode) -> bool {
158 *self == other.to_int()
159 }
160}
161
162impl cmp::Eq for Opcode { }
163
164
165//--- PartialCmp and Cmp
166
167impl cmp::PartialOrd for Opcode {
168 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
169 self.to_int().partial_cmp(&other.to_int())
170 }
171}
172
173impl cmp::PartialOrd<u8> for Opcode {
174 fn partial_cmp(&self, other: &u8) -> Option<cmp::Ordering> {
175 self.to_int().partial_cmp(other)
176 }
177}
178
179impl cmp::PartialOrd<Opcode> for u8 {
180 fn partial_cmp(&self, other: &Opcode) -> Option<cmp::Ordering> {
181 self.partial_cmp(&other.to_int())
182 }
183}
184
185impl cmp::Ord for Opcode {
186 fn cmp(&self, other: &Self) -> cmp::Ordering {
187 self.to_int().cmp(&other.to_int())
188 }
189}
190
191
192//--- Hash
193
194impl hash::Hash for Opcode {
195 fn hash<H: hash::Hasher>(&self, state: &mut H) {
196 self.to_int().hash(state)
197 }
198}