Kea  2.5.3
option_data_types.h
Go to the documentation of this file.
1 // Copyright (C) 2012-2023 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>
11 #include <dhcp/opaque_data_tuple.h>
12 #include <dhcp/option.h>
13 #include <exceptions/exceptions.h>
14 #include <util/io_utilities.h>
15 
16 #include <stdint.h>
17 #include <utility>
18 
19 namespace isc {
20 namespace dhcp {
21 
23 class InvalidDataType : public Exception {
24 public:
25  InvalidDataType(const char* file, size_t line, const char* what) :
26  isc::Exception(file, line, what) { };
27 };
28 
30 class BadDataTypeCast : public Exception {
31 public:
32  BadDataTypeCast(const char* file, size_t line, const char* what) :
33  isc::Exception(file, line, what) { };
34 };
35 
64 };
65 
68  const char* name; // option name
69  uint16_t code; // option code
70  const char* space; // option space
71  OptionDataType type; // data type
72  bool array; // is array
73  const OptionDataType* records; // record fields
74  size_t records_size; // number of fields in a record
75  const char* encapsulates; // option space encapsulated by the
76  // particular option.
77 };
78 
81  const struct OptionDefParams* optionDefParams; // parameters structure
82  const int size; // structure size
83  const char* space; // option space
84 };
85 
91 template<typename T>
93  static const bool valid = false;
94  static const int len = 0;
95  static const bool integer_type = false;
97 };
98 
100 template<>
102  static const bool valid = true;
103  static const int len = 0;
104  static const bool integer_type = false;
106 };
107 
109 template<>
110 struct OptionDataTypeTraits<bool> {
111  static const bool valid = true;
112  static const int len = sizeof(uint8_t);
113  static const bool integer_type = false;
115 };
116 
118 template<>
119 struct OptionDataTypeTraits<int8_t> {
120  static const bool valid = true;
121  static const int len = 1;
122  static const bool integer_type = true;
124 };
125 
127 template<>
128 struct OptionDataTypeTraits<int16_t> {
129  static const bool valid = true;
130  static const int len = 2;
131  static const bool integer_type = true;
133 };
134 
136 template<>
137 struct OptionDataTypeTraits<int32_t> {
138  static const bool valid = true;
139  static const int len = 4;
140  static const bool integer_type = true;
142 };
143 
145 template<>
146 struct OptionDataTypeTraits<uint8_t> {
147  static const bool valid = true;
148  static const int len = 1;
149  static const bool integer_type = true;
151 };
152 
154 template<>
155 struct OptionDataTypeTraits<uint16_t> {
156  static const bool valid = true;
157  static const int len = 2;
158  static const bool integer_type = true;
160 };
161 
163 template<>
164 struct OptionDataTypeTraits<uint32_t> {
165  static const bool valid = true;
166  static const int len = 4;
167  static const bool integer_type = true;
169 };
170 
172 template<>
174  static const bool valid = true;
175  // The len value is used to determine the size of the data
176  // to be written to an option buffer. IOAddress object may
177  // either represent an IPv4 or IPv6 addresses which have
178  // different lengths. Thus we can't put fixed value here.
179  // The length of a data to be written into an option buffer
180  // have to be determined in the runtime for a particular
181  // IOAddress object. Thus setting len to zero.
182  static const int len = 0;
183  static const bool integer_type = false;
185 };
186 
188 template<>
189 struct OptionDataTypeTraits<std::string> {
190  static const bool valid = true;
191  // The len value is used to determine the size of the data
192  // to be written to an option buffer. For strings this
193  // size is unknown until we actually deal with the particular
194  // string to be written. Thus setting it to zero.
195  static const int len = 0;
196  static const bool integer_type = false;
198 };
199 
201 class PSIDLen {
202 public:
203 
205  PSIDLen() : psid_len_(0) { }
206 
214  explicit PSIDLen(const uint8_t psid_len)
215  : psid_len_(psid_len) {
216  if (psid_len_ > sizeof(uint16_t) * 8) {
217  isc_throw(isc::OutOfRange, "invalid value "
218  << asUnsigned() << " of PSID length");
219  }
220  }
221 
223  uint8_t asUint8() const {
224  return (psid_len_);
225  }
226 
235  unsigned int asUnsigned() const {
236  return (static_cast<unsigned>(psid_len_));
237  }
238 
239 private:
240 
242  uint8_t psid_len_;
243 };
244 
246 class PSID {
247 public:
248 
250  PSID() : psid_(0) { }
251 
257  explicit PSID(const uint16_t psid)
258  : psid_(psid) {
259  }
260 
262  uint16_t asUint16() const {
263  return (psid_);
264  }
265 
266 private:
267 
269  uint16_t psid_;
270 
271 };
272 
274 typedef std::pair<PSIDLen, PSID> PSIDTuple;
275 
277 class PrefixLen {
278 public:
279 
281  PrefixLen() : prefix_len_(0) { }
282 
290  explicit PrefixLen(const uint8_t prefix_len)
291  : prefix_len_(prefix_len) {
292  }
293 
295  uint8_t asUint8() const {
296  return (prefix_len_);
297  }
298 
304  unsigned int asUnsigned() const {
305  return (static_cast<unsigned>(prefix_len_));
306  }
307 
308 private:
309 
311  uint8_t prefix_len_;
312 };
313 
315 typedef std::pair<PrefixLen, asiolink::IOAddress> PrefixTuple;
316 
329 public:
330 
335  static OptionDataType getDataType(const std::string& data_type);
336 
341  static const std::string& getDataTypeName(const OptionDataType data_type);
342 
359  static int getDataTypeLen(const OptionDataType data_type);
360 
369  static asiolink::IOAddress readAddress(const std::vector<uint8_t>& buf,
370  const short family);
371 
376  static void writeAddress(const asiolink::IOAddress& address,
377  std::vector<uint8_t>& buf);
378 
384  static void writeBinary(const std::string& hex_str,
385  std::vector<uint8_t>& buf);
386 
394  static std::string readTuple(const std::vector<uint8_t>& buf,
395  OpaqueDataTuple::LengthFieldType lengthfieldtype);
396 
403  static void readTuple(const std::vector<uint8_t>& buf,
404  OpaqueDataTuple& tuple);
405 
411  static void writeTuple(const std::string& value,
412  OpaqueDataTuple::LengthFieldType lengthfieldtype,
413  std::vector<uint8_t>& buf);
414 
419  static void writeTuple(const OpaqueDataTuple& tuple,
420  std::vector<uint8_t>& buf);
421 
431 
439  static bool readBool(const std::vector<uint8_t>& buf);
440 
448  static void writeBool(const bool value, std::vector<uint8_t>& buf);
449 
458  template<typename T>
459  static T readInt(const std::vector<uint8_t>& buf) {
461  isc_throw(isc::dhcp::InvalidDataType, "specified data type to be returned"
462  " by readInteger is unsupported integer type");
463  }
464 
465  if (buf.size() < OptionDataTypeTraits<T>::len) {
467  "failed to read an integer value from a buffer"
468  << " - buffer is truncated.");
469  }
470 
471  T value;
473  case 1:
474  value = *(buf.begin());
475  break;
476  case 2:
477  // Calling readUint16 works either for unsigned
478  // or signed types.
479  value = isc::util::readUint16(&(*buf.begin()), buf.size());
480  break;
481  case 4:
482  // Calling readUint32 works either for unsigned
483  // or signed types.
484  value = isc::util::readUint32(&(*buf.begin()), buf.size());
485  break;
486  default:
487  // This should not happen because we made checks on data types
488  // but it does not hurt to keep throw statement here.
490  "invalid size of the data type to be read as integer.");
491  }
492  return (value);
493  }
494 
500  template<typename T>
501  static void writeInt(const T value,
502  std::vector<uint8_t>& buf) {
504  isc_throw(InvalidDataType, "provided data type is not the supported.");
505  }
507  case 1:
508  buf.push_back(static_cast<uint8_t>(value));
509  break;
510  case 2:
511  buf.resize(buf.size() + 2);
512  isc::util::writeUint16(static_cast<uint16_t>(value), &buf[buf.size() - 2], 2);
513  break;
514  case 4:
515  buf.resize(buf.size() + 4);
516  isc::util::writeUint32(static_cast<uint32_t>(value), &buf[buf.size() - 4], 4);
517  break;
518  default:
519  // The cases above cover whole range of possible data lengths because
520  // we check at the beginning of this function that given data type is
521  // a supported integer type which can be only 1,2 or 4 bytes long.
522  ;
523  }
524  }
525 
536  static std::string readFqdn(const std::vector<uint8_t>& buf);
537 
552  static void writeFqdn(const std::string& fqdn,
553  std::vector<uint8_t>& buf,
554  const bool downcase = false);
555 
565  static unsigned int getLabelCount(const std::string& text_name);
566 
577  static PrefixTuple readPrefix(const std::vector<uint8_t>& buf);
578 
587  static void writePrefix(const PrefixLen& prefix_len,
588  const asiolink::IOAddress& prefix,
589  std::vector<uint8_t>& buf);
590 
600  static PSIDTuple readPsid(const std::vector<uint8_t>& buf);
601 
617  static void writePsid(const PSIDLen& psid_len, const PSID& psid,
618  std::vector<uint8_t>& buf);
619 
627  static std::string readString(const std::vector<uint8_t>& buf);
628 
633  static void writeString(const std::string& value,
634  std::vector<uint8_t>& buf);
635 private:
636 
639  std::map<std::string, OptionDataType> data_types_;
640 
643  std::map<OptionDataType, std::string> data_type_names_;
644 
650 
659  static OptionDataTypeUtil& instance();
660 
665  OptionDataType getDataTypeImpl(const std::string& data_type) const;
666 
671  const std::string& getDataTypeNameImpl(const OptionDataType data_type) const;
672 };
673 
674 
675 } // isc::dhcp namespace
676 } // isc namespace
677 
678 #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 value, void *buffer, size_t length)
Write Unsigned 32-Bit Integer to Buffer.
Definition: io_utilities.h:105
uint32_t readUint32(const void *buffer, size_t length)
Read Unsigned 32-Bit Integer from Buffer.
Definition: io_utilities.h:79
uint8_t * writeUint16(uint16_t value, void *buffer, size_t length)
Write Unsigned 16-Bit Integer to Buffer.
Definition: io_utilities.h:55
uint16_t readUint16(const void *buffer, size_t length)
Read Unsigned 16-Bit Integer from Buffer.
Definition: io_utilities.h:28
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