Kea 2.5.8
option_opaque_data_tuples.cc
Go to the documentation of this file.
1// Copyright (C) 2015-2024 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
12#include <sstream>
13
14namespace isc {
15namespace dhcp {
16
18 const uint16_t type,
19 OpaqueDataTuple::LengthFieldType length_field_type)
20 : Option(u, type), length_field_type_(length_field_type) {
21 if (length_field_type_ == OpaqueDataTuple::LENGTH_EMPTY) {
22 length_field_type_ = OptionDataTypeUtil::getTupleLenFieldType(u);
23 }
24}
25
27 const uint16_t type,
30 OpaqueDataTuple::LengthFieldType length_field_type)
31 : Option(u, type), length_field_type_(length_field_type) {
32 if (length_field_type_ == OpaqueDataTuple::LENGTH_EMPTY) {
33 length_field_type_ = OptionDataTypeUtil::getTupleLenFieldType(u);
34 }
35 unpack(begin, end);
36}
37
40 return (cloneInternal<OptionOpaqueDataTuples>());
41}
42
43void
45 packHeader(buf, check);
46
47 for (auto const& it : tuples_) {
48 it.pack(buf);
49 }
50 // That's it. We don't pack any sub-options here, because this option
51 // must not contain sub-options.
52}
53
54void
57 // We are skipping typical OutOfRange check for Option#unpack(begin, end),
58 // since empty collection of tuples is also a valid case where
59 // std::distance(begin, end) = 0
60
61 // Start reading opaque data.
62 size_t offset = 0;
63 while (offset < std::distance(begin, end)) {
64 // Parse a tuple.
65 OpaqueDataTuple tuple(length_field_type_, begin + offset, end);
66 addTuple(tuple);
67 // The tuple has been parsed correctly which implies that it is safe to
68 // advance the offset by its total length.
69 offset += tuple.getTotalLength();
70 }
71}
72
73void
75 if (tuple.getLengthFieldType() != length_field_type_) {
76 isc_throw(isc::BadValue, "attempted to add opaque data tuple having"
77 " invalid size of the length field "
78 << tuple.getDataFieldSize() << " to opaque data tuple option");
79 }
80
81 tuples_.push_back(tuple);
82}
83
84
85void
86OptionOpaqueDataTuples::setTuple(const size_t at, const OpaqueDataTuple& tuple) {
87 if (at >= getTuplesNum()) {
88 isc_throw(isc::OutOfRange, "attempted to set an opaque data for the"
89 " opaque data tuple option at position " << at << " which"
90 " is out of range");
91
92 } else if (tuple.getLengthFieldType() != length_field_type_) {
93 isc_throw(isc::BadValue, "attempted to set opaque data tuple having"
94 " invalid size of the length field "
95 << tuple.getDataFieldSize() << " to opaque data tuple option");
96 }
97
98 tuples_[at] = tuple;
99}
100
102OptionOpaqueDataTuples::getTuple(const size_t at) const {
103 if (at >= getTuplesNum()) {
104 isc_throw(isc::OutOfRange, "attempted to get an opaque data for the"
105 " opaque data tuple option at position " << at << " which is"
106 " out of range. There are only " << getTuplesNum() << " tuples");
107 }
108 return (tuples_[at]);
109}
110
111bool
112OptionOpaqueDataTuples::hasTuple(const std::string& tuple_str) const {
113 // Iterate over existing tuples (there shouldn't be many of them),
114 // and try to match the searched one.
115 for (auto const& it : tuples_) {
116 if (it == tuple_str) {
117 return (true);
118 }
119 }
120 return (false);
121}
122
123uint16_t
125 // The option starts with the header.
126 uint16_t length = getHeaderLen();
127 // Now iterate over existing tuples and add their size.
128 for (auto const& it : tuples_) {
129 length += it.getTotalLength();
130 }
131
132 return (length);
133}
134
135std::string
137 std::ostringstream s;
138
139 // Apply indentation
140 s << std::string(indent, ' ');
141
142 // Print type and length
143 s << "type=" << getType() << ", len=" << len() - getHeaderLen() << std::dec;
144 // Iterate over all tuples and print their size and contents.
145 for (unsigned i = 0; i < getTuplesNum(); ++i) {
146 // Print the tuple.
147 s << ", data-len" << i << "=" << getTuple(i).getLength();
148 s << ", data" << i << "='" << getTuple(i) << "'";
149 }
150
151 return (s.str());
152}
153
154} // namespace isc::dhcp
155} // namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
Represents a single instance of the opaque data preceded by length.
int getDataFieldSize() const
Returns the size of the tuple length field.
LengthFieldType
Size of the length field in the tuple.
LengthFieldType getLengthFieldType() const
Returns tuple length data field type.
size_t getTotalLength() const
Returns a total size of the tuple, including length field.
size_t getLength() const
Returns the length of the data in the tuple.
static OpaqueDataTuple::LengthFieldType getTupleLenFieldType(Option::Universe u)
Returns Length Field Type for a tuple.
void setTuple(const size_t at, const OpaqueDataTuple &tuple)
Replaces tuple at the specified index with a new tuple.
virtual std::string toText(int indent=0) const
Returns text representation of the option.
size_t getTuplesNum() const
Returns the number of opaque data tuples added to the option.
virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end)
Parses buffer holding an option.
void addTuple(const OpaqueDataTuple &tuple)
Adds a new opaque data tuple to the option.
virtual uint16_t len() const
Returns the full length of the option, including option header.
OptionPtr clone() const
Copies this option and returns a pointer to the copy.
virtual void pack(isc::util::OutputBuffer &buf, bool check=true) const
Renders option into the buffer in the wire format.
OpaqueDataTuple getTuple(const size_t at) const
Returns opaque data tuple at the specified position.
bool hasTuple(const std::string &tuple_str) const
Checks if the object holds the opaque data tuple with the specified string.
OptionOpaqueDataTuples(Option::Universe u, const uint16_t type, OpaqueDataTuple::LengthFieldType length_field_type=OpaqueDataTuple::LENGTH_EMPTY)
Constructor.
virtual uint16_t getHeaderLen() const
Returns length of header (2 for v4, 4 for v6)
Definition: option.cc:321
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:83
uint16_t getType() const
Returns option type (0-255 for DHCPv4, 0-65535 for DHCPv6)
Definition: option.h:293
void packHeader(isc::util::OutputBuffer &buf, bool check=true) const
Store option's header in a buffer.
Definition: option.cc:119
void check() const
A protected method used for option correctness.
Definition: option.cc:90
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:347
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
Definition: option.h:30
boost::shared_ptr< Option > OptionPtr
Definition: option.h:37
Defines the logger used by the top-level component of kea-lfc.