43 :
Option(u, def.getCode(), first, last),
46 createBuffers(
getData(), rec_level);
61 << address <<
". Expected a valid IPv"
63 "4" :
"6") <<
" address.");
68 buffers_.push_back(buf);
78 buffers_.push_back(buf);
87 buffers_.push_back(buf);
96 buffers_.push_back(buf);
106 " an option comprising an array of IPv6 prefix values");
111 buffers_.push_back(buf);
120 " an option comprising an array of PSID length / value"
126 buffers_.push_back(buf);
130OptionCustom::checkIndex(
const uint32_t index)
const {
131 if (index >= buffers_.size()) {
133 <<
" is out of range.");
149 if (data_size == 0) {
162 buffer.resize(data_size);
167OptionCustom::createBuffers() {
168 definition_.validate();
170 std::vector<OptionBuffer> buffers;
184 definition_.getRecordFields();
186 for (
auto const& field : fields) {
188 createBuffer(buf, field);
191 buffers.push_back(buf);
193 }
else if (!definition_.getArrayType() &&
203 createBuffer(buf, data_type);
205 buffers.push_back(buf);
210 std::swap(buffers, buffers_);
214OptionCustom::bufferLength(
const OptionDataType data_type,
bool in_array,
215 OptionBuffer::const_iterator begin,
216 OptionBuffer::const_iterator end)
const {
224 if (data_size == 0) {
238 data_size = fqdn.size() + 1;
239 }
catch (
const std::exception& ex) {
241 isc_throw(SkipThisOptionError,
"failed to read "
242 "domain-name from wire format: "
248 }
else if (!definition_.getArrayType() &&
257 data_size = std::distance(begin, end);
263 if ((begin == end) && !in_array)
269 data_size =
sizeof(uint8_t) + (prefix.first.asUint8() + 7) / 8;
275 data_size = value.size();
283 isc_throw(OutOfRange,
"option buffer truncated");
291OptionCustom::createBuffers(
const OptionBuffer& data_buf,
size_t rec_level) {
294 definition_.validate();
296 std::vector<OptionBuffer> buffers;
297 OptionBuffer::const_iterator data = data_buf.begin();
305 definition_.getRecordFields();
308 for (
auto const& field : fields) {
309 size_t data_size = bufferLength(field,
false,
310 data, data_buf.end());
314 if (
static_cast<size_t>(std::distance(data, data_buf.end())) < data_size) {
315 isc_throw(OutOfRange,
"option buffer truncated");
319 buffers.push_back(
OptionBuffer(data, data + data_size));
325 if (definition_.getArrayType()) {
326 while (data != data_buf.end()) {
328 size_t data_size = bufferLength(fields.back(),
true,
329 data, data_buf.end());
331 if (
static_cast<size_t>(std::distance(data, data_buf.end())) < data_size) {
334 buffers.push_back(
OptionBuffer(data, data + data_size));
356 if (
static_cast<size_t>(std::distance(data, data_buf.end())) < data_size) {
357 isc_throw(OutOfRange,
"option buffer truncated");
361 if (definition_.getArrayType()) {
362 while (data != data_buf.end()) {
363 data_size = bufferLength(data_type,
true, data, data_buf.end());
375 if (
static_cast<size_t>(std::distance(data, data_buf.end())) < data_size) {
378 buffers.push_back(
OptionBuffer(data, data + data_size));
385 data_size = bufferLength(data_type,
false, data, data_buf.end());
386 if ((data_size > 0) &&
387 (
static_cast<size_t>(std::distance(data, data_buf.end())) >= data_size)) {
388 buffers.push_back(
OptionBuffer(data, data + data_size));
391 isc_throw(OutOfRange,
"option buffer truncated");
406 std::swap(buffers_, buffers);
411 const uint32_t index)
const {
412 std::ostringstream text;
424 std::string printable(data.cbegin(), data.cend());
425 text <<
" '" << printable <<
"'";
437 text << readInteger<int16_t>(index);
440 text << readInteger<int32_t>(index);
446 text << readInteger<uint16_t>(index);
449 text << readInteger<uint32_t>(index);
456 text <<
"\"" <<
readFqdn(index) <<
"\"";
459 text <<
"\"" <<
readTuple(index) <<
"\"";
467 text <<
"len=" << t.first.asUnsigned() <<
",psid=" << t.second.asUint16();
487 for (
auto const& it : buffers_) {
508 if (buffers_[index].size() == asiolink::V4ADDRESS_LEN) {
510 }
else if (buffers_[index].size() == asiolink::V6ADDRESS_LEN) {
514 <<
" IP address. Invalid buffer length "
515 << buffers_[index].size() <<
".");
521 const uint32_t index) {
524 if ((address.
isV4() && buffers_[index].size() != V4ADDRESS_LEN) ||
525 (address.
isV6() && buffers_[index].size() != V6ADDRESS_LEN)) {
527 << address <<
". Expected a valid IPv"
528 << (buffers_[index].size() == V4ADDRESS_LEN ?
"4" :
"6")
534 std::swap(buf, buffers_[index]);
540 return (buffers_[index]);
545 const uint32_t index) {
547 buffers_[index] = buf;
559 const uint32_t index)
const {
568 buffers_[index].clear();
577 buffers_[index].clear();
591 buffers_[index].clear();
615 std::swap(buffers_[index], buf);
627 const uint32_t index) {
634 std::swap(buffers_[index], buf);
646 const uint32_t index) {
653 std::swap(buffers_[index], buf);
670 buffers_[index].clear();
690 for (
auto const& buf : buffers_) {
691 length += buf.size();
696 length += it.second->len();
699 return (
static_cast<uint16_t
>(length));
704 setData(first, last);
712 std::stringstream output;
719 definition_.getRecordFields();
725 for (
auto const& field : fields) {
726 output <<
" " << dataFieldToText(field, j);
731 if (definition_.getArrayType()) {
733 output <<
" " << dataFieldToText(fields.back(), i);
743 output <<
" " << dataFieldToText(definition_.getType(), i);
750 return (output.str());
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
The IOAddress class represents an IP addresses (version agnostic).
bool isV6() const
Convenience function to check for an IPv6 address.
bool isV4() const
Convenience function to check for an IPv4 address.
static const IOAddress & IPV6_ZERO_ADDRESS()
Returns an IPv6 zero address.
Exception to be thrown when cast to the data type was unsuccessful.
Represents a single instance of the opaque data preceded by length.
LengthFieldType
Size of the length field in the tuple.
std::string readString(const uint32_t index=0) const
Read a buffer as string value.
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.
static PrefixTuple readPrefix(const std::vector< uint8_t > &buf)
Read prefix from a buffer.
static asiolink::IOAddress readAddress(const std::vector< uint8_t > &buf, const short family)
Read IPv4 or IPv6 address from a buffer.
static void writeFqdn(const std::string &fqdn, std::vector< uint8_t > &buf, const bool downcase=false)
Append FQDN into a buffer.
static void writePrefix(const PrefixLen &prefix_len, const asiolink::IOAddress &prefix, std::vector< uint8_t > &buf)
Append prefix into a buffer.
static const std::string & getDataTypeName(const OptionDataType data_type)
Return option data type name from the data type enumerator.
static int getDataTypeLen(const OptionDataType data_type)
Get data type buffer length.
static std::string readTuple(const std::vector< uint8_t > &buf, OpaqueDataTuple::LengthFieldType lengthfieldtype)
Read length and string tuple from a buffer.
static std::string readFqdn(const std::vector< uint8_t > &buf, bool raw=false)
Read FQDN from a buffer as a string value.
static void writeAddress(const asiolink::IOAddress &address, std::vector< uint8_t > &buf)
Append IPv4 or IPv6 address to a buffer.
static PSIDTuple readPsid(const std::vector< uint8_t > &buf)
Read PSID length / value tuple from a buffer.
static void writePsid(const PSIDLen &psid_len, const PSID &psid, std::vector< uint8_t > &buf)
Append PSID length/value into a buffer.
static void writeString(const std::string &value, std::vector< uint8_t > &buf)
Write UTF8-encoded string into a buffer.
static void writeTuple(const std::string &value, OpaqueDataTuple::LengthFieldType lengthfieldtype, std::vector< uint8_t > &buf)
Append length and string tuple to a buffer.
static OpaqueDataTuple::LengthFieldType getTupleLenFieldType(Option::Universe u)
Returns Length Field Type for a tuple.
static void writeBool(const bool value, std::vector< uint8_t > &buf)
Append boolean value into a buffer.
static bool readBool(const std::vector< uint8_t > &buf)
Read boolean value from a buffer.
static std::string readString(const std::vector< uint8_t > &buf)
Read string value from a buffer.
Base class representing a DHCP option definition.
std::vector< OptionDataType > RecordFieldsCollection
List of fields within the record.
std::string getEncapsulatedSpace() const
Return name of the encapsulated option space.
std::string headerToText(const int indent=0, const std::string &type_name="") const
Returns option header in the textual format.
std::string suboptionsToText(const int indent=0) const
Returns collection of suboptions in the textual format.
static bool lenient_parsing_
Governs whether options should be parsed less strictly.
std::string getEncapsulatedSpace() const
Returns the name of the option space encapsulated by this option.
void setEncapsulatedSpace(const std::string &encapsulated_space)
Sets the name of the option space encapsulated by this option.
virtual const OptionBuffer & getData() const
Returns pointer to actual data.
virtual uint16_t getHeaderLen() const
Returns length of header (2 for v4, 4 for v6).
Universe
defines option universe DHCPv4 or DHCPv6
void packOptions(isc::util::OutputBuffer &buf, bool check=true) const
Store sub options in a buffer.
OptionCollection options_
collection for storing suboptions
void unpackOptions(const OptionBuffer &buf, size_t rec_level=0)
Builds a collection of sub options from the buffer.
OptionPtr cloneInternal() const
Copies this option and returns a pointer to the copy.
Universe getUniverse() const
returns option universe (V4 or V6)
void packHeader(isc::util::OutputBuffer &buf, bool check=true) const
Store option's header in a buffer.
Option(Universe u, uint16_t type)
ctor, used for options constructed, usually during transmission
void check() const
A protected method used for option correctness.
Encapsulates PSID length.
Encapsulates prefix length.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
#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.
std::pair< PSIDLen, PSID > PSIDTuple
Defines a pair of PSID length / value.
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
std::pair< PrefixLen, asiolink::IOAddress > PrefixTuple
Defines a pair of prefix length / value.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
OptionDataType
Data types of DHCP option fields.
boost::shared_ptr< Option > OptionPtr
string encodeHex(const vector< uint8_t > &binary)
Encode binary data in the base16 format.
bool isPrintable(const string &content)
Check if a string is printable.
Defines the logger used by the top-level component of kea-lfc.