26std::vector<uint16_t> psid_bitmask = { 0xffff,
27 0x8000, 0xc000, 0xe000, 0xf000,
28 0xf800, 0xfc00, 0xfe00, 0xff00,
29 0xff80, 0xffc0, 0xffe0, 0xfff0,
30 0xfff8, 0xfffc, 0xfffe, 0xffff
37OptionDataTypeUtil::OptionDataTypeUtil() {
84 return (OptionDataTypeUtil::instance().getDataTypeImpl(data_type));
88OptionDataTypeUtil::getDataTypeImpl(
const std::string& data_type)
const {
89 std::map<std::string, OptionDataType>::const_iterator data_type_it =
90 data_types_.find(data_type);
91 if (data_type_it != data_types_.end()) {
92 return (data_type_it->second);
114 return (asiolink::V4ADDRESS_LEN);
117 return (asiolink::V6ADDRESS_LEN);
130 return (OptionDataTypeUtil::instance().getDataTypeNameImpl(data_type));
134OptionDataTypeUtil::getDataTypeNameImpl(
const OptionDataType data_type)
const {
135 std::map<OptionDataType, std::string>::const_iterator data_type_it =
136 data_type_names_.find(data_type);
137 if (data_type_it != data_type_names_.end()) {
138 return (data_type_it->second);
144OptionDataTypeUtil::instance() {
145 static OptionDataTypeUtil instance;
151 const short family) {
153 if (family == AF_INET) {
154 if (buf.size() < V4ADDRESS_LEN) {
156 <<
" IPv4 address. Invalid buffer size: " << buf.size());
159 }
else if (family == AF_INET6) {
160 if (buf.size() < V6ADDRESS_LEN) {
162 <<
" IPv6 address. Invalid buffer size: " << buf.size());
167 <<
" IP address. Invalid family: " << family);
173 std::vector<uint8_t>& buf) {
174 const std::vector<uint8_t>& vec = address.toBytes();
175 buf.insert(buf.end(), vec.begin(), vec.end());
180 std::vector<uint8_t>& buf) {
189 <<
" to binary data type: " << ex.
what());
193 buf.insert(buf.end(), binary.begin(), binary.end());
208 if (buf.size() < 1) {
210 <<
" tuple (length). Invalid buffer size: "
213 uint8_t len = buf[0];
214 if (buf.size() < 1 + len) {
216 <<
" tuple (length " <<
static_cast<unsigned>(len)
217 <<
"). Invalid buffer size: " << buf.size());
221 std::memcpy(&value[0], &buf[1], len);
224 if (buf.size() < 2) {
226 <<
" tuple (length). Invalid buffer size: "
230 if (buf.size() < 2 + len) {
232 <<
" tuple (length " << len
233 <<
"). Invalid buffer size: " << buf.size());
237 std::memcpy(&value[0], &buf[2], len);
241 <<
" tuple. Invalid length type field: "
242 <<
static_cast<unsigned>(lengthfieldtype));
250 tuple.unpack(buf.begin(), buf.end());
259 std::vector<uint8_t>& buf) {
261 if (value.size() > std::numeric_limits<uint8_t>::max()) {
263 << value.size() <<
" larger than "
264 << +std::numeric_limits<uint8_t>::max() <<
")");
266 buf.push_back(
static_cast<uint8_t
>(value.size()));
269 if (value.size() > std::numeric_limits<uint16_t>::max()) {
271 << value.size() <<
" larger than "
272 << std::numeric_limits<uint16_t>::max() <<
")");
274 buf.resize(buf.size() + 2);
276 &buf[buf.size() - 2], 2);
279 <<
" tuple. Invalid length type field: "
280 <<
static_cast<unsigned>(lengthfieldtype));
282 buf.insert(buf.end(), value.begin(), value.end());
287 std::vector<uint8_t>& buf) {
288 if (tuple.getLength() == 0) {
292 if (tuple.getLength() > std::numeric_limits<uint8_t>::max()) {
294 << tuple.getLength() <<
" larger than "
295 << +std::numeric_limits<uint8_t>::max() <<
")");
297 buf.push_back(
static_cast<uint8_t
>(tuple.getLength()));
300 if (tuple.getLength() > std::numeric_limits<uint16_t>::max()) {
302 << tuple.getLength() <<
" larger than "
303 << std::numeric_limits<uint16_t>::max() <<
")");
305 buf.resize(buf.size() + 2);
307 &buf[buf.size() - 2], 2);
310 <<
" tuple. Invalid length type field: "
311 << tuple.getLengthFieldType());
313 buf.insert(buf.end(), tuple.getData().begin(), tuple.getData().end());
320 <<
" value. Invalid buffer size " << buf.size());
324 }
else if (buf[0] == 0) {
328 <<
" value. Invalid value " <<
static_cast<int>(buf[0]));
333 std::vector<uint8_t>& buf) {
334 buf.push_back(
static_cast<uint8_t
>(value ? 1 : 0));
342 <<
" The buffer is empty.");
360 std::vector<uint8_t>& buf,
365 if (labels.getDataLength() > 0) {
367 const uint8_t* data = labels.getData(&read_len);
368 buf.insert(buf.end(), data, data + read_len);
382 if (text_name.empty()) {
400 "a truncated buffer");
413 uint8_t prefix_len_bytes = (prefix_len.asUint8() / 8);
423 const uint8_t zero_padded_bits =
424 static_cast<uint8_t
>((8 - (prefix_len.asUint8() % 8)) % 8);
427 if (zero_padded_bits > 0) {
434 if ((buf.size() - 1) < prefix_len_bytes) {
436 << prefix_len.asUnsigned() <<
" from a truncated buffer");
445 if (buf.size() > 1) {
448 std::vector<uint8_t> prefix_buf(buf.begin() + 1, buf.end());
451 if (prefix_buf.size() < V6ADDRESS_LEN) {
452 prefix_buf.resize(V6ADDRESS_LEN);
453 if (prefix_len_bytes < prefix_buf.size()) {
456 std::fill(prefix_buf.begin() + prefix_len_bytes,
457 prefix_buf.end(), 0);
459 if (zero_padded_bits) {
463 prefix_buf.at(prefix_len_bytes - 1) =
464 (prefix_buf.at(prefix_len_bytes - 1)
474 return (std::make_pair(prefix_len, prefix));
480 }
catch (
const std::exception& ex) {
492 std::vector<uint8_t>& buf) {
494 if (!prefix.isV6()) {
501 buf.push_back(prefix_len.asUint8());
504 uint8_t prefix_len_bytes = prefix_len.asUint8() / 8;
507 const uint8_t zero_padded_bits =
508 static_cast<uint8_t
>((8 - (prefix_len.asUint8() % 8)) % 8);
511 if (zero_padded_bits > 0) {
517 std::vector<uint8_t> prefix_bytes = prefix.toBytes();
518 buf.insert(buf.end(), prefix_bytes.begin(),
519 prefix_bytes.begin() + prefix_len_bytes);
522 if (zero_padded_bits) {
523 *buf.rbegin() = (*buf.rbegin() >> zero_padded_bits) << zero_padded_bits;
529 if (buf.size() < 3) {
531 <<
" Invalid buffer size " << buf.size()
532 <<
". Expected 3 bytes (PSID length and PSID value)");
536 uint8_t psid_len = buf[0];
539 if (psid_len > (
sizeof(uint16_t) * 8)) {
541 <<
static_cast<unsigned>(psid_len)
542 <<
", this value is expected to be in range of 0 to 16");
553 if ((psid & ~psid_bitmask[psid_len]) != 0) {
555 <<
" for a specified PSID length "
556 <<
static_cast<unsigned>(psid_len));
565 psid >>= (
sizeof(psid) * 8 - psid_len);
567 return (std::make_pair(
PSIDLen(psid_len),
PSID(psid)));
572 std::vector<uint8_t>& buf) {
573 if (psid_len.asUint8() > (
sizeof(psid) * 8)) {
575 << psid_len.asUnsigned()
576 <<
", this value is expected to be in range of 0 to 16");
579 if ((psid_len.asUint8() > 0) &&
580 (psid.asUint16() > (0xFFFF >> (
sizeof(uint16_t) * 8 - psid_len.asUint8())))) {
582 <<
" for a specified PSID length "
583 << psid_len.asUnsigned());
586 buf.resize(buf.size() + 3);
587 buf.at(buf.size() - 3) = psid_len.asUint8();
589 (psid.asUint16() << (
sizeof(uint16_t) * 8 - psid_len.asUint8())),
590 &buf[buf.size() - 2], 2);
598 auto begin = buf.begin();
600 if (std::distance(begin, end) == 0) {
602 "contained only NULLs");
605 value.insert(value.end(), begin, end);
613 std::vector<uint8_t>& buf) {
614 if (value.size() > 0) {
615 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)
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.
LengthFieldType
Size of the length field 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.
Encapsulates prefix length.
Light-weight Accessor to Name data.
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 &encoded_str, vector< uint8_t > &output)
Decode a base16 encoded string into binary data.
Iterator seekTrimmed(Iterator const &begin, Iterator end, uint8_t const trim_val)
Finds the "trimmed" end of a buffer.
uint16_t readUint16(void const *const buffer, size_t const length)
uint16_t wrapper over readUint.
uint8_t * writeUint16(uint16_t const value, void *const buffer, size_t const length)
uint16_t wrapper over writeUint.
Defines the logger used by the top-level component of kea-lfc.