Kea: option_definition.cc Source File

| Kea 3.0.0

option_definition.cc
Go to the documentation of this file.
1// Copyright (C) 2012-2025 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
9#include <dhcp/dhcp4.h>
10#include <dhcp/dhcp6.h>
11#include <dhcp/option4_addrlst.h>
12#include <dhcp/option4_client_fqdn.h>
13#include <dhcp/option4_dnr.h>
14#include <dhcp/option6_addrlst.h>
15#include <dhcp/option6_client_fqdn.h>
16#include <dhcp/option6_dnr.h>
17#include <dhcp/option6_ia.h>
18#include <dhcp/option6_iaaddr.h>
19#include <dhcp/option6_iaprefix.h>
20#include <dhcp/option6_pdexclude.h>
21#include <dhcp/option6_status_code.h>
22#include <dhcp/option_custom.h>
23#include <dhcp/option_definition.h>
24#include <dhcp/option_int.h>
25#include <dhcp/option_int_array.h>
26#include <dhcp/option_opaque_data_tuples.h>
27#include <dhcp/option_classless_static_route.h>
28#include <dhcp/option_string.h>
29#include <dhcp/option_vendor.h>
30#include <dhcp/option_vendor_class.h>
31#include <util/encode/encode.h>
32#include <dns/labelsequence.h>
33#include <dns/name.h>
34#include <util/str.h>
35#include <boost/algorithm/string/classification.hpp>
36#include <boost/algorithm/string/predicate.hpp>
37#include <boost/algorithm/string/replace.hpp>
38#include <boost/dynamic_bitset.hpp>
39#include <boost/make_shared.hpp>
40#include <sstream>
41
42using namespace std;
43using namespace isc::util;
44
45namespace isc {
46namespace dhcp {
47
48OptionDefinition::OptionDefinition(const std::string& name,
49 const uint16_t code,
50 const std::string& space,
51 const std::string& type,
52 const bool array_type /* = false */)
53 : name_(name),
54 code_(code),
55 type_(OPT_UNKNOWN_TYPE),
56 array_type_(array_type),
57 encapsulated_space_(""),
58 record_fields_(),
59 user_context_(),
60 option_space_name_(space) {
61 // Data type is held as enum value by this class.
62 // Use the provided option type string to get the
63 // corresponding enum value.
64 type_ = OptionDataTypeUtil::getDataType(type);
65}
66
67 OptionDefinition::OptionDefinition(const std::string& name,
68 const uint16_t code,
69 const std::string& space,
70 const OptionDataType type,
71 const bool array_type /* = false */)
72 : name_(name),
73 code_(code),
74 type_(type),
75 array_type_(array_type),
76 encapsulated_space_(""),
77 option_space_name_(space){
78}
79
80 OptionDefinition::OptionDefinition(const std::string& name,
81 const uint16_t code,
82 const std::string& space,
83 const std::string& type,
84 const char* encapsulated_space)
85 : name_(name),
86 code_(code),
87 // Data type is held as enum value by this class.
88 // Use the provided option type string to get the
89 // corresponding enum value.
90 type_(OptionDataTypeUtil::getDataType(type)),
91 array_type_(false),
92 encapsulated_space_(encapsulated_space),
93 record_fields_(),
94 user_context_(),
95 option_space_name_(space) {
96}
97
98 OptionDefinition::OptionDefinition(const std::string& name,
99 const uint16_t code,
100 const std::string& space,
101 const OptionDataType type,
102 const char* encapsulated_space)
103 : name_(name),
104 code_(code),
105 type_(type),
106 array_type_(false),
107 encapsulated_space_(encapsulated_space),
108 record_fields_(),
109 user_context_(),
110 option_space_name_(space) {
111}
112
113 OptionDefinitionPtr
114OptionDefinition::create(const std::string& name,
115 const uint16_t code,
116 const std::string& space,
117 const std::string& type,
118 const bool array_type) {
119 return (boost::make_shared<OptionDefinition>(name, code, space, type, array_type));
120}
121
122 OptionDefinitionPtr
123 OptionDefinition::create(const std::string& name,
124 const uint16_t code,
125 const std::string& space,
126 const OptionDataType type,
127 const bool array_type) {
128 return (boost::make_shared<OptionDefinition>(name, code, space, type, array_type));
129}
130
131 OptionDefinitionPtr
132 OptionDefinition::create(const std::string& name,
133 const uint16_t code,
134 const std::string& space,
135 const std::string& type,
136 const char* encapsulated_space) {
137 return (boost::make_shared<OptionDefinition>(name, code, space, type, encapsulated_space));
138}
139
140 OptionDefinitionPtr
141 OptionDefinition::create(const std::string& name,
142 const uint16_t code,
143 const std::string& space,
144 const OptionDataType type,
145 const char* encapsulated_space) {
146 return (boost::make_shared<OptionDefinition>(name, code, space, type, encapsulated_space));
147}
148
149bool
150OptionDefinition::equals(const OptionDefinition& other) const {
151 return (name_ == other.name_ &&
152 code_ == other.code_ &&
153 type_ == other.type_ &&
154 array_type_ == other.array_type_ &&
155 encapsulated_space_ == other.encapsulated_space_ &&
156 record_fields_ == other.record_fields_ &&
157 option_space_name_ == other.option_space_name_);
158}
159
160void
161OptionDefinition::addRecordField(const std::string& data_type_name) {
162 OptionDataType data_type = OptionDataTypeUtil::getDataType(data_type_name);
163 addRecordField(data_type);
164}
165
166void
167 OptionDefinition::addRecordField(const OptionDataType data_type) {
168 if (type_ != OPT_RECORD_TYPE) {
169 isc_throw(isc::InvalidOperation,
170 "'record' option type must be used instead of '"
171 << OptionDataTypeUtil::getDataTypeName(type_)
172 << "' to add data fields to the record");
173 }
174 if (data_type >= OPT_RECORD_TYPE ||
175 data_type == OPT_ANY_ADDRESS_TYPE ||
176 data_type == OPT_EMPTY_TYPE) {
177 isc_throw(isc::BadValue,
178 "attempted to add invalid data type '"
179 << OptionDataTypeUtil::getDataTypeName(data_type)
180 << "' to the record.");
181 }
182 record_fields_.push_back(data_type);
183}
184
185 OptionPtr
186OptionDefinition::optionFactory(Option::Universe u,
187 uint16_t type,
188 OptionBufferConstIter begin,
189 OptionBufferConstIter end,
190 bool convenient_notation) const {
191
192 try {
193 // Some of the options are represented by the specialized classes derived
194 // from Option class (e.g. IA_NA, IAADDR). Although, they can be also
195 // represented by the generic classes, we want the object of the specialized
196 // type to be returned. Therefore, we first check that if we are dealing
197 // with such an option. If the instance is returned we just exit at this
198 // point. If not, we will search for a generic option type to return.
199 OptionPtr option = factorySpecialFormatOption(u, begin, end, convenient_notation);
200 if (option) {
201 return (option);
202 }
203
204 switch (type_) {
205 case OPT_EMPTY_TYPE:
206 if (getEncapsulatedSpace().empty()) {
207 return (factoryEmpty(u, type));
208 } else {
209 return (OptionPtr(new OptionCustom(*this, u, begin, end)));
210 }
211
212 case OPT_BINARY_TYPE:
213 // If this is Internal type, and it wasn't handled by factorySpecialFormatOption() before,
214 // let's treat it like normal Binary type.
215 case OPT_INTERNAL_TYPE:
216 return (factoryGeneric(u, type, begin, end));
217
218 case OPT_UINT8_TYPE:
219 return (array_type_ ?
220 factoryIntegerArray<uint8_t>(u, type, begin, end) :
221 factoryInteger<uint8_t>(u, type, getEncapsulatedSpace(),
222 begin, end));
223
224 case OPT_INT8_TYPE:
225 return (array_type_ ?
226 factoryIntegerArray<int8_t>(u, type, begin, end) :
227 factoryInteger<int8_t>(u, type, getEncapsulatedSpace(),
228 begin, end));
229
230 case OPT_UINT16_TYPE:
231 return (array_type_ ?
232 factoryIntegerArray<uint16_t>(u, type, begin, end) :
233 factoryInteger<uint16_t>(u, type, getEncapsulatedSpace(),
234 begin, end));
235
236 case OPT_INT16_TYPE:
237 return (array_type_ ?
238 factoryIntegerArray<uint16_t>(u, type, begin, end) :
239 factoryInteger<int16_t>(u, type, getEncapsulatedSpace(),
240 begin, end));
241
242 case OPT_UINT32_TYPE:
243 return (array_type_ ?
244 factoryIntegerArray<uint32_t>(u, type, begin, end) :
245 factoryInteger<uint32_t>(u, type, getEncapsulatedSpace(),
246 begin, end));
247
248 case OPT_INT32_TYPE:
249 return (array_type_ ?
250 factoryIntegerArray<uint32_t>(u, type, begin, end) :
251 factoryInteger<int32_t>(u, type, getEncapsulatedSpace(),
252 begin, end));
253
254 case OPT_IPV4_ADDRESS_TYPE:
255 // If definition specifies that an option is an array
256 // of IPv4 addresses we return an instance of specialized
257 // class (OptionAddrLst4). For non-array types there is no
258 // specialized class yet implemented so we drop through
259 // to return an instance of OptionCustom.
260 if (array_type_) {
261 return (factoryAddrList4(type, begin, end));
262 }
263 break;
264
265 case OPT_IPV6_ADDRESS_TYPE:
266 // Handle array type only here (see comments for
267 // OPT_IPV4_ADDRESS_TYPE case).
268 if (array_type_) {
269 return (factoryAddrList6(type, begin, end));
270 }
271 break;
272
273 case OPT_STRING_TYPE:
274 return (OptionPtr(new OptionString(u, type, begin, end)));
275
276 case OPT_TUPLE_TYPE:
277 // Handle array type only here (see comments for
278 // OPT_IPV4_ADDRESS_TYPE case).
279 if (array_type_) {
280 return (factoryOpaqueDataTuples(u, type, begin, end));
281 }
282 break;
283
284 default:
285 // Do nothing. We will return generic option a few lines down.
286 ;
287 }
288 return (OptionPtr(new OptionCustom(*this, u, begin, end)));
289 } catch (const SkipThisOptionError&) {
290 // We need to throw this one as is.
291 throw;
292 } catch (const SkipRemainingOptionsError&) {
293 // We need to throw this one as is.
294 throw;
295 } catch (const Exception& ex) {
296 isc_throw(InvalidOptionValue, ex.what());
297 }
298}
299
300 OptionPtr
301 OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
302 const OptionBuffer& buf) const {
303 return (optionFactory(u, type, buf.begin(), buf.end()));
304}
305
306 OptionPtr
307 OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
308 const std::vector<std::string>& values) const {
309 OptionBuffer buf;
310 if (!array_type_ && type_ != OPT_RECORD_TYPE) {
311 if (values.empty()) {
312 if (type_ != OPT_EMPTY_TYPE) {
313 isc_throw(InvalidOptionValue, "no option value specified");
314 }
315 } else if (type_ == OPT_INTERNAL_TYPE) {
316 // If an Option of type Internal is configured using csv-format=true, it means it is
317 // convenient notation option config that needs special parsing. Let's treat it like
318 // String type. optionFactory() will be called with convenient_notation flag set to
319 // true, so that the factory will have a chance to handle it in a special way.
320
321 // At this stage any escape backslash chars were lost during last call of
322 // isc::util::str::tokens() inside of
323 // OptionDataParser::createOption(ConstElementPtr option_data), so we must
324 // restore them. Some INTERNAL options may use escaped delimiters, e.g. DNR options.
325 // Values are concatenated back to comma separated format and will be written to
326 // the OptionBuffer as one String type option.
327 std::ostringstream stream;
328 bool first = true;
329 for (auto val : values) {
330 boost::algorithm::replace_all(val, ",", "\\,");
331 if (first) {
332 first = false;
333 } else {
334 stream << ",";
335 }
336
337 stream << val;
338 }
339
340 writeToBuffer(u, stream.str(), OPT_STRING_TYPE, buf);
341 } else {
342 writeToBuffer(u, util::str::trim(values[0]), type_, buf);
343 }
344 } else if (array_type_ && type_ != OPT_RECORD_TYPE) {
345 for (size_t i = 0; i < values.size(); ++i) {
346 writeToBuffer(u, util::str::trim(values[i]), type_, buf);
347 }
348 } else if (type_ == OPT_RECORD_TYPE) {
349 const RecordFieldsCollection& records = getRecordFields();
350 if (records.size() > values.size()) {
351 isc_throw(InvalidOptionValue, "number of data fields for the option"
352 << " type '" << getCode() << "' is greater than number"
353 << " of values provided.");
354 }
355 for (size_t i = 0; i < records.size(); ++i) {
356 writeToBuffer(u, util::str::trim(values[i]), records[i], buf);
357 }
358 if (array_type_ && (values.size() > records.size())) {
359 for (size_t i = records.size(); i < values.size(); ++i) {
360 writeToBuffer(u, util::str::trim(values[i]),
361 records.back(), buf);
362 }
363 }
364 }
365 return (optionFactory(u, type, buf.begin(), buf.end(), (type_ == OPT_INTERNAL_TYPE)));
366}
367
368void
369OptionDefinition::validate() const {
370
371 using namespace boost::algorithm;
372
373 std::ostringstream err_str;
374
375 // Allowed characters in the option name are: lower or
376 // upper case letters, digits, underscores and hyphens.
377 // Empty option spaces are not allowed.
378 if (!all(name_, boost::is_from_range('a', 'z') ||
379 boost::is_from_range('A', 'Z') ||
380 boost::is_digit() ||
381 boost::is_any_of(std::string("-_"))) ||
382 name_.empty() ||
383 // Hyphens and underscores are not allowed at the beginning
384 // and at the end of the option name.
385 all(find_head(name_, 1), boost::is_any_of(std::string("-_"))) ||
386 all(find_tail(name_, 1), boost::is_any_of(std::string("-_")))) {
387 err_str << "invalid option name '" << name_ << "'";
388
389 } else if (!OptionSpace::validateName(option_space_name_)) {
390 err_str << "invalid option space name: '"
391 << option_space_name_ << "'";
392
393 } else if (!encapsulated_space_.empty() &&
394 !OptionSpace::validateName(encapsulated_space_)) {
395 err_str << "invalid encapsulated option space name: '"
396 << encapsulated_space_ << "'";
397
398 } else if (type_ >= OPT_UNKNOWN_TYPE) {
399 // Option definition must be of a known type.
400 err_str << "option type " << type_ << " not supported.";
401
402 } else if (type_ == OPT_RECORD_TYPE) {
403 // At least two data fields should be added to the record. Otherwise
404 // non-record option definition could be used.
405 if (getRecordFields().size() < 2) {
406 err_str << "invalid number of data fields: "
407 << getRecordFields().size()
408 << " specified for the option of type 'record'. Expected at"
409 << " least 2 fields.";
410
411 } else {
412 // If the number of fields is valid we have to check if their order
413 // is valid too. We check that string or binary data fields are not
414 // laid before other fields. But we allow that they are laid at the
415 // end of an option.
416 const RecordFieldsCollection& fields = getRecordFields();
417 for (RecordFieldsConstIter it = fields.begin();
418 it != fields.end(); ++it) {
419 if (*it == OPT_STRING_TYPE &&
420 it < fields.end() - 1) {
421 err_str << "string data field can't be laid before data"
422 << " fields of other types.";
423 break;
424 }
425 if (*it == OPT_BINARY_TYPE &&
426 it < fields.end() - 1) {
427 err_str << "binary data field can't be laid before data"
428 << " fields of other types.";
429 break;
430 }
431 // Empty type is not allowed within a record.
432 if (*it == OPT_EMPTY_TYPE) {
433 err_str << "empty data type can't be stored as a field in"
434 << " an option record.";
435 break;
436 }
437 // Internal type is not allowed within a record.
438 if (*it == OPT_INTERNAL_TYPE) {
439 err_str << "internal data type can't be stored as a field in"
440 << " an option record.";
441 break;
442 }
443 }
444 // If the array flag is set the last field is an array.
445 if (err_str.str().empty() && array_type_) {
446 const OptionDataType& last_type = fields.back();
447 if (last_type == OPT_STRING_TYPE) {
448 err_str
449 << "array of strings is not a valid option definition.";
450 } else if (last_type == OPT_BINARY_TYPE) {
451 err_str << "array of binary values is not a valid option "
452 "definition.";
453 }
454 // Empty type was already checked.
455 }
456 }
457
458 } else if (array_type_) {
459 if (type_ == OPT_STRING_TYPE) {
460 // Array of strings is not allowed because there is no way
461 // to determine the size of a particular string and thus there
462 // it no way to tell when other data fields begin.
463 err_str << "array of strings is not a valid option definition.";
464 } else if (type_ == OPT_BINARY_TYPE) {
465 err_str << "array of binary values is not"
466 << " a valid option definition.";
467
468 } else if (type_ == OPT_EMPTY_TYPE) {
469 err_str << "array of empty value is not"
470 << " a valid option definition.";
471
472 } else if (type_ == OPT_INTERNAL_TYPE) {
473 err_str << "array of internal type value is not"
474 << " a valid option definition.";
475
476 }
477 }
478
479 // Non-empty error string means that we have hit the error. We throw
480 // exception and include error string.
481 if (!err_str.str().empty()) {
482 isc_throw(MalformedOptionDefinition, err_str.str());
483 }
484}
485
486bool
487OptionDefinition::haveCompressedFqdnListFormat() const {
488 return (haveType(OPT_FQDN_TYPE) && getArrayType());
489}
490
491bool
492OptionDefinition::convertToBool(const std::string& value_str) const {
493 // Case-insensitive check that the input is one of: "true" or "false".
494 if (boost::iequals(value_str, "true")) {
495 return (true);
496
497 } else if (boost::iequals(value_str, "false")) {
498 return (false);
499
500 }
501
502 // The input string is neither "true" nor "false", so let's check
503 // if it is not an integer wrapped in a string.
504 int result;
505 try {
506 result = boost::lexical_cast<int>(value_str);
507
508 } catch (const boost::bad_lexical_cast&) {
509 isc_throw(BadDataTypeCast, "unable to covert the value '"
510 << value_str << "' to boolean data type");
511 }
512 // The boolean value is encoded in DHCP option as 0 or 1. Therefore,
513 // we only allow a user to specify those values for options which
514 // have boolean fields.
515 if (result != 1 && result != 0) {
516 isc_throw(BadDataTypeCast, "unable to convert '" << value_str
517 << "' to boolean data type");
518 }
519 return (static_cast<bool>(result));
520}
521
522template<typename T>
523T
524OptionDefinition::lexicalCastWithRangeCheck(const std::string& value_str)
525 const {
526 // The lexical cast should be attempted when converting to an integer
527 // value only.
528 if (!OptionDataTypeTraits<T>::integer_type) {
529 isc_throw(BadDataTypeCast,
530 "must not convert '" << value_str
531 << "' to non-integer data type");
532 }
533
534 // We use the 64-bit value here because it has wider range than
535 // any other type we use here and it allows to detect out of
536 // bounds conditions e.g. negative value specified for uintX_t
537 // data type. Obviously if the value exceeds the limits of int64
538 // this function will not handle that properly.
539 int64_t result = 0;
540 try {
541 result = boost::lexical_cast<int64_t>(value_str);
542
543 } catch (const boost::bad_lexical_cast&) {
544 // boost::lexical_cast does not handle hexadecimal
545 // but stringstream does so do it the hard way.
546 std::stringstream ss;
547 ss << std::hex << value_str;
548 ss >> result;
549 if (ss.fail() || !ss.eof()) {
550 isc_throw(BadDataTypeCast, "unable to convert the value '"
551 << value_str << "' to integer data type");
552 }
553 }
554 // Perform range checks.
555 if (OptionDataTypeTraits<T>::integer_type) {
556 if (result > numeric_limits<T>::max() ||
557 result < numeric_limits<T>::min()) {
558 isc_throw(BadDataTypeCast, "unable to convert '"
559 << value_str << "' to numeric type. This value is "
560 "expected to be in the range of "
561 << +numeric_limits<T>::min() << ".."
562 << +numeric_limits<T>::max());
563 }
564 }
565 return (static_cast<T>(result));
566}
567
568void
569OptionDefinition::writeToBuffer(Option::Universe u,
570 const std::string& value,
571 const OptionDataType type,
572 OptionBuffer& buf) const {
573 // We are going to write value given by value argument to the buffer.
574 // The actual type of the value is given by second argument. Check
575 // this argument to determine how to write this value to the buffer.
576 switch (type) {
577 case OPT_BINARY_TYPE:
578 OptionDataTypeUtil::writeBinary(value, buf);
579 return;
580 case OPT_BOOLEAN_TYPE:
581 // We encode the true value as 1 and false as 0 on 8 bits.
582 // That way we actually waste 7 bits but it seems to be the
583 // simpler way to encode boolean.
584 // @todo Consider if any other encode methods can be used.
585 OptionDataTypeUtil::writeBool(convertToBool(value), buf);
586 return;
587 case OPT_INT8_TYPE:
588 OptionDataTypeUtil::writeInt<uint8_t>
589 (lexicalCastWithRangeCheck<int8_t>(value),
590 buf);
591 return;
592 case OPT_INT16_TYPE:
593 OptionDataTypeUtil::writeInt<uint16_t>
594 (lexicalCastWithRangeCheck<int16_t>(value),
595 buf);
596 return;
597 case OPT_INT32_TYPE:
598 OptionDataTypeUtil::writeInt<uint32_t>
599 (lexicalCastWithRangeCheck<int32_t>(value),
600 buf);
601 return;
602 case OPT_UINT8_TYPE:
603 OptionDataTypeUtil::writeInt<uint8_t>
604 (lexicalCastWithRangeCheck<uint8_t>(value),
605 buf);
606 return;
607 case OPT_UINT16_TYPE:
608 OptionDataTypeUtil::writeInt<uint16_t>
609 (lexicalCastWithRangeCheck<uint16_t>(value),
610 buf);
611 return;
612 case OPT_UINT32_TYPE:
613 OptionDataTypeUtil::writeInt<uint32_t>
614 (lexicalCastWithRangeCheck<uint32_t>(value),
615 buf);
616 return;
617 case OPT_IPV4_ADDRESS_TYPE:
618 case OPT_IPV6_ADDRESS_TYPE:
619 {
620 asiolink::IOAddress address(value);
621 if (!address.isV4() && !address.isV6()) {
622 isc_throw(BadDataTypeCast, "provided address "
623 << address
624 << " is not a valid IPv4 or IPv6 address.");
625 }
626 OptionDataTypeUtil::writeAddress(address, buf);
627 return;
628 }
629 case OPT_IPV6_PREFIX_TYPE:
630 {
631 std::string txt = value;
632
633 // first let's remove any whitespaces
634 boost::erase_all(txt, " "); // space
635 boost::erase_all(txt, "\t"); // tabulation
636
637 // Is this prefix/len notation?
638 size_t pos = txt.find("/");
639
640 if (pos == string::npos) {
641 isc_throw(BadDataTypeCast, "provided address/prefix "
642 << value
643 << " is not valid.");
644 }
645
646 std::string txt_address = txt.substr(0, pos);
647 isc::asiolink::IOAddress address = isc::asiolink::IOAddress(txt_address);
648 if (!address.isV6()) {
649 isc_throw(BadDataTypeCast, "provided address "
650 << txt_address
651 << " is not a valid IPv4 or IPv6 address.");
652 }
653
654 std::string txt_prefix = txt.substr(pos + 1);
655 uint8_t len = 0;
656 try {
657 // start with the first character after /
658 len = lexicalCastWithRangeCheck<uint8_t>(txt_prefix);
659 } catch (...) {
660 isc_throw(BadDataTypeCast, "provided prefix "
661 << txt_prefix
662 << " is not valid.");
663 }
664
665 // Write a prefix.
666 OptionDataTypeUtil::writePrefix(PrefixLen(len), address, buf);
667
668 return;
669 }
670 case OPT_PSID_TYPE:
671 {
672 std::string txt = value;
673
674 // first let's remove any whitespaces
675 boost::erase_all(txt, " "); // space
676 boost::erase_all(txt, "\t"); // tabulation
677
678 // Is this prefix/len notation?
679 size_t pos = txt.find("/");
680
681 if (pos == string::npos) {
682 isc_throw(BadDataTypeCast, "provided PSID value "
683 << value << " is not valid");
684 }
685
686 const std::string txt_psid = txt.substr(0, pos);
687 const std::string txt_psid_len = txt.substr(pos + 1);
688
689 uint16_t psid = 0;
690 uint8_t psid_len = 0;
691
692 try {
693 psid = lexicalCastWithRangeCheck<uint16_t>(txt_psid);
694 } catch (...) {
695 isc_throw(BadDataTypeCast, "provided PSID "
696 << txt_psid << " is not valid");
697 }
698
699 try {
700 psid_len = lexicalCastWithRangeCheck<uint8_t>(txt_psid_len);
701 } catch (...) {
702 isc_throw(BadDataTypeCast, "provided PSID length "
703 << txt_psid_len << " is not valid");
704 }
705
706 OptionDataTypeUtil::writePsid(PSIDLen(psid_len), PSID(psid), buf);
707 return;
708 }
709 case OPT_STRING_TYPE:
710 OptionDataTypeUtil::writeString(value, buf);
711 return;
712 case OPT_FQDN_TYPE:
713 OptionDataTypeUtil::writeFqdn(value, buf);
714 return;
715 case OPT_TUPLE_TYPE:
716 {
717 // In case of V4_SZTP_REDIRECT option #143, bootstrap-server-list is formatted
718 // as a list of tuples "uri-length;URI" where uri-length is coded on 2 octets,
719 // which is not typical for V4 Universe.
720 OpaqueDataTuple::LengthFieldType lft = getCode() == DHO_V4_SZTP_REDIRECT
721 ? OpaqueDataTuple::LENGTH_2_BYTES
722 : OptionDataTypeUtil::getTupleLenFieldType(u);
723 OptionDataTypeUtil::writeTuple(value, lft, buf);
724 return;
725 }
726 default:
727 // We hit this point because invalid option data type has been specified
728 // This may be the case because 'empty' or 'record' data type has been
729 // specified. We don't throw exception here because it will be thrown
730 // at the exit point from this function.
731 ;
732 }
733 isc_throw(isc::BadValue, "attempt to write invalid option data field type"
734 " into the option buffer: " << type);
735
736}
737
738 OptionPtr
739OptionDefinition::factoryAddrList4(uint16_t type,
740 OptionBufferConstIter begin,
741 OptionBufferConstIter end) {
742 boost::shared_ptr<Option4AddrLst> option(new Option4AddrLst(type, begin,
743 end));
744 return (option);
745}
746
747 OptionPtr
748OptionDefinition::factoryAddrList6(uint16_t type,
749 OptionBufferConstIter begin,
750 OptionBufferConstIter end) {
751 boost::shared_ptr<Option6AddrLst> option(new Option6AddrLst(type, begin,
752 end));
753 return (option);
754}
755
756
757 OptionPtr
758OptionDefinition::factoryEmpty(Option::Universe u, uint16_t type) {
759 OptionPtr option(new Option(u, type));
760 return (option);
761}
762
763 OptionPtr
764OptionDefinition::factoryGeneric(Option::Universe u, uint16_t type,
765 OptionBufferConstIter begin,
766 OptionBufferConstIter end) {
767 OptionPtr option(new Option(u, type, begin, end));
768 return (option);
769}
770
771 OptionPtr
772OptionDefinition::factoryIA6(uint16_t type,
773 OptionBufferConstIter begin,
774 OptionBufferConstIter end) {
775 if (static_cast<size_t>(std::distance(begin, end)) < Option6IA::OPTION6_IA_LEN) {
776 isc_throw(isc::OutOfRange, "input option buffer has invalid size,"
777 << " expected at least " << Option6IA::OPTION6_IA_LEN
778 << " bytes");
779 }
780 boost::shared_ptr<Option6IA> option(new Option6IA(type, begin, end));
781 return (option);
782}
783
784 OptionPtr
785OptionDefinition::factoryIAAddr6(uint16_t type,
786 OptionBufferConstIter begin,
787 OptionBufferConstIter end) {
788 if (static_cast<size_t>(std::distance(begin, end)) < Option6IAAddr::OPTION6_IAADDR_LEN) {
789 isc_throw(isc::OutOfRange,
790 "input option buffer has invalid size, expected at least "
791 << Option6IAAddr::OPTION6_IAADDR_LEN << " bytes");
792 }
793 boost::shared_ptr<Option6IAAddr> option(new Option6IAAddr(type, begin,
794 end));
795 return (option);
796}
797
798 OptionPtr
799OptionDefinition::factoryIAPrefix6(uint16_t type,
800 OptionBufferConstIter begin,
801 OptionBufferConstIter end) {
802 if (static_cast<size_t>(std::distance(begin, end)) < Option6IAPrefix::OPTION6_IAPREFIX_LEN) {
803 isc_throw(isc::OutOfRange,
804 "input option buffer has invalid size, expected at least "
805 << Option6IAPrefix::OPTION6_IAPREFIX_LEN << " bytes");
806 }
807 boost::shared_ptr<Option6IAPrefix> option(new Option6IAPrefix(type, begin,
808 end));
809 return (option);
810}
811
812 OptionPtr
813OptionDefinition::factoryOpaqueDataTuples(Option::Universe u,
814 uint16_t type,
815 OptionBufferConstIter begin,
816 OptionBufferConstIter end) {
817 boost::shared_ptr<OptionOpaqueDataTuples>
818 option(new OptionOpaqueDataTuples(u, type, begin, end));
819
820 return (option);
821}
822
823 OptionPtr
824 OptionDefinition::factoryOpaqueDataTuples(Option::Universe u,
825 uint16_t type,
826 OptionBufferConstIter begin,
827 OptionBufferConstIter end,
828 OpaqueDataTuple::LengthFieldType length_field_type) {
829 boost::shared_ptr<OptionOpaqueDataTuples>
830 option(new OptionOpaqueDataTuples(u, type, begin, end, length_field_type));
831
832 return (option);
833}
834
835 OptionPtr
836OptionDefinition::factoryFqdnList(Option::Universe u,
837 OptionBufferConstIter begin,
838 OptionBufferConstIter end) const {
839
840 const std::vector<uint8_t> data(begin, end);
841 if (data.empty()) {
842 isc_throw(InvalidOptionValue, "FQDN list option has invalid length of 0");
843 }
844 InputBuffer in_buf(static_cast<const void*>(&data[0]), data.size());
845 std::vector<uint8_t> out_buf;
846 out_buf.reserve(data.size());
847 while (in_buf.getPosition() < in_buf.getLength()) {
848 // Reuse readFqdn and writeFqdn code but on the whole buffer
849 // so the DNS name code handles compression for us.
850 try {
851 isc::dns::Name name(in_buf);
852 isc::dns::LabelSequence labels(name);
853 if (labels.getDataLength() > 0) {
854 size_t read_len = 0;
855 const uint8_t* label = labels.getData(&read_len);
856 out_buf.insert(out_buf.end(), label, label + read_len);
857 }
858 } catch (const isc::Exception& ex) {
859 if (Option::lenient_parsing_) {
860 isc_throw(SkipThisOptionError,
861 "invalid FQDN list content: " << ex.what());
862 }
863
864 isc_throw(InvalidOptionValue, ex.what());
865 }
866 }
867 return OptionPtr(new OptionCustom(*this, u,
868 out_buf.begin(), out_buf.end()));
869}
870
871 OptionPtr
872OptionDefinition::factorySpecialFormatOption(Option::Universe u,
873 OptionBufferConstIter begin,
874 OptionBufferConstIter end,
875 bool convenient_notation) const {
876 if ((u == Option::V6) && haveSpace(DHCP6_OPTION_SPACE)) {
877 switch (getCode()) {
878 case D6O_IA_NA:
879 case D6O_IA_PD:
880 // Record of 3 uint32, no array.
881 return (factoryIA6(getCode(), begin, end));
882
883 case D6O_IAADDR:
884 // Record of an IPv6 address followed by 2 uint32, no array.
885 return (factoryIAAddr6(getCode(), begin, end));
886
887 case D6O_IAPREFIX:
888 // Record of 2 uint32, one uint8 and an IPv6 address, no array.
889 return (factoryIAPrefix6(getCode(), begin, end));
890
891 case D6O_CLIENT_FQDN:
892 // Record of one uint8 and one FQDN, no array.
893 return (OptionPtr(new Option6ClientFqdn(begin, end)));
894
895 case D6O_VENDOR_OPTS:
896 // Type uint32.
897 // Vendor-Specific Information (option code 17).
898 return (OptionPtr(new OptionVendor(Option::V6, begin, end)));
899
900 case D6O_VENDOR_CLASS:
901 // Record of one uint32 and one string.
902 // Vendor Class (option code 16).
903 return (OptionPtr(new OptionVendorClass(Option::V6, begin, end)));
904
905 case D6O_STATUS_CODE:
906 // Record of one uint16 and one string.
907 // Status Code (option code 13).
908 return (OptionPtr(new Option6StatusCode(begin, end)));
909
910 case D6O_BOOTFILE_PARAM:
911 // Array of tuples.
912 // Bootfile params (option code 60).
913 return (factoryOpaqueDataTuples(Option::V6, getCode(), begin, end));
914
915 case D6O_PD_EXCLUDE:
916 // Type IPv6 prefix.
917 // Prefix Exclude (option code 67),
918 return (OptionPtr(new Option6PDExclude(begin, end)));
919
920 case D6O_V6_DNR:
921 return (OptionPtr(new Option6Dnr(begin, end, convenient_notation)));
922
923 default:
924 break;
925 }
926 } else if ((u == Option::V4) && haveSpace(DHCP4_OPTION_SPACE)) {
927 switch (getCode()) {
928 case DHO_SERVICE_SCOPE:
929 // Record of a boolean and a string.
930 return (OptionPtr(new Option4SlpServiceScope(begin, end)));
931
932 case DHO_FQDN:
933 // Record of 3 uint8 and a FQDN, no array.
934 return (OptionPtr(new Option4ClientFqdn(begin, end)));
935
936 case DHO_CLASSLESS_STATIC_ROUTE:
937 return (OptionPtr(new OptionClasslessStaticRoute(begin, end, convenient_notation)));
938
939 case DHO_VIVCO_SUBOPTIONS:
940 // Record of uint32 followed by binary.
941 // V-I Vendor Class (option code 124).
942 return (OptionPtr(new OptionVendorClass(Option::V4, begin, end)));
943
944 case DHO_VIVSO_SUBOPTIONS:
945 // Type uint32.
946 // Vendor-Specific Information (option code 125).
947 return (OptionPtr(new OptionVendor(Option::V4, begin, end)));
948
949 case DHO_V4_SZTP_REDIRECT:
950 // Array of tuples.
951 // DHCPv4 SZTP Redirect Option (option code 143).
952 return (factoryOpaqueDataTuples(Option::V4, getCode(), begin, end, OpaqueDataTuple::LENGTH_2_BYTES));
953
954 case DHO_V4_DNR:
955 return (OptionPtr(new Option4Dnr(begin, end, convenient_notation)));
956
957 default:
958 break;
959 }
960 }
961 if ((u == Option::V4) && haveCompressedFqdnListFormat()) {
962 return (factoryFqdnList(Option::V4, begin, end));
963 }
964 return (OptionPtr());
965}
966
967} // end of isc::dhcp namespace
968} // end of isc namespace
isc::BadValue
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Definition exceptions/exceptions.h:132
isc::Exception
This is a base class for exceptions thrown from the DNS library module.
Definition exceptions/exceptions.h:23
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
isc::InvalidOperation
A generic exception that is thrown if a function is called in a prohibited way.
Definition exceptions/exceptions.h:143
isc::OutOfRange
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
Definition exceptions/exceptions.h:115
isc::asiolink::IOAddress::isV6
bool isV6() const
Convenience function to check for an IPv6 address.
Definition io_address.h:136
isc::dhcp::InvalidOptionValue
Exception to be thrown when invalid option value has been specified for a particular option definitio...
Definition option_definition.h:30
isc::dhcp::MalformedOptionDefinition
Exception to be thrown when option definition is invalid.
Definition option_definition.h:37
isc::dhcp::OpaqueDataTuple::LengthFieldType
LengthFieldType
Size of the length field in the tuple.
Definition opaque_data_tuple.h:56
isc::dhcp::OpaqueDataTuple::LENGTH_2_BYTES
@ LENGTH_2_BYTES
Definition opaque_data_tuple.h:59
isc::dhcp::Option4AddrLst
DHCPv4 Option class for handling list of IPv4 addresses.
Definition option4_addrlst.h:34
isc::dhcp::Option6AddrLst
DHCPv6 Option class for handling list of IPv6 addresses.
Definition option6_addrlst.h:22
isc::dhcp::Option6IAAddr
Definition option6_iaaddr.h:22
isc::dhcp::Option6IAAddr::OPTION6_IAADDR_LEN
static const size_t OPTION6_IAADDR_LEN
length of the fixed part of the IAADDR option
Definition option6_iaaddr.h:26
isc::dhcp::Option6IAPrefix
Class that represents IAPREFIX option in DHCPv6.
Definition option6_iaprefix.h:51
isc::dhcp::Option6IAPrefix::OPTION6_IAPREFIX_LEN
static const size_t OPTION6_IAPREFIX_LEN
length of the fixed part of the IAPREFIX option
Definition option6_iaprefix.h:55
isc::dhcp::Option6IA
Definition option6_ia.h:22
isc::dhcp::Option6IA::OPTION6_IA_LEN
static const size_t OPTION6_IA_LEN
Length of IA_NA and IA_PD content.
Definition option6_ia.h:26
isc::dhcp::OptionCustom
Option with defined data fields represented as buffers that can be accessed using data field index.
Definition option_custom.h:31
isc::dhcp::OptionDataTypeUtil
Utility class for option data types.
Definition option_data_types.h:331
isc::dhcp::OptionDataTypeUtil::writeFqdn
static void writeFqdn(const std::string &fqdn, std::vector< uint8_t > &buf, const bool downcase=false)
Append FQDN into a buffer.
Definition option_data_types.cc:359
isc::dhcp::OptionDataTypeUtil::writePrefix
static void writePrefix(const PrefixLen &prefix_len, const asiolink::IOAddress &prefix, std::vector< uint8_t > &buf)
Append prefix into a buffer.
Definition option_data_types.cc:490
isc::dhcp::OptionDataTypeUtil::writeInt
static void writeInt(const T value, std::vector< uint8_t > &buf)
Append integer or unsigned integer value to a buffer.
Definition option_data_types.h:504
isc::dhcp::OptionDataTypeUtil::getDataTypeName
static const std::string & getDataTypeName(const OptionDataType data_type)
Return option data type name from the data type enumerator.
Definition option_data_types.cc:129
isc::dhcp::OptionDataTypeUtil::getDataType
static OptionDataType getDataType(const std::string &data_type)
Return option data type from its name.
Definition option_data_types.cc:83
isc::dhcp::OptionDataTypeUtil::writeBinary
static void writeBinary(const std::string &hex_str, std::vector< uint8_t > &buf)
Append hex-encoded binary values to a buffer.
Definition option_data_types.cc:179
isc::dhcp::OptionDataTypeUtil::writeAddress
static void writeAddress(const asiolink::IOAddress &address, std::vector< uint8_t > &buf)
Append IPv4 or IPv6 address to a buffer.
Definition option_data_types.cc:172
isc::dhcp::OptionDataTypeUtil::writePsid
static void writePsid(const PSIDLen &psid_len, const PSID &psid, std::vector< uint8_t > &buf)
Append PSID length/value into a buffer.
Definition option_data_types.cc:571
isc::dhcp::OptionDataTypeUtil::writeString
static void writeString(const std::string &value, std::vector< uint8_t > &buf)
Write UTF8-encoded string into a buffer.
Definition option_data_types.cc:612
isc::dhcp::OptionDataTypeUtil::writeTuple
static void writeTuple(const std::string &value, OpaqueDataTuple::LengthFieldType lengthfieldtype, std::vector< uint8_t > &buf)
Append length and string tuple to a buffer.
Definition option_data_types.cc:257
isc::dhcp::OptionDataTypeUtil::getTupleLenFieldType
static OpaqueDataTuple::LengthFieldType getTupleLenFieldType(Option::Universe u)
Returns Length Field Type for a tuple.
Definition option_data_types.cc:197
isc::dhcp::OptionDataTypeUtil::writeBool
static void writeBool(const bool value, std::vector< uint8_t > &buf)
Append boolean value into a buffer.
Definition option_data_types.cc:332
isc::dhcp::OptionDefinition::getCode
uint16_t getCode() const
Return option code.
Definition option_definition.h:356
isc::dhcp::OptionDefinition::factoryEmpty
static OptionPtr factoryEmpty(Option::Universe u, uint16_t type)
Empty option factory.
Definition option_definition.cc:758
isc::dhcp::OptionDefinition::factoryInteger
static OptionPtr factoryInteger(Option::Universe u, uint16_t type, const std::string &encapsulated_space, OptionBufferConstIter begin, OptionBufferConstIter end)
Factory function to create option with integer value.
Definition option_definition.h:621
isc::dhcp::OptionDefinition::factoryIAPrefix6
static OptionPtr factoryIAPrefix6(uint16_t type, OptionBufferConstIter begin, OptionBufferConstIter end)
Factory for IAPREFIX-type of option.
Definition option_definition.cc:799
isc::dhcp::OptionDefinition::factoryIntegerArray
static OptionPtr factoryIntegerArray(Option::Universe u, uint16_t type, OptionBufferConstIter begin, OptionBufferConstIter end)
Factory function to create option with array of integer values.
Definition option_definition.h:641
isc::dhcp::OptionDefinition::OptionDefinition
OptionDefinition(const std::string &name, const uint16_t code, const std::string &space, const std::string &type, const bool array_type=false)
Constructor.
Definition option_definition.cc:48
isc::dhcp::OptionDefinition::factoryAddrList6
static OptionPtr factoryAddrList6(uint16_t type, OptionBufferConstIter begin, OptionBufferConstIter end)
Factory to create option with address list.
Definition option_definition.cc:748
isc::dhcp::OptionDefinition::factoryAddrList4
static OptionPtr factoryAddrList4(uint16_t type, OptionBufferConstIter begin, OptionBufferConstIter end)
Factory to create option with address list.
Definition option_definition.cc:739
isc::dhcp::OptionDefinition::RecordFieldsConstIter
std::vector< OptionDataType >::const_iterator RecordFieldsConstIter
Const iterator for record data fields.
Definition option_definition.h:144
isc::dhcp::OptionDefinition::optionFactory
OptionPtr optionFactory(Option::Universe u, uint16_t type, OptionBufferConstIter begin, OptionBufferConstIter end, bool convenient_notation=false) const
Option factory.
Definition option_definition.cc:186
isc::dhcp::OptionDefinition::factoryIAAddr6
static OptionPtr factoryIAAddr6(uint16_t type, OptionBufferConstIter begin, OptionBufferConstIter end)
Factory for IAADDR-type of option.
Definition option_definition.cc:785
isc::dhcp::OptionDefinition::addRecordField
void addRecordField(const std::string &data_type_name)
Adds data field to the record.
Definition option_definition.cc:161
isc::dhcp::OptionDefinition::equals
bool equals(const OptionDefinition &other) const
Check if option definition is equal to other.
Definition option_definition.cc:150
isc::dhcp::OptionDefinition::getRecordFields
const RecordFieldsCollection & getRecordFields() const
Return list of record fields.
Definition option_definition.h:373
isc::dhcp::OptionDefinition::validate
void validate() const
Check if the option definition is valid.
Definition option_definition.cc:369
isc::dhcp::OptionDefinition::RecordFieldsCollection
std::vector< OptionDataType > RecordFieldsCollection
List of fields within the record.
Definition option_definition.h:142
isc::dhcp::OptionDefinition::factoryIA6
static OptionPtr factoryIA6(uint16_t type, OptionBufferConstIter begin, OptionBufferConstIter end)
Factory for IA-type of option.
Definition option_definition.cc:772
isc::dhcp::OptionDefinition::getEncapsulatedSpace
std::string getEncapsulatedSpace() const
Return name of the encapsulated option space.
Definition option_definition.h:361
isc::dhcp::OptionDefinition::create
static OptionDefinitionPtr create(const std::string &name, const uint16_t code, const std::string &space, const std::string &type, const bool array_type=false)
Factory function creating an instance of the OptionDefinition.
Definition option_definition.cc:114
isc::dhcp::OptionDefinition::factoryOpaqueDataTuples
static OptionPtr factoryOpaqueDataTuples(Option::Universe u, uint16_t type, OptionBufferConstIter begin, OptionBufferConstIter end)
Factory to create option with tuple list.
Definition option_definition.cc:813
isc::dhcp::OptionDefinition::getArrayType
bool getArrayType() const
Return array type indicator.
Definition option_definition.h:351
isc::dhcp::OptionDefinition::factoryGeneric
static OptionPtr factoryGeneric(Option::Universe u, uint16_t type, OptionBufferConstIter begin, OptionBufferConstIter end)
Factory to create generic option.
Definition option_definition.cc:764
isc::dhcp::OptionOpaqueDataTuples
This class encapsulates a collection of data tuples and could be used by multiple options.
Definition option_opaque_data_tuples.h:37
isc::dhcp::OptionSpace::validateName
static bool validateName(const std::string &name)
Checks that the provided option space name is valid.
Definition option_space.cc:26
isc::dhcp::OptionString
Class which represents an option carrying a single string value.
Definition option_string.h:28
isc::dhcp::Option
Definition option.h:81
isc::dhcp::Option::lenient_parsing_
static bool lenient_parsing_
Governs whether options should be parsed less strictly.
Definition option.h:490
isc::dhcp::Option::Universe
Universe
defines option universe DHCPv4 or DHCPv6
Definition option.h:90
isc::dhcp::Option::V6
@ V6
Definition option.h:90
isc::dhcp::Option::V4
@ V4
Definition option.h:90
isc::dhcp::SkipRemainingOptionsError
Exception thrown during option unpacking This exception is thrown when an error has occurred,...
Definition option.h:52
isc::dhcp::SkipThisOptionError
Exception thrown during option unpacking This exception is thrown when an error has occurred unpackin...
Definition option.h:67
isc::dns::LabelSequence
Light-weight Accessor to Name data.
Definition labelsequence.h:35
isc::dns::Name
The Name class encapsulates DNS names.
Definition name.h:219
isc::util::InputBuffer
The InputBuffer class is a buffer abstraction for manipulating read-only data.
Definition buffer.h:81
dhcp4.h
dhcp6.h
D6O_CLIENT_FQDN
@ D6O_CLIENT_FQDN
Definition dhcp6.h:59
D6O_VENDOR_OPTS
@ D6O_VENDOR_OPTS
Definition dhcp6.h:37
D6O_BOOTFILE_PARAM
@ D6O_BOOTFILE_PARAM
Definition dhcp6.h:80
D6O_IA_NA
@ D6O_IA_NA
Definition dhcp6.h:23
D6O_PD_EXCLUDE
@ D6O_PD_EXCLUDE
Definition dhcp6.h:87
D6O_IA_PD
@ D6O_IA_PD
Definition dhcp6.h:45
D6O_V6_DNR
@ D6O_V6_DNR
Definition dhcp6.h:164
D6O_IAADDR
@ D6O_IAADDR
Definition dhcp6.h:25
D6O_VENDOR_CLASS
@ D6O_VENDOR_CLASS
Definition dhcp6.h:36
D6O_STATUS_CODE
@ D6O_STATUS_CODE
Definition dhcp6.h:33
D6O_IAPREFIX
@ D6O_IAPREFIX
Definition dhcp6.h:46
encode.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
labelsequence.h
name.h
isc::data
Definition base_stamped_element.cc:12
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::dhcp::DHO_V4_SZTP_REDIRECT
@ DHO_V4_SZTP_REDIRECT
Definition dhcp4.h:199
isc::dhcp::DHO_SERVICE_SCOPE
@ DHO_SERVICE_SCOPE
Definition dhcp4.h:148
isc::dhcp::DHO_CLASSLESS_STATIC_ROUTE
@ DHO_CLASSLESS_STATIC_ROUTE
Definition dhcp4.h:185
isc::dhcp::DHO_VIVCO_SUBOPTIONS
@ DHO_VIVCO_SUBOPTIONS
Definition dhcp4.h:188
isc::dhcp::DHO_V4_DNR
@ DHO_V4_DNR
Definition dhcp4.h:217
isc::dhcp::DHO_FQDN
@ DHO_FQDN
Definition dhcp4.h:150
isc::dhcp::DHO_VIVSO_SUBOPTIONS
@ DHO_VIVSO_SUBOPTIONS
Definition dhcp4.h:189
isc::dhcp::OptionBufferConstIter
OptionBuffer::const_iterator OptionBufferConstIter
const_iterator for walking over OptionBuffer
Definition option.h:30
isc::dhcp::OptionDataType
OptionDataType
Data types of DHCP option fields.
Definition option_data_types.h:45
isc::dhcp::OPT_BOOLEAN_TYPE
@ OPT_BOOLEAN_TYPE
Definition option_data_types.h:48
isc::dhcp::OPT_ANY_ADDRESS_TYPE
@ OPT_ANY_ADDRESS_TYPE
Definition option_data_types.h:55
isc::dhcp::OPT_EMPTY_TYPE
@ OPT_EMPTY_TYPE
Definition option_data_types.h:46
isc::dhcp::OPT_INTERNAL_TYPE
@ OPT_INTERNAL_TYPE
Definition option_data_types.h:64
isc::dhcp::OPT_INT16_TYPE
@ OPT_INT16_TYPE
Definition option_data_types.h:50
isc::dhcp::OPT_FQDN_TYPE
@ OPT_FQDN_TYPE
Definition option_data_types.h:62
isc::dhcp::OPT_IPV6_ADDRESS_TYPE
@ OPT_IPV6_ADDRESS_TYPE
Definition option_data_types.h:57
isc::dhcp::OPT_UINT32_TYPE
@ OPT_UINT32_TYPE
Definition option_data_types.h:54
isc::dhcp::OPT_TUPLE_TYPE
@ OPT_TUPLE_TYPE
Definition option_data_types.h:61
isc::dhcp::OPT_STRING_TYPE
@ OPT_STRING_TYPE
Definition option_data_types.h:60
isc::dhcp::OPT_UNKNOWN_TYPE
@ OPT_UNKNOWN_TYPE
Definition option_data_types.h:66
isc::dhcp::OPT_UINT16_TYPE
@ OPT_UINT16_TYPE
Definition option_data_types.h:53
isc::dhcp::OPT_BINARY_TYPE
@ OPT_BINARY_TYPE
Definition option_data_types.h:47
isc::dhcp::OPT_UINT8_TYPE
@ OPT_UINT8_TYPE
Definition option_data_types.h:52
isc::dhcp::OPT_PSID_TYPE
@ OPT_PSID_TYPE
Definition option_data_types.h:59
isc::dhcp::OPT_INT32_TYPE
@ OPT_INT32_TYPE
Definition option_data_types.h:51
isc::dhcp::OPT_IPV4_ADDRESS_TYPE
@ OPT_IPV4_ADDRESS_TYPE
Definition option_data_types.h:56
isc::dhcp::OPT_IPV6_PREFIX_TYPE
@ OPT_IPV6_PREFIX_TYPE
Definition option_data_types.h:58
isc::dhcp::OPT_RECORD_TYPE
@ OPT_RECORD_TYPE
Definition option_data_types.h:65
isc::dhcp::OPT_INT8_TYPE
@ OPT_INT8_TYPE
Definition option_data_types.h:49
isc::dhcp::OptionDefinitionPtr
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
Definition option_definition.h:55
isc::dhcp::OptionBuffer
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition option.h:24
isc::dhcp::OptionPtr
boost::shared_ptr< Option > OptionPtr
Definition option.h:37
isc::util::str::trim
string trim(const string &input)
Trim leading and trailing spaces.
Definition str.cc:32
isc::util
Definition time_utils.cc:43
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148
option4_addrlst.h
option4_client_fqdn.h
option4_dnr.h
option6_addrlst.h
option6_client_fqdn.h
option6_dnr.h
option6_ia.h
option6_iaaddr.h
option6_iaprefix.h
option6_pdexclude.h
option6_status_code.h
option_classless_static_route.h
option_custom.h
option_definition.h
option_int.h
option_int_array.h
option_opaque_data_tuples.h
option_string.h
option_vendor.h
option_vendor_class.h
DHCP4_OPTION_SPACE
#define DHCP4_OPTION_SPACE
global std option spaces
Definition std_option_defs.h:16
DHCP6_OPTION_SPACE
#define DHCP6_OPTION_SPACE
Definition std_option_defs.h:17
str.h
isc::dhcp::OptionDataTypeTraits::integer_type
static const bool integer_type
Definition option_data_types.h:98