Coverage Report

Created: 2026-05-16 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kea/src/lib/dhcp/option6_client_fqdn.h
Line
Count
Source
1
// Copyright (C) 2013-2025 Internet Systems Consortium, Inc. ("ISC")
2
//
3
// This Source Code Form is subject to the terms of the Mozilla Public
4
// License, v. 2.0. If a copy of the MPL was not distributed with this
5
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7
#ifndef OPTION6_CLIENT_FQDN_H
8
#define OPTION6_CLIENT_FQDN_H
9
10
#include <dhcp/option.h>
11
#include <dns/name.h>
12
13
#include <string>
14
15
namespace isc {
16
namespace dhcp {
17
18
/// @brief Exception thrown when invalid flags have been specified for
19
/// DHCPv6 Client Fqdn %Option.
20
class InvalidOption6FqdnFlags : public Exception {
21
public:
22
    InvalidOption6FqdnFlags(const char* file, size_t line, const char* what) :
23
39
        isc::Exception(file, line, what) {}
24
};
25
26
/// @brief Exception thrown when invalid domain name is specified.
27
class InvalidOption6FqdnDomainName : public Exception {
28
public:
29
    InvalidOption6FqdnDomainName(const char* file, size_t line,
30
                                const char* what) :
31
181
        isc::Exception(file, line, what) {}
32
};
33
34
/// Forward declaration to implementation of @c Option6ClientFqdn class.
35
class Option6ClientFqdnImpl;
36
37
/// @brief Represents DHCPv6 Client FQDN %Option (code 39).
38
///
39
/// This option has been defined in the RFC 4704 and it has a following
40
/// structure:
41
/// - option-code = 39 (2 octets)
42
/// - option-len (2 octets)
43
/// - flags (1 octet)
44
/// - domain-name - variable length field comprising partial or fully qualified
45
/// domain name.
46
///
47
/// The flags field has the following structure:
48
/// @code
49
///        0 1 2 3 4 5 6 7
50
///       +-+-+-+-+-+-+-+-+
51
///       |  MBZ    |N|O|S|
52
///       +-+-+-+-+-+-+-+-+
53
/// @endcode
54
/// where:
55
/// - N flag specifies whether server should (0) or should not (1) perform DNS
56
///  Update,
57
/// - O flag is set by the server to indicate that it has overridden client's
58
/// preference set with the S bit.
59
/// - S flag specifies whether server should (1) or should not (0) perform
60
/// forward (FQDN-to-address) updates.
61
///
62
/// This class exposes a set of functions to modify flags and check their
63
/// correctness.
64
///
65
/// Domain names being carried by DHCPv6 Client Fqdn %Option can be fully
66
/// qualified or partial. Partial domain names are encoded similar to the
67
/// fully qualified domain names, except that they lack terminating zero
68
/// at the end of their wire representation. It is also accepted to create an
69
/// instance of this option which has empty domain-name. Clients use empty
70
/// domain-names to indicate that server should generate complete fully
71
/// qualified domain-name.
72
///
73
/// Since domain names are case insensitive (see RFC 4343), this class
74
/// converts them to lower case format regardless if they are received over
75
/// the wire or created from strings.
76
///
77
/// <b>Design choice:</b> This class uses pimpl idiom to separate the interface
78
/// from implementation specifics. Implementations may use different approaches
79
/// to handle domain names (mostly validation of the domain-names). The existing
80
/// @c isc::dns::Name class is a natural (and the simplest) choice to handle
81
/// domain-names. Use of this class however, implies that libdhcp must be linked
82
/// with libdns. At some point these libraries may need to be separated, i.e. to
83
/// support compilation and use of standalone DHCP server. This will require
84
/// that the part of implementation which deals with domain-names is modified to
85
/// not use classes from libdns. These changes will be transparent for this
86
/// interface.
87
class Option6ClientFqdn : public Option {
88
public:
89
90
    ///
91
    ///@name A set of constants setting respective bits in 'flags' field
92
    //@{
93
    static const uint8_t FLAG_S = 0x01; ///< S bit.
94
    static const uint8_t FLAG_O = 0x02; ///< O bit.
95
    static const uint8_t FLAG_N = 0x04; ///< N bit.
96
    //@}
97
98
    /// @brief Mask which zeroes MBZ flag bits.
99
    static const uint8_t FLAG_MASK = 0x7;
100
101
    /// @brief The length of the flag field within DHCPv6 Client Fqdn %Option.
102
    static const uint16_t FLAG_FIELD_LEN = 1;
103
104
    /// @brief Type of the domain-name: partial or full.
105
    enum DomainNameType : uint16_t {
106
        PARTIAL,
107
        FULL
108
    };
109
110
    /// @brief Constructor, creates option instance using flags and domain name.
111
    ///
112
    /// This constructor is used to create instance of the option which will be
113
    /// included in outgoing messages.
114
    ///
115
    /// @param flags a combination of flag bits to be stored in flags field.
116
    /// @param domain_name a name to be stored in the domain-name field.
117
    /// @param domain_name_type indicates if the domain name is partial
118
    /// or full.
119
    explicit Option6ClientFqdn(const uint8_t flags,
120
                               const std::string& domain_name,
121
                               const DomainNameType domain_name_type = FULL);
122
123
    /// @brief Constructor, creates option instance using flags.
124
    ///
125
    /// This constructor creates an instance of the option with empty
126
    /// domain-name. This domain-name is marked partial.
127
    ///
128
    /// @param flags A combination of flag bits to be stored in flags field.
129
    Option6ClientFqdn(const uint8_t flags);
130
131
    /// @brief Constructor, creates an option instance from part of the buffer.
132
    ///
133
    /// This constructor is mainly used to parse options in the received
134
    /// messages. Function parameters specify buffer bounds from which the
135
    /// option should be created. The size of the buffer chunk, specified by
136
    /// the constructor's parameters should be equal or larger than the size
137
    /// of the option. Otherwise, constructor will throw an exception.
138
    ///
139
    /// @param first the lower bound of the buffer to create option from.
140
    /// @param last the upper bound of the buffer to create option from.
141
    explicit Option6ClientFqdn(OptionBufferConstIter first,
142
                               OptionBufferConstIter last);
143
144
    /// @brief Copy constructor
145
    Option6ClientFqdn(const Option6ClientFqdn& source);
146
147
    /// @brief Copies this option and returns a pointer to the copy.
148
    virtual OptionPtr clone() const;
149
150
    /// @brief Destructor
151
    virtual ~Option6ClientFqdn();
152
153
    /// @brief Assignment operator
154
    Option6ClientFqdn& operator=(const Option6ClientFqdn& source);
155
156
    /// @brief Checks if the specified flag of the DHCPv6 Client FQDN %Option
157
    /// is set.
158
    ///
159
    /// This method checks the single bit of flags field. Therefore, a caller
160
    /// should use one of the: @c FLAG_S, @c FLAG_N, @c FLAG_O constants as
161
    /// an argument of the function. Attempt to use any other value (including
162
    /// combinations of these constants) will result in exception.
163
    ///
164
    /// @param flag A value specifying the flags bit to be checked. It can be
165
    /// one of the following: @c FLAG_S, @c FLAG_N, @c FLAG_O.
166
    ///
167
    /// @return true if the bit of the specified flag is set, false otherwise.
168
    bool getFlag(const uint8_t flag) const;
169
170
    /// @brief Modifies the value of the specified DHCPv6 Client Fqdn %Option
171
    /// flag.
172
    ///
173
    /// This method sets the single bit of flags field. Therefore, a caller
174
    /// should use one of the: @c FLAG_S, @c FLAG_N, @c FLAG_O constants as
175
    /// an argument of the function. Attempt to use any other value (including
176
    /// combinations of these constants) will result in exception.
177
    ///
178
    /// @param flag A value specifying the flags bit to be modified. It can
179
    /// be one of the following: @c FLAG_S, @c FLAG_N, @c FLAG_O.
180
    /// @param set a boolean value which indicates whether flag should be
181
    /// set (true), or cleared (false).
182
    void setFlag(const uint8_t flag, const bool set);
183
184
    /// @brief Sets the flag field value to 0.
185
    void resetFlags();
186
187
    /// @brief Returns the domain-name in the text format.
188
    ///
189
    /// If domain-name is partial, it lacks the dot at the end (e.g. myhost).
190
    /// If domain-name is fully qualified, it has the dot at the end (e.g.
191
    /// myhost.example.com.).
192
    ///
193
    /// @return domain-name in the text format.
194
    std::string getDomainName() const;
195
196
    /// @brief Writes domain-name in the wire format into a buffer.
197
    ///
198
    /// The data being written are appended at the end of the buffer.
199
    ///
200
    /// @param [out] buf buffer where domain-name will be written.
201
    void packDomainName(isc::util::OutputBuffer& buf) const;
202
203
    /// @brief Set new domain-name.
204
    ///
205
    /// @param domain_name domain name field value in the text format.
206
    /// @param domain_name_type type of the domain name: partial or fully
207
    /// qualified.
208
    void setDomainName(const std::string& domain_name,
209
                       const DomainNameType domain_name_type);
210
211
    /// @brief Set empty domain-name.
212
    ///
213
    /// This function is equivalent to @c Option6ClientFqdn::setDomainName
214
    /// with empty partial domain-name. It is exception safe.
215
    void resetDomainName();
216
217
    /// @brief Returns enumerator value which indicates whether domain-name is
218
    /// partial or full.
219
    ///
220
    /// @return An enumerator value indicating whether domain-name is partial
221
    /// or full.
222
    DomainNameType getDomainNameType() const;
223
224
    /// @brief Writes option in the wire format into a buffer.
225
    ///
226
    /// @param [out] buf output buffer where option data will be stored.
227
    /// @param check if set to false, allows options larger than 255 for v4
228
    virtual void pack(isc::util::OutputBuffer& buf, bool check = true) const;
229
230
    /// @brief Parses option from the received buffer.
231
    ///
232
    /// Method creates an instance of the DHCPv6 Client FQDN %Option from the
233
    /// wire format. Parameters specify the bounds of the buffer to read option
234
    /// data from. The size of the buffer limited by the specified parameters
235
    /// should be equal or larger than size of the option (including its
236
    /// header). Otherwise exception will be thrown.
237
    ///
238
    /// @param first lower bound of the buffer to parse option from.
239
    /// @param last upper bound of the buffer to parse option from.
240
    virtual void unpack(OptionBufferConstIter first,
241
                        OptionBufferConstIter last);
242
243
    /// @brief Returns string representation of the option.
244
    ///
245
    /// The string returned by the method comprises the bit value of each
246
    /// option flag and the domain-name.
247
    ///
248
    /// @param indent number of spaces before printed text.
249
    ///
250
    /// @return string with text representation.
251
    virtual std::string toText(int indent = 0) const;
252
253
    /// @brief Returns length of the complete option (data length +
254
    /// DHCPv6 option header).
255
    ///
256
    /// @return length of the option.
257
    virtual uint16_t len() const;
258
259
private:
260
261
    /// @brief A pointer to the implementation.
262
    Option6ClientFqdnImpl* impl_;
263
};
264
265
/// A pointer to the @c Option6ClientFqdn object.
266
typedef boost::shared_ptr<Option6ClientFqdn> Option6ClientFqdnPtr;
267
268
} // namespace isc::dhcp
269
} // namespace isc
270
271
#endif // OPTION6_CLIENT_FQDN_H