Kea  1.5.0
option_data_types.cc
Go to the documentation of this file.
1 // Copyright (C) 2012-2017 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 #include <config.h>
8 
10 #include <dns/labelsequence.h>
11 #include <dns/name.h>
12 #include <util/encode/hex.h>
13 #include <algorithm>
14 #include <limits>
15 
16 using namespace isc::asiolink;
17 
18 namespace isc {
19 namespace dhcp {
20 
21 OptionDataTypeUtil::OptionDataTypeUtil() {
22  data_types_["empty"] = OPT_EMPTY_TYPE;
23  data_types_["binary"] = OPT_BINARY_TYPE;
24  data_types_["boolean"] = OPT_BOOLEAN_TYPE;
25  data_types_["int8"] = OPT_INT8_TYPE;
26  data_types_["int16"] = OPT_INT16_TYPE;
27  data_types_["int32"] = OPT_INT32_TYPE;
28  data_types_["uint8"] = OPT_UINT8_TYPE;
29  data_types_["uint16"] = OPT_UINT16_TYPE;
30  data_types_["uint32"] = OPT_UINT32_TYPE;
31  data_types_["ipv4-address"] = OPT_IPV4_ADDRESS_TYPE;
32  data_types_["ipv6-address"] = OPT_IPV6_ADDRESS_TYPE;
33  data_types_["ipv6-prefix"] = OPT_IPV6_PREFIX_TYPE;
34  data_types_["psid"] = OPT_PSID_TYPE;
35  data_types_["string"] = OPT_STRING_TYPE;
36  data_types_["tuple"] = OPT_TUPLE_TYPE;
37  data_types_["fqdn"] = OPT_FQDN_TYPE;
38  data_types_["record"] = OPT_RECORD_TYPE;
39 
40  data_type_names_[OPT_EMPTY_TYPE] = "empty";
41  data_type_names_[OPT_BINARY_TYPE] = "binary";
42  data_type_names_[OPT_BOOLEAN_TYPE] = "boolean";
43  data_type_names_[OPT_INT8_TYPE] = "int8";
44  data_type_names_[OPT_INT16_TYPE] = "int16";
45  data_type_names_[OPT_INT32_TYPE] = "int32";
46  data_type_names_[OPT_UINT8_TYPE] = "uint8";
47  data_type_names_[OPT_UINT16_TYPE] = "uint16";
48  data_type_names_[OPT_UINT32_TYPE] = "uint32";
49  data_type_names_[OPT_IPV4_ADDRESS_TYPE] = "ipv4-address";
50  data_type_names_[OPT_IPV6_ADDRESS_TYPE] = "ipv6-address";
51  data_type_names_[OPT_IPV6_PREFIX_TYPE] = "ipv6-prefix";
52  data_type_names_[OPT_PSID_TYPE] = "psid";
53  data_type_names_[OPT_STRING_TYPE] = "string";
54  data_type_names_[OPT_TUPLE_TYPE] = "tuple";
55  data_type_names_[OPT_FQDN_TYPE] = "fqdn";
56  data_type_names_[OPT_RECORD_TYPE] = "record";
57  // The "unknown" data type is declared here so as
58  // it can be returned by reference by a getDataTypeName
59  // function it no other type is suitable. Other than that
60  // this is unused.
61  data_type_names_[OPT_UNKNOWN_TYPE] = "unknown";
62 }
63 
65 OptionDataTypeUtil::getDataType(const std::string& data_type) {
66  return (OptionDataTypeUtil::instance().getDataTypeImpl(data_type));
67 }
68 
70 OptionDataTypeUtil::getDataTypeImpl(const std::string& data_type) const {
71  std::map<std::string, OptionDataType>::const_iterator data_type_it =
72  data_types_.find(data_type);
73  if (data_type_it != data_types_.end()) {
74  return (data_type_it->second);
75  }
76  return (OPT_UNKNOWN_TYPE);
77 }
78 
79 int
80 OptionDataTypeUtil::getDataTypeLen(const OptionDataType data_type) {
81  switch (data_type) {
82  case OPT_BOOLEAN_TYPE:
83  case OPT_INT8_TYPE:
84  case OPT_UINT8_TYPE:
85  return (1);
86 
87  case OPT_INT16_TYPE:
88  case OPT_UINT16_TYPE:
89  return (2);
90 
91  case OPT_INT32_TYPE:
92  case OPT_UINT32_TYPE:
93  return (4);
94 
96  return (asiolink::V4ADDRESS_LEN);
97 
99  return (asiolink::V6ADDRESS_LEN);
100 
101  case OPT_PSID_TYPE:
102  return (3);
103 
104  default:
105  ;
106  }
107  return (0);
108 }
109 
110 const std::string&
111 OptionDataTypeUtil::getDataTypeName(const OptionDataType data_type) {
112  return (OptionDataTypeUtil::instance().getDataTypeNameImpl(data_type));
113 }
114 
115 const std::string&
116 OptionDataTypeUtil::getDataTypeNameImpl(const OptionDataType data_type) const {
117  std::map<OptionDataType, std::string>::const_iterator data_type_it =
118  data_type_names_.find(data_type);
119  if (data_type_it != data_type_names_.end()) {
120  return (data_type_it->second);
121  }
122  return (data_type_names_.find(OPT_UNKNOWN_TYPE)->second);
123 }
124 
125 OptionDataTypeUtil&
126 OptionDataTypeUtil::instance() {
127  static OptionDataTypeUtil instance;
128  return (instance);
129 }
130 
131 asiolink::IOAddress
132 OptionDataTypeUtil::readAddress(const std::vector<uint8_t>& buf,
133  const short family) {
134  using namespace isc::asiolink;
135  if (family == AF_INET) {
136  if (buf.size() < V4ADDRESS_LEN) {
137  isc_throw(BadDataTypeCast, "unable to read data from the buffer as"
138  << " IPv4 address. Invalid buffer size: " << buf.size());
139  }
140  return (IOAddress::fromBytes(AF_INET, &buf[0]));
141  } else if (family == AF_INET6) {
142  if (buf.size() < V6ADDRESS_LEN) {
143  isc_throw(BadDataTypeCast, "unable to read data from the buffer as"
144  << " IPv6 address. Invalid buffer size: " << buf.size());
145  }
146  return (IOAddress::fromBytes(AF_INET6, &buf[0]));
147  } else {
148  isc_throw(BadDataTypeCast, "unable to read data from the buffer as"
149  << " IP address. Invalid family: " << family);
150  }
151 }
152 
153 void
154 OptionDataTypeUtil::writeAddress(const asiolink::IOAddress& address,
155  std::vector<uint8_t>& buf) {
156  const std::vector<uint8_t>& vec = address.toBytes();
157  buf.insert(buf.end(), vec.begin(), vec.end());
158 }
159 
160 void
161 OptionDataTypeUtil::writeBinary(const std::string& hex_str,
162  std::vector<uint8_t>& buf) {
163  // Binary value means that the value is encoded as a string
164  // of hexadecimal digits. We need to decode this string
165  // to the binary format here.
166  OptionBuffer binary;
167  try {
168  util::encode::decodeHex(hex_str, binary);
169  } catch (const Exception& ex) {
170  isc_throw(BadDataTypeCast, "unable to cast " << hex_str
171  << " to binary data type: " << ex.what());
172  }
173  // Decode was successful so append decoded binary value
174  // to the buffer.
175  buf.insert(buf.end(), binary.begin(), binary.end());
176 }
177 
178 std::string
179 OptionDataTypeUtil::readTuple(const std::vector<uint8_t>& buf,
180  OpaqueDataTuple::LengthFieldType lengthfieldtype) {
181  if (lengthfieldtype == OpaqueDataTuple::LENGTH_1_BYTE) {
182  if (buf.size() < 1) {
183  isc_throw(BadDataTypeCast, "unable to read data from the buffer as"
184  << " tuple (length). Invalid buffer size: "
185  << buf.size());
186  }
187  uint8_t len = buf[0];
188  if (buf.size() < 1 + len) {
189  isc_throw(BadDataTypeCast, "unable to read data from the buffer as"
190  << " tuple (length " << static_cast<unsigned>(len)
191  << "). Invalid buffer size: " << buf.size());
192  }
193  std::string value;
194  value.resize(len);
195  std::memcpy(&value[0], &buf[1], len);
196  return (value);
197  } else if (lengthfieldtype == OpaqueDataTuple::LENGTH_2_BYTES) {
198  if (buf.size() < 2) {
199  isc_throw(BadDataTypeCast, "unable to read data from the buffer as"
200  << " tuple (length). Invalid buffer size: "
201  << buf.size());
202  }
203  uint16_t len = isc::util::readUint16(&buf[0], 2);
204  if (buf.size() < 2 + len) {
205  isc_throw(BadDataTypeCast, "unable to read data from the buffer as"
206  << " tuple (length " << len
207  << "). Invalid buffer size: " << buf.size());
208  }
209  std::string value;
210  value.resize(len);
211  std::memcpy(&value[0], &buf[2], len);
212  return (value);
213  } else {
214  isc_throw(BadDataTypeCast, "unable to read data from the buffer as"
215  << " tuple. Invalid length type field: "
216  << static_cast<unsigned>(lengthfieldtype));
217  }
218 }
219 
220 void
221 OptionDataTypeUtil::readTuple(const std::vector<uint8_t>& buf,
222  OpaqueDataTuple& tuple) {
223  try {
224  tuple.unpack(buf.begin(), buf.end());
225  } catch (const OpaqueDataTupleError& ex) {
227  }
228 }
229 
230 void
231 OptionDataTypeUtil::writeTuple(const std::string& value,
232  OpaqueDataTuple::LengthFieldType lengthfieldtype,
233  std::vector<uint8_t>& buf) {
234  if (lengthfieldtype == OpaqueDataTuple::LENGTH_1_BYTE) {
235  if (value.size() > std::numeric_limits<uint8_t>::max()) {
236  isc_throw(BadDataTypeCast, "invalid tuple value (size "
237  << value.size() << " larger than "
238  << std::numeric_limits<uint8_t>::max() << ")");
239  }
240  buf.push_back(static_cast<uint8_t>(value.size()));
241 
242  } else if (lengthfieldtype == OpaqueDataTuple::LENGTH_2_BYTES) {
243  if (value.size() > std::numeric_limits<uint16_t>::max()) {
244  isc_throw(BadDataTypeCast, "invalid tuple value (size "
245  << value.size() << " larger than "
246  << std::numeric_limits<uint16_t>::max() << ")");
247  }
248  buf.resize(buf.size() + 2);
249  isc::util::writeUint16(static_cast<uint16_t>(value.size()),
250  &buf[buf.size() - 2], 2);
251  } else {
252  isc_throw(BadDataTypeCast, "unable to write data to the buffer as"
253  << " tuple. Invalid length type field: "
254  << static_cast<unsigned>(lengthfieldtype));
255  }
256  buf.insert(buf.end(), value.begin(), value.end());
257 }
258 
259 void
260 OptionDataTypeUtil::writeTuple(const OpaqueDataTuple& tuple,
261  std::vector<uint8_t>& buf) {
262  if (tuple.getLength() == 0) {
263  isc_throw(BadDataTypeCast, "invalid empty tuple value");
264  }
265  if (tuple.getLengthFieldType() == OpaqueDataTuple::LENGTH_1_BYTE) {
266  if (tuple.getLength() > std::numeric_limits<uint8_t>::max()) {
267  isc_throw(BadDataTypeCast, "invalid tuple value (size "
268  << tuple.getLength() << " larger than "
269  << std::numeric_limits<uint8_t>::max() << ")");
270  }
271  buf.push_back(static_cast<uint8_t>(tuple.getLength()));
272 
273  } else if (tuple.getLengthFieldType() == OpaqueDataTuple::LENGTH_2_BYTES) {
274  if (tuple.getLength() > std::numeric_limits<uint16_t>::max()) {
275  isc_throw(BadDataTypeCast, "invalid tuple value (size "
276  << tuple.getLength() << " larger than "
277  << std::numeric_limits<uint16_t>::max() << ")");
278  }
279  buf.resize(buf.size() + 2);
280  isc::util::writeUint16(static_cast<uint16_t>(tuple.getLength()),
281  &buf[buf.size() - 2], 2);
282  } else {
283  isc_throw(BadDataTypeCast, "unable to write data to the buffer as"
284  << " tuple. Invalid length type field: "
285  << tuple.getLengthFieldType());
286  }
287  buf.insert(buf.end(), tuple.getData().begin(), tuple.getData().end());
288 }
289 
290 bool
291 OptionDataTypeUtil::readBool(const std::vector<uint8_t>& buf) {
292  if (buf.empty()) {
293  isc_throw(BadDataTypeCast, "unable to read the buffer as boolean"
294  << " value. Invalid buffer size " << buf.size());
295  }
296  if (buf[0] == 1) {
297  return (true);
298  } else if (buf[0] == 0) {
299  return (false);
300  }
301  isc_throw(BadDataTypeCast, "unable to read the buffer as boolean"
302  << " value. Invalid value " << static_cast<int>(buf[0]));
303 }
304 
305 void
306 OptionDataTypeUtil::writeBool(const bool value,
307  std::vector<uint8_t>& buf) {
308  buf.push_back(static_cast<uint8_t>(value ? 1 : 0));
309 }
310 
311 std::string
312 OptionDataTypeUtil::readFqdn(const std::vector<uint8_t>& buf) {
313  // If buffer is empty emit an error.
314  if (buf.empty()) {
315  isc_throw(BadDataTypeCast, "unable to read FQDN from a buffer."
316  << " The buffer is empty.");
317  }
318  // Set up an InputBuffer so as we can use isc::dns::Name object to get the FQDN.
319  isc::util::InputBuffer in_buf(static_cast<const void*>(&buf[0]), buf.size());
320  try {
321  // Try to create an object from the buffer. If exception is thrown
322  // it means that the buffer doesn't hold a valid domain name (invalid
323  // syntax).
324  isc::dns::Name name(in_buf);
325  return (name.toText());
326  } catch (const isc::Exception& ex) {
327  // Unable to convert the data in the buffer into FQDN.
329  }
330 }
331 
332 void
333 OptionDataTypeUtil::writeFqdn(const std::string& fqdn,
334  std::vector<uint8_t>& buf,
335  bool downcase) {
336  try {
337  isc::dns::Name name(fqdn, downcase);
338  isc::dns::LabelSequence labels(name);
339  if (labels.getDataLength() > 0) {
340  size_t read_len = 0;
341  const uint8_t* data = labels.getData(&read_len);
342  buf.insert(buf.end(), data, data + read_len);
343  }
344  } catch (const isc::Exception& ex) {
346  }
347 }
348 
349 unsigned int
350 OptionDataTypeUtil::getLabelCount(const std::string& text_name) {
351  // The isc::dns::Name class doesn't accept empty names. However, in some
352  // cases we may be dealing with empty names (e.g. sent by the DHCP clients).
353  // Empty names should not be sent as hostnames but if they are, for some
354  // reason, we don't want to throw an exception from this function. We
355  // rather want to signal empty name by returning 0 number of labels.
356  if (text_name.empty()) {
357  return (0);
358  }
359  try {
360  isc::dns::Name name(text_name);
361  return (name.getLabelCount());
362  } catch (const isc::Exception& ex) {
364  }
365 }
366 
368 OptionDataTypeUtil::readPrefix(const std::vector<uint8_t>& buf) {
369  // Prefix typically consists of the prefix length and the
370  // actual value. If prefix length is 0, the buffer length should
371  // be at least 1 byte to hold this length value.
372  if (buf.empty()) {
373  isc_throw(BadDataTypeCast, "unable to read prefix length from "
374  "a truncated buffer");
375  }
376 
377  // Surround everything with try-catch to unify exceptions being
378  // thrown by various functions and constructors.
379  try {
380  // Try to create PrefixLen object from the prefix length held
381  // in the buffer. This may cause an exception if the length is
382  // invalid (greater than 128).
383  PrefixLen prefix_len(buf.at(0));
384 
385  // Convert prefix length to bytes, because we operate on bytes,
386  // rather than bits.
387  uint8_t prefix_len_bytes = (prefix_len.asUint8() / 8);
388  // Check if we need to zero pad any bits. This is the case when
389  // the prefix length is not divisible by 8 (bits per byte). The
390  // calculations below may require some explanations. We first
391  // perform prefix_len % 8 to get the number of useful bits beyond
392  // the current prefix_len_bytes value. By substracting it from 8
393  // we get the number of zero padded bits, but with the special
394  // case of 8 when the result of substraction is 0. The value of
395  // 8 really means no padding so we make a modulo division once
396  // again to turn 8s to 0s.
397  const uint8_t zero_padded_bits =
398  static_cast<uint8_t>((8 - (prefix_len.asUint8() % 8)) % 8);
399  // If there are zero padded bits, it means that we need an extra
400  // byte to be retrieved from the buffer.
401  if (zero_padded_bits > 0) {
402  ++prefix_len_bytes;
403  }
404 
405  // Make sure that the buffer is long enough. We substract 1 to
406  // also account for the fact that the buffer includes a prefix
407  // length besides a prefix.
408  if ((buf.size() - 1) < prefix_len_bytes) {
409  isc_throw(BadDataTypeCast, "unable to read a prefix having length of "
410  << prefix_len.asUnsigned() << " from a truncated buffer");
411  }
412 
413  // It is possible for a prefix to be zero if the prefix length
414  // is zero.
416 
417  // If there is anything more than prefix length is this buffer
418  // we need to read it.
419  if (buf.size() > 1) {
420  // Buffer has to be copied, because we will modify its
421  // contents by setting certain bits to 0, if necessary.
422  std::vector<uint8_t> prefix_buf(buf.begin() + 1, buf.end());
423  // All further conversions require that the buffer length is
424  // 16 bytes.
425  if (prefix_buf.size() < V6ADDRESS_LEN) {
426  prefix_buf.resize(V6ADDRESS_LEN);
427  if (prefix_len_bytes < prefix_buf.size()) {
428  // Zero all bits in the buffer beyond prefix length
429  // position.
430  std::fill(prefix_buf.begin() + prefix_len_bytes,
431  prefix_buf.end(), 0);
432 
433  if (zero_padded_bits) {
434  // There is a byte that require zero padding. We
435  // achieve that by shifting the value of that byte
436  // back and forth by the number of zeroed bits.
437  prefix_buf.at(prefix_len_bytes - 1) =
438  (prefix_buf.at(prefix_len_bytes - 1)
439  >> zero_padded_bits)
440  << zero_padded_bits;
441  }
442  }
443  }
444  // Convert the buffer to the IOAddress object.
445  prefix = IOAddress::fromBytes(AF_INET6, &prefix_buf[0]);
446  }
447 
448  return (std::make_pair(prefix_len, prefix));
449 
450  } catch (const BadDataTypeCast& ex) {
451  // Pass through the BadDataTypeCast exceptions.
452  throw;
453 
454  } catch (const std::exception& ex) {
455  // If an exception of a different type has been thrown, insert
456  // a text that indicates that the failure occurred during reading
457  // the prefix and modify exception type to BadDataTypeCast.
458  isc_throw(BadDataTypeCast, "unable to read a prefix from a buffer: "
459  << ex.what());
460  }
461 }
462 
463 void
464 OptionDataTypeUtil::writePrefix(const PrefixLen& prefix_len,
465  const IOAddress& prefix,
466  std::vector<uint8_t>& buf) {
467  // Prefix must be an IPv6 prefix.
468  if (!prefix.isV6()) {
469  isc_throw(BadDataTypeCast, "illegal prefix value "
470  << prefix);
471  }
472 
473  // We don't need to validate the prefix_len value, because it is
474  // already validated by the PrefixLen class.
475  buf.push_back(prefix_len.asUint8());
476 
477  // Convert the prefix length to a number of bytes.
478  uint8_t prefix_len_bytes = prefix_len.asUint8() / 8;
479  // Check if there are any bits that require zero padding. See the
480  // commentary in readPrefix to see how this is calculated.
481  const uint8_t zero_padded_bits =
482  static_cast<uint8_t>((8 - (prefix_len.asUint8() % 8)) % 8);
483  // If zero padding is needed it means that we need to extend the
484  // buffer to hold the "partially occupied" byte.
485  if (zero_padded_bits > 0) {
486  ++prefix_len_bytes;
487  }
488 
489  // Convert the prefix to byte representation and append it to
490  // our output buffer.
491  std::vector<uint8_t> prefix_bytes = prefix.toBytes();
492  buf.insert(buf.end(), prefix_bytes.begin(),
493  prefix_bytes.begin() + prefix_len_bytes);
494  // If the last byte requires zero padding we achieve that by shifting
495  // bits back and forth by the number of insignificant bits.
496  if (zero_padded_bits) {
497  *buf.rbegin() = (*buf.rbegin() >> zero_padded_bits) << zero_padded_bits;
498  }
499 }
500 
501 PSIDTuple
502 OptionDataTypeUtil::readPsid(const std::vector<uint8_t>& buf) {
503  if (buf.size() < 3) {
504  isc_throw(BadDataTypeCast, "unable to read PSID from the buffer."
505  << " Invalid buffer size " << buf.size()
506  << ". Expected 3 bytes (PSID length and PSID value)");
507  }
508 
509  // Read PSID length.
510  uint8_t psid_len = buf[0];
511 
512  // PSID length must not be greater than 16 bits.
513  if (psid_len > sizeof(uint16_t) * 8) {
514  isc_throw(BadDataTypeCast, "invalid PSID length value "
515  << static_cast<unsigned>(psid_len)
516  << ", this value is expected to be in range of 0 to 16");
517  }
518 
519  // Read two bytes of PSID value.
520  uint16_t psid = isc::util::readUint16(&buf[1], 2);
521 
522  // We need to check that the PSID value does not exceed the maximum value
523  // for a specified PSID length. That means that all bits placed further than
524  // psid_len from the left must be set to 0. So, we create a bit mask
525  // by shifting a value of 0xFFFF to the left and right by psid_len. This
526  // leaves us with psid_len leftmost bits unset and the rest set. Next, we
527  // apply the mask on the PSID value from the buffer and make sure the result
528  // is 0. Otherwise, it means that there are some bits set in the PSID which
529  // aren't supposed to be set.
530  if ((psid_len > 0) &&
531  ((psid & static_cast<uint16_t>(static_cast<uint16_t>(0xFFFF << psid_len)
532  >> psid_len)) != 0)) {
533  isc_throw(BadDataTypeCast, "invalid PSID value " << psid
534  << " for a specified PSID length "
535  << static_cast<unsigned>(psid_len));
536  }
537 
538  // All is good, so we can convert the PSID value read from the buffer to
539  // the port set number.
540  if (psid_len == sizeof(psid) * 8) {
541  // Shift by 16 always gives zero (CID 1398333)
542  psid = 0;
543  } else {
544  psid = psid >> (sizeof(psid) * 8 - psid_len);
545  }
546  return (std::make_pair(PSIDLen(psid_len), PSID(psid)));
547 }
548 
549 void
550 OptionDataTypeUtil::writePsid(const PSIDLen& psid_len, const PSID& psid,
551  std::vector<uint8_t>& buf) {
552  if (psid_len.asUint8() > sizeof(psid) * 8) {
553  isc_throw(BadDataTypeCast, "invalid PSID length value "
554  << psid_len.asUnsigned()
555  << ", this value is expected to be in range of 0 to 16");
556  }
557 
558  if (psid_len.asUint8() > 0 &&
559  (psid.asUint16() > (0xFFFF >> (sizeof(uint16_t) * 8 - psid_len.asUint8())))) {
560  isc_throw(BadDataTypeCast, "invalid PSID value " << psid.asUint16()
561  << " for a specified PSID length "
562  << psid_len.asUnsigned());
563  }
564 
565  buf.resize(buf.size() + 3);
566  buf.at(buf.size() - 3) = psid_len.asUint8();
567  isc::util::writeUint16(static_cast<uint16_t>
568  (psid.asUint16() << (sizeof(uint16_t) * 8 - psid_len.asUint8())),
569  &buf[buf.size() - 2], 2);
570 }
571 
572 
573 std::string
574 OptionDataTypeUtil::readString(const std::vector<uint8_t>& buf) {
575  std::string value;
576  if (!buf.empty()) {
577  value.insert(value.end(), buf.begin(), buf.end());
578  }
579  return (value);
580 }
581 
582 void
583 OptionDataTypeUtil::writeString(const std::string& value,
584  std::vector<uint8_t>& buf) {
585  if (value.size() > 0) {
586  buf.insert(buf.end(), value.begin(), value.end());
587  }
588 }
589 
590 } // end of isc::dhcp namespace
591 } // end of isc namespace
isc::dhcp::OPT_UNKNOWN_TYPE
@ OPT_UNKNOWN_TYPE
Definition: option_data_types.h:64
isc::dhcp::OptionBuffer
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition: option.h:25
isc::dhcp::OPT_UINT32_TYPE
@ OPT_UINT32_TYPE
Definition: option_data_types.h:54
isc::dhcp::OpaqueDataTuple::getLength
size_t getLength() const
Returns the length of the data in the tuple.
Definition: opaque_data_tuple.h:153
isc::dhcp::PSIDLen::asUint8
uint8_t asUint8() const
Returns PSID length as uint8_t value.
Definition: option_data_types.h:223
option_data_types.h
isc::dhcp::OPT_BOOLEAN_TYPE
@ OPT_BOOLEAN_TYPE
Definition: option_data_types.h:48
isc::dhcp::OPT_IPV4_ADDRESS_TYPE
@ OPT_IPV4_ADDRESS_TYPE
Definition: option_data_types.h:56
isc::dhcp::PSIDLen::asUnsigned
unsigned int asUnsigned() const
Returns PSID length as unsigned int.
Definition: option_data_types.h:235
isc::dhcp::OPT_STRING_TYPE
@ OPT_STRING_TYPE
Definition: option_data_types.h:60
name.h
isc::util::writeUint16
uint8_t * writeUint16(uint16_t value, void *buffer, size_t length)
Write Unsigned 16-Bit Integer to Buffer.
Definition: io_utilities.h:55
isc::dns::Name::toText
std::string toText(bool omit_final_dot=false) const
Convert the Name to a string.
Definition: name.cc:507
isc::dns::Name::getLabelCount
unsigned int getLabelCount() const
Returns the number of labels contained in the Name.
Definition: name.h:370
isc::dhcp::OpaqueDataTuple::LengthFieldType
LengthFieldType
Size of the length field in the tuple.
Definition: opaque_data_tuple.h:55
isc::dhcp::OPT_EMPTY_TYPE
@ OPT_EMPTY_TYPE
Definition: option_data_types.h:46
isc::dns::LabelSequence::getDataLength
size_t getDataLength() const
Return the length of the wire-format data of this LabelSequence.
Definition: labelsequence.cc:88
labelsequence.h
isc::dhcp::OpaqueDataTuple::getLengthFieldType
LengthFieldType getLengthFieldType() const
Returns tuple length data field type.
Definition: opaque_data_tuple.h:148
isc::Exception
This is a base class for exceptions thrown from the DNS library module.
Definition: exceptions/exceptions.h:23
isc
Defines the logger used by the top-level component of kea-dhcp-ddns.
Definition: agent_parser.cc:144
isc::Exception::what
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Definition: exceptions/exceptions.cc:32
hex.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:192
isc::dhcp::OpaqueDataTupleError
Exception to be thrown when the operation on OpaqueDataTuple object results in an error.
Definition: opaque_data_tuple.h:22
isc::dhcp::PSID::asUint16
uint16_t asUint16() const
Returns PSID value as a number.
Definition: option_data_types.h:262
isc::dhcp::OPT_INT16_TYPE
@ OPT_INT16_TYPE
Definition: option_data_types.h:50
isc::dns::Name
The Name class encapsulates DNS names.
Definition: name.h:223
isc::dhcp::OPT_UINT8_TYPE
@ OPT_UINT8_TYPE
Definition: option_data_types.h:52
isc::dhcp::PrefixLen
Encapsulates prefix length.
Definition: option_data_types.h:277
isc::util::readUint16
uint16_t readUint16(const void *buffer, size_t length)
Read Unsigned 16-Bit Integer from Buffer.
Definition: io_utilities.h:28
isc::dhcp::OPT_INT8_TYPE
@ OPT_INT8_TYPE
Definition: option_data_types.h:49
isc::dhcp::PrefixTuple
std::pair< PrefixLen, asiolink::IOAddress > PrefixTuple
Defines a pair of prefix length / value.
Definition: option_data_types.h:315
isc::dhcp::PrefixLen::asUint8
uint8_t asUint8() const
Returns prefix length as uint8_t value.
Definition: option_data_types.h:295
isc::dhcp::BadDataTypeCast
Exception to be thrown when cast to the data type was unsuccessful.
Definition: option_data_types.h:30
isc::dhcp::OPT_RECORD_TYPE
@ OPT_RECORD_TYPE
Definition: option_data_types.h:63
isc::dhcp::OPT_BINARY_TYPE
@ OPT_BINARY_TYPE
Definition: option_data_types.h:47
isc::dhcp::OPT_PSID_TYPE
@ OPT_PSID_TYPE
Definition: option_data_types.h:59
isc::util::InputBuffer
The InputBuffer class is a buffer abstraction for manipulating read-only data.
Definition: buffer.h:81
isc::dns::LabelSequence::getData
const uint8_t * getData(size_t *len) const
Return the wire-format data for this LabelSequence.
Definition: labelsequence.cc:82
isc::dhcp::OpaqueDataTuple
Represents a single instance of the opaque data preceded by length.
Definition: opaque_data_tuple.h:45
isc::dhcp::OptionDataType
OptionDataType
Data types of DHCP option fields.
Definition: option_data_types.h:45
isc::dhcp::OPT_INT32_TYPE
@ OPT_INT32_TYPE
Definition: option_data_types.h:51
isc::dhcp::PSIDLen
Encapsulates PSID length.
Definition: option_data_types.h:201
isc::dhcp::OPT_IPV6_PREFIX_TYPE
@ OPT_IPV6_PREFIX_TYPE
Definition: option_data_types.h:58
isc::dhcp::OPT_FQDN_TYPE
@ OPT_FQDN_TYPE
Definition: option_data_types.h:62
isc::dhcp::OPT_TUPLE_TYPE
@ OPT_TUPLE_TYPE
Definition: option_data_types.h:61
isc::dhcp::PSIDTuple
std::pair< PSIDLen, PSID > PSIDTuple
Defines a pair of PSID length / value.
Definition: option_data_types.h:274
isc::dhcp::OPT_UINT16_TYPE
@ OPT_UINT16_TYPE
Definition: option_data_types.h:53
isc::dhcp::OpaqueDataTuple::getData
const Buffer & getData() const
Returns a reference to the buffer holding tuple data.
Definition: opaque_data_tuple.h:167
isc::dhcp::PSID
Encapsulates PSID value.
Definition: option_data_types.h:246
isc::dhcp::OPT_IPV6_ADDRESS_TYPE
@ OPT_IPV6_ADDRESS_TYPE
Definition: option_data_types.h:57
isc::dhcp::PrefixLen::asUnsigned
unsigned int asUnsigned() const
Returns prefix length as unsigned int.
Definition: option_data_types.h:304
isc::dhcp::OpaqueDataTuple::unpack
void unpack(InputIterator begin, InputIterator end)
Parses wire data and creates a tuple from it.
Definition: opaque_data_tuple.h:213
isc::util::encode::decodeHex
void decodeHex(const string &input, vector< uint8_t > &result)
Decode a text encoded in the base16 ('hex') format into the original data.
Definition: base_n.cc:466
isc::dns::LabelSequence
Light-weight Accessor to Name data.
Definition: labelsequence.h:35