Kea  2.3.3-git
option_vendor.cc
Go to the documentation of this file.
1 // Copyright (C) 2013-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 #include <config.h>
8 
9 #include <dhcp/dhcp4.h>
10 #include <dhcp/dhcp6.h>
11 #include <dhcp/option_vendor.h>
12 #include <sstream>
13 
14 using namespace isc::dhcp;
15 
16 OptionVendor::OptionVendor(Option::Universe u, const uint32_t vendor_id)
17  : Option(u, u == Option::V4 ?
18  static_cast<uint16_t>(DHO_VIVSO_SUBOPTIONS) :
19  static_cast<uint16_t>(D6O_VENDOR_OPTS)),
20  vendor_id_(vendor_id) {
21 }
22 
25  : Option(u, u == Option::V4?
26  static_cast<uint16_t>(DHO_VIVSO_SUBOPTIONS) :
27  static_cast<uint16_t>(D6O_VENDOR_OPTS)),
28  vendor_id_(0) {
29  unpack(begin, end);
30 }
31 
34  return (cloneInternal<OptionVendor>());
35 }
36 
38  packHeader(buf, check);
39 
40  // Store vendor-id
41  buf.writeUint32(vendor_id_);
42 
43  // The format is slightly different for v4
44  if (universe_ == Option::V4) {
45  // Calculate and store data-len as follows:
46  // data-len = total option length - header length
47  // - enterprise id field length - data-len field size
48  buf.writeUint8(dataLen());
49  }
50 
51  packOptions(buf, check);
52 }
53 
56 
57  // We throw SkipRemainingOptionsError so callers can
58  // abandon further unpacking, if desired.
59  if (distance(begin, end) < sizeof(uint32_t)) {
61  "Truncated vendor-specific information option"
62  << ", length=" << distance(begin, end));
63  }
64 
65  vendor_id_ = isc::util::readUint32(&(*begin), distance(begin, end));
66 
67  OptionBuffer vendor_buffer(begin + 4, end);
68 
69  if (universe_ == Option::V6) {
70  LibDHCP::unpackVendorOptions6(vendor_id_, vendor_buffer, options_);
71  } else {
72  LibDHCP::unpackVendorOptions4(vendor_id_, vendor_buffer, options_);
73  }
74 }
75 
76 uint16_t OptionVendor::len() const {
77  uint16_t length = getHeaderLen();
78 
79  length += sizeof(uint32_t); // Vendor-id field
80 
81  // Data-len field exists in DHCPv4 vendor options only
82  if (universe_ == Option::V4) {
83  length += sizeof(uint8_t); // data-len
84  }
85 
86  // length of all suboptions
87  for (OptionCollection::const_iterator it = options_.begin();
88  it != options_.end();
89  ++it) {
90  length += (*it).second->len();
91  }
92  return (length);
93 }
94 
95 uint8_t
96 OptionVendor::dataLen() const {
97  // Calculate and store data-len as follows:
98  // data-len = total option length - header length
99  // - enterprise id field length - data-len field size
100  return (len() - getHeaderLen() - sizeof(uint32_t) - sizeof(uint8_t));
101 }
102 
103 std::string
104 OptionVendor::toText(int indent) const {
105  std::stringstream output;
106  output << headerToText(indent) << ": "
107  << getVendorId() << " (uint32)";
108 
109  // For the DHCPv4 there is one more field.
110  if (getUniverse() == Option::V4) {
111  output << " " << static_cast<int>(dataLen()) << " (uint8)";
112  }
113 
114  // Append suboptions.
115  output << suboptionsToText(indent + 2);
116 
117  return (output.str());
118 }
std::string suboptionsToText(const int indent=0) const
Returns collection of suboptions in the textual format.
Definition: option.cc:307
uint32_t getVendorId() const
Returns enterprise identifier.
Definition: option_vendor.h:85
Exception thrown during option unpacking This exception is thrown when an error has occurred...
Definition: option.h:52
OptionVendor(Option::Universe u, const uint32_t vendor_id)
Constructor.
static size_t unpackVendorOptions4(const uint32_t vendor_id, const OptionBuffer &buf, isc::dhcp::OptionCollection &options)
Parses provided buffer as DHCPv4 vendor options and creates Option objects.
Definition: libdhcp++.cc:783
boost::shared_ptr< Option > OptionPtr
Definition: option.h:36
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:83
void packHeader(isc::util::OutputBuffer &buf, bool check=true) const
Store option&#39;s header in a buffer.
Definition: option.cc:119
virtual uint16_t getHeaderLen() const
Returns length of header (2 for v4, 4 for v6)
Definition: option.cc:321
Universe universe_
option universe (V4 or V6)
Definition: option.h:587
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition: option.h:24
virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end)
Parses received buffer.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
void packOptions(isc::util::OutputBuffer &buf, bool check=true) const
Store sub options in a buffer.
Definition: option.cc:136
std::string headerToText(const int indent=0, const std::string &type_name="") const
Returns option header in the textual format.
Definition: option.cc:288
Universe getUniverse() const
returns option universe (V4 or V6)
Definition: option.h:233
OptionCollection options_
collection for storing suboptions
Definition: option.h:596
OptionPtr clone() const
Copies this option and returns a pointer to the copy.
void check() const
A protected method used for option correctness.
Definition: option.cc:90
virtual std::string toText(int indent=0) const
Returns the option in the textual format.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
uint32_t readUint32(const uint8_t *buffer, size_t length)
Read Unsigned 32-Bit Integer from Buffer.
Definition: io_utilities.h:79
virtual void pack(isc::util::OutputBuffer &buf, bool check=true) const
Writes option in wire-format to buf, returns pointer to first unused byte after stored option...
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
Definition: option.h:30
void writeUint32(uint32_t data)
Write an unsigned 32-bit integer in host byte order into the buffer in network byte order...
Definition: buffer.h:520
static size_t unpackVendorOptions6(const uint32_t vendor_id, const OptionBuffer &buf, isc::dhcp::OptionCollection &options)
Parses provided buffer as DHCPv6 vendor options and creates Option objects.
Definition: libdhcp++.cc:686
void writeUint8(uint8_t data)
Write an unsigned 8-bit integer into the buffer.
Definition: buffer.h:466
virtual uint16_t len() const
returns complete length of option