Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
3 : : *
4 : : * Permission to use, copy, modify, and/or distribute this software for any
5 : : * purpose with or without fee is hereby granted, provided that the above
6 : : * copyright notice and this permission notice appear in all copies.
7 : : *
8 : : * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 : : * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 : : * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 : : * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 : : * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 : : * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 : : * PERFORMANCE OF THIS SOFTWARE.
15 : : */
16 : :
17 : : #include <stdint.h>
18 : :
19 : : #include <ostream>
20 : :
21 : : #ifndef __RCODE_H
22 : : #define __RCODE_H 1
23 : :
24 : : namespace isc {
25 : : namespace dns {
26 : :
27 : : /// \brief DNS Response Codes (RCODEs) class.
28 : : ///
29 : : /// The \c Rcode class objects represent standard Response Codes
30 : : /// (RCODEs) of the header section of DNS messages, and extended response
31 : : /// codes as defined in the EDNS specification.
32 : : ///
33 : : /// Originally RCODEs were defined as 4-bit integers (RFC1035), and then
34 : : /// extended to 12 bits as part of the %EDNS specification (RFC2671).
35 : : /// This API uses the 12-bit version of the definition from the beginning;
36 : : /// applications don't have to aware of the original definition except when
37 : : /// dealing with the wire-format representation of the %EDNS OPT RR
38 : : /// (which is rare).
39 : : ///
40 : : /// Like the \c Opcode class, Rcodes could be represented as bare integers,
41 : : /// but we define a separate class to benefit from C++ type safety.
42 : : ///
43 : : /// For convenience we also provide
44 : : /// an enum type for pre-defined RCODE values, but it is generally advisable
45 : : /// to handle RCODEs through this class. In fact, public interfaces of
46 : : /// this library uses this class to pass or return RCODEs instead of the
47 : : /// bare code values.
48 : : class Rcode {
49 : : public:
50 : : /// Constants for pre-defined RCODE values.
51 : : enum CodeValue {
52 : : NOERROR_CODE = 0, ///< 0: No error (RFC1035)
53 : : FORMERR_CODE = 1, ///< 1: Format error (RFC1035)
54 : : SERVFAIL_CODE = 2, ///< 2: Server failure (RFC1035)
55 : : NXDOMAIN_CODE = 3, ///< 3: Name Error (RFC1035)
56 : : NOTIMP_CODE = 4, ///< 4: Not Implemented (RFC1035)
57 : : REFUSED_CODE = 5, ///< 5: Refused (RFC1035)
58 : : YXDOMAIN_CODE = 6, ///< 6: Name unexpectedly exists (RFC2136)
59 : : YXRRSET_CODE = 7, ///< 7: RRset unexpectedly exists (RFC2136)
60 : : NXRRSET_CODE = 8, ///< 8: RRset should exist but not (RFC2136)
61 : : NOTAUTH_CODE = 9, ///< 9: Server isn't authoritative (RFC2136)
62 : : NOTZONE_CODE = 10, ///< 10: Name is not within the zone (RFC2136)
63 : : RESERVED11_CODE = 11, ///< 11: Reserved for future use (RFC1035)
64 : : RESERVED12_CODE = 12, ///< 12: Reserved for future use (RFC1035)
65 : : RESERVED13_CODE = 13, ///< 13: Reserved for future use (RFC1035)
66 : : RESERVED14_CODE = 14, ///< 14: Reserved for future use (RFC1035)
67 : : RESERVED15_CODE = 15, ///< 15: Reserved for future use (RFC1035)
68 : : BADVERS_CODE = 16 ///< 16: EDNS version not implemented (RFC2671)
69 : : };
70 : :
71 : : /// \name Constructors and Destructor
72 : : ///
73 : : /// We use the default versions of destructor, copy constructor,
74 : : /// and assignment operator.
75 : : ///
76 : : /// The default constructor is hidden as a result of defining the other
77 : : /// constructors. This is intentional; we don't want to allow an
78 : : /// \c Rcode object to be constructed with an invalid state.
79 : : //@{
80 : : /// \brief Constructor from the code value.
81 : : ///
82 : : /// Since RCODEs are 12-bit values, parameters larger than 0xfff are
83 : : /// invalid.
84 : : /// If \c code is larger than 0xfff an exception of class
85 : : /// \c isc::OutOfRange will be thrown.
86 : : ///
87 : : /// \param code The underlying 12-bit code value of the \c Rcode.
88 : : explicit Rcode(const uint16_t code);
89 : :
90 : : /// \brief Constructor from a pair of base and extended parts of code.
91 : : ///
92 : : /// This constructor takes two parameters, one for the lower 4 bits of
93 : : /// the code value, the other for the upper 8 bits, and combines them
94 : : /// to build a complete 12-bit code value.
95 : : ///
96 : : /// The first parameter, \c code, is the lower 4 bits, and therefore must
97 : : /// not exceed 15. Otherwise, an exception of class
98 : : /// \c isc::OutOfRange will be thrown.
99 : : ///
100 : : /// This version of constructor is provided specifically for constructing
101 : : /// an Rcode from a DNS header and an %EDNS OPT RR. Normal applications
102 : : /// won't have to use this constructor.
103 : : ///
104 : : /// \param code The lower 4 bits of the underlying code value.
105 : : /// \param extended_code The upper 8 bits of the underlying code value.
106 : : Rcode(const uint8_t code, const uint8_t extended_code);
107 : : //@}
108 : :
109 : : /// \brief Returns the \c Rcode code value.
110 : : ///
111 : : /// This method never throws an exception.
112 : : ///
113 : : /// \return The underlying code value corresponding to the \c Rcode.
114 : 1504 : uint16_t getCode() const { return (code_); }
115 : :
116 : : /// \brief Returns the upper 8-bit of the \c Rcode code value.
117 : : ///
118 : : /// Normal applications won't have to use this method. This is provided
119 : : /// in case the upper 8 bits are necessary for the EDNS protocol
120 : : /// processing.
121 : : ///
122 : : /// This method never throws an exception.
123 : : ///
124 : : /// \return The upper 8-bit of the underlying code value.
125 : : uint8_t getExtendedCode() const;
126 : :
127 : : /// \brief Return true iff two Rcodes are equal.
128 : : ///
129 : : /// Two Rcodes are equal iff their type codes are equal.
130 : : ///
131 : : /// This method never throws an exception.
132 : : ///
133 : : /// \param other the \c Rcode object to compare against.
134 : : /// \return true if the two Rcodes are equal; otherwise false.
135 : : bool equals(const Rcode& other) const
136 : 663 : { return (code_ == other.code_); }
137 : :
138 : : /// \brief Same as \c equals().
139 : : bool operator==(const Rcode& other) const { return (equals(other)); }
140 : :
141 : : /// \brief Return true iff two Rcodes are not equal.
142 : : ///
143 : : /// This method never throws an exception.
144 : : ///
145 : : /// \param other the \c Rcode object to compare against.
146 : : /// \return true if the two Rcodes are not equal; otherwise false.
147 : : bool nequals(const Rcode& other) const
148 : 321 : { return (code_ != other.code_); }
149 : :
150 : : /// \brief Same as \c nequals().
151 : : bool operator!=(const Rcode& other) const { return (nequals(other)); }
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 : 544 : Rcode::NOERROR() {
229 [ + + ][ + - ]: 1550 : static Rcode c(0);
[ + - ][ + + ]
[ + - ][ + - ]
230 : 544 : return (c);
231 : : }
232 : :
233 : : inline const Rcode&
234 : 33 : Rcode::FORMERR() {
235 [ + + ][ + - ]: 87 : static Rcode c(1);
[ + - ][ # # ]
[ # # ][ # # ]
236 : 33 : return (c);
237 : : }
238 : :
239 : : inline const Rcode&
240 : 45 : Rcode::SERVFAIL() {
241 [ + + ][ + - ]: 94 : static Rcode c(2);
[ + - ]
242 : 45 : return (c);
243 : : }
244 : :
245 : : inline const Rcode&
246 : 14 : Rcode::NXDOMAIN() {
247 [ + + ][ + - ]: 194 : static Rcode c(3);
[ + - ]
248 : 14 : return (c);
249 : : }
250 : :
251 : : inline const Rcode&
252 : 24 : Rcode::NOTIMP() {
253 [ + + ][ + - ]: 229 : static Rcode c(4);
[ + - ][ - + ]
[ # # ][ # # ]
254 : 24 : return (c);
255 : : }
256 : :
257 : : inline const Rcode&
258 : 36 : Rcode::REFUSED() {
259 [ + + ][ + - ]: 103 : static Rcode c(5);
[ + - ]
260 : 36 : return (c);
261 : : }
262 : :
263 : : inline const Rcode&
264 : : Rcode::YXDOMAIN() {
265 [ + + ][ + - ]: 32 : static Rcode c(6);
[ + - ]
266 : : return (c);
267 : : }
268 : :
269 : : inline const Rcode&
270 : : Rcode::YXRRSET() {
271 [ + - ][ + - ]: 32 : static Rcode c(7);
[ + - ][ + + ]
[ + - ][ + - ]
272 : : return (c);
273 : : }
274 : :
275 : : inline const Rcode&
276 : : Rcode::NXRRSET() {
277 [ + + ][ + - ]: 30 : static Rcode c(8);
[ + - ]
278 : : return (c);
279 : : }
280 : :
281 : : inline const Rcode&
282 : 7 : Rcode::NOTAUTH() {
283 [ + + ][ + - ]: 100 : static Rcode c(9);
[ + - ][ - + ]
[ # # ][ # # ]
284 : 7 : return (c);
285 : : }
286 : :
287 : : inline const Rcode&
288 : : Rcode::NOTZONE() {
289 [ + + ][ + - ]: 30 : static Rcode c(10);
[ + - ]
290 : : return (c);
291 : : }
292 : :
293 : : inline const Rcode&
294 : : Rcode::RESERVED11() {
295 [ + + ][ + - ]: 30 : static Rcode c(11);
[ + - ]
296 : : return (c);
297 : : }
298 : :
299 : : inline const Rcode&
300 : : Rcode::RESERVED12() {
301 [ + + ][ + - ]: 30 : static Rcode c(12);
[ + - ]
302 : : return (c);
303 : : }
304 : :
305 : : inline const Rcode&
306 : : Rcode::RESERVED13() {
307 [ + + ][ + - ]: 30 : static Rcode c(13);
[ + - ]
308 : : return (c);
309 : : }
310 : :
311 : : inline const Rcode&
312 : : Rcode::RESERVED14() {
313 [ + + ][ + - ]: 31 : static Rcode c(14);
[ + - ]
314 : : return (c);
315 : : }
316 : :
317 : : inline const Rcode&
318 : 5 : Rcode::RESERVED15() {
319 [ + + ][ + - ]: 36 : static Rcode c(15);
[ + - ]
320 : 5 : return (c);
321 : : }
322 : :
323 : : inline const Rcode&
324 : 9 : Rcode::BADVERS() {
325 [ + + ][ + - ]: 23 : static Rcode c(16);
[ + - ][ + + ]
[ + - ][ + - ]
326 : 9 : return (c);
327 : : }
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
343 : :
344 : : // Local Variables:
345 : : // mode: c++
346 : : // End:
|