Kea  1.5.0
option_custom.h
Go to the documentation of this file.
1 // Copyright (C) 2012-2017 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 <util/io_utilities.h>
14 
15 namespace isc {
16 namespace dhcp {
17 
31 class OptionCustom : public Option {
32 public:
33 
43  OptionCustom(const OptionDefinition& def, Universe u);
44 
60  OptionCustom(const OptionDefinition& def, Universe u, const OptionBuffer& data);
61 
82 
84  virtual OptionPtr clone() const;
85 
90  void addArrayDataField(const asiolink::IOAddress& address);
91 
95  void addArrayDataField(const bool value);
96 
101  template<typename T>
102  void addArrayDataField(const T value) {
103  checkArrayType();
104  OptionDataType data_type = definition_.getType();
105  // Handle record last field.
106  if (data_type == OPT_RECORD_TYPE) {
107  data_type = definition_.getRecordFields().back();
108  }
109  if (OptionDataTypeTraits<T>::type != data_type) {
111  "specified data type " << data_type << " does not"
112  " match the data type in an option definition");
113  }
114 
115  OptionBuffer buf;
116  OptionDataTypeUtil::writeInt<T>(value, buf);
117  buffers_.push_back(buf);
118  }
119 
123  void addArrayDataField(const std::string& value);
124 
128  void addArrayDataField(const OpaqueDataTuple& value);
129 
134  void addArrayDataField(const PrefixLen& prefix_len,
135  const asiolink::IOAddress& prefix);
136 
141  void addArrayDataField(const PSIDLen& psid_len, const PSID& psid);
142 
146  uint32_t getDataFieldsNum() const { return (buffers_.size()); }
147 
154  asiolink::IOAddress readAddress(const uint32_t index = 0) const;
155 
163  void writeAddress(const asiolink::IOAddress& address,
164  const uint32_t index = 0);
165 
172  const OptionBuffer& readBinary(const uint32_t index = 0) const;
173 
178  void writeBinary(const OptionBuffer& buf, const uint32_t index = 0);
179 
186  std::string readTuple(const uint32_t index = 0) const;
187 
194  void readTuple(OpaqueDataTuple& tuple, const uint32_t index = 0) const;
195 
200  void writeTuple(const std::string& value, const uint32_t index = 0);
201 
206  void writeTuple(const OpaqueDataTuple& value, const uint32_t index = 0);
207 
214  bool readBoolean(const uint32_t index = 0) const;
215 
222  void writeBoolean(const bool value, const uint32_t index = 0);
223 
232  std::string readFqdn(const uint32_t index = 0) const;
233 
240  void writeFqdn(const std::string& fqdn, const uint32_t index = 0);
241 
250  template<typename T>
251  T readInteger(const uint32_t index = 0) const {
252  // Check that the index is not out of range.
253  checkIndex(index);
254  // Check that T points to a valid integer type and this type
255  // is consistent with an option definition.
256  checkDataType<T>(index);
257  // When we created the buffer we have checked that it has a
258  // valid size so this condition here should be always fulfilled.
259  assert(buffers_[index].size() == OptionDataTypeTraits<T>::len);
260  // Read an integer value.
261  return (OptionDataTypeUtil::readInt<T>(buffers_[index]));
262  }
263 
272  template<typename T>
273  void writeInteger(const T value, const uint32_t index = 0) {
274  // Check that the index is not out of range.
275  checkIndex(index);
276  // Check that T points to a valid integer type and this type
277  // is consistent with an option definition.
278  checkDataType<T>(index);
279  // Get some temporary buffer.
280  OptionBuffer buf;
281  // Try to write to the buffer.
282  OptionDataTypeUtil::writeInt<T>(value, buf);
283  // If successful, replace the old buffer with new one.
284  std::swap(buffers_[index], buf);
285  }
286 
293  PrefixTuple readPrefix(const uint32_t index = 0) const;
294 
302  void writePrefix(const PrefixLen& prefix_len,
303  const asiolink::IOAddress& prefix,
304  const uint32_t index = 0);
305 
312  PSIDTuple readPsid(const uint32_t index = 0) const;
313 
323  void writePsid(const PSIDLen& psid_len, const PSID& psid,
324  const uint32_t index = 0);
325 
332  std::string readString(const uint32_t index = 0) const;
333 
338  void writeString(const std::string& text,
339  const uint32_t index = 0);
340 
344  virtual void pack(isc::util::OutputBuffer& buf) const;
345 
350  virtual void unpack(OptionBufferConstIter begin,
352 
358  virtual std::string toText(int indent = 0) const;
359 
364  virtual uint16_t len() const;
365 
372  void initialize(const OptionBufferConstIter first,
373  const OptionBufferConstIter last);
374 
375 private:
376 
384  inline void checkArrayType() const {
385  if (!definition_.getArrayType()) {
386  isc_throw(InvalidOperation, "failed to add new array entry to an"
387  << " option. The option is not an array.");
388  }
389  }
390 
401  template<typename T>
402  // cppcheck-suppress unusedPrivateFunction
403  void checkDataType(const uint32_t index) const;
404 
410  void checkIndex(const uint32_t index) const;
411 
416  void createBuffer(OptionBuffer& buffer,
417  const OptionDataType data_type) const;
418 
420  void createBuffers();
421 
431  size_t bufferLength(const OptionDataType data_type, bool in_array,
432  OptionBuffer::const_iterator begin,
433  OptionBuffer::const_iterator end) const;
434 
438  void createBuffers(const OptionBuffer& data_buf);
439 
446  std::string dataFieldToText(const OptionDataType data_type,
447  const uint32_t index) const;
448 
452  using Option::setData;
453 
455  OptionDefinition definition_;
456 
460  std::vector<OptionBuffer> buffers_;
461 };
462 
464 typedef boost::shared_ptr<OptionCustom> OptionCustomPtr;
465 
466 template<typename T>
467 void
468 OptionCustom::checkDataType(const uint32_t index) const {
469  // Check that the requested return type is a supported integer.
471  isc_throw(isc::dhcp::InvalidDataType, "specified data type"
472  " is not a supported integer type.");
473  }
474 
475  // Get the option definition type.
476  OptionDataType data_type = definition_.getType();
477  if (data_type == OPT_RECORD_TYPE) {
478  const OptionDefinition::RecordFieldsCollection& record_fields =
479  definition_.getRecordFields();
480  if (definition_.getArrayType()) {
481  // If the array flag is set the last record field is an array.
482  if (index < record_fields.size()) {
483  // Get the data type to be returned.
484  data_type = record_fields[index];
485  } else {
486  // Get the data type to be returned from the last record field.
487  data_type = record_fields.back();
488  }
489  } else {
490  // When we initialized buffers we have already checked that
491  // the number of these buffers is equal to number of option
492  // fields in the record so the condition below should be met.
493  assert(index < record_fields.size());
494  // Get the data type to be returned.
495  data_type = record_fields[index];
496  }
497  }
498 
499  if (OptionDataTypeTraits<T>::type != data_type) {
501  "specified data type " << data_type << " does not"
502  " match the data type in an option definition for field"
503  " index " << index);
504  }
505 }
506 } // namespace isc::dhcp
507 } // namespace isc
508 
509 #endif // OPTION_CUSTOM_H
isc::dhcp::OptionBuffer
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition: option.h:25
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:273
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:51
isc::dhcp::OptionCustom
Option with defined data fields represented as buffers that can be accessed using data field index.
Definition: option_custom.h:31
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:643
io_address.h
isc::dhcp::OptionDefinition::getRecordFields
const RecordFieldsCollection & getRecordFields() const
Return list of record fields.
Definition: option_definition.h:281
isc::dhcp::OptionCustom::initialize
void initialize(const OptionBufferConstIter first, const OptionBufferConstIter last)
Sets content of this option from buffer.
Definition: option_custom.cc:684
isc::dhcp::OptionCustom::readString
std::string readString(const uint32_t index=0) const
Read a buffer as string value.
Definition: option_custom.cc:637
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:543
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:581
isc::dhcp::OptionCustom::readAddress
asiolink::IOAddress readAddress(const uint32_t index=0) const
Read a buffer as IP address.
Definition: option_custom.cc:479
isc::dhcp::OptionDefinition
Base class representing a DHCP option definition.
Definition: option_definition.h:137
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:497
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:664
isc
Defines the logger used by the top-level component of kea-dhcp-ddns.
Definition: agent_parser.cc:144
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:528
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:192
isc::dhcp::OptionCustom::clone
virtual OptionPtr clone() const
Copies this option and returns a pointer to the copy.
Definition: option_custom.cc:46
isc::dhcp::OptionDataTypeTraits
Trait class for data types supported in DHCP option definitions.
Definition: option_data_types.h:92
isc::InvalidOperation
A generic exception that is thrown if a function is called in a prohibited way.
Definition: exceptions/exceptions.h:143
isc::dhcp::PrefixLen
Encapsulates prefix length.
Definition: option_data_types.h:277
isc::util::OutputBuffer
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
isc::dhcp::OptionDefinition::getArrayType
bool getArrayType() const
Return array type indicator.
Definition: option_definition.h:259
isc::dhcp::OptionCustom::toText
virtual std::string toText(int indent=0) const
Returns string representation of the option.
Definition: option_custom.cc:693
isc::dhcp::InvalidDataType
Exception to be thrown when invalid type specified as template parameter.
Definition: option_data_types.h:23
isc::dhcp::OptionCustomPtr
boost::shared_ptr< OptionCustom > OptionCustomPtr
A pointer to the OptionCustom object.
Definition: option_custom.h:464
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:604
isc::dhcp::PrefixTuple
std::pair< PrefixLen, asiolink::IOAddress > PrefixTuple
Defines a pair of prefix length / value.
Definition: option_data_types.h:315
option_definition.h
isc::dhcp::OPT_RECORD_TYPE
@ OPT_RECORD_TYPE
Definition: option_data_types.h:63
isc::dhcp::OptionCustom::readBinary
const OptionBuffer & readBinary(const uint32_t index=0) const
Read a buffer as binary data.
Definition: option_custom.cc:515
isc::dhcp::OptionCustom::readBoolean
bool readBoolean(const uint32_t index=0) const
Read a buffer as boolean value.
Definition: option_custom.cc:561
isc::dhcp::Option::setData
void setData(InputIterator first, InputIterator last)
Sets content of this option from buffer.
Definition: option.h:366
isc::dhcp::OptionCustom::pack
virtual void pack(isc::util::OutputBuffer &buf) const
Writes DHCP option in a wire format to a buffer.
Definition: option_custom.cc:457
isc::dhcp::OpaqueDataTuple
Represents a single instance of the opaque data preceded by length.
Definition: opaque_data_tuple.h:45
io_utilities.h
isc::dhcp::OptionDataType
OptionDataType
Data types of DHCP option fields.
Definition: option_data_types.h:45
isc::dhcp::OptionCustom::writeBinary
void writeBinary(const OptionBuffer &buf, const uint32_t index=0)
Write binary data into a buffer.
Definition: option_custom.cc:521
isc::dhcp::OptionCustom::getDataFieldsNum
uint32_t getDataFieldsNum() const
Return a number of the data fields.
Definition: option_custom.h:146
isc::dhcp::OptionPtr
boost::shared_ptr< Option > OptionPtr
Definition: option.h:37
isc::dhcp::OptionCustom::unpack
virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end)
Parses received buffer.
Definition: option_custom.cc:658
isc::dhcp::OptionDefinition::getType
OptionDataType getType() const
Return option data type.
Definition: option_definition.h:288
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:567
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:618
isc::dhcp::OptionCustom::readPrefix
PrefixTuple readPrefix(const uint32_t index=0) const
Read a buffer as variable length prefix.
Definition: option_custom.cc:598
isc::dhcp::PSIDLen
Encapsulates PSID length.
Definition: option_data_types.h:201
isc::dhcp::Option::Universe
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:67
option.h
isc::dhcp::OptionCustom::addArrayDataField
void addArrayDataField(const T value)
Create new buffer and store integer value in it.
Definition: option_custom.h:102
isc::dhcp::OptionCustom::readInteger
T readInteger(const uint32_t index=0) const
Read a buffer as integer value.
Definition: option_custom.h:251
isc::dhcp::PSIDTuple
std::pair< PSIDLen, PSID > PSIDTuple
Defines a pair of PSID length / value.
Definition: option_data_types.h:274
isc::dhcp::Option
Definition: option.h:58
isc::dhcp::PSID
Encapsulates PSID value.
Definition: option_data_types.h:246
isc::dhcp::OptionBufferConstIter
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
Definition: option.h:31
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:624
isc::dhcp::OptionDefinition::RecordFieldsCollection
std::vector< OptionDataType > RecordFieldsCollection
List of fields within the record.
Definition: option_definition.h:141
isc::dhcp::OptionCustom::readFqdn
std::string readFqdn(const uint32_t index=0) const
Read a buffer as FQDN.
Definition: option_custom.cc:575
isc::dhcp::OptionCustom::OptionCustom
OptionCustom(const OptionDefinition &def, Universe u)
Constructor, used for options to be sent.
Definition: option_custom.cc:18