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 + 
static_cast<size_t>(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 + 
static_cast<size_t>(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) {
 
  292        if (tuple.
getLength() > std::numeric_limits<uint8_t>::max()) {
 
  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()) {
 
  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: " 
  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,
 
  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)) {
 
  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 " 
  586    buf.resize(buf.size() + 3);
 
  587    buf.at(buf.size() - 3) = 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)
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 &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.