/src/kea/src/lib/dns/rcode.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2010-2024 Internet Systems Consortium, Inc. ("ISC") |
3 | | * |
4 | | * This Source Code Form is subject to the terms of the Mozilla Public |
5 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
6 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
7 | | */ |
8 | | |
9 | | #include <stdint.h> |
10 | | |
11 | | #include <ostream> |
12 | | |
13 | | #ifndef RCODE_H |
14 | | #define RCODE_H |
15 | | |
16 | | namespace isc { |
17 | | namespace dns { |
18 | | |
19 | | /// \brief DNS Response Codes (RCODEs) class. |
20 | | /// |
21 | | /// The \c Rcode class objects represent standard Response Codes |
22 | | /// (RCODEs) of the header section of DNS messages, and extended response |
23 | | /// codes as defined in the EDNS specification. |
24 | | /// |
25 | | /// Originally RCODEs were defined as 4-bit integers (RFC1035), and then |
26 | | /// extended to 12 bits as part of the %EDNS specification (RFC2671). |
27 | | /// This API uses the 12-bit version of the definition from the beginning; |
28 | | /// applications don't have to aware of the original definition except when |
29 | | /// dealing with the wire-format representation of the %EDNS OPT RR |
30 | | /// (which is rare). |
31 | | /// |
32 | | /// Like the \c Opcode class, Rcodes could be represented as bare integers, |
33 | | /// but we define a separate class to benefit from C++ type safety. |
34 | | /// |
35 | | /// For convenience we also provide |
36 | | /// an enum type for pre-defined RCODE values, but it is generally advisable |
37 | | /// to handle RCODEs through this class. In fact, public interfaces of |
38 | | /// this library uses this class to pass or return RCODEs instead of the |
39 | | /// bare code values. |
40 | | class Rcode { |
41 | | public: |
42 | | /// Constants for pre-defined RCODE values. |
43 | | enum CodeValue { |
44 | | NOERROR_CODE = 0, ///< 0: No error (RFC1035) |
45 | | FORMERR_CODE = 1, ///< 1: Format error (RFC1035) |
46 | | SERVFAIL_CODE = 2, ///< 2: Server failure (RFC1035) |
47 | | NXDOMAIN_CODE = 3, ///< 3: Name Error (RFC1035) |
48 | | NOTIMP_CODE = 4, ///< 4: Not Implemented (RFC1035) |
49 | | REFUSED_CODE = 5, ///< 5: Refused (RFC1035) |
50 | | YXDOMAIN_CODE = 6, ///< 6: Name unexpectedly exists (RFC2136) |
51 | | YXRRSET_CODE = 7, ///< 7: RRset unexpectedly exists (RFC2136) |
52 | | NXRRSET_CODE = 8, ///< 8: RRset should exist but not (RFC2136) |
53 | | NOTAUTH_CODE = 9, ///< 9: Server isn't authoritative (RFC2136) |
54 | | NOTZONE_CODE = 10, ///< 10: Name is not within the zone (RFC2136) |
55 | | RESERVED11_CODE = 11, ///< 11: Reserved for future use (RFC1035) |
56 | | RESERVED12_CODE = 12, ///< 12: Reserved for future use (RFC1035) |
57 | | RESERVED13_CODE = 13, ///< 13: Reserved for future use (RFC1035) |
58 | | RESERVED14_CODE = 14, ///< 14: Reserved for future use (RFC1035) |
59 | | RESERVED15_CODE = 15, ///< 15: Reserved for future use (RFC1035) |
60 | | BADVERS_CODE = 16 ///< 16: EDNS version not implemented (RFC2671) |
61 | | }; |
62 | | |
63 | | /// \name Constructors and Destructor |
64 | | /// |
65 | | /// We use the default versions of destructor, copy constructor, |
66 | | /// and assignment operator. |
67 | | /// |
68 | | /// The default constructor is hidden as a result of defining the other |
69 | | /// constructors. This is intentional; we don't want to allow an |
70 | | /// \c Rcode object to be constructed with an invalid state. |
71 | | //@{ |
72 | | /// \brief Constructor from the code value. |
73 | | /// |
74 | | /// Since RCODEs are 12-bit values, parameters larger than 0xfff are |
75 | | /// invalid. |
76 | | /// If \c code is larger than 0xfff an exception of class |
77 | | /// \c isc::OutOfRange will be thrown. |
78 | | /// |
79 | | /// \param code The underlying 12-bit code value of the \c Rcode. |
80 | | explicit Rcode(const uint16_t code); |
81 | | |
82 | | /// \brief Constructor from a pair of base and extended parts of code. |
83 | | /// |
84 | | /// This constructor takes two parameters, one for the lower 4 bits of |
85 | | /// the code value, the other for the upper 8 bits, and combines them |
86 | | /// to build a complete 12-bit code value. |
87 | | /// |
88 | | /// The first parameter, \c code, is the lower 4 bits, and therefore must |
89 | | /// not exceed 15. Otherwise, an exception of class |
90 | | /// \c isc::OutOfRange will be thrown. |
91 | | /// |
92 | | /// This version of constructor is provided specifically for constructing |
93 | | /// an Rcode from a DNS header and an %EDNS OPT RR. Normal applications |
94 | | /// won't have to use this constructor. |
95 | | /// |
96 | | /// \param code The lower 4 bits of the underlying code value. |
97 | | /// \param extended_code The upper 8 bits of the underlying code value. |
98 | | Rcode(const uint8_t code, const uint8_t extended_code); |
99 | | //@} |
100 | | |
101 | | /// \brief Returns the \c Rcode code value. |
102 | | /// |
103 | | /// This method never throws an exception. |
104 | | /// |
105 | | /// \return The underlying code value corresponding to the \c Rcode. |
106 | 190 | uint16_t getCode() const { |
107 | 190 | return (code_); |
108 | 190 | } |
109 | | |
110 | | /// \brief Returns the upper 8-bit of the \c Rcode code value. |
111 | | /// |
112 | | /// Normal applications won't have to use this method. This is provided |
113 | | /// in case the upper 8 bits are necessary for the EDNS protocol |
114 | | /// processing. |
115 | | /// |
116 | | /// This method never throws an exception. |
117 | | /// |
118 | | /// \return The upper 8-bit of the underlying code value. |
119 | | uint8_t getExtendedCode() const; |
120 | | |
121 | | /// \brief Return true iff two Rcodes are equal. |
122 | | /// |
123 | | /// Two Rcodes are equal iff their type codes are equal. |
124 | | /// |
125 | | /// This method never throws an exception. |
126 | | /// |
127 | | /// \param other the \c Rcode object to compare against. |
128 | | /// \return true if the two Rcodes are equal; otherwise false. |
129 | 0 | bool equals(const Rcode& other) const { |
130 | 0 | return (code_ == other.code_); |
131 | 0 | } |
132 | | |
133 | | /// \brief Same as \c equals(). |
134 | 0 | bool operator==(const Rcode& other) const { |
135 | 0 | return (equals(other)); |
136 | 0 | } |
137 | | |
138 | | /// \brief Return true iff two Rcodes are not equal. |
139 | | /// |
140 | | /// This method never throws an exception. |
141 | | /// |
142 | | /// \param other the \c Rcode object to compare against. |
143 | | /// \return true if the two Rcodes are not equal; otherwise false. |
144 | 0 | bool nequals(const Rcode& other) const { |
145 | 0 | return (code_ != other.code_); |
146 | 0 | } |
147 | | |
148 | | /// \brief Same as \c nequals(). |
149 | 0 | bool operator!=(const Rcode& other) const { |
150 | 0 | return (nequals(other)); |
151 | 0 | } |
152 | | |
153 | | /// \brief Convert the \c Rcode to a string. |
154 | | /// |
155 | | /// For pre-defined code values (see Rcode::CodeValue), |
156 | | /// this method returns a string representation of the "mnemonic' used |
157 | | /// for the enum and constant objects. For example, the string for |
158 | | /// code value 0 is "NOERROR", etc. |
159 | | /// For other code values it returns a string representation of the decimal |
160 | | /// number of the value, e.g. "32", "100", etc. |
161 | | /// |
162 | | /// If resource allocation for the string fails, a corresponding standard |
163 | | /// exception will be thrown. |
164 | | /// |
165 | | /// \return A string representation of the \c Rcode. |
166 | | std::string toText() const; |
167 | | |
168 | | /// A constant object for the NOERROR Rcode (see \c Rcode::NOERROR_CODE). |
169 | | static const Rcode& NOERROR(); |
170 | | |
171 | | /// A constant object for the FORMERR Rcode (see \c Rcode::FORMERR_CODE). |
172 | | static const Rcode& FORMERR(); |
173 | | |
174 | | /// A constant object for the SERVFAIL Rcode (see \c Rcode::SERVFAIL_CODE). |
175 | | static const Rcode& SERVFAIL(); |
176 | | |
177 | | /// A constant object for the NXDOMAIN Rcode (see \c Rcode::NXDOMAIN_CODE). |
178 | | static const Rcode& NXDOMAIN(); |
179 | | |
180 | | /// A constant object for the NOTIMP Rcode (see \c Rcode::NOTIMP_CODE). |
181 | | static const Rcode& NOTIMP(); |
182 | | |
183 | | /// A constant object for the REFUSED Rcode (see \c Rcode::REFUSED_CODE). |
184 | | static const Rcode& REFUSED(); |
185 | | |
186 | | /// A constant object for the YXDOMAIN Rcode (see \c Rcode::YXDOMAIN_CODE). |
187 | | static const Rcode& YXDOMAIN(); |
188 | | |
189 | | /// A constant object for the YXRRSET Rcode (see \c Rcode::YXRRSET_CODE). |
190 | | static const Rcode& YXRRSET(); |
191 | | |
192 | | /// A constant object for the NXRRSET Rcode (see \c Rcode::NXRRSET_CODE). |
193 | | static const Rcode& NXRRSET(); |
194 | | |
195 | | /// A constant object for the NOTAUTH Rcode (see \c Rcode::NOTAUTH_CODE). |
196 | | static const Rcode& NOTAUTH(); |
197 | | |
198 | | /// A constant object for the NOTZONE Rcode (see \c Rcode::NOTZONE_CODE). |
199 | | static const Rcode& NOTZONE(); |
200 | | |
201 | | /// A constant object for a reserved (code 11) Rcode. |
202 | | /// (see \c Rcode::RESERVED11_CODE). |
203 | | static const Rcode& RESERVED11(); |
204 | | |
205 | | /// A constant object for a reserved (code 12) Rcode. |
206 | | /// (see \c Rcode::RESERVED12_CODE). |
207 | | static const Rcode& RESERVED12(); |
208 | | |
209 | | /// A constant object for a reserved (code 13) Rcode. |
210 | | /// (see \c Rcode::RESERVED13_CODE). |
211 | | static const Rcode& RESERVED13(); |
212 | | |
213 | | /// A constant object for a reserved (code 14) Rcode. |
214 | | /// (see \c Rcode::RESERVED14_CODE). |
215 | | static const Rcode& RESERVED14(); |
216 | | |
217 | | /// A constant object for a reserved (code 15) Rcode. |
218 | | /// (see \c Rcode::RESERVED15_CODE). |
219 | | static const Rcode& RESERVED15(); |
220 | | |
221 | | /// A constant object for the BADVERS Rcode (see \c Rcode::BADVERS_CODE). |
222 | | static const Rcode& BADVERS(); |
223 | | private: |
224 | | uint16_t code_; |
225 | | }; |
226 | | |
227 | | inline const Rcode& |
228 | 160 | Rcode::NOERROR() { |
229 | 160 | static Rcode c(0); |
230 | 160 | return (c); |
231 | 160 | } |
232 | | |
233 | | inline const Rcode& |
234 | 0 | Rcode::FORMERR() { |
235 | 0 | static Rcode c(1); |
236 | 0 | return (c); |
237 | 0 | } |
238 | | |
239 | | inline const Rcode& |
240 | 0 | Rcode::SERVFAIL() { |
241 | 0 | static Rcode c(2); |
242 | 0 | return (c); |
243 | 0 | } |
244 | | |
245 | | inline const Rcode& |
246 | 0 | Rcode::NXDOMAIN() { |
247 | 0 | static Rcode c(3); |
248 | 0 | return (c); |
249 | 0 | } |
250 | | |
251 | | inline const Rcode& |
252 | 0 | Rcode::NOTIMP() { |
253 | 0 | static Rcode c(4); |
254 | 0 | return (c); |
255 | 0 | } |
256 | | |
257 | | inline const Rcode& |
258 | 0 | Rcode::REFUSED() { |
259 | 0 | static Rcode c(5); |
260 | 0 | return (c); |
261 | 0 | } |
262 | | |
263 | | inline const Rcode& |
264 | 0 | Rcode::YXDOMAIN() { |
265 | 0 | static Rcode c(6); |
266 | 0 | return (c); |
267 | 0 | } |
268 | | |
269 | | inline const Rcode& |
270 | 0 | Rcode::YXRRSET() { |
271 | 0 | static Rcode c(7); |
272 | 0 | return (c); |
273 | 0 | } |
274 | | |
275 | | inline const Rcode& |
276 | 0 | Rcode::NXRRSET() { |
277 | 0 | static Rcode c(8); |
278 | 0 | return (c); |
279 | 0 | } |
280 | | |
281 | | inline const Rcode& |
282 | 0 | Rcode::NOTAUTH() { |
283 | 0 | static Rcode c(9); |
284 | 0 | return (c); |
285 | 0 | } |
286 | | |
287 | | inline const Rcode& |
288 | 0 | Rcode::NOTZONE() { |
289 | 0 | static Rcode c(10); |
290 | 0 | return (c); |
291 | 0 | } |
292 | | |
293 | | inline const Rcode& |
294 | 0 | Rcode::RESERVED11() { |
295 | 0 | static Rcode c(11); |
296 | 0 | return (c); |
297 | 0 | } |
298 | | |
299 | | inline const Rcode& |
300 | 0 | Rcode::RESERVED12() { |
301 | 0 | static Rcode c(12); |
302 | 0 | return (c); |
303 | 0 | } |
304 | | |
305 | | inline const Rcode& |
306 | 0 | Rcode::RESERVED13() { |
307 | 0 | static Rcode c(13); |
308 | 0 | return (c); |
309 | 0 | } |
310 | | |
311 | | inline const Rcode& |
312 | 0 | Rcode::RESERVED14() { |
313 | 0 | static Rcode c(14); |
314 | 0 | return (c); |
315 | 0 | } |
316 | | |
317 | | inline const Rcode& |
318 | 0 | Rcode::RESERVED15() { |
319 | 0 | static Rcode c(15); |
320 | 0 | return (c); |
321 | 0 | } |
322 | | |
323 | | inline const Rcode& |
324 | 0 | Rcode::BADVERS() { |
325 | 0 | static Rcode c(16); |
326 | 0 | return (c); |
327 | 0 | } |
328 | | |
329 | | /// \brief Insert the \c Rcode as a string into stream. |
330 | | /// |
331 | | /// This method convert \c rcode into a string and inserts it into the |
332 | | /// output stream \c os. |
333 | | /// |
334 | | /// \param os A \c std::ostream object on which the insertion operation is |
335 | | /// performed. |
336 | | /// \param rcode A reference to an \c Rcode object output by the operation. |
337 | | /// \return A reference to the same \c std::ostream object referenced by |
338 | | /// parameter \c os after the insertion operation. |
339 | | std::ostream& operator<<(std::ostream& os, const Rcode& rcode); |
340 | | } |
341 | | } |
342 | | #endif // RCODE_H |