Kea 2.5.5
option_opaque_data_tuples.cc
Go to the documentation of this file.
1// Copyright (C) 2015-2023 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 (TuplesCollection::const_iterator it = tuples_.begin();
48 it != tuples_.end(); ++it) {
49 it->pack(buf);
50 }
51 // That's it. We don't pack any sub-options here, because this option
52 // must not contain sub-options.
53}
54
55void
58 // We are skipping typical OutOfRange check for Option#unpack(begin, end),
59 // since empty collection of tuples is also a valid case where
60 // std::distance(begin, end) = 0
61
62 // Start reading opaque data.
63 size_t offset = 0;
64 while (offset < std::distance(begin, end)) {
65 // Parse a tuple.
66 OpaqueDataTuple tuple(length_field_type_, begin + offset, end);
67 addTuple(tuple);
68 // The tuple has been parsed correctly which implies that it is safe to
69 // advance the offset by its total length.
70 offset += tuple.getTotalLength();
71 }
72}
73
74void
76 if (tuple.getLengthFieldType() != length_field_type_) {
77 isc_throw(isc::BadValue, "attempted to add opaque data tuple having"
78 " invalid size of the length field "
79 << tuple.getDataFieldSize() << " to opaque data tuple option");
80 }
81
82 tuples_.push_back(tuple);
83}
84
85
86void
87OptionOpaqueDataTuples::setTuple(const size_t at, const OpaqueDataTuple& tuple) {
88 if (at >= getTuplesNum()) {
89 isc_throw(isc::OutOfRange, "attempted to set an opaque data for the"
90 " opaque data tuple option at position " << at << " which"
91 " is out of range");
92
93 } else if (tuple.getLengthFieldType() != length_field_type_) {
94 isc_throw(isc::BadValue, "attempted to set opaque data tuple having"
95 " invalid size of the length field "
96 << tuple.getDataFieldSize() << " to opaque data tuple option");
97 }
98
99 tuples_[at] = tuple;
100}
101
103OptionOpaqueDataTuples::getTuple(const size_t at) const {
104 if (at >= getTuplesNum()) {
105 isc_throw(isc::OutOfRange, "attempted to get an opaque data for the"
106 " opaque data tuple option at position " << at << " which is"
107 " out of range. There are only " << getTuplesNum() << " tuples");
108 }
109 return (tuples_[at]);
110}
111
112bool
113OptionOpaqueDataTuples::hasTuple(const std::string& tuple_str) const {
114 // Iterate over existing tuples (there shouldn't be many of them),
115 // and try to match the searched one.
116 for (TuplesCollection::const_iterator it = tuples_.begin();
117 it != tuples_.end(); ++it) {
118 if (*it == tuple_str) {
119 return (true);
120 }
121 }
122 return (false);
123}
124
125uint16_t
127 // The option starts with the header.
128 uint16_t length = getHeaderLen();
129 // Now iterate over existing tuples and add their size.
130 for (TuplesCollection::const_iterator it = tuples_.begin();
131 it != tuples_.end(); ++it) {
132 length += it->getTotalLength();
133 }
134
135 return (length);
136}
137
138std::string
140 std::ostringstream s;
141
142 // Apply indentation
143 s << std::string(indent, ' ');
144
145 // Print type and length
146 s << "type=" << getType() << ", len=" << len() - getHeaderLen() << std::dec;
147 // Iterate over all tuples and print their size and contents.
148 for (unsigned i = 0; i < getTuplesNum(); ++i) {
149 // Print the tuple.
150 s << ", data-len" << i << "=" << getTuple(i).getLength();
151 s << ", data" << i << "='" << getTuple(i) << "'";
152 }
153
154 return (s.str());
155}
156
157} // namespace isc::dhcp
158} // 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:294
#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.