Coverage Report

Created: 2026-08-14 08:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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