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>
13#include <util/io_utilities.h>
14
15namespace isc {
16namespace dhcp {
17
31class OptionCustom : public Option {
32public:
33
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
375private:
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
464typedef boost::shared_ptr<OptionCustom> OptionCustomPtr;
465
466template<typename T>
467void
468OptionCustom::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
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:31
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.
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.
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.
virtual void pack(isc::util::OutputBuffer &buf) const
Writes DHCP option in a wire format to 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:67
void setData(InputIterator first, InputIterator last)
Sets content of this option from buffer.
Definition: option.h:366
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.
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:31
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:25
boost::shared_ptr< Option > OptionPtr
Definition: option.h:38
Defines the logger used by the top-level component of kea-dhcp-ddns.
Trait class for data types supported in DHCP option definitions.