25std::vector<uint16_t> psid_bitmask = { 0xffff,
26 0x8000, 0xc000, 0xe000, 0xf000,
27 0xf800, 0xfc00, 0xfe00, 0xff00,
28 0xff80, 0xffc0, 0xffe0, 0xfff0,
29 0xfff8, 0xfffc, 0xfffe, 0xffff
36OptionDataTypeUtil::OptionDataTypeUtil() {
81 return (OptionDataTypeUtil::instance().getDataTypeImpl(data_type));
85OptionDataTypeUtil::getDataTypeImpl(
const std::string& data_type)
const {
86 std::map<std::string, OptionDataType>::const_iterator data_type_it =
87 data_types_.find(data_type);
88 if (data_type_it != data_types_.end()) {
89 return (data_type_it->second);
111 return (asiolink::V4ADDRESS_LEN);
114 return (asiolink::V6ADDRESS_LEN);
127 return (OptionDataTypeUtil::instance().getDataTypeNameImpl(data_type));
131OptionDataTypeUtil::getDataTypeNameImpl(
const OptionDataType data_type)
const {
132 std::map<OptionDataType, std::string>::const_iterator data_type_it =
133 data_type_names_.find(data_type);
134 if (data_type_it != data_type_names_.end()) {
135 return (data_type_it->second);
141OptionDataTypeUtil::instance() {
142 static OptionDataTypeUtil instance;
148 const short family) {
150 if (family == AF_INET) {
151 if (buf.size() < V4ADDRESS_LEN) {
153 <<
" IPv4 address. Invalid buffer size: " << buf.size());
156 }
else if (family == AF_INET6) {
157 if (buf.size() < V6ADDRESS_LEN) {
159 <<
" IPv6 address. Invalid buffer size: " << buf.size());
164 <<
" IP address. Invalid family: " << family);
170 std::vector<uint8_t>& buf) {
171 const std::vector<uint8_t>& vec = address.
toBytes();
172 buf.insert(buf.end(), vec.begin(), vec.end());
177 std::vector<uint8_t>& buf) {
186 <<
" to binary data type: " << ex.
what());
190 buf.insert(buf.end(), binary.begin(), binary.end());
197 if (buf.size() < 1) {
199 <<
" tuple (length). Invalid buffer size: "
202 uint8_t len = buf[0];
203 if (buf.size() < 1 + len) {
205 <<
" tuple (length " <<
static_cast<unsigned>(len)
206 <<
"). Invalid buffer size: " << buf.size());
210 std::memcpy(&value[0], &buf[1], len);
213 if (buf.size() < 2) {
215 <<
" tuple (length). Invalid buffer size: "
219 if (buf.size() < 2 + len) {
221 <<
" tuple (length " << len
222 <<
"). Invalid buffer size: " << buf.size());
226 std::memcpy(&value[0], &buf[2], len);
230 <<
" tuple. Invalid length type field: "
231 <<
static_cast<unsigned>(lengthfieldtype));
239 tuple.
unpack(buf.begin(), buf.end());
248 std::vector<uint8_t>& buf) {
250 if (value.size() > std::numeric_limits<uint8_t>::max()) {
252 << value.size() <<
" larger than "
253 << +std::numeric_limits<uint8_t>::max() <<
")");
255 buf.push_back(
static_cast<uint8_t
>(value.size()));
258 if (value.size() > std::numeric_limits<uint16_t>::max()) {
260 << value.size() <<
" larger than "
261 << std::numeric_limits<uint16_t>::max() <<
")");
263 buf.resize(buf.size() + 2);
265 &buf[buf.size() - 2], 2);
268 <<
" tuple. Invalid length type field: "
269 <<
static_cast<unsigned>(lengthfieldtype));
271 buf.insert(buf.end(), value.begin(), value.end());
276 std::vector<uint8_t>& buf) {
281 if (tuple.
getLength() > std::numeric_limits<uint8_t>::max()) {
284 << +std::numeric_limits<uint8_t>::max() <<
")");
286 buf.push_back(
static_cast<uint8_t
>(tuple.
getLength()));
289 if (tuple.
getLength() > std::numeric_limits<uint16_t>::max()) {
292 << std::numeric_limits<uint16_t>::max() <<
")");
294 buf.resize(buf.size() + 2);
296 &buf[buf.size() - 2], 2);
299 <<
" tuple. Invalid length type field: "
302 buf.insert(buf.end(), tuple.
getData().begin(), tuple.
getData().end());
309 <<
" value. Invalid buffer size " << buf.size());
313 }
else if (buf[0] == 0) {
317 <<
" value. Invalid value " <<
static_cast<int>(buf[0]));
322 std::vector<uint8_t>& buf) {
323 buf.push_back(
static_cast<uint8_t
>(value ? 1 : 0));
331 <<
" The buffer is empty.");
349 std::vector<uint8_t>& buf,
356 const uint8_t* data = labels.
getData(&read_len);
357 buf.insert(buf.end(), data, data + read_len);
371 if (text_name.empty()) {
389 "a truncated buffer");
402 uint8_t prefix_len_bytes = (prefix_len.
asUint8() / 8);
412 const uint8_t zero_padded_bits =
413 static_cast<uint8_t
>((8 - (prefix_len.
asUint8() % 8)) % 8);
416 if (zero_padded_bits > 0) {
423 if ((buf.size() - 1) < prefix_len_bytes) {
425 << prefix_len.
asUnsigned() <<
" from a truncated buffer");
434 if (buf.size() > 1) {
437 std::vector<uint8_t> prefix_buf(buf.begin() + 1, buf.end());
440 if (prefix_buf.size() < V6ADDRESS_LEN) {
441 prefix_buf.resize(V6ADDRESS_LEN);
442 if (prefix_len_bytes < prefix_buf.size()) {
445 std::fill(prefix_buf.begin() + prefix_len_bytes,
446 prefix_buf.end(), 0);
448 if (zero_padded_bits) {
452 prefix_buf.at(prefix_len_bytes - 1) =
453 (prefix_buf.at(prefix_len_bytes - 1)
463 return (std::make_pair(prefix_len, prefix));
469 }
catch (
const std::exception& ex) {
481 std::vector<uint8_t>& buf) {
483 if (!prefix.
isV6()) {
490 buf.push_back(prefix_len.
asUint8());
493 uint8_t prefix_len_bytes = prefix_len.
asUint8() / 8;
496 const uint8_t zero_padded_bits =
497 static_cast<uint8_t
>((8 - (prefix_len.
asUint8() % 8)) % 8);
500 if (zero_padded_bits > 0) {
506 std::vector<uint8_t> prefix_bytes = prefix.
toBytes();
507 buf.insert(buf.end(), prefix_bytes.begin(),
508 prefix_bytes.begin() + prefix_len_bytes);
511 if (zero_padded_bits) {
512 *buf.rbegin() = (*buf.rbegin() >> zero_padded_bits) << zero_padded_bits;
518 if (buf.size() < 3) {
520 <<
" Invalid buffer size " << buf.size()
521 <<
". Expected 3 bytes (PSID length and PSID value)");
525 uint8_t psid_len = buf[0];
528 if (psid_len > (
sizeof(uint16_t) * 8)) {
530 <<
static_cast<unsigned>(psid_len)
531 <<
", this value is expected to be in range of 0 to 16");
542 if ((psid & ~psid_bitmask[psid_len]) != 0) {
544 <<
" for a specified PSID length "
545 <<
static_cast<unsigned>(psid_len));
554 psid >>= (
sizeof(psid) * 8 - psid_len);
556 return (std::make_pair(
PSIDLen(psid_len),
PSID(psid)));
561 std::vector<uint8_t>& buf) {
562 if (psid_len.
asUint8() > (
sizeof(psid) * 8)) {
565 <<
", this value is expected to be in range of 0 to 16");
568 if ((psid_len.
asUint8() > 0) &&
569 (psid.
asUint16() > (0xFFFF >> (
sizeof(uint16_t) * 8 - psid_len.
asUint8())))) {
571 <<
" for a specified PSID length "
575 buf.resize(buf.size() + 3);
576 buf.at(buf.size() - 3) = psid_len.
asUint8();
579 &buf[buf.size() - 2], 2);
587 auto begin = buf.begin();
589 if (std::distance(begin, end) == 0) {
591 "contained only NULLs");
594 value.insert(value.end(), begin, end);
602 std::vector<uint8_t>& buf) {
603 if (value.size() > 0) {
604 buf.insert(buf.end(), value.begin(), value.end());
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
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.
std::vector< uint8_t > toBytes() const
Return address as set of bytes.
static const IOAddress & IPV6_ZERO_ADDRESS()
Returns an IPv6 zero address.
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
Exception to be thrown when cast to the data type was unsuccessful.
Exception to be thrown when the operation on OpaqueDataTuple object results in an error.
Represents a single instance of the opaque data preceded by length.
const Buffer & getData() const
Returns a reference to the buffer holding tuple data.
LengthFieldType
Size of the length field in the tuple.
LengthFieldType getLengthFieldType() const
Returns tuple length data field type.
void unpack(InputIterator begin, InputIterator end)
Parses wire data and creates a tuple from it.
size_t getLength() const
Returns the length of the data in the tuple.
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 unsigned int getLabelCount(const std::string &text_name)
Return the number of labels in the Name.
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 OptionDataType getDataType(const std::string &data_type)
Return option data type from its name.
static void writeBinary(const std::string &hex_str, std::vector< uint8_t > &buf)
Append hex-encoded binary values to a buffer.
static int getDataTypeLen(const OptionDataType data_type)
Get data type buffer length.
static std::string readFqdn(const std::vector< uint8_t > &buf)
Read FQDN from a buffer as a string value.
static std::string readTuple(const std::vector< uint8_t > &buf, OpaqueDataTuple::LengthFieldType lengthfieldtype)
Read length and string tuple from a buffer.
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 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.
Encapsulates PSID length.
uint8_t asUint8() const
Returns PSID length as uint8_t value.
unsigned int asUnsigned() const
Returns PSID length as unsigned int.
uint16_t asUint16() const
Returns PSID value as a number.
Encapsulates prefix length.
unsigned int asUnsigned() const
Returns prefix length as unsigned int.
uint8_t asUint8() const
Returns prefix length as uint8_t value.
Light-weight Accessor to Name data.
const uint8_t * getData(size_t *len) const
Return the wire-format data for this LabelSequence.
size_t getDataLength() const
Return the length of the wire-format data of this LabelSequence.
The Name class encapsulates DNS names.
std::string toText(bool omit_final_dot=false) const
Convert the Name to a string.
unsigned int getLabelCount() const
Returns the number of labels contained in the Name.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
std::pair< PSIDLen, PSID > PSIDTuple
Defines a pair of PSID length / value.
OptionDataType
Data types of DHCP option fields.
std::pair< PrefixLen, asiolink::IOAddress > PrefixTuple
Defines a pair of prefix length / value.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
void decodeHex(const string &input, vector< uint8_t > &result)
Decode a text encoded in the base16 ('hex') format into the original data.
Iterator seekTrimmed(Iterator begin, Iterator end, uint8_t trim_val)
Finds the "trimmed" end of a buffer.
uint8_t * writeUint16(uint16_t value, void *buffer, size_t length)
Write Unsigned 16-Bit Integer to Buffer.
uint16_t readUint16(const void *buffer, size_t length)
Read Unsigned 16-Bit Integer from Buffer.
Defines the logger used by the top-level component of kea-lfc.