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
void writeTuple(const std::string &value, const uint32_t index=0)
Write a length and string tuple into a buffer.
void addArrayDataField(const asiolink::IOAddress &address)
Create new buffer and set its value as an IP address.
Encapsulates PSID length.
asiolink::IOAddress readAddress(const uint32_t index=0) const
Read a buffer as IP address.
Base class representing a DHCP option definition.
boost::shared_ptr< OptionCustom > OptionCustomPtr
A pointer to the OptionCustom object.
uint32_t getDataFieldsNum() const
Return a number of the data fields.
bool readBoolean(const uint32_t index=0) const
Read a buffer as boolean value.
void writeAddress(const asiolink::IOAddress &address, const uint32_t index=0)
Write an IP address into a buffer.
std::vector< OptionDataType > RecordFieldsCollection
List of fields within the record.
std::string readFqdn(const uint32_t index=0) const
Read a buffer as FQDN.
OptionCustom(const OptionDefinition &def, Universe u)
Constructor, used for options to be sent.
boost::shared_ptr< Option > OptionPtr
Definition: option.h:37
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:67
std::pair< PrefixLen, asiolink::IOAddress > PrefixTuple
Defines a pair of prefix length / value.
Exception to be thrown when invalid type specified as template parameter.
virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end)
Parses received buffer.
void writeBoolean(const bool value, const uint32_t index=0)
Write a boolean value into a buffer.
PSIDTuple readPsid(const uint32_t index=0) const
Read a buffer as a PSID length / value tuple.
virtual uint16_t len() const
Returns length of the complete option (data length + DHCPv4/DHCPv6 option header)
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition: option.h:25
std::string readTuple(const uint32_t index=0) const
Read a buffer as length and string tuple.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
OptionDataType
Data types of DHCP option fields.
Encapsulates PSID value.
virtual OptionPtr clone() const
Copies this option and returns a pointer to the copy.
void writePsid(const PSIDLen &psid_len, const PSID &psid, const uint32_t index=0)
Write PSID length / value into a buffer.
void writePrefix(const PrefixLen &prefix_len, const asiolink::IOAddress &prefix, const uint32_t index=0)
Write prefix length and value into a buffer.
PrefixTuple readPrefix(const uint32_t index=0) const
Read a buffer as variable length prefix.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
Definition: option.h:31
std::pair< PSIDLen, PSID > PSIDTuple
Defines a pair of PSID length / value.
Defines the logger used by the top-level component of kea-dhcp-ddns.
virtual void pack(isc::util::OutputBuffer &buf) const
Writes DHCP option in a wire format to a buffer.
void writeInteger(const T value, const uint32_t index=0)
Write an integer value into a buffer.
const RecordFieldsCollection & getRecordFields() const
Return list of record fields.
void writeBinary(const OptionBuffer &buf, const uint32_t index=0)
Write binary data into a buffer.
virtual std::string toText(int indent=0) const
Returns string representation of the option.
A generic exception that is thrown if a function is called in a prohibited way.
void writeFqdn(const std::string &fqdn, const uint32_t index=0)
Write an FQDN into a buffer.
Represents a single instance of the opaque data preceded by length.
T readInteger(const uint32_t index=0) const
Read a buffer as integer value.
Trait class for data types supported in DHCP option definitions.
std::string readString(const uint32_t index=0) const
Read a buffer as string value.
bool getArrayType() const
Return array type indicator.
OptionDataType getType() const
Return option data type.
Option with defined data fields represented as buffers that can be accessed using data field index.
Definition: option_custom.h:31
void setData(InputIterator first, InputIterator last)
Sets content of this option from buffer.
Definition: option.h:366
Encapsulates prefix length.
void writeString(const std::string &text, const uint32_t index=0)
Write a string value into a buffer.
void addArrayDataField(const T value)
Create new buffer and store integer value in it.
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.