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());
205 if (buf.size() < 1) {
207 <<
" tuple (length). Invalid buffer size: "
210 uint8_t len = buf[0];
211 if (buf.size() < 1 + len) {
213 <<
" tuple (length " <<
static_cast<unsigned>(len)
214 <<
"). Invalid buffer size: " << buf.size());
218 std::memcpy(&value[0], &buf[1], len);
221 if (buf.size() < 2) {
223 <<
" tuple (length). Invalid buffer size: "
227 if (buf.size() < 2 + len) {
229 <<
" tuple (length " << len
230 <<
"). Invalid buffer size: " << buf.size());
234 std::memcpy(&value[0], &buf[2], len);
238 <<
" tuple. Invalid length type field: "
239 <<
static_cast<unsigned>(lengthfieldtype));
247 tuple.
unpack(buf.begin(), buf.end());
256 std::vector<uint8_t>& buf) {
258 if (value.size() > std::numeric_limits<uint8_t>::max()) {
260 << value.size() <<
" larger than "
261 << +std::numeric_limits<uint8_t>::max() <<
")");
263 buf.push_back(
static_cast<uint8_t
>(value.size()));
266 if (value.size() > std::numeric_limits<uint16_t>::max()) {
268 << value.size() <<
" larger than "
269 << std::numeric_limits<uint16_t>::max() <<
")");
271 buf.resize(buf.size() + 2);
273 &buf[buf.size() - 2], 2);
276 <<
" tuple. Invalid length type field: "
277 <<
static_cast<unsigned>(lengthfieldtype));
279 buf.insert(buf.end(), value.begin(), value.end());
284 std::vector<uint8_t>& buf) {
289 if (tuple.
getLength() > std::numeric_limits<uint8_t>::max()) {
292 << +std::numeric_limits<uint8_t>::max() <<
")");
294 buf.push_back(
static_cast<uint8_t
>(tuple.
getLength()));
297 if (tuple.
getLength() > std::numeric_limits<uint16_t>::max()) {
300 << std::numeric_limits<uint16_t>::max() <<
")");
302 buf.resize(buf.size() + 2);
304 &buf[buf.size() - 2], 2);
307 <<
" tuple. Invalid length type field: "
310 buf.insert(buf.end(), tuple.
getData().begin(), tuple.
getData().end());
317 <<
" value. Invalid buffer size " << buf.size());
321 }
else if (buf[0] == 0) {
325 <<
" value. Invalid value " <<
static_cast<int>(buf[0]));
330 std::vector<uint8_t>& buf) {
331 buf.push_back(
static_cast<uint8_t
>(value ? 1 : 0));
339 <<
" The buffer is empty.");
357 std::vector<uint8_t>& buf,
364 const uint8_t* data = labels.
getData(&read_len);
365 buf.insert(buf.end(), data, data + read_len);
379 if (text_name.empty()) {
397 "a truncated buffer");
410 uint8_t prefix_len_bytes = (prefix_len.
asUint8() / 8);
420 const uint8_t zero_padded_bits =
421 static_cast<uint8_t
>((8 - (prefix_len.
asUint8() % 8)) % 8);
424 if (zero_padded_bits > 0) {
431 if ((buf.size() - 1) < prefix_len_bytes) {
433 << prefix_len.
asUnsigned() <<
" from a truncated buffer");
442 if (buf.size() > 1) {
445 std::vector<uint8_t> prefix_buf(buf.begin() + 1, buf.end());
448 if (prefix_buf.size() < V6ADDRESS_LEN) {
449 prefix_buf.resize(V6ADDRESS_LEN);
450 if (prefix_len_bytes < prefix_buf.size()) {
453 std::fill(prefix_buf.begin() + prefix_len_bytes,
454 prefix_buf.end(), 0);
456 if (zero_padded_bits) {
460 prefix_buf.at(prefix_len_bytes - 1) =
461 (prefix_buf.at(prefix_len_bytes - 1)
471 return (std::make_pair(prefix_len, prefix));
477 }
catch (
const std::exception& ex) {
489 std::vector<uint8_t>& buf) {
491 if (!prefix.
isV6()) {
498 buf.push_back(prefix_len.
asUint8());
501 uint8_t prefix_len_bytes = prefix_len.
asUint8() / 8;
504 const uint8_t zero_padded_bits =
505 static_cast<uint8_t
>((8 - (prefix_len.
asUint8() % 8)) % 8);
508 if (zero_padded_bits > 0) {
514 std::vector<uint8_t> prefix_bytes = prefix.
toBytes();
515 buf.insert(buf.end(), prefix_bytes.begin(),
516 prefix_bytes.begin() + prefix_len_bytes);
519 if (zero_padded_bits) {
520 *buf.rbegin() = (*buf.rbegin() >> zero_padded_bits) << zero_padded_bits;
526 if (buf.size() < 3) {
528 <<
" Invalid buffer size " << buf.size()
529 <<
". Expected 3 bytes (PSID length and PSID value)");
533 uint8_t psid_len = buf[0];
536 if (psid_len > (
sizeof(uint16_t) * 8)) {
538 <<
static_cast<unsigned>(psid_len)
539 <<
", this value is expected to be in range of 0 to 16");
550 if ((psid & ~psid_bitmask[psid_len]) != 0) {
552 <<
" for a specified PSID length "
553 <<
static_cast<unsigned>(psid_len));
562 psid >>= (
sizeof(psid) * 8 - psid_len);
564 return (std::make_pair(
PSIDLen(psid_len),
PSID(psid)));
569 std::vector<uint8_t>& buf) {
570 if (psid_len.
asUint8() > (
sizeof(psid) * 8)) {
573 <<
", this value is expected to be in range of 0 to 16");
576 if ((psid_len.
asUint8() > 0) &&
577 (psid.
asUint16() > (0xFFFF >> (
sizeof(uint16_t) * 8 - psid_len.
asUint8())))) {
579 <<
" for a specified PSID length "
583 buf.resize(buf.size() + 3);
584 buf.at(buf.size() - 3) = psid_len.
asUint8();
587 &buf[buf.size() - 2], 2);
595 auto begin = buf.begin();
597 if (std::distance(begin, end) == 0) {
599 "contained only NULLs");
602 value.insert(value.end(), begin, end);
610 std::vector<uint8_t>& buf) {
611 if (value.size() > 0) {
612 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 OpaqueDataTuple::LengthFieldType getTupleLenFieldType(Option::Universe u)
Returns Length Field Type for a tuple.
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.
Universe
defines option universe DHCPv4 or DHCPv6
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.