Kea: option_custom.h Source File

| Kea 3.2.0-git

option_custom.h
Go to the documentation of this file.
1// Copyright (C) 2012-2026 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_CUSTOM_H
8#define OPTION_CUSTOM_H
9
10#include <asiolink/io_address.h>
11#include <dhcp/option.h>
12#include <dhcp/option_definition.h>
13#include <exceptions/isc_assert.h>
14
15namespace isc {
16namespace dhcp {
17
31 class OptionCustom : public Option {
32public:
33
43 OptionCustom(const OptionDefinition& def, Universe u);
44
60 OptionCustom(const OptionDefinition& def, Universe u, const OptionBuffer& data);
61
81 OptionCustom(const OptionDefinition& def, Universe u,
82 OptionBufferConstIter first, OptionBufferConstIter last,
83 size_t rec_level = 0);
84
86 virtual OptionPtr clone() const;
87
92 void addArrayDataField(const asiolink::IOAddress& address);
93
97 void addArrayDataField(const bool value);
98
103 template<typename T>
104 void addArrayDataField(const T value) {
105 checkArrayType();
106 OptionDataType data_type = definition_.getType();
107 // Handle record last field.
108 if (data_type == OPT_RECORD_TYPE) {
109 data_type = definition_.getRecordFields().back();
110 }
111 if (OptionDataTypeTraits<T>::type != data_type) {
112 isc_throw(isc::dhcp::InvalidDataType,
113 "specified data type " << data_type << " does not"
114 " match the data type in an option definition");
115 }
116
117 OptionBuffer buf;
118 OptionDataTypeUtil::writeInt<T>(value, buf);
119 buffers_.push_back(buf);
120 }
121
125 void addArrayDataField(const std::string& value);
126
130 void addArrayDataField(const OpaqueDataTuple& value);
131
136 void addArrayDataField(const PrefixLen& prefix_len,
137 const asiolink::IOAddress& prefix);
138
143 void addArrayDataField(const PSIDLen& psid_len, const PSID& psid);
144
148 uint32_t getDataFieldsNum() const { return (buffers_.size()); }
149
156 asiolink::IOAddress readAddress(const uint32_t index = 0) const;
157
165 void writeAddress(const asiolink::IOAddress& address,
166 const uint32_t index = 0);
167
174 const OptionBuffer& readBinary(const uint32_t index = 0) const;
175
180 void writeBinary(const OptionBuffer& buf, const uint32_t index = 0);
181
188 std::string readTuple(const uint32_t index = 0) const;
189
196 void readTuple(OpaqueDataTuple& tuple, const uint32_t index = 0) const;
197
202 void writeTuple(const std::string& value, const uint32_t index = 0);
203
208 void writeTuple(const OpaqueDataTuple& value, const uint32_t index = 0);
209
216 bool readBoolean(const uint32_t index = 0) const;
217
224 void writeBoolean(const bool value, const uint32_t index = 0);
225
234 std::string readFqdn(const uint32_t index = 0) const;
235
242 void writeFqdn(const std::string& fqdn, const uint32_t index = 0);
243
252 template<typename T>
253 T readInteger(const uint32_t index = 0) const {
254 // Check that the index is not out of range.
255 checkIndex(index);
256 // Check that T points to a valid integer type and this type
257 // is consistent with an option definition.
258 checkDataType<T>(index);
259 // When we created the buffer we have checked that it has a
260 // valid size so this condition here should be always fulfilled.
261 isc_throw_assert(buffers_[index].size() == OptionDataTypeTraits<T>::len);
262 // Read an integer value.
263 return (OptionDataTypeUtil::readInt<T>(buffers_[index]));
264 }
265
274 template<typename T>
275 void writeInteger(const T value, const uint32_t index = 0) {
276 // Check that the index is not out of range.
277 checkIndex(index);
278 // Check that T points to a valid integer type and this type
279 // is consistent with an option definition.
280 checkDataType<T>(index);
281 // Get some temporary buffer.
282 OptionBuffer buf;
283 // Try to write to the buffer.
284 OptionDataTypeUtil::writeInt<T>(value, buf);
285 // If successful, replace the old buffer with new one.
286 std::swap(buffers_[index], buf);
287 }
288
295 PrefixTuple readPrefix(const uint32_t index = 0) const;
296
304 void writePrefix(const PrefixLen& prefix_len,
305 const asiolink::IOAddress& prefix,
306 const uint32_t index = 0);
307
314 PSIDTuple readPsid(const uint32_t index = 0) const;
315
325 void writePsid(const PSIDLen& psid_len, const PSID& psid,
326 const uint32_t index = 0);
327
334 std::string readString(const uint32_t index = 0) const;
335
340 void writeString(const std::string& text,
341 const uint32_t index = 0);
342
347 virtual void pack(isc::util::OutputBuffer& buf, bool check = true) const;
348
353 virtual void unpack(OptionBufferConstIter begin,
354 OptionBufferConstIter end);
355
361 virtual std::string toText(int indent = 0) const;
362
367 virtual uint16_t len() const;
368
375 void initialize(const OptionBufferConstIter first,
376 const OptionBufferConstIter last);
377
378private:
379
387 inline void checkArrayType() const {
388 if (!definition_.getArrayType()) {
389 isc_throw(InvalidOperation, "failed to add new array entry to an"
390 << " option. The option is not an array.");
391 }
392 }
393
404 template<typename T>
405 // cppcheck-suppress unusedPrivateFunction
406 void checkDataType(const uint32_t index) const;
407
413 void checkIndex(const uint32_t index) const;
414
419 void createBuffer(OptionBuffer& buffer,
420 const OptionDataType data_type) const;
421
423 void createBuffers();
424
434 size_t bufferLength(const OptionDataType data_type, bool in_array,
435 OptionBuffer::const_iterator begin,
436 OptionBuffer::const_iterator end) const;
437
442 void createBuffers(const OptionBuffer& data_buf, size_t rec_level = 0);
443
450 std::string dataFieldToText(const OptionDataType data_type,
451 const uint32_t index) const;
452
456 using Option::setData;
457
459 OptionDefinition definition_;
460
464 std::vector<OptionBuffer> buffers_;
465};
466
468 typedef boost::shared_ptr<OptionCustom> OptionCustomPtr;
469
470template<typename T>
471void
472OptionCustom::checkDataType(const uint32_t index) const {
473 // Check that the requested return type is a supported integer.
474 if (!OptionDataTypeTraits<T>::integer_type) {
475 isc_throw(isc::dhcp::InvalidDataType, "specified data type"
476 " is not a supported integer type.");
477 }
478
479 // Get the option definition type.
480 OptionDataType data_type = definition_.getType();
481 if (data_type == OPT_RECORD_TYPE) {
482 const OptionDefinition::RecordFieldsCollection& record_fields =
483 definition_.getRecordFields();
484 if (definition_.getArrayType()) {
485 // If the array flag is set the last record field is an array.
486 if (index < record_fields.size()) {
487 // Get the data type to be returned.
488 data_type = record_fields[index];
489 } else {
490 // Get the data type to be returned from the last record field.
491 data_type = record_fields.back();
492 }
493 } else {
494 // When we initialized buffers we have already checked that
495 // the number of these buffers is equal to number of option
496 // fields in the record so the condition below should be met.
497 isc_throw_assert(index < record_fields.size());
498 // Get the data type to be returned.
499 data_type = record_fields[index];
500 }
501 }
502
503 if (OptionDataTypeTraits<T>::type != data_type) {
504 isc_throw(isc::dhcp::InvalidDataType,
505 "specified data type " << data_type << " does not"
506 " match the data type in an option definition for field"
507 " index " << index);
508 }
509}
510} // namespace isc::dhcp
511} // namespace isc
512
513#endif // OPTION_CUSTOM_H
isc::InvalidOperation
A generic exception that is thrown if a function is called in a prohibited way.
Definition exceptions/exceptions.h:143
isc::asiolink::IOAddress
The IOAddress class represents an IP addresses (version agnostic).
Definition io_address.h:53
isc::dhcp::InvalidDataType
Exception to be thrown when invalid type specified as template parameter.
Definition option_data_types.h:23
isc::dhcp::OpaqueDataTuple
Represents a single instance of the opaque data preceded by length.
Definition opaque_data_tuple.h:46
isc::dhcp::OptionCustom::readString
std::string readString(const uint32_t index=0) const
Read a buffer as string value.
Definition option_custom.cc:656
isc::dhcp::OptionCustom::addArrayDataField
void addArrayDataField(const T value)
Create new buffer and store integer value in it.
Definition option_custom.h:104
isc::dhcp::OptionCustom::readBoolean
bool readBoolean(const uint32_t index=0) const
Read a buffer as boolean value.
Definition option_custom.cc:580
isc::dhcp::OptionCustom::len
virtual uint16_t len() const
Returns length of the complete option (data length + DHCPv4/DHCPv6 option header).
Definition option_custom.cc:683
isc::dhcp::OptionCustom::readTuple
std::string readTuple(const uint32_t index=0) const
Read a buffer as length and string tuple.
Definition option_custom.cc:549
isc::dhcp::OptionCustom::writeFqdn
void writeFqdn(const std::string &fqdn, const uint32_t index=0)
Write an FQDN into a buffer.
Definition option_custom.cc:600
isc::dhcp::OptionCustom::readFqdn
std::string readFqdn(const uint32_t index=0) const
Read a buffer as FQDN.
Definition option_custom.cc:594
isc::dhcp::OptionCustom::writePrefix
void writePrefix(const PrefixLen &prefix_len, const asiolink::IOAddress &prefix, const uint32_t index=0)
Write prefix length and value into a buffer.
Definition option_custom.cc:623
isc::dhcp::OptionCustom::unpack
virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end)
Parses received buffer.
Definition option_custom.cc:677
isc::dhcp::OptionCustom::writeAddress
void writeAddress(const asiolink::IOAddress &address, const uint32_t index=0)
Write an IP address into a buffer.
Definition option_custom.cc:518
isc::dhcp::OptionCustom::pack
virtual void pack(isc::util::OutputBuffer &buf, bool check=true) const
Writes DHCP option in a wire format to a buffer.
Definition option_custom.cc:479
isc::dhcp::OptionCustom::initialize
void initialize(const OptionBufferConstIter first, const OptionBufferConstIter last)
Sets content of this option from buffer.
Definition option_custom.cc:700
isc::dhcp::OptionCustom::readBinary
const OptionBuffer & readBinary(const uint32_t index=0) const
Read a buffer as binary data.
Definition option_custom.cc:536
isc::dhcp::OptionCustom::readPrefix
PrefixTuple readPrefix(const uint32_t index=0) const
Read a buffer as variable length prefix.
Definition option_custom.cc:617
isc::dhcp::OptionCustom::writePsid
void writePsid(const PSIDLen &psid_len, const PSID &psid, const uint32_t index=0)
Write PSID length / value into a buffer.
Definition option_custom.cc:643
isc::dhcp::OptionCustom::writeBoolean
void writeBoolean(const bool value, const uint32_t index=0)
Write a boolean value into a buffer.
Definition option_custom.cc:586
isc::dhcp::OptionCustom::readAddress
asiolink::IOAddress readAddress(const uint32_t index=0) const
Read a buffer as IP address.
Definition option_custom.cc:500
isc::dhcp::OptionCustom::readPsid
PSIDTuple readPsid(const uint32_t index=0) const
Read a buffer as a PSID length / value tuple.
Definition option_custom.cc:637
isc::dhcp::OptionCustom::writeString
void writeString(const std::string &text, const uint32_t index=0)
Write a string value into a buffer.
Definition option_custom.cc:662
isc::dhcp::OptionCustom::readInteger
T readInteger(const uint32_t index=0) const
Read a buffer as integer value.
Definition option_custom.h:253
isc::dhcp::OptionCustom::writeBinary
void writeBinary(const OptionBuffer &buf, const uint32_t index=0)
Write binary data into a buffer.
Definition option_custom.cc:542
isc::dhcp::OptionCustom::addArrayDataField
void addArrayDataField(const asiolink::IOAddress &address)
Create new buffer and set its value as an IP address.
Definition option_custom.cc:55
isc::dhcp::OptionCustom::clone
virtual OptionPtr clone() const
Copies this option and returns a pointer to the copy.
Definition option_custom.cc:50
isc::dhcp::OptionCustom::writeTuple
void writeTuple(const std::string &value, const uint32_t index=0)
Write a length and string tuple into a buffer.
Definition option_custom.cc:563
isc::dhcp::OptionCustom::toText
virtual std::string toText(int indent=0) const
Returns string representation of the option.
Definition option_custom.cc:709
isc::dhcp::OptionCustom::OptionCustom
OptionCustom(const OptionDefinition &def, Universe u)
Constructor, used for options to be sent.
Definition option_custom.cc:21
isc::dhcp::OptionCustom::getDataFieldsNum
uint32_t getDataFieldsNum() const
Return a number of the data fields.
Definition option_custom.h:148
isc::dhcp::OptionCustom::writeInteger
void writeInteger(const T value, const uint32_t index=0)
Write an integer value into a buffer.
Definition option_custom.h:275
isc::dhcp::OptionDataTypeUtil::writeInt
static void writeInt(const T value, std::vector< uint8_t > &buf)
Append integer or unsigned integer value to a buffer.
Definition option_data_types.h:510
isc::dhcp::OptionDataTypeUtil::readInt
static T readInt(const std::vector< uint8_t > &buf)
Read integer value from a buffer.
Definition option_data_types.h:467
isc::dhcp::OptionDefinition
Base class representing a DHCP option definition.
Definition option_definition.h:138
isc::dhcp::OptionDefinition::getType
OptionDataType getType() const
Return option data type.
Definition option_definition.h:387
isc::dhcp::OptionDefinition::getRecordFields
const RecordFieldsCollection & getRecordFields() const
Return list of record fields.
Definition option_definition.h:373
isc::dhcp::OptionDefinition::RecordFieldsCollection
std::vector< OptionDataType > RecordFieldsCollection
List of fields within the record.
Definition option_definition.h:142
isc::dhcp::OptionDefinition::getArrayType
bool getArrayType() const
Return array type indicator.
Definition option_definition.h:351
isc::dhcp::Option::Universe
Universe
defines option universe DHCPv4 or DHCPv6
Definition option.h:90
isc::dhcp::Option::setData
void setData(InputIterator first, InputIterator last)
Sets content of this option from buffer.
Definition option.h:434
isc::dhcp::Option::Option
Option(Universe u, uint16_t type)
ctor, used for options constructed, usually during transmission
Definition option.cc:39
isc::dhcp::Option::check
void check() const
A protected method used for option correctness.
Definition option.cc:90
isc::dhcp::PSIDLen
Encapsulates PSID length.
Definition option_data_types.h:204
isc::dhcp::PSID
Encapsulates PSID value.
Definition option_data_types.h:249
isc::dhcp::PrefixLen
Encapsulates prefix length.
Definition option_data_types.h:280
isc::util::OutputBuffer
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition buffer.h:346
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
io_address.h
isc_assert.h
isc_throw_assert
#define isc_throw_assert(expr)
Replacement for assert() that throws if the expression is false.
Definition isc_assert.h:18
isc::data
Definition base_stamped_element.cc:12
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::dhcp::PSIDTuple
std::pair< PSIDLen, PSID > PSIDTuple
Defines a pair of PSID length / value.
Definition option_data_types.h:277
isc::dhcp::OptionCustomPtr
boost::shared_ptr< OptionCustom > OptionCustomPtr
A pointer to the OptionCustom object.
Definition option_custom.h:468
isc::dhcp::OptionBufferConstIter
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
Definition option.h:30
isc::dhcp::PrefixTuple
std::pair< PrefixLen, asiolink::IOAddress > PrefixTuple
Defines a pair of prefix length / value.
Definition option_data_types.h:323
isc::dhcp::OptionBuffer
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition option.h:24
isc::dhcp::OptionDataType
OptionDataType
Data types of DHCP option fields.
Definition option_data_types.h:45
isc::dhcp::OPT_RECORD_TYPE
@ OPT_RECORD_TYPE
Definition option_data_types.h:65
isc::dhcp::OptionPtr
boost::shared_ptr< Option > OptionPtr
Definition option.h:37
isc
Defines the logger used by the top-level component of kea-lfc.
Definition check_exists_add.cc:18
option.h
option_definition.h
isc::dhcp::OptionDataTypeTraits::len
static const int len
Definition option_data_types.h:97
isc::dhcp::OptionDataTypeTraits::integer_type
static const bool integer_type
Definition option_data_types.h:98
isc::dhcp::OptionDataTypeTraits::type
static const OptionDataType type
Definition option_data_types.h:99