| Kea 3.0.2-git

option_int_array.h
Go to the documentation of this file.
1// Copyright (C) 2012-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#ifndef OPTION_INT_ARRAY_H
8#define OPTION_INT_ARRAY_H
9
10#include <dhcp/libdhcp++.h>
11#include <dhcp/option.h>
12#include <dhcp/option_data_types.h>
13#include <util/io.h>
14#include <boost/shared_ptr.hpp>
15#include <sstream>
16#include <stdint.h>
17
18 namespace isc {
19 namespace dhcp {
20
22 template<typename T>
23 class OptionIntArray;
24
30 typedef OptionIntArray<uint8_t> OptionUint8Array;
31 typedef boost::shared_ptr<OptionUint8Array> OptionUint8ArrayPtr;
32 typedef OptionIntArray<uint16_t> OptionUint16Array;
33 typedef boost::shared_ptr<OptionUint16Array> OptionUint16ArrayPtr;
34 typedef OptionIntArray<uint32_t> OptionUint32Array;
35 typedef boost::shared_ptr<OptionUint32Array> OptionUint32ArrayPtr;
37
55 template<typename T>
56 class OptionIntArray : public Option {
57 private:
58
60 typedef boost::shared_ptr<OptionIntArray<T> > OptionIntArrayTypePtr;
61
62 public:
63
73 OptionIntArray(const Option::Universe u, const uint16_t type)
74 : Option(u, type),
75 values_(0) {
76 if (!OptionDataTypeTraits<T>::integer_type) {
77 isc_throw(dhcp::InvalidDataType, "non-integer type");
78 }
79 }
80
91 OptionIntArray(const Option::Universe u, const uint16_t type,
92 const OptionBuffer& buf)
93 : Option(u, type) {
94 if (!OptionDataTypeTraits<T>::integer_type) {
95 isc_throw(dhcp::InvalidDataType, "non-integer type");
96 }
97 unpack(buf.begin(), buf.end());
98 }
99
115 OptionIntArray(const Option::Universe u, const uint16_t type,
116 OptionBufferConstIter begin, OptionBufferConstIter end)
117 : Option(u, type) {
118 if (!OptionDataTypeTraits<T>::integer_type) {
119 isc_throw(dhcp::InvalidDataType, "non-integer type");
120 }
121 unpack(begin, end);
122 }
123
125 virtual OptionPtr clone() const {
126 return (cloneInternal<OptionIntArray<T> >());
127 }
128
132 void addValue(const T value) {
133 values_.push_back(value);
134 }
135
145 virtual void pack(isc::util::OutputBuffer& buf, bool check = true) const {
146 // Pack option header.
147 packHeader(buf, check);
148 // Pack option data.
149 for (size_t i = 0; i < values_.size(); ++i) {
150 // Depending on the data type length we use different utility functions
151 // writeUint16 or writeUint32 which write the data in the network byte
152 // order to the provided buffer. The same functions can be safely used
153 // for either unsigned or signed integers so there is not need to create
154 // special cases for intX_t types.
155 switch (OptionDataTypeTraits<T>::len) {
156 case 1:
157 buf.writeUint8(values_[i]);
158 break;
159 case 2:
160 buf.writeUint16(values_[i]);
161 break;
162 case 4:
163 buf.writeUint32(values_[i]);
164 break;
165 default:
166 isc_throw(dhcp::InvalidDataType, "non-integer type");
167 }
168 }
169 // We don't pack sub-options here because we have array-type option.
170 // We don't allow sub-options in array-type options as there is no
171 // way to distinguish them from the data fields on option reception.
172 }
173
185 virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end) {
186 if (distance(begin, end) == 0) {
187 isc_throw(OutOfRange, "option " << getType() << " empty");
188 }
189 if (distance(begin, end) % sizeof(T) != 0) {
190 isc_throw(OutOfRange, "OptionIntArray " << getType() << " truncated");
191 }
192 // @todo consider what to do if buffer is longer than data type.
193
194 values_.clear();
195 while (begin != end) {
196 // Depending on the data type length we use different utility functions
197 // readUint16 or readUint32 which read the data laid in the network byte
198 // order from the provided buffer. The same functions can be safely used
199 // for either unsigned or signed integers so there is not need to create
200 // special cases for intX_t types.
201 int data_size_len = OptionDataTypeTraits<T>::len;
202 switch (data_size_len) {
203 case 1:
204 values_.push_back(*begin);
205 break;
206 case 2:
207 values_.push_back(isc::util::readUint16(&(*begin),
208 std::distance(begin, end)));
209 break;
210 case 4:
211 values_.push_back(isc::util::readUint32(&(*begin),
212 std::distance(begin, end)));
213 break;
214 default:
215 isc_throw(dhcp::InvalidDataType, "non-integer type");
216 }
217 // Use local variable to set a new value for this iterator.
218 // When using OptionDataTypeTraits<T>::len directly some versions
219 // of clang complain about unresolved reference to
220 // OptionDataTypeTraits structure during linking.
221 begin += data_size_len;
222 }
223 // We do not unpack sub-options here because we have array-type option.
224 // Such option have variable number of data fields, thus there is no
225 // way to assess where sub-options start.
226 }
227
231 const std::vector<T>& getValues() const { return (values_); }
232
236 void setValues(const std::vector<T>& values) { values_ = values; }
237
243 virtual uint16_t len() const {
244 uint16_t length = (getUniverse() == Option::V4) ? OPTION4_HDR_LEN : OPTION6_HDR_LEN;
245 length += values_.size() * sizeof(T);
246 // length of all suboptions
247 for (auto const& it : options_) {
248 length += it.second->len();
249 }
250 return (length);
251 }
252
259 virtual std::string toText(int indent = 0) const {
260 std::stringstream output;
261 output << headerToText(indent) << ":";
262
263 std::string data_type = OptionDataTypeUtil::getDataTypeName(OptionDataTypeTraits<T>::type);
264 for (auto const& value : values_) {
265 output << " ";
266
267 // For 1 byte long data types we need to cast to the integer
268 // because they are usually implemented as "char" types, in
269 // which case the character rather than number would be printed.
270 if (OptionDataTypeTraits<T>::len == 1) {
271 output << static_cast<int>(value);
272
273 } else {
274 output << value;
275 }
276
277 // Append data type.
278 output << "(" << data_type << ")";
279 }
280
281 return (output.str());
282 }
283
284 private:
285
286 std::vector<T> values_;
287};
288
289} // isc::dhcp namespace
290} // isc namespace
291
292#endif // OPTION_INT_ARRAY_H
isc::OutOfRange
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
Definition exceptions/exceptions.h:115
isc::dhcp::InvalidDataType
Exception to be thrown when invalid type specified as template parameter.
Definition option_data_types.h:23
isc::dhcp::OptionDataTypeUtil::getDataTypeName
static const std::string & getDataTypeName(const OptionDataType data_type)
Return option data type name from the data type enumerator.
Definition option_data_types.cc:129
isc::dhcp::OptionIntArray
Forward declaration to OptionIntArray.
Definition option_int_array.h:56
isc::dhcp::OptionIntArray::OptionIntArray
OptionIntArray(const Option::Universe u, const uint16_t type)
Constructor.
Definition option_int_array.h:73
isc::dhcp::OptionIntArray::unpack
virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end)
Parses received buffer.
Definition option_int_array.h:185
isc::dhcp::OptionIntArray::pack
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.
Definition option_int_array.h:145
isc::dhcp::OptionIntArray::len
virtual uint16_t len() const
returns complete length of option
Definition option_int_array.h:243
isc::dhcp::OptionIntArray::getValues
const std::vector< T > & getValues() const
Return collection of option values.
Definition option_int_array.h:231
isc::dhcp::OptionIntArray::clone
virtual OptionPtr clone() const
Copies this option and returns a pointer to the copy.
Definition option_int_array.h:125
isc::dhcp::OptionIntArray::OptionIntArray
OptionIntArray(const Option::Universe u, const uint16_t type, const OptionBuffer &buf)
Constructor.
Definition option_int_array.h:91
isc::dhcp::OptionIntArray::OptionIntArray
OptionIntArray(const Option::Universe u, const uint16_t type, OptionBufferConstIter begin, OptionBufferConstIter end)
Constructor.
Definition option_int_array.h:115
isc::dhcp::OptionIntArray::setValues
void setValues(const std::vector< T > &values)
Set option values.
Definition option_int_array.h:236
isc::dhcp::OptionIntArray::toText
virtual std::string toText(int indent=0) const
Returns textual representation of the option.
Definition option_int_array.h:259
isc::dhcp::OptionIntArray::addValue
void addValue(const T value)
Adds a new value to the array.
Definition option_int_array.h:132
isc::dhcp::Option::headerToText
std::string headerToText(const int indent=0, const std::string &type_name="") const
Returns option header in the textual format.
Definition option.cc:294
isc::dhcp::Option::Universe
Universe
defines option universe DHCPv4 or DHCPv6
Definition option.h:90
isc::dhcp::Option::V4
@ V4
Definition option.h:90
isc::dhcp::Option::getType
uint16_t getType() const
Returns option type (0-255 for DHCPv4, 0-65535 for DHCPv6).
Definition option.h:300
isc::dhcp::Option::OPTION6_HDR_LEN
static const size_t OPTION6_HDR_LEN
length of any DHCPv6 option header
Definition option.h:87
isc::dhcp::Option::options_
OptionCollection options_
collection for storing suboptions
Definition option.h:603
isc::dhcp::Option::cloneInternal
OptionPtr cloneInternal() const
Copies this option and returns a pointer to the copy.
Definition option.h:504
isc::dhcp::Option::getUniverse
Universe getUniverse() const
returns option universe (V4 or V6)
Definition option.h:240
isc::dhcp::Option::packHeader
void packHeader(isc::util::OutputBuffer &buf, bool check=true) const
Store option's header in a buffer.
Definition option.cc:119
isc::dhcp::Option::Option
Option(Universe u, uint16_t type)
ctor, used for options constructed, usually during transmission
Definition option.cc:39
isc::dhcp::Option::check
void check() const
A protected method used for option correctness.
Definition option.cc:90
isc::dhcp::Option::OPTION4_HDR_LEN
static const size_t OPTION4_HDR_LEN
length of the usual DHCPv4 option header (there are exceptions)
Definition option.h:84
isc::util::OutputBuffer
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition buffer.h:346
isc::util::OutputBuffer::writeUint8
void writeUint8(uint8_t data)
Write an unsigned 8-bit integer into the buffer.
Definition buffer.h:476
isc::util::OutputBuffer::writeUint16
void writeUint16(uint16_t data)
Write an unsigned 16-bit integer in host byte order into the buffer in network byte order.
Definition buffer.h:501
isc::util::OutputBuffer::writeUint32
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:531
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
isc::dhcp::OptionUint8ArrayPtr
boost::shared_ptr< OptionUint8Array > OptionUint8ArrayPtr
Definition option_int_array.h:31
isc::dhcp::OptionUint32Array
OptionIntArray< uint32_t > OptionUint32Array
Definition option_int_array.h:34
isc::dhcp::OptionUint8Array
OptionIntArray< uint8_t > OptionUint8Array
Definition option_int_array.h:30
isc::dhcp::OptionUint32ArrayPtr
boost::shared_ptr< OptionUint32Array > OptionUint32ArrayPtr
Definition option_int_array.h:35
isc::dhcp::OptionUint16ArrayPtr
boost::shared_ptr< OptionUint16Array > OptionUint16ArrayPtr
Definition option_int_array.h:33
isc::dhcp::OptionUint16Array
OptionIntArray< uint16_t > OptionUint16Array
Definition option_int_array.h:32
io.h
libdhcp++.h
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::dhcp::OptionBufferConstIter
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
Definition option.h:30
isc::dhcp::OptionBuffer
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition option.h:24
isc::dhcp::OptionPtr
boost::shared_ptr< Option > OptionPtr
Definition option.h:37
isc::util::readUint16
uint16_t readUint16(void const *const buffer, size_t const length)
uint16_t wrapper over readUint.
Definition io.h:76
isc::util::readUint32
uint32_t readUint32(void const *const buffer, size_t const length)
uint32_t wrapper over readUint.
Definition io.h:82
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148
option.h
option_data_types.h
isc::dhcp::OptionDataTypeTraits::len
static const int len
Definition option_data_types.h:97
isc::dhcp::OptionDataTypeTraits::integer_type
static const bool integer_type
Definition option_data_types.h:98
isc::dhcp::OptionDataTypeTraits::type
static const OptionDataType type
Definition option_data_types.h:99