Kea  2.3.6
option_custom.h
Go to the documentation of this file.
1 // Copyright (C) 2012-2022 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 #include <util/io_utilities.h>
15 
16 namespace isc {
17 namespace dhcp {
18 
32 class OptionCustom : public Option {
33 public:
34 
44  OptionCustom(const OptionDefinition& def, Universe u);
45 
61  OptionCustom(const OptionDefinition& def, Universe u, const OptionBuffer& data);
62 
83 
85  virtual OptionPtr clone() const;
86 
91  void addArrayDataField(const asiolink::IOAddress& address);
92 
96  void addArrayDataField(const bool value);
97 
102  template<typename T>
103  void addArrayDataField(const T value) {
104  checkArrayType();
105  OptionDataType data_type = definition_.getType();
106  // Handle record last field.
107  if (data_type == OPT_RECORD_TYPE) {
108  data_type = definition_.getRecordFields().back();
109  }
110  if (OptionDataTypeTraits<T>::type != data_type) {
112  "specified data type " << data_type << " does not"
113  " match the data type in an option definition");
114  }
115 
116  OptionBuffer buf;
117  OptionDataTypeUtil::writeInt<T>(value, buf);
118  buffers_.push_back(buf);
119  }
120 
124  void addArrayDataField(const std::string& value);
125 
129  void addArrayDataField(const OpaqueDataTuple& value);
130 
135  void addArrayDataField(const PrefixLen& prefix_len,
136  const asiolink::IOAddress& prefix);
137 
142  void addArrayDataField(const PSIDLen& psid_len, const PSID& psid);
143 
147  uint32_t getDataFieldsNum() const { return (buffers_.size()); }
148 
155  asiolink::IOAddress readAddress(const uint32_t index = 0) const;
156 
164  void writeAddress(const asiolink::IOAddress& address,
165  const uint32_t index = 0);
166 
173  const OptionBuffer& readBinary(const uint32_t index = 0) const;
174 
179  void writeBinary(const OptionBuffer& buf, const uint32_t index = 0);
180 
187  std::string readTuple(const uint32_t index = 0) const;
188 
195  void readTuple(OpaqueDataTuple& tuple, const uint32_t index = 0) const;
196 
201  void writeTuple(const std::string& value, const uint32_t index = 0);
202 
207  void writeTuple(const OpaqueDataTuple& value, const uint32_t index = 0);
208 
215  bool readBoolean(const uint32_t index = 0) const;
216 
223  void writeBoolean(const bool value, const uint32_t index = 0);
224 
233  std::string readFqdn(const uint32_t index = 0) const;
234 
241  void writeFqdn(const std::string& fqdn, const uint32_t index = 0);
242 
251  template<typename T>
252  T readInteger(const uint32_t index = 0) const {
253  // Check that the index is not out of range.
254  checkIndex(index);
255  // Check that T points to a valid integer type and this type
256  // is consistent with an option definition.
257  checkDataType<T>(index);
258  // When we created the buffer we have checked that it has a
259  // valid size so this condition here should be always fulfilled.
260  isc_throw_assert(buffers_[index].size() == OptionDataTypeTraits<T>::len);
261  // Read an integer value.
262  return (OptionDataTypeUtil::readInt<T>(buffers_[index]));
263  }
264 
273  template<typename T>
274  void writeInteger(const T value, const uint32_t index = 0) {
275  // Check that the index is not out of range.
276  checkIndex(index);
277  // Check that T points to a valid integer type and this type
278  // is consistent with an option definition.
279  checkDataType<T>(index);
280  // Get some temporary buffer.
281  OptionBuffer buf;
282  // Try to write to the buffer.
283  OptionDataTypeUtil::writeInt<T>(value, buf);
284  // If successful, replace the old buffer with new one.
285  std::swap(buffers_[index], buf);
286  }
287 
294  PrefixTuple readPrefix(const uint32_t index = 0) const;
295 
303  void writePrefix(const PrefixLen& prefix_len,
304  const asiolink::IOAddress& prefix,
305  const uint32_t index = 0);
306 
313  PSIDTuple readPsid(const uint32_t index = 0) const;
314 
324  void writePsid(const PSIDLen& psid_len, const PSID& psid,
325  const uint32_t index = 0);
326 
333  std::string readString(const uint32_t index = 0) const;
334 
339  void writeString(const std::string& text,
340  const uint32_t index = 0);
341 
346  virtual void pack(isc::util::OutputBuffer& buf, bool check = true) const;
347 
352  virtual void unpack(OptionBufferConstIter begin,
354 
360  virtual std::string toText(int indent = 0) const;
361 
366  virtual uint16_t len() const;
367 
374  void initialize(const OptionBufferConstIter first,
375  const OptionBufferConstIter last);
376 
377 private:
378 
386  inline void checkArrayType() const {
387  if (!definition_.getArrayType()) {
388  isc_throw(InvalidOperation, "failed to add new array entry to an"
389  << " option. The option is not an array.");
390  }
391  }
392 
403  template<typename T>
404  // cppcheck-suppress unusedPrivateFunction
405  void checkDataType(const uint32_t index) const;
406 
412  void checkIndex(const uint32_t index) const;
413 
418  void createBuffer(OptionBuffer& buffer,
419  const OptionDataType data_type) const;
420 
422  void createBuffers();
423 
433  size_t bufferLength(const OptionDataType data_type, bool in_array,
434  OptionBuffer::const_iterator begin,
435  OptionBuffer::const_iterator end) const;
436 
440  void createBuffers(const OptionBuffer& data_buf);
441 
448  std::string dataFieldToText(const OptionDataType data_type,
449  const uint32_t index) const;
450 
454  using Option::setData;
455 
457  OptionDefinition definition_;
458 
462  std::vector<OptionBuffer> buffers_;
463 };
464 
466 typedef boost::shared_ptr<OptionCustom> OptionCustomPtr;
467 
468 template<typename T>
469 void
470 OptionCustom::checkDataType(const uint32_t index) const {
471  // Check that the requested return type is a supported integer.
473  isc_throw(isc::dhcp::InvalidDataType, "specified data type"
474  " is not a supported integer type.");
475  }
476 
477  // Get the option definition type.
478  OptionDataType data_type = definition_.getType();
479  if (data_type == OPT_RECORD_TYPE) {
480  const OptionDefinition::RecordFieldsCollection& record_fields =
481  definition_.getRecordFields();
482  if (definition_.getArrayType()) {
483  // If the array flag is set the last record field is an array.
484  if (index < record_fields.size()) {
485  // Get the data type to be returned.
486  data_type = record_fields[index];
487  } else {
488  // Get the data type to be returned from the last record field.
489  data_type = record_fields.back();
490  }
491  } else {
492  // When we initialized buffers we have already checked that
493  // the number of these buffers is equal to number of option
494  // fields in the record so the condition below should be met.
495  isc_throw_assert(index < record_fields.size());
496  // Get the data type to be returned.
497  data_type = record_fields[index];
498  }
499  }
500 
501  if (OptionDataTypeTraits<T>::type != data_type) {
503  "specified data type " << data_type << " does not"
504  " match the data type in an option definition for field"
505  " index " << index);
506  }
507 }
508 } // namespace isc::dhcp
509 } // namespace isc
510 
511 #endif // OPTION_CUSTOM_H
A generic exception that is thrown if a function is called in a prohibited way.
Exception to be thrown when invalid type specified as template parameter.
Represents a single instance of the opaque data preceded by length.
Option with defined data fields represented as buffers that can be accessed using data field index.
Definition: option_custom.h:32
std::string readString(const uint32_t index=0) const
Read a buffer as string value.
void addArrayDataField(const T value)
Create new buffer and store integer value in it.
bool readBoolean(const uint32_t index=0) const
Read a buffer as boolean value.
virtual uint16_t len() const
Returns length of the complete option (data length + DHCPv4/DHCPv6 option header)
std::string readTuple(const uint32_t index=0) const
Read a buffer as length and string tuple.
void writeFqdn(const std::string &fqdn, const uint32_t index=0)
Write an FQDN into a buffer.
std::string readFqdn(const uint32_t index=0) const
Read a buffer as FQDN.
void writePrefix(const PrefixLen &prefix_len, const asiolink::IOAddress &prefix, const uint32_t index=0)
Write prefix length and value into a buffer.
virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end)
Parses received buffer.
void writeAddress(const asiolink::IOAddress &address, const uint32_t index=0)
Write an IP address into a buffer.
virtual void pack(isc::util::OutputBuffer &buf, bool check=true) const
Writes DHCP option in a wire format to a buffer.
void initialize(const OptionBufferConstIter first, const OptionBufferConstIter last)
Sets content of this option from buffer.
const OptionBuffer & readBinary(const uint32_t index=0) const
Read a buffer as binary data.
PrefixTuple readPrefix(const uint32_t index=0) const
Read a buffer as variable length prefix.
void writePsid(const PSIDLen &psid_len, const PSID &psid, const uint32_t index=0)
Write PSID length / value into a buffer.
void writeBoolean(const bool value, const uint32_t index=0)
Write a boolean value into a buffer.
asiolink::IOAddress readAddress(const uint32_t index=0) const
Read a buffer as IP address.
PSIDTuple readPsid(const uint32_t index=0) const
Read a buffer as a PSID length / value tuple.
void writeString(const std::string &text, const uint32_t index=0)
Write a string value into a buffer.
T readInteger(const uint32_t index=0) const
Read a buffer as integer value.
void writeBinary(const OptionBuffer &buf, const uint32_t index=0)
Write binary data into a buffer.
void addArrayDataField(const asiolink::IOAddress &address)
Create new buffer and set its value as an IP address.
virtual OptionPtr clone() const
Copies this option and returns a pointer to the copy.
void writeTuple(const std::string &value, const uint32_t index=0)
Write a length and string tuple into a buffer.
virtual std::string toText(int indent=0) const
Returns string representation of the option.
OptionCustom(const OptionDefinition &def, Universe u)
Constructor, used for options to be sent.
uint32_t getDataFieldsNum() const
Return a number of the data fields.
void writeInteger(const T value, const uint32_t index=0)
Write an integer value into a buffer.
Base class representing a DHCP option definition.
OptionDataType getType() const
Return option data type.
const RecordFieldsCollection & getRecordFields() const
Return list of record fields.
std::vector< OptionDataType > RecordFieldsCollection
List of fields within the record.
bool getArrayType() const
Return array type indicator.
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:83
void setData(InputIterator first, InputIterator last)
Sets content of this option from buffer.
Definition: option.h:427
void check() const
A protected method used for option correctness.
Definition: option.cc:90
Encapsulates PSID length.
Encapsulates PSID value.
Encapsulates prefix length.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define isc_throw_assert(expr)
Replacement for assert() that throws if the expression is false.
Definition: isc_assert.h:18
std::pair< PSIDLen, PSID > PSIDTuple
Defines a pair of PSID length / value.
OptionDataType
Data types of DHCP option fields.
boost::shared_ptr< OptionCustom > OptionCustomPtr
A pointer to the OptionCustom object.
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
Definition: option.h:30
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
boost::shared_ptr< Option > OptionPtr
Definition: option.h:36
Defines the logger used by the top-level component of kea-lfc.
Trait class for data types supported in DHCP option definitions.