Kea 2.5.8
option_data_types.h
Go to the documentation of this file.
1// Copyright (C) 2012-2024 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 OPTION_DATA_TYPES_H
8#define OPTION_DATA_TYPES_H
9
10#include <asiolink/io_address.h>
12#include <dhcp/option.h>
14#include <util/io.h>
15
16#include <stdint.h>
17#include <utility>
18
19namespace isc {
20namespace dhcp {
21
23class InvalidDataType : public Exception {
24public:
25 InvalidDataType(const char* file, size_t line, const char* what) :
26 isc::Exception(file, line, what) { };
27};
28
30class BadDataTypeCast : public Exception {
31public:
32 BadDataTypeCast(const char* file, size_t line, const char* what) :
33 isc::Exception(file, line, what) { };
34};
35
62 // Type to be used only internally. Allows convenient notation of the option config.
66};
67
70 const char* name; // option name
71 uint16_t code; // option code
72 const char* space; // option space
73 OptionDataType type; // data type
74 bool array; // is array
75 const OptionDataType* records; // record fields
76 size_t records_size; // number of fields in a record
77 const char* encapsulates; // option space encapsulated by the
78 // particular option.
79};
80
83 const struct OptionDefParams* optionDefParams; // parameters structure
84 const int size; // structure size
85 const char* space; // option space
86};
87
93template<typename T>
95 static const bool valid = false;
96 static const int len = 0;
97 static const bool integer_type = false;
99};
100
102template<>
104 static const bool valid = true;
105 static const int len = 0;
106 static const bool integer_type = false;
108};
109
111template<>
113 static const bool valid = true;
114 static const int len = sizeof(uint8_t);
115 static const bool integer_type = false;
117};
118
120template<>
121struct OptionDataTypeTraits<int8_t> {
122 static const bool valid = true;
123 static const int len = 1;
124 static const bool integer_type = true;
126};
127
129template<>
130struct OptionDataTypeTraits<int16_t> {
131 static const bool valid = true;
132 static const int len = 2;
133 static const bool integer_type = true;
135};
136
138template<>
139struct OptionDataTypeTraits<int32_t> {
140 static const bool valid = true;
141 static const int len = 4;
142 static const bool integer_type = true;
144};
145
147template<>
148struct OptionDataTypeTraits<uint8_t> {
149 static const bool valid = true;
150 static const int len = 1;
151 static const bool integer_type = true;
153};
154
156template<>
157struct OptionDataTypeTraits<uint16_t> {
158 static const bool valid = true;
159 static const int len = 2;
160 static const bool integer_type = true;
162};
163
165template<>
166struct OptionDataTypeTraits<uint32_t> {
167 static const bool valid = true;
168 static const int len = 4;
169 static const bool integer_type = true;
171};
172
174template<>
176 static const bool valid = true;
177 // The len value is used to determine the size of the data
178 // to be written to an option buffer. IOAddress object may
179 // either represent an IPv4 or IPv6 addresses which have
180 // different lengths. Thus we can't put fixed value here.
181 // The length of a data to be written into an option buffer
182 // have to be determined in the runtime for a particular
183 // IOAddress object. Thus setting len to zero.
184 static const int len = 0;
185 static const bool integer_type = false;
187};
188
190template<>
191struct OptionDataTypeTraits<std::string> {
192 static const bool valid = true;
193 // The len value is used to determine the size of the data
194 // to be written to an option buffer. For strings this
195 // size is unknown until we actually deal with the particular
196 // string to be written. Thus setting it to zero.
197 static const int len = 0;
198 static const bool integer_type = false;
200};
201
203class PSIDLen {
204public:
205
207 PSIDLen() : psid_len_(0) { }
208
216 explicit PSIDLen(const uint8_t psid_len)
217 : psid_len_(psid_len) {
218 if (psid_len_ > sizeof(uint16_t) * 8) {
219 isc_throw(isc::OutOfRange, "invalid value "
220 << asUnsigned() << " of PSID length");
221 }
222 }
223
225 uint8_t asUint8() const {
226 return (psid_len_);
227 }
228
237 unsigned int asUnsigned() const {
238 return (static_cast<unsigned>(psid_len_));
239 }
240
241private:
242
244 uint8_t psid_len_;
245};
246
248class PSID {
249public:
250
252 PSID() : psid_(0) { }
253
259 explicit PSID(const uint16_t psid)
260 : psid_(psid) {
261 }
262
264 uint16_t asUint16() const {
265 return (psid_);
266 }
267
268private:
269
271 uint16_t psid_;
272
273};
274
276typedef std::pair<PSIDLen, PSID> PSIDTuple;
277
280public:
281
283 PrefixLen() : prefix_len_(0) { }
284
292 explicit PrefixLen(const uint8_t prefix_len)
293 : prefix_len_(prefix_len) {
294 }
295
297 uint8_t asUint8() const {
298 return (prefix_len_);
299 }
300
306 unsigned int asUnsigned() const {
307 return (static_cast<unsigned>(prefix_len_));
308 }
309
310private:
311
313 uint8_t prefix_len_;
314};
315
317typedef std::pair<PrefixLen, asiolink::IOAddress> PrefixTuple;
318
331public:
332
337 static OptionDataType getDataType(const std::string& data_type);
338
343 static const std::string& getDataTypeName(const OptionDataType data_type);
344
361 static int getDataTypeLen(const OptionDataType data_type);
362
371 static asiolink::IOAddress readAddress(const std::vector<uint8_t>& buf,
372 const short family);
373
378 static void writeAddress(const asiolink::IOAddress& address,
379 std::vector<uint8_t>& buf);
380
386 static void writeBinary(const std::string& hex_str,
387 std::vector<uint8_t>& buf);
388
396 static std::string readTuple(const std::vector<uint8_t>& buf,
397 OpaqueDataTuple::LengthFieldType lengthfieldtype);
398
405 static void readTuple(const std::vector<uint8_t>& buf,
406 OpaqueDataTuple& tuple);
407
413 static void writeTuple(const std::string& value,
414 OpaqueDataTuple::LengthFieldType lengthfieldtype,
415 std::vector<uint8_t>& buf);
416
421 static void writeTuple(const OpaqueDataTuple& tuple,
422 std::vector<uint8_t>& buf);
423
433
441 static bool readBool(const std::vector<uint8_t>& buf);
442
450 static void writeBool(const bool value, std::vector<uint8_t>& buf);
451
460 template<typename T>
461 static T readInt(const std::vector<uint8_t>& buf) {
463 isc_throw(isc::dhcp::InvalidDataType, "specified data type to be returned"
464 " by readInteger is unsupported integer type");
465 }
466
467 if (buf.size() < OptionDataTypeTraits<T>::len) {
469 "failed to read an integer value from a buffer"
470 << " - buffer is truncated.");
471 }
472
473 T value;
475 case 1:
476 value = *(buf.begin());
477 break;
478 case 2:
479 // Calling readUint16 works either for unsigned
480 // or signed types.
481 value = isc::util::readUint16(&(*buf.begin()), buf.size());
482 break;
483 case 4:
484 // Calling readUint32 works either for unsigned
485 // or signed types.
486 value = isc::util::readUint32(&(*buf.begin()), buf.size());
487 break;
488 default:
489 // This should not happen because we made checks on data types
490 // but it does not hurt to keep throw statement here.
492 "invalid size of the data type to be read as integer.");
493 }
494 return (value);
495 }
496
502 template<typename T>
503 static void writeInt(const T value,
504 std::vector<uint8_t>& buf) {
506 isc_throw(InvalidDataType, "provided data type is not the supported.");
507 }
509 case 1:
510 buf.push_back(static_cast<uint8_t>(value));
511 break;
512 case 2:
513 buf.resize(buf.size() + 2);
514 isc::util::writeUint16(static_cast<uint16_t>(value), &buf[buf.size() - 2], 2);
515 break;
516 case 4:
517 buf.resize(buf.size() + 4);
518 isc::util::writeUint32(static_cast<uint32_t>(value), &buf[buf.size() - 4], 4);
519 break;
520 default:
521 // The cases above cover whole range of possible data lengths because
522 // we check at the beginning of this function that given data type is
523 // a supported integer type which can be only 1,2 or 4 bytes long.
524 ;
525 }
526 }
527
538 static std::string readFqdn(const std::vector<uint8_t>& buf);
539
554 static void writeFqdn(const std::string& fqdn,
555 std::vector<uint8_t>& buf,
556 const bool downcase = false);
557
567 static unsigned int getLabelCount(const std::string& text_name);
568
579 static PrefixTuple readPrefix(const std::vector<uint8_t>& buf);
580
589 static void writePrefix(const PrefixLen& prefix_len,
590 const asiolink::IOAddress& prefix,
591 std::vector<uint8_t>& buf);
592
602 static PSIDTuple readPsid(const std::vector<uint8_t>& buf);
603
619 static void writePsid(const PSIDLen& psid_len, const PSID& psid,
620 std::vector<uint8_t>& buf);
621
629 static std::string readString(const std::vector<uint8_t>& buf);
630
635 static void writeString(const std::string& value,
636 std::vector<uint8_t>& buf);
637private:
638
641 std::map<std::string, OptionDataType> data_types_;
642
645 std::map<OptionDataType, std::string> data_type_names_;
646
652
661 static OptionDataTypeUtil& instance();
662
667 OptionDataType getDataTypeImpl(const std::string& data_type) const;
668
673 const std::string& getDataTypeNameImpl(const OptionDataType data_type) const;
674};
675
676
677} // isc::dhcp namespace
678} // isc namespace
679
680#endif // OPTION_DATA_TYPES_H
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
Exception to be thrown when cast to the data type was unsuccessful.
BadDataTypeCast(const char *file, size_t line, const char *what)
Exception to be thrown when invalid type specified as template parameter.
InvalidDataType(const char *file, size_t line, const char *what)
Represents a single instance of the opaque data preceded by length.
LengthFieldType
Size of the length field in the tuple.
Utility class for option data types.
static PrefixTuple readPrefix(const std::vector< uint8_t > &buf)
Read prefix from a buffer.
static asiolink::IOAddress readAddress(const std::vector< uint8_t > &buf, const short family)
Read IPv4 or IPv6 address from a buffer.
static unsigned int getLabelCount(const std::string &text_name)
Return the number of labels in the Name.
static void writeFqdn(const std::string &fqdn, std::vector< uint8_t > &buf, const bool downcase=false)
Append FQDN into a buffer.
static void writePrefix(const PrefixLen &prefix_len, const asiolink::IOAddress &prefix, std::vector< uint8_t > &buf)
Append prefix into a buffer.
static void writeInt(const T value, std::vector< uint8_t > &buf)
Append integer or unsigned integer value to a buffer.
static const std::string & getDataTypeName(const OptionDataType data_type)
Return option data type name from the data type enumerator.
static OptionDataType getDataType(const std::string &data_type)
Return option data type from its name.
static void writeBinary(const std::string &hex_str, std::vector< uint8_t > &buf)
Append hex-encoded binary values to a buffer.
static int getDataTypeLen(const OptionDataType data_type)
Get data type buffer length.
static T readInt(const std::vector< uint8_t > &buf)
Read integer value from a buffer.
static std::string readFqdn(const std::vector< uint8_t > &buf)
Read FQDN from a buffer as a string value.
static std::string readTuple(const std::vector< uint8_t > &buf, OpaqueDataTuple::LengthFieldType lengthfieldtype)
Read length and string tuple from a buffer.
static void writeAddress(const asiolink::IOAddress &address, std::vector< uint8_t > &buf)
Append IPv4 or IPv6 address to a buffer.
static PSIDTuple readPsid(const std::vector< uint8_t > &buf)
Read PSID length / value tuple from a buffer.
static void writePsid(const PSIDLen &psid_len, const PSID &psid, std::vector< uint8_t > &buf)
Append PSID length/value into a buffer.
static void writeString(const std::string &value, std::vector< uint8_t > &buf)
Write UTF8-encoded string into a buffer.
static void writeTuple(const std::string &value, OpaqueDataTuple::LengthFieldType lengthfieldtype, std::vector< uint8_t > &buf)
Append length and string tuple to a buffer.
static OpaqueDataTuple::LengthFieldType getTupleLenFieldType(Option::Universe u)
Returns Length Field Type for a tuple.
static void writeBool(const bool value, std::vector< uint8_t > &buf)
Append boolean value into a buffer.
static bool readBool(const std::vector< uint8_t > &buf)
Read boolean value from a buffer.
static std::string readString(const std::vector< uint8_t > &buf)
Read string value from a buffer.
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:83
Encapsulates PSID length.
PSIDLen()
Default constructor.
uint8_t asUint8() const
Returns PSID length as uint8_t value.
unsigned int asUnsigned() const
Returns PSID length as unsigned int.
PSIDLen(const uint8_t psid_len)
Constructor.
Encapsulates PSID value.
uint16_t asUint16() const
Returns PSID value as a number.
PSID(const uint16_t psid)
Constructor.
PSID()
Default constructor.
Encapsulates prefix length.
PrefixLen(const uint8_t prefix_len)
Constructor.
unsigned int asUnsigned() const
Returns prefix length as unsigned int.
PrefixLen()
Default constructor.
uint8_t asUint8() const
Returns prefix length as uint8_t value.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
std::pair< PSIDLen, PSID > PSIDTuple
Defines a pair of PSID length / value.
OptionDataType
Data types of DHCP option fields.
std::pair< PrefixLen, asiolink::IOAddress > PrefixTuple
Defines a pair of prefix length / value.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition: option.h:24
uint8_t * writeUint32(uint32_t const value, void *const buffer, size_t const length)
uint32_t wrapper over writeUint.
Definition: io.h:100
uint16_t readUint16(void const *const buffer, size_t const length)
uint16_t wrapper over readUint.
Definition: io.h:76
uint8_t * writeUint16(uint16_t const value, void *const buffer, size_t const length)
uint16_t wrapper over writeUint.
Definition: io.h:94
uint32_t readUint32(void const *const buffer, size_t const length)
uint32_t wrapper over readUint.
Definition: io.h:82
Defines the logger used by the top-level component of kea-lfc.
Trait class for data types supported in DHCP option definitions.
static const OptionDataType type
Encapsulation of option definition parameters and the structure size.
const struct OptionDefParams * optionDefParams
Parameters being used to make up an option definition.
const OptionDataType * records