Kea  1.5.0
dhcp_parsers.cc
Go to the documentation of this file.
1 // Copyright (C) 2013-2018 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 // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include <config.h>
5 #include <dhcp/iface_mgr.h>
6 #include <dhcp/libdhcp++.h>
7 #include <dhcpsrv/cfgmgr.h>
8 #include <dhcpsrv/cfg_option.h>
9 #include <dhcpsrv/dhcpsrv_log.h>
14 #include <dhcpsrv/cfg_mac_source.h>
15 #include <util/encode/hex.h>
16 #include <util/strutil.h>
17 
18 #include <boost/algorithm/string.hpp>
19 #include <boost/foreach.hpp>
20 #include <boost/lexical_cast.hpp>
21 #include <boost/scoped_ptr.hpp>
22 
23 #include <map>
24 #include <string>
25 #include <vector>
26 
27 using namespace std;
28 using namespace isc::asiolink;
29 using namespace isc::data;
30 using namespace isc::util;
31 
32 namespace isc {
33 namespace dhcp {
34 
35 // ******************** MACSourcesListConfigParser *************************
36 
37 void
38 MACSourcesListConfigParser::parse(CfgMACSource& mac_sources, ConstElementPtr value) {
39  CfgIface cfg_iface;
40  uint32_t source = 0;
41  size_t cnt = 0;
42 
43  // By default, there's only one source defined: ANY.
44  // If user specified anything, we need to get rid of that default.
45  mac_sources.clear();
46 
47  BOOST_FOREACH(ConstElementPtr source_elem, value->listValue()) {
48  std::string source_str = source_elem->stringValue();
49  try {
50  source = CfgMACSource::MACSourceFromText(source_str);
51  mac_sources.add(source);
52  ++cnt;
53  } catch (const InvalidParameter& ex) {
54  isc_throw(DhcpConfigError, "The mac-sources value '" << source_str
55  << "' was specified twice (" << value->getPosition() << ")");
56  } catch (const std::exception& ex) {
57  isc_throw(DhcpConfigError, "Failed to convert '"
58  << source_str << "' to any recognized MAC source:"
59  << ex.what() << " (" << value->getPosition() << ")");
60  }
61  }
62 
63  if (!cnt) {
64  isc_throw(DhcpConfigError, "If specified, MAC Sources cannot be empty");
65  }
66 }
67 
68 // ******************** ControlSocketParser *************************
69 void ControlSocketParser::parse(SrvConfig& srv_cfg, isc::data::ConstElementPtr value) {
70  if (!value) {
71  // Sanity check: not supposed to fail.
72  isc_throw(DhcpConfigError, "Logic error: specified control-socket is null");
73  }
74 
75  if (value->getType() != Element::map) {
76  // Sanity check: not supposed to fail.
77  isc_throw(DhcpConfigError, "Specified control-socket is expected to be a map"
78  ", i.e. a structure defined within { }");
79  }
80  srv_cfg.setControlSocketInfo(value);
81 }
82 
83 template<typename SearchKey>
85 OptionDataParser::findOptionDefinition(const std::string& option_space,
86  const SearchKey& search_key) const {
87  OptionDefinitionPtr def = LibDHCP::getOptionDef(option_space, search_key);
88 
89  if (!def) {
90  // Check if this is a vendor-option. If it is, get vendor-specific
91  // definition.
92  uint32_t vendor_id = LibDHCP::optionSpaceToVendorId(option_space);
93  if (vendor_id) {
94  const Option::Universe u = address_family_ == AF_INET ?
95  Option::V4 : Option::V6;
96  def = LibDHCP::getVendorOptionDef(u, vendor_id, search_key);
97  }
98  }
99 
100  if (!def) {
101  // Check if this is an option specified by a user.
102  def = CfgMgr::instance().getStagingCfg()->getCfgOptionDef()
103  ->get(option_space, search_key);
104  }
105 
106  return (def);
107 }
108 
109 // ******************************** OptionDefParser ****************************
110 
111 std::pair<isc::dhcp::OptionDefinitionPtr, std::string>
112 OptionDefParser::parse(ConstElementPtr option_def) {
113 
114  // Get mandatory parameters.
115  std::string name = getString(option_def, "name");
116  uint32_t code = getInteger(option_def, "code");
117  std::string type = getString(option_def, "type");
118 
119  // Get optional parameters. Whoever called this parser, should have
120  // called SimpleParser::setDefaults first.
121  bool array_type = getBoolean(option_def, "array");
122  std::string record_types = getString(option_def, "record-types");
123  std::string space = getString(option_def, "space");
124  std::string encapsulates = getString(option_def, "encapsulate");
125  ConstElementPtr user_context = option_def->get("user-context");
126 
127  if (!OptionSpace::validateName(space)) {
128  isc_throw(DhcpConfigError, "invalid option space name '"
129  << space << "' ("
130  << getPosition("space", option_def) << ")");
131  }
132 
133  // Create option definition.
135  // We need to check if user has set encapsulated option space
136  // name. If so, different constructor will be used.
137  if (!encapsulates.empty()) {
138  // Arrays can't be used together with sub-options.
139  if (array_type) {
140  isc_throw(DhcpConfigError, "option '" << space << "."
141  << "name" << "', comprising an array of data"
142  << " fields may not encapsulate any option space ("
143  << option_def->getPosition() << ")");
144 
145  } else if (encapsulates == space) {
146  isc_throw(DhcpConfigError, "option must not encapsulate"
147  << " an option space it belongs to: '"
148  << space << "." << name << "' is set to"
149  << " encapsulate '" << space << "' ("
150  << option_def->getPosition() << ")");
151 
152  } else {
153  def.reset(new OptionDefinition(name, code, type,
154  encapsulates.c_str()));
155  }
156 
157  } else {
158  def.reset(new OptionDefinition(name, code, type, array_type));
159 
160  }
161 
162  if (user_context) {
163  def->setContext(user_context);
164  }
165 
166  // Split the list of record types into tokens.
167  std::vector<std::string> record_tokens =
168  isc::util::str::tokens(record_types, ",");
169  // Iterate over each token and add a record type into
170  // option definition.
171  BOOST_FOREACH(std::string record_type, record_tokens) {
172  try {
173  boost::trim(record_type);
174  if (!record_type.empty()) {
175  def->addRecordField(record_type);
176  }
177  } catch (const Exception& ex) {
178  isc_throw(DhcpConfigError, "invalid record type values"
179  << " specified for the option definition: "
180  << ex.what() << " ("
181  << getPosition("record-types", option_def) << ")");
182  }
183  }
184 
185  // Validate the definition.
186  try {
187  def->validate();
188  } catch (const std::exception& ex) {
190  << " (" << option_def->getPosition() << ")");
191  }
192 
193  // Option definition has been created successfully.
194  return make_pair(def, space);
195 }
196 
197 // ******************************** OptionDefListParser ************************
198 void
199 OptionDefListParser::parse(CfgOptionDefPtr storage, ConstElementPtr option_def_list) {
200  if (!option_def_list) {
201  // Sanity check: not supposed to fail.
202  isc_throw(DhcpConfigError, "parser error: a pointer to a list of"
203  << " option definitions is NULL ("
204  << option_def_list->getPosition() << ")");
205  }
206 
207  OptionDefParser parser;
208  BOOST_FOREACH(ConstElementPtr option_def, option_def_list->listValue()) {
210 
211  def = parser.parse(option_def);
212  try {
213  storage->add(def.first, def.second);
214  } catch (const std::exception& ex) {
215  // Append position if there is a failure.
216  isc_throw(DhcpConfigError, ex.what() << " ("
217  << option_def->getPosition() << ")");
218  }
219  }
220 
221  // All definitions have been prepared. Put them as runtime options into
222  // the libdhcp++.
223  LibDHCP::setRuntimeOptionDefs(storage->getContainer());
224 }
225 
226 //****************************** RelayInfoParser ********************************
227 RelayInfoParser::RelayInfoParser(const Option::Universe& family)
228  : family_(family) {
229 };
230 
231 void
233  ConstElementPtr relay_elem) {
234 
235  if (relay_elem->getType() != Element::map) {
236  isc_throw(DhcpConfigError, "relay must be a map");
237  }
238 
239  ConstElementPtr address = relay_elem->get("ip-address");
240  ConstElementPtr addresses = relay_elem->get("ip-addresses");
241 
242  if (address && addresses) {
244  "specify either ip-address or ip-addresses, not both");
245  }
246 
247  if (!address && !addresses) {
248  isc_throw(DhcpConfigError, "ip-addresses is required");
249  }
250 
251  // Create our resultant RelayInfo structure
252  *relay_info = isc::dhcp::Network::RelayInfo();
253 
254  if (address) {
255  addAddress("ip-address", getString(relay_elem, "ip-address"),
256  relay_elem, relay_info);
258  DHCPSRV_CFGMGR_RELAY_IP_ADDRESS_DEPRECATED)
259  .arg(getPosition("ip-address", relay_elem));
260  return;
261  }
262 
263  if (addresses->getType() != Element::list) {
264  isc_throw(DhcpConfigError, "ip-addresses must be a list "
265  << " (" << getPosition("ip-addresses", relay_elem) << ")");
266  }
267 
268  BOOST_FOREACH(ConstElementPtr address_element, addresses->listValue()) {
269  addAddress("ip-addresses", address_element->stringValue(),
270  relay_elem, relay_info);
271  }
272 }
273 
274 void
275 RelayInfoParser::addAddress(const std::string& name,
276  const std::string& address_str,
277  ConstElementPtr relay_elem,
278  const isc::dhcp::Network::RelayInfoPtr& relay_info) {
279  boost::scoped_ptr<isc::asiolink::IOAddress> ip;
280  try {
281  ip.reset(new isc::asiolink::IOAddress(address_str));
282  } catch (const std::exception& ex) {
283  isc_throw(DhcpConfigError, "address " << address_str
284  << " is not a valid: "
285  << (family_ == Option::V4 ? "IPv4" : "IPv6")
286  << "address"
287  << " (" << getPosition(name, relay_elem) << ")");
288  }
289 
290  // Check if the address family matches.
291  if ((ip->isV4() && family_ != Option::V4) ||
292  (ip->isV6() && family_ != Option::V6) ) {
293  isc_throw(DhcpConfigError, "address " << address_str
294  << " is not a: "
295  << (family_ == Option::V4 ? "IPv4" : "IPv6")
296  << "address"
297  << " (" << getPosition(name, relay_elem) << ")");
298  }
299 
300  try {
301  relay_info->addAddress(*ip);
302  } catch (const std::exception& ex) {
303  isc_throw(DhcpConfigError, "cannot add address: " << address_str
304  << "to relay info: " << ex.what()
305  << " (" << getPosition(name, relay_elem) << ")");
306  }
307 }
308 
309 //****************************** PoolParser ********************************
310 
311 void
313  ConstElementPtr pool_structure,
314  const uint16_t address_family) {
315 
316  ConstElementPtr text_pool = pool_structure->get("pool");
317 
318  if (!text_pool) {
319  isc_throw(DhcpConfigError, "Mandatory 'pool' entry missing in "
320  "definition: (" << pool_structure->getPosition() << ")");
321  }
322 
323  // That should be a single pool representation. It should contain
324  // text is form prefix/len or first - last. Note that spaces
325  // are allowed
326  string txt = text_pool->stringValue();
327 
328  // first let's remove any whitespaces
329  boost::erase_all(txt, " "); // space
330  boost::erase_all(txt, "\t"); // tabulation
331 
332  PoolPtr pool;
333 
334  // Is this prefix/len notation?
335  size_t pos = txt.find("/");
336  if (pos != string::npos) {
337  isc::asiolink::IOAddress addr("::");
338  uint8_t len = 0;
339  try {
340  addr = isc::asiolink::IOAddress(txt.substr(0, pos));
341 
342  // start with the first character after /
343  string prefix_len = txt.substr(pos + 1);
344 
345  // It is lexical cast to int and then downcast to uint8_t.
346  // Direct cast to uint8_t (which is really an unsigned char)
347  // will result in interpreting the first digit as output
348  // value and throwing exception if length is written on two
349  // digits (because there are extra characters left over).
350 
351  // No checks for values over 128. Range correctness will
352  // be checked in Pool4 constructor, here we only check
353  // the representation fits in an uint8_t as this can't
354  // be done by a direct lexical cast as explained...
355  int val_len = boost::lexical_cast<int>(prefix_len);
356  if ((val_len < std::numeric_limits<uint8_t>::min()) ||
357  (val_len > std::numeric_limits<uint8_t>::max())) {
358  // This exception will be handled 4 line later!
359  isc_throw(OutOfRange, "");
360  }
361  len = static_cast<uint8_t>(val_len);
362  } catch (...) {
363  isc_throw(DhcpConfigError, "Failed to parse pool "
364  "definition: " << txt << " ("
365  << text_pool->getPosition() << ")");
366  }
367 
368  try {
369  pool = poolMaker(addr, len);
370  pools->push_back(pool);
371  } catch (const std::exception& ex) {
372  isc_throw(DhcpConfigError, "Failed to create pool defined by: "
373  << txt << " (" << text_pool->getPosition() << ")");
374  }
375 
376  } else {
377  isc::asiolink::IOAddress min("::");
378  isc::asiolink::IOAddress max("::");
379 
380  // Is this min-max notation?
381  pos = txt.find("-");
382  if (pos != string::npos) {
383  // using min-max notation
384  try {
385  min = isc::asiolink::IOAddress(txt.substr(0, pos));
386  max = isc::asiolink::IOAddress(txt.substr(pos + 1));
387  } catch (...) {
388  isc_throw(DhcpConfigError, "Failed to parse pool "
389  "definition: " << txt << " ("
390  << text_pool->getPosition() << ")");
391  }
392 
393  try {
394  pool = poolMaker(min, max);
395  pools->push_back(pool);
396  } catch (const std::exception& ex) {
397  isc_throw(DhcpConfigError, "Failed to create pool defined by: "
398  << txt << " (" << text_pool->getPosition() << ")");
399  }
400  }
401  }
402 
403  if (!pool) {
404  isc_throw(DhcpConfigError, "invalid pool definition: "
405  << text_pool->stringValue() <<
406  ". There are two acceptable formats <min address-max address>"
407  " or <prefix/len> ("
408  << text_pool->getPosition() << ")");
409  }
410 
411  // If there's user-context specified, store it.
412  ConstElementPtr user_context = pool_structure->get("user-context");
413  if (user_context) {
414  // The grammar accepts only maps but still check it.
415  if (user_context->getType() != Element::map) {
416  isc_throw(isc::dhcp::DhcpConfigError, "User context has to be a map ("
417  << user_context->getPosition() << ")");
418  }
419  pool->setContext(user_context);
420  }
421 
422  // Parser pool specific options.
423  ConstElementPtr option_data = pool_structure->get("option-data");
424  if (option_data) {
425  try {
426  CfgOptionPtr cfg = pool->getCfgOption();
427  OptionDataListParser option_parser(address_family);
428  option_parser.parse(cfg, option_data);
429  } catch (const std::exception& ex) {
431  << " (" << option_data->getPosition() << ")");
432  }
433  }
434 
435  // Client-class.
436  ConstElementPtr client_class = pool_structure->get("client-class");
437  if (client_class) {
438  string cclass = client_class->stringValue();
439  if (!cclass.empty()) {
440  pool->allowClientClass(cclass);
441  }
442  }
443 
444  // Try setting up required client classes.
445  ConstElementPtr class_list = pool_structure->get("require-client-classes");
446  if (class_list) {
447  const std::vector<data::ElementPtr>& classes = class_list->listValue();
448  for (auto cclass = classes.cbegin();
449  cclass != classes.cend(); ++cclass) {
450  if (((*cclass)->getType() != Element::string) ||
451  (*cclass)->stringValue().empty()) {
452  isc_throw(DhcpConfigError, "invalid class name ("
453  << (*cclass)->getPosition() << ")");
454  }
455  pool->requireClientClass((*cclass)->stringValue());
456  }
457  }
458 }
459 
460 //****************************** Pool4Parser *************************
461 
462 PoolPtr
463 Pool4Parser::poolMaker (IOAddress &addr, uint32_t len, int32_t) {
464  return (PoolPtr(new Pool4(addr, len)));
465 }
466 
467 PoolPtr
469  return (PoolPtr(new Pool4(min, max)));
470 }
471 
472 //****************************** Pool4ListParser *************************
473 
474 void
476  BOOST_FOREACH(ConstElementPtr pool, pools_list->listValue()) {
477  Pool4Parser parser;
478  parser.parse(pools, pool, AF_INET);
479  }
480 }
481 
482 //****************************** SubnetConfigParser *************************
483 
485  : pools_(new PoolStorage()),
486  address_family_(family),
487  options_(new CfgOption()) {
489 }
490 
491 SubnetPtr
493 
494  ConstElementPtr options_params = subnet->get("option-data");
495  if (options_params) {
497  opt_parser.parse(options_, options_params);
498  }
499 
500  ConstElementPtr relay_params = subnet->get("relay");
501  if (relay_params) {
503  RelayInfoParser parser(u);
504  parser.parse(relay_info_, relay_params);
505  }
506 
507  // Create a subnet.
508  try {
509  createSubnet(subnet);
510  } catch (const std::exception& ex) {
512  "subnet configuration failed: " << ex.what());
513  }
514 
515  return (subnet_);
516 }
517 
519 SubnetConfigParser::hrModeFromText(const std::string& txt) {
520  if ( (txt.compare("disabled") == 0) ||
521  (txt.compare("off") == 0) ) {
522  return (Network::HR_DISABLED);
523  } else if (txt.compare("out-of-pool") == 0) {
524  return (Network::HR_OUT_OF_POOL);
525  } else if (txt.compare("global") == 0) {
526  return (Network::HR_GLOBAL);
527  } else if (txt.compare("all") == 0) {
528  return (Network::HR_ALL);
529  } else {
530  // Should never happen...
531  isc_throw(BadValue, "Can't convert '" << txt
532  << "' into any valid reservation-mode values");
533  }
534 }
535 
536 void
537 SubnetConfigParser::createSubnet(ConstElementPtr params) {
538  std::string subnet_txt;
539  try {
540  subnet_txt = getString(params, "subnet");
541  } catch (const DhcpConfigError &) {
542  // rethrow with precise error
543  isc_throw(DhcpConfigError,
544  "mandatory 'subnet' parameter is missing for a subnet being"
545  " configured (" << params->getPosition() << ")");
546  }
547 
548  // Remove any spaces or tabs.
549  boost::erase_all(subnet_txt, " ");
550  boost::erase_all(subnet_txt, "\t");
551 
552  // The subnet format is prefix/len. We are going to extract
553  // the prefix portion of a subnet string to create IOAddress
554  // object from it. IOAddress will be passed to the Subnet's
555  // constructor later on. In order to extract the prefix we
556  // need to get all characters preceding "/".
557  size_t pos = subnet_txt.find("/");
558  if (pos == string::npos) {
559  ConstElementPtr elem = params->get("subnet");
560  isc_throw(DhcpConfigError,
561  "Invalid subnet syntax (prefix/len expected):" << subnet_txt
562  << " (" << elem->getPosition() << ")");
563  }
564 
565  // Try to create the address object. It also validates that
566  // the address syntax is ok.
567  isc::asiolink::IOAddress addr(subnet_txt.substr(0, pos));
568 
569  // Now parse out the prefix length.
570  unsigned int len;
571  try {
572  len = boost::lexical_cast<unsigned int>(subnet_txt.substr(pos + 1));
573  } catch (const boost::bad_lexical_cast&) {
574  ConstElementPtr elem = params->get("subnet");
575  isc_throw(DhcpConfigError, "prefix length: '" <<
576  subnet_txt.substr(pos+1) << "' is not an integer ("
577  << elem->getPosition() << ")");
578  }
579 
580  // Sanity check the prefix length
581  if ((addr.isV6() && len > 128) ||
582  (addr.isV4() && len > 32)) {
583  ConstElementPtr elem = params->get("subnet");
584  isc_throw(BadValue,
585  "Invalid prefix length specified for subnet: " << len
586  << " (" << elem->getPosition() << ")");
587  }
588 
589  // Call the subclass's method to instantiate the subnet
590  initSubnet(params, addr, len);
591 
592  // Add pools to it.
593  for (PoolStorage::iterator it = pools_->begin(); it != pools_->end();
594  ++it) {
595  try {
596  subnet_->addPool(*it);
597  } catch (const BadValue& ex) {
598  // addPool() can throw BadValue if the pool is overlapping or
599  // is out of bounds for the subnet.
600  isc_throw(DhcpConfigError,
601  ex.what() << " (" << params->getPosition() << ")");
602  }
603  }
604  // If there's user-context specified, store it.
605  ConstElementPtr user_context = params->get("user-context");
606  if (user_context) {
607  // The grammar accepts only maps but still check it.
608  if (user_context->getType() != Element::map) {
609  isc_throw(isc::dhcp::DhcpConfigError, "User context has to be a map ("
610  << user_context->getPosition() << ")");
611  }
612  subnet_->setContext(user_context);
613  }
614 
615 }
616 
617 //****************************** Subnet4ConfigParser *************************
618 
620  :SubnetConfigParser(AF_INET) {
621 }
622 
626  ConstElementPtr pools = subnet->get("pools");
627  if (pools) {
628  Pools4ListParser parser;
629  parser.parse(pools_, pools);
630  }
631 
632  SubnetPtr generic = SubnetConfigParser::parse(subnet);
633 
634  if (!generic) {
635  // Sanity check: not supposed to fail.
637  "Failed to create an IPv4 subnet (" <<
638  subnet->getPosition() << ")");
639  }
640 
641  Subnet4Ptr sn4ptr = boost::dynamic_pointer_cast<Subnet4>(subnet_);
642  if (!sn4ptr) {
643  // If we hit this, it is a programming error.
645  "Invalid Subnet4 cast in Subnet4ConfigParser::parse");
646  }
647 
648  // Set relay information if it was parsed
649  if (relay_info_) {
650  sn4ptr->setRelayInfo(*relay_info_);
651  }
652 
653  // Parse Host Reservations for this subnet if any.
654  ConstElementPtr reservations = subnet->get("reservations");
655  if (reservations) {
656  HostCollection hosts;
658  parser.parse(subnet_->getID(), reservations, hosts);
659  for (auto h = hosts.begin(); h != hosts.end(); ++h) {
660  CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
661  }
662  }
663 
664  return (sn4ptr);
665 }
666 
667 void
669  asiolink::IOAddress addr, uint8_t len) {
670  // The renew-timer and rebind-timer are optional. If not set, the
671  // option 58 and 59 will not be sent to a client. In this case the
672  // client should formulate default values based on the valid-lifetime.
674  if (params->contains("renew-timer")) {
675  t1 = getInteger(params, "renew-timer");
676  }
677 
679  if (params->contains("rebind-timer")) {
680  t2 = getInteger(params, "rebind-timer");
681  }
682 
683  // The valid-lifetime is mandatory. It may be specified for a
684  // particular subnet. If not, the global value should be present.
685  // If there is no global value, exception is thrown.
686  Triplet<uint32_t> valid = getInteger(params, "valid-lifetime");
687 
688  // Subnet ID is optional. If it is not supplied the value of 0 is used,
689  // which means autogenerate. The value was inserted earlier by calling
690  // SimpleParser4::setAllDefaults.
691  SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id"));
692 
693  stringstream s;
694  s << addr << "/" << static_cast<int>(len) << " with params: ";
695  // t1 and t2 are optional may be not specified.
696  if (!t1.unspecified()) {
697  s << "t1=" << t1 << ", ";
698  }
699  if (!t2.unspecified()) {
700  s << "t2=" << t2 << ", ";
701  }
702  s <<"valid-lifetime=" << valid;
703 
704  LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_NEW_SUBNET4).arg(s.str());
705 
706  Subnet4Ptr subnet4(new Subnet4(addr, len, t1, t2, valid, subnet_id));
707  subnet_ = subnet4;
708 
709  // Set the match-client-id value for the subnet. It is always present.
710  // If not explicitly specified, the default value was filled in when
711  // SimpleParser4::setAllDefaults was called.
712  bool match_client_id = getBoolean(params, "match-client-id");
713  subnet4->setMatchClientId(match_client_id);
714 
715  // Set the authoritative value for the subnet. It is always present.
716  // If not explicitly specified, the default value was filled in when
717  // SimpleParser4::setAllDefaults was called.
718  bool authoritative = getBoolean(params, "authoritative");
719  subnet4->setAuthoritative(authoritative);
720 
721  // Set next-server. The default value is 0.0.0.0. Nevertheless, the
722  // user could have messed that up by specifying incorrect value.
723  // To avoid using 0.0.0.0, user can specify "".
724  string next_server;
725  try {
726  next_server = getString(params, "next-server");
727  if (!next_server.empty()) {
728  subnet4->setSiaddr(IOAddress(next_server));
729  }
730  } catch (...) {
731  ConstElementPtr next = params->get("next-server");
732  string pos;
733  if (next) {
734  pos = next->getPosition().str();
735  } else {
736  pos = params->getPosition().str();
737  }
738  isc_throw(DhcpConfigError, "invalid parameter next-server : "
739  << next_server << "(" << pos << ")");
740  }
741 
742  // Set server-hostname.
743  std::string sname = getString(params, "server-hostname");
744  if (!sname.empty()) {
745  if (sname.length() >= Pkt4::MAX_SNAME_LEN) {
746  ConstElementPtr error = params->get("server-hostname");
747  isc_throw(DhcpConfigError, "server-hostname must be at most "
748  << Pkt4::MAX_SNAME_LEN - 1 << " bytes long, it is "
749  << sname.length() << " ("
750  << error->getPosition() << ")");
751  }
752  subnet4->setSname(sname);
753  }
754 
755  // Set boot-file-name.
756  std::string filename =getString(params, "boot-file-name");
757  if (!filename.empty()) {
758  if (filename.length() > Pkt4::MAX_FILE_LEN) {
759  ConstElementPtr error = params->get("boot-file-name");
760  isc_throw(DhcpConfigError, "boot-file-name must be at most "
761  << Pkt4::MAX_FILE_LEN - 1 << " bytes long, it is "
762  << filename.length() << " ("
763  << error->getPosition() << ")");
764  }
765  subnet4->setFilename(filename);
766  }
767 
768  // Get interface name. If it is defined, then the subnet is available
769  // directly over specified network interface.
770  std::string iface = getString(params, "interface");
771  if (!iface.empty()) {
772  if (!IfaceMgr::instance().getIface(iface)) {
773  ConstElementPtr error = params->get("interface");
774  isc_throw(DhcpConfigError, "Specified network interface name " << iface
775  << " for subnet " << subnet4->toText()
776  << " is not present in the system ("
777  << error->getPosition() << ")");
778  }
779 
780  subnet4->setIface(iface);
781  }
782 
783  // Let's set host reservation mode. If not specified, the default value of
784  // all will be used.
785  try {
786  std::string hr_mode = getString(params, "reservation-mode");
787  subnet4->setHostReservationMode(hrModeFromText(hr_mode));
788  } catch (const BadValue& ex) {
789  isc_throw(DhcpConfigError, "Failed to process specified value "
790  " of reservation-mode parameter: " << ex.what()
791  << "(" << getPosition("reservation-mode", params) << ")");
792  }
793 
794  // Try setting up client class.
795  string client_class = getString(params, "client-class");
796  if (!client_class.empty()) {
797  subnet4->allowClientClass(client_class);
798  }
799 
800  // Try setting up required client classes.
801  ConstElementPtr class_list = params->get("require-client-classes");
802  if (class_list) {
803  const std::vector<data::ElementPtr>& classes = class_list->listValue();
804  for (auto cclass = classes.cbegin();
805  cclass != classes.cend(); ++cclass) {
806  if (((*cclass)->getType() != Element::string) ||
807  (*cclass)->stringValue().empty()) {
808  isc_throw(DhcpConfigError, "invalid class name ("
809  << (*cclass)->getPosition() << ")");
810  }
811  subnet4->requireClientClass((*cclass)->stringValue());
812  }
813  }
814 
815  // 4o6 specific parameter: 4o6-interface. If not explicitly specified,
816  // it will have the default value of "".
817  string iface4o6 = getString(params, "4o6-interface");
818  if (!iface4o6.empty()) {
819  subnet4->get4o6().setIface4o6(iface4o6);
820  subnet4->get4o6().enabled(true);
821  }
822 
823  // 4o6 specific parameter: 4o6-subnet. If not explicitly specified, it
824  // will have the default value of "".
825  string subnet4o6 = getString(params, "4o6-subnet");
826  if (!subnet4o6.empty()) {
827  size_t slash = subnet4o6.find("/");
828  if (slash == std::string::npos) {
829  isc_throw(DhcpConfigError, "Missing / in the 4o6-subnet parameter:"
830  << subnet4o6 << ", expected format: prefix6/length");
831  }
832  string prefix = subnet4o6.substr(0, slash);
833  string lenstr = subnet4o6.substr(slash + 1);
834 
835  uint8_t len = 128;
836  try {
837  len = boost::lexical_cast<unsigned int>(lenstr.c_str());
838  } catch (const boost::bad_lexical_cast &) {
839  isc_throw(DhcpConfigError, "Invalid prefix length specified in "
840  "4o6-subnet parameter: " << subnet4o6 << ", expected 0..128 value");
841  }
842  subnet4->get4o6().setSubnet4o6(IOAddress(prefix), len);
843  subnet4->get4o6().enabled(true);
844  }
845 
846  // Try 4o6 specific parameter: 4o6-interface-id
847  std::string ifaceid = getString(params, "4o6-interface-id");
848  if (!ifaceid.empty()) {
849  OptionBuffer tmp(ifaceid.begin(), ifaceid.end());
851  subnet4->get4o6().setInterfaceId(opt);
852  subnet4->get4o6().enabled(true);
853  }
854 
857 
858  // Here globally defined options were merged to the subnet specific
859  // options but this is no longer the case (they have a different
860  // and not consecutive priority).
861 
862  // Copy options to the subnet configuration.
863  options_->copyTo(*subnet4->getCfgOption());
864 }
865 
866 //**************************** Subnets4ListConfigParser **********************
867 
868 size_t
870  size_t cnt = 0;
871  BOOST_FOREACH(ConstElementPtr subnet_json, subnets_list->listValue()) {
872 
873  Subnet4ConfigParser parser;
874  Subnet4Ptr subnet = parser.parse(subnet_json);
875  if (subnet) {
876 
877  // Adding a subnet to the Configuration Manager may fail if the
878  // subnet id is invalid (duplicate). Thus, we catch exceptions
879  // here to append a position in the configuration string.
880  try {
881  cfg->getCfgSubnets4()->add(subnet);
882  cnt++;
883  } catch (const std::exception& ex) {
884  isc_throw(DhcpConfigError, ex.what() << " ("
885  << subnet_json->getPosition() << ")");
886  }
887  }
888  }
889  return (cnt);
890 }
891 
892 size_t
894  data::ConstElementPtr subnets_list) {
895  size_t cnt = 0;
896  BOOST_FOREACH(ConstElementPtr subnet_json, subnets_list->listValue()) {
897 
898  Subnet4ConfigParser parser;
899  Subnet4Ptr subnet = parser.parse(subnet_json);
900  if (subnet) {
901  try {
902  subnets.push_back(subnet);
903  ++cnt;
904  } catch (const std::exception& ex) {
905  isc_throw(DhcpConfigError, ex.what() << " ("
906  << subnet_json->getPosition() << ")");
907  }
908  }
909  }
910  return (cnt);
911 }
912 
913 
914 //**************************** Pool6Parser *********************************
915 
916 PoolPtr
917 Pool6Parser::poolMaker (IOAddress &addr, uint32_t len, int32_t ptype)
918 {
919  return (PoolPtr(new Pool6(static_cast<isc::dhcp::Lease::Type>
920  (ptype), addr, len)));
921 }
922 
923 PoolPtr
924 Pool6Parser::poolMaker (IOAddress &min, IOAddress &max, int32_t ptype)
925 {
926  return (PoolPtr(new Pool6(static_cast<isc::dhcp::Lease::Type>
927  (ptype), min, max)));
928 }
929 
930 
931 //**************************** Pool6ListParser ***************************
932 
933 void
935  BOOST_FOREACH(ConstElementPtr pool, pools_list->listValue()) {
936  Pool6Parser parser;
937  parser.parse(pools, pool, AF_INET6);
938  }
939 }
940 
941 //**************************** PdPoolParser ******************************
942 
944 }
945 
946 void
948  std::string addr_str = getString(pd_pool_, "prefix");
949 
950  uint8_t prefix_len = getUint8(pd_pool_, "prefix-len");
951 
952  uint8_t delegated_len = getUint8(pd_pool_, "delegated-len");
953 
954  std::string excluded_prefix_str = "::";
955  if (pd_pool_->contains("excluded-prefix")) {
956  excluded_prefix_str = getString(pd_pool_, "excluded-prefix");
957  }
958 
959  uint8_t excluded_prefix_len = 0;
960  if (pd_pool_->contains("excluded-prefix-len")) {
961  excluded_prefix_len = getUint8(pd_pool_, "excluded-prefix-len");
962  }
963 
964  ConstElementPtr option_data = pd_pool_->get("option-data");
965  if (option_data) {
966  OptionDataListParser opts_parser(AF_INET6);
967  opts_parser.parse(options_, option_data);
968  }
969 
970  ConstElementPtr user_context = pd_pool_->get("user-context");
971  if (user_context) {
972  user_context_ = user_context;
973  }
974 
975  ConstElementPtr client_class = pd_pool_->get("client-class");
976  if (client_class) {
977  client_class_ = client_class;
978  }
979 
980  ConstElementPtr class_list = pd_pool_->get("require-client-classes");
981 
982  // Check the pool parameters. It will throw an exception if any
983  // of the required parameters are invalid.
984  try {
985  // Attempt to construct the local pool.
986  pool_.reset(new Pool6(IOAddress(addr_str),
987  prefix_len,
988  delegated_len,
989  IOAddress(excluded_prefix_str),
990  excluded_prefix_len));
991  // Merge options specified for a pool into pool configuration.
992  options_->copyTo(*pool_->getCfgOption());
993  } catch (const std::exception& ex) {
994  // Some parameters don't exist or are invalid. Since we are not
995  // aware whether they don't exist or are invalid, let's append
996  // the position of the pool map element.
998  << " (" << pd_pool_->getPosition() << ")");
999  }
1000 
1001  if (user_context_) {
1002  pool_->setContext(user_context_);
1003  }
1004 
1005  if (client_class_) {
1006  string cclass = client_class_->stringValue();
1007  if (!cclass.empty()) {
1008  pool_->allowClientClass(cclass);
1009  }
1010  }
1011 
1012  if (class_list) {
1013  const std::vector<data::ElementPtr>& classes = class_list->listValue();
1014  for (auto cclass = classes.cbegin();
1015  cclass != classes.cend(); ++cclass) {
1016  if (((*cclass)->getType() != Element::string) ||
1017  (*cclass)->stringValue().empty()) {
1018  isc_throw(DhcpConfigError, "invalid class name ("
1019  << (*cclass)->getPosition() << ")");
1020  }
1021  pool_->requireClientClass((*cclass)->stringValue());
1022  }
1023  }
1024 
1025  // Add the local pool to the external storage ptr.
1026  pools->push_back(pool_);
1027 }
1028 
1029 //**************************** PdPoolsListParser ************************
1030 
1031 void
1033  // Loop through the list of pd pools.
1034  BOOST_FOREACH(ConstElementPtr pd_pool, pd_pool_list->listValue()) {
1035  PdPoolParser parser;
1036  parser.parse(pools, pd_pool);
1037  }
1038 }
1039 
1040 //**************************** Subnet6ConfigParser ***********************
1041 
1043  :SubnetConfigParser(AF_INET6) {
1044 }
1045 
1046 Subnet6Ptr
1049  ConstElementPtr pools = subnet->get("pools");
1050  if (pools) {
1051  Pools6ListParser parser;
1052  parser.parse(pools_, pools);
1053  }
1054  ConstElementPtr pd_pools = subnet->get("pd-pools");
1055  if (pd_pools) {
1056  PdPoolsListParser parser;
1057  parser.parse(pools_, pd_pools);
1058  }
1059 
1060  SubnetPtr generic = SubnetConfigParser::parse(subnet);
1061 
1062  if (!generic) {
1063  // Sanity check: not supposed to fail.
1065  "Failed to create an IPv6 subnet (" <<
1066  subnet->getPosition() << ")");
1067  }
1068 
1069  Subnet6Ptr sn6ptr = boost::dynamic_pointer_cast<Subnet6>(subnet_);
1070  if (!sn6ptr) {
1071  // If we hit this, it is a programming error.
1073  "Invalid Subnet6 cast in Subnet6ConfigParser::parse");
1074  }
1075 
1076  // Set relay information if it was provided
1077  if (relay_info_) {
1078  sn6ptr->setRelayInfo(*relay_info_);
1079  }
1080 
1081  // Parse Host Reservations for this subnet if any.
1082  ConstElementPtr reservations = subnet->get("reservations");
1083  if (reservations) {
1084  HostCollection hosts;
1086  parser.parse(subnet_->getID(), reservations, hosts);
1087  for (auto h = hosts.begin(); h != hosts.end(); ++h) {
1088  CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(*h);
1089  }
1090  }
1091 
1092  return (sn6ptr);
1093 }
1094 
1095 // Unused?
1096 void
1098  asiolink::IOAddress& addr) {
1099  LOG_WARN(dhcpsrv_logger, DHCPSRV_CFGMGR_OPTION_DUPLICATE)
1100  .arg(code).arg(addr.toText());
1101 }
1102 
1103 void
1105  asiolink::IOAddress addr, uint8_t len) {
1106  // Get all 'time' parameters using inheritance.
1107  // If the subnet-specific value is defined then use it, else
1108  // use the global value. The global value must always be
1109  // present. If it is not, it is an internal error and exception
1110  // is thrown.
1111  Triplet<uint32_t> t1 = getInteger(params, "renew-timer");
1112  Triplet<uint32_t> t2 = getInteger(params, "rebind-timer");
1113  Triplet<uint32_t> pref = getInteger(params, "preferred-lifetime");
1114  Triplet<uint32_t> valid = getInteger(params, "valid-lifetime");
1115 
1116  // Subnet ID is optional. If it is not supplied the value of 0 is used,
1117  // which means autogenerate. The value was inserted earlier by calling
1118  // SimpleParser6::setAllDefaults.
1119  SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id"));
1120 
1121  // We want to log whether rapid-commit is enabled, so we get this
1122  // before the actual subnet creation.
1123  bool rapid_commit = getBoolean(params, "rapid-commit");
1124 
1125  std::ostringstream output;
1126  output << addr << "/" << static_cast<int>(len)
1127  << " with params t1=" << t1 << ", t2="
1128  << t2 << ", preferred-lifetime=" << pref
1129  << ", valid-lifetime=" << valid
1130  << ", rapid-commit is " << (rapid_commit ? "enabled" : "disabled");
1131 
1132 
1133  LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_NEW_SUBNET6).arg(output.str());
1134 
1135  // Create a new subnet.
1136  Subnet6* subnet6 = new Subnet6(addr, len, t1, t2, pref, valid,
1137  subnet_id);
1138  subnet_.reset(subnet6);
1139 
1140  // Enable or disable Rapid Commit option support for the subnet.
1141  subnet6->setRapidCommit(rapid_commit);
1142 
1143  // Get interface-id option content. For now we support string
1144  // representation only
1145  std::string ifaceid = getString(params, "interface-id");
1146  std::string iface = getString(params, "interface");
1147 
1148  // Specifying both interface for locally reachable subnets and
1149  // interface id for relays is mutually exclusive. Need to test for
1150  // this condition.
1151  if (!ifaceid.empty() && !iface.empty()) {
1153  "parser error: interface (defined for locally reachable "
1154  "subnets) and interface-id (defined for subnets reachable"
1155  " via relays) cannot be defined at the same time for "
1156  "subnet " << addr << "/" << (int)len << "("
1157  << params->getPosition() << ")");
1158  }
1159 
1160  // Configure interface-id for remote interfaces, if defined
1161  if (!ifaceid.empty()) {
1162  OptionBuffer tmp(ifaceid.begin(), ifaceid.end());
1163  OptionPtr opt(new Option(Option::V6, D6O_INTERFACE_ID, tmp));
1164  subnet6->setInterfaceId(opt);
1165  }
1166 
1167  // Get interface name. If it is defined, then the subnet is available
1168  // directly over specified network interface.
1169  if (!iface.empty()) {
1170  if (!IfaceMgr::instance().getIface(iface)) {
1171  ConstElementPtr error = params->get("interface");
1172  isc_throw(DhcpConfigError, "Specified network interface name " << iface
1173  << " for subnet " << subnet6->toText()
1174  << " is not present in the system ("
1175  << error->getPosition() << ")");
1176  }
1177 
1178  subnet6->setIface(iface);
1179  }
1180 
1181  // Let's set host reservation mode. If not specified, the default value of
1182  // all will be used.
1183  try {
1184  std::string hr_mode = getString(params, "reservation-mode");
1185  subnet6->setHostReservationMode(hrModeFromText(hr_mode));
1186  } catch (const BadValue& ex) {
1187  isc_throw(DhcpConfigError, "Failed to process specified value "
1188  " of reservation-mode parameter: " << ex.what()
1189  << "(" << getPosition("reservation-mode", params) << ")");
1190  }
1191 
1192  // Try setting up client class.
1193  string client_class = getString(params, "client-class");
1194  if (!client_class.empty()) {
1195  subnet6->allowClientClass(client_class);
1196  }
1197 
1198  // Try setting up required client classes.
1199  ConstElementPtr class_list = params->get("require-client-classes");
1200  if (class_list) {
1201  const std::vector<data::ElementPtr>& classes = class_list->listValue();
1202  for (auto cclass = classes.cbegin();
1203  cclass != classes.cend(); ++cclass) {
1204  if (((*cclass)->getType() != Element::string) ||
1205  (*cclass)->stringValue().empty()) {
1206  isc_throw(DhcpConfigError, "invalid class name ("
1207  << (*cclass)->getPosition() << ")");
1208  }
1209  subnet6->requireClientClass((*cclass)->stringValue());
1210  }
1211  }
1212 
1215 
1216  // Copy options to the subnet configuration.
1217  options_->copyTo(*subnet6->getCfgOption());
1218 }
1219 
1220 //**************************** Subnet6ListConfigParser ********************
1221 
1222 size_t
1224  size_t cnt = 0;
1225  BOOST_FOREACH(ConstElementPtr subnet_json, subnets_list->listValue()) {
1226 
1227  Subnet6ConfigParser parser;
1228  Subnet6Ptr subnet = parser.parse(subnet_json);
1229 
1230  // Adding a subnet to the Configuration Manager may fail if the
1231  // subnet id is invalid (duplicate). Thus, we catch exceptions
1232  // here to append a position in the configuration string.
1233  try {
1234  cfg->getCfgSubnets6()->add(subnet);
1235  cnt++;
1236  } catch (const std::exception& ex) {
1237  isc_throw(DhcpConfigError, ex.what() << " ("
1238  << subnet_json->getPosition() << ")");
1239  }
1240  }
1241  return (cnt);
1242 }
1243 
1244 size_t
1246  ConstElementPtr subnets_list) {
1247  size_t cnt = 0;
1248  BOOST_FOREACH(ConstElementPtr subnet_json, subnets_list->listValue()) {
1249 
1250  Subnet6ConfigParser parser;
1251  Subnet6Ptr subnet = parser.parse(subnet_json);
1252  try {
1253  subnets.push_back(subnet);
1254  ++cnt;
1255  } catch (const std::exception& ex) {
1256  isc_throw(DhcpConfigError, ex.what() << " ("
1257  << subnet_json->getPosition() << ")");
1258  }
1259  }
1260  return (cnt);
1261 }
1262 
1263 
1264 //**************************** D2ClientConfigParser **********************
1265 
1267 D2ClientConfigParser::getProtocol(ConstElementPtr scope,
1268  const std::string& name) {
1271  (scope, name, "NameChangeRequest protocol"));
1272 }
1273 
1275 D2ClientConfigParser::getFormat(ConstElementPtr scope,
1276  const std::string& name) {
1279  (scope, name, "NameChangeRequest format"));
1280 }
1281 
1283 D2ClientConfigParser::getMode(ConstElementPtr scope,
1284  const std::string& name) {
1287  (scope, name, "ReplaceClientName mode"));
1288 }
1289 
1292  D2ClientConfigPtr new_config;
1293 
1294  // Get all parameters that are needed to create the D2ClientConfig.
1295  bool enable_updates = getBoolean(client_config, "enable-updates");
1296 
1297  IOAddress server_ip = getAddress(client_config, "server-ip");
1298 
1299  uint32_t server_port = getUint32(client_config, "server-port");
1300 
1301  std::string sender_ip_str = getString(client_config, "sender-ip");
1302 
1303  uint32_t sender_port = getUint32(client_config, "sender-port");
1304 
1305  uint32_t max_queue_size = getUint32(client_config, "max-queue-size");
1306 
1307  dhcp_ddns::NameChangeProtocol ncr_protocol =
1308  getProtocol(client_config, "ncr-protocol");
1309 
1310  dhcp_ddns::NameChangeFormat ncr_format =
1311  getFormat(client_config, "ncr-format");
1312 
1313  bool override_no_update =
1314  getBoolean(client_config, "override-no-update");
1315 
1316  bool override_client_update =
1317  getBoolean(client_config, "override-client-update");
1318 
1319  D2ClientConfig::ReplaceClientNameMode replace_client_name_mode =
1320  getMode(client_config, "replace-client-name");
1321 
1322  std::string generated_prefix =
1323  getString(client_config, "generated-prefix");
1324 
1325  std::string hostname_char_set =
1326  getString(client_config, "hostname-char-set");
1327 
1328  std::string hostname_char_replacement =
1329  getString(client_config, "hostname-char-replacement");
1330 
1331  // qualifying-suffix is the only parameter which has no default
1332  std::string qualifying_suffix = "";
1333  bool found_qualifying_suffix = false;
1334  if (client_config->contains("qualifying-suffix")) {
1335  qualifying_suffix = getString(client_config, "qualifying-suffix");
1336  found_qualifying_suffix = true;
1337  }
1338 
1339  IOAddress sender_ip(0);
1340  if (sender_ip_str.empty()) {
1341  // The default sender IP depends on the server IP family
1342  sender_ip = (server_ip.isV4() ? IOAddress::IPV4_ZERO_ADDRESS() :
1344  } else {
1345  try {
1346  sender_ip = IOAddress(sender_ip_str);
1347  } catch (const std::exception& ex) {
1348  isc_throw(DhcpConfigError, "invalid address (" << sender_ip_str
1349  << ") specified for parameter 'sender-ip' ("
1350  << getPosition("sender-ip", client_config) << ")");
1351  }
1352  }
1353 
1354  // Qualifying-suffix is required when updates are enabled
1355  if (enable_updates && !found_qualifying_suffix) {
1357  "parameter 'qualifying-suffix' is required when "
1358  "updates are enabled ("
1359  << client_config->getPosition() << ")");
1360  }
1361 
1362  // Now we check for logical errors. This repeats what is done in
1363  // D2ClientConfig::validate(), but doing it here permits us to
1364  // emit meaningful parameter position info in the error.
1365  if (ncr_format != dhcp_ddns::FMT_JSON) {
1366  isc_throw(D2ClientError, "D2ClientConfig error: NCR Format: "
1367  << dhcp_ddns::ncrFormatToString(ncr_format)
1368  << " is not supported. ("
1369  << getPosition("ncr-format", client_config) << ")");
1370  }
1371 
1372  if (ncr_protocol != dhcp_ddns::NCR_UDP) {
1373  isc_throw(D2ClientError, "D2ClientConfig error: NCR Protocol: "
1374  << dhcp_ddns::ncrProtocolToString(ncr_protocol)
1375  << " is not supported. ("
1376  << getPosition("ncr-protocol", client_config) << ")");
1377  }
1378 
1379  if (sender_ip.getFamily() != server_ip.getFamily()) {
1381  "D2ClientConfig error: address family mismatch: "
1382  << "server-ip: " << server_ip.toText()
1383  << " is: " << (server_ip.isV4() ? "IPv4" : "IPv6")
1384  << " while sender-ip: " << sender_ip.toText()
1385  << " is: " << (sender_ip.isV4() ? "IPv4" : "IPv6")
1386  << " (" << getPosition("sender-ip", client_config) << ")");
1387  }
1388 
1389  if (server_ip == sender_ip && server_port == sender_port) {
1391  "D2ClientConfig error: server and sender cannot"
1392  " share the exact same IP address/port: "
1393  << server_ip.toText() << "/" << server_port
1394  << " (" << getPosition("sender-ip", client_config) << ")");
1395  }
1396 
1397  try {
1398  // Attempt to create the new client config.
1399  new_config.reset(new D2ClientConfig(enable_updates,
1400  server_ip,
1401  server_port,
1402  sender_ip,
1403  sender_port,
1404  max_queue_size,
1405  ncr_protocol,
1406  ncr_format,
1407  override_no_update,
1408  override_client_update,
1409  replace_client_name_mode,
1410  generated_prefix,
1411  qualifying_suffix,
1412  hostname_char_set,
1413  hostname_char_replacement));
1414  } catch (const std::exception& ex) {
1415  isc_throw(DhcpConfigError, ex.what() << " ("
1416  << client_config->getPosition() << ")");
1417  }
1418 
1419  // Add user context
1420  ConstElementPtr user_context = client_config->get("user-context");
1421  if (user_context) {
1422  new_config->setContext(user_context);
1423  }
1424 
1425  return(new_config);
1426 }
1427 
1430  // enable-updates is unconditionally required
1431  { "server-ip", Element::string, "127.0.0.1" },
1432  { "server-port", Element::integer, "53001" },
1433  // default sender-ip depends on server-ip family, so we leave default blank
1434  // parser knows to use the appropriate ZERO address based on server-ip
1435  { "sender-ip", Element::string, "" },
1436  { "sender-port", Element::integer, "0" },
1437  { "max-queue-size", Element::integer, "1024" },
1438  { "ncr-protocol", Element::string, "UDP" },
1439  { "ncr-format", Element::string, "JSON" },
1440  { "override-no-update", Element::boolean, "false" },
1441  { "override-client-update", Element::boolean, "false" },
1442  { "replace-client-name", Element::string, "never" },
1443  { "generated-prefix", Element::string, "myhost" },
1444  { "hostname-char-set", Element::string, "" },
1445  { "hostname-char-replacement", Element::string, "" }
1446  // qualifying-suffix has no default
1447 };
1448 
1449 size_t
1451  ElementPtr mutable_d2 = boost::const_pointer_cast<Element>(d2_config);
1452  return (SimpleParser::setDefaults(mutable_d2, D2_CLIENT_CONFIG_DEFAULTS));
1453 }
1454 
1455 }; // namespace dhcp
1456 }; // namespace isc
isc::dhcp::D2ClientConfig::stringToReplaceClientNameMode
static ReplaceClientNameMode stringToReplaceClientNameMode(const std::string &mode_str)
Converts labels to ReplaceClientNameMode enum values.
Definition: d2_client_cfg.cc:41
isc::dhcp::RelayInfoParser::parse
void parse(const isc::dhcp::Network::RelayInfoPtr &relay_info, isc::data::ConstElementPtr relay_elem)
parses the actual relay parameters
Definition: dhcp_parsers.cc:232
isc::dhcp::Subnet6Collection
boost::multi_index_container< Subnet6Ptr, boost::multi_index::indexed_by< boost::multi_index::random_access< boost::multi_index::tag< SubnetRandomAccessIndexTag > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > > >> Subnet6Collection
A collection of Subnet6 objects.
Definition: subnet.h:843
isc::util::str::tokens
vector< string > tokens(const std::string &text, const std::string &delim, bool escape)
Split String into Tokens.
Definition: strutil.cc:77
isc::dhcp::OptionBuffer
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition: option.h:25
isc::dhcp::CfgOptionDefPtr
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
Definition: cfg_option_def.h:139
isc::dhcp::DhcpConfigError
To be removed. Please use ConfigError instead.
Definition: dhcp_config_error.h:58
option_data_parser.h
isc::Unexpected
A generic exception that is thrown when an unexpected error condition occurs.
Definition: exceptions/exceptions.h:153
isc::data::SimpleParser::getAndConvert
target_type getAndConvert(isc::data::ConstElementPtr scope, const std::string &name, const std::string &type_name)
Returns a converted value from a scope.
Definition: lib/cc/simple_parser.h:208
isc::dhcp::PdPoolParser
Parser for IPv6 prefix delegation definitions.
Definition: dhcp_parsers.h:647
isc::dhcp::Subnet6ConfigParser
This class parses a single IPv6 subnet.
Definition: dhcp_parsers.h:712
isc::dhcp::Network::setIface
void setIface(const std::string &iface_name)
Sets local name of the interface for which this network is selected.
Definition: network.h:137
isc::dhcp::OptionDefinitionPtr
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
Definition: option_definition.h:51
isc::dhcp::SubnetConfigParser::hrModeFromText
static Network::HRMode hrModeFromText(const std::string &txt)
Attempts to convert text representation to HRMode enum.
Definition: dhcp_parsers.cc:519
isc::dhcp::SubnetPtr
boost::shared_ptr< Subnet > SubnetPtr
A generic pointer to either Subnet4 or Subnet6 object.
Definition: subnet.h:455
isc::dhcp::CfgMgr::instance
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
isc::dhcp::SubnetConfigParser::initSubnet
virtual void initSubnet(isc::data::ConstElementPtr params, isc::asiolink::IOAddress addr, uint8_t len)=0
Instantiates the subnet based on a given IP prefix and prefix length.
isc::dhcp::RelayInfoParser::addAddress
void addAddress(const std::string &name, const std::string &address_str, isc::data::ConstElementPtr relay_elem, const isc::dhcp::Network::RelayInfoPtr &relay_info)
Attempts to add an IP address to list of relay addresses.
Definition: dhcp_parsers.cc:275
isc::dhcp::OptionDataListParser::parse
void parse(const CfgOptionPtr &cfg, isc::data::ConstElementPtr option_data_list)
Parses a list of options, instantiates them and stores in cfg.
Definition: option_data_parser.cc:381
iface_mgr.h
isc::dhcp::Network6::setRapidCommit
void setRapidCommit(const bool rapid_commit)
Enables or disables Rapid Commit option support for the subnet.
Definition: network.h:479
isc::dhcp::Subnet6ConfigParser::duplicate_option_warning
virtual void duplicate_option_warning(uint32_t code, asiolink::IOAddress &addr)
Issues a DHCP6 server specific warning regarding duplicate subnet options.
Definition: dhcp_parsers.cc:1097
isc::dhcp::OptionDefParser::parse
OptionDefinitionTuple parse(isc::data::ConstElementPtr option_def)
Parses an entry that describes single option definition.
Definition: dhcp_parsers.cc:112
isc::dhcp::Pools6ListParser::parse
void parse(PoolStoragePtr pools, data::ConstElementPtr pools_list)
parses the actual structure
Definition: dhcp_parsers.cc:934
libdhcp++.h
isc::data::SimpleParser::getInteger
static int64_t getInteger(isc::data::ConstElementPtr scope, const std::string &name)
Returns an integer parameter from a scope.
Definition: lib/cc/simple_parser.cc:41
isc::dhcp::Subnet4
A configuration holder for IPv4 subnet.
Definition: subnet.h:471
isc::dhcp::SubnetConfigParser::pools_
PoolStoragePtr pools_
Storage for pools belonging to this subnet.
Definition: dhcp_parsers.h:509
isc::data::SimpleParser::getAddress
static isc::asiolink::IOAddress getAddress(const ConstElementPtr &scope, const std::string &name)
Returns a IOAddress parameter from a scope.
Definition: lib/cc/simple_parser.cc:75
D6O_INTERFACE_ID
@ D6O_INTERFACE_ID
Definition: dhcp6.h:38
isc::dhcp::Pool4Parser
Parser for IPv4 pool definitions.
Definition: dhcp_parsers.h:322
isc::dhcp::DHCPSRV_DBG_TRACE_DETAIL
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
Definition: dhcpsrv_log.h:38
isc::util::str::trim
string trim(const string &instring)
Trim Leading and Trailing Spaces.
Definition: strutil.cc:53
isc::dhcp::SrvConfig::setControlSocketInfo
void setControlSocketInfo(const isc::data::ConstElementPtr &control_socket)
Sets information about the control socket.
Definition: srv_config.h:359
isc::dhcp::Network::HR_OUT_OF_POOL
@ HR_OUT_OF_POOL
Only out-of-pool reservations is allowed.
Definition: network.h:100
isc::dhcp::Network::setHostReservationMode
void setHostReservationMode(HRMode mode)
Sets host reservation mode.
Definition: network.h:298
isc::dhcp::Lease::Type
Type
Type of lease or pool.
Definition: lease.h:38
isc::dhcp::Network::HR_GLOBAL
@ HR_GLOBAL
Only global reservations are allowed.
Definition: network.h:104
dhcp_parsers.h
isc::data::SimpleDefaults
std::vector< SimpleDefault > SimpleDefaults
This specifies all default values in a given scope (e.g. a subnet)
Definition: lib/cc/simple_parser.h:31
isc::dhcp::SubnetConfigParser::relay_info_
isc::dhcp::Network::RelayInfoPtr relay_info_
Pointer to relay information.
Definition: dhcp_parsers.h:518
isc::data
Definition: cfg_to_element.h:25
isc::dhcp::Network::RelayInfoPtr
boost::shared_ptr< Network::RelayInfo > RelayInfoPtr
Pointer to the RelayInfo structure.
Definition: network.h:116
isc::dhcp::CfgOption
Represents option data configuration for the DHCP server.
Definition: cfg_option.h:248
isc::dhcp::SubnetConfigParser::address_family_
uint16_t address_family_
Address family: AF_INET or AF_INET6.
Definition: dhcp_parsers.h:515
isc::dhcp::Pool6Parser::poolMaker
PoolPtr poolMaker(asiolink::IOAddress &addr, uint32_t len, int32_t ptype)
Creates a Pool6 object given a IPv6 prefix and the prefix length.
Definition: dhcp_parsers.cc:917
isc::dhcp::OptionDefinition
Base class representing a DHCP option definition.
Definition: option_definition.h:137
isc::dhcp::PdPoolsListParser
Parser for a list of prefix delegation pools.
Definition: dhcp_parsers.h:690
isc::dhcp::Pool4
Pool information for IPv4 addresses.
Definition: pool.h:243
isc::Exception
This is a base class for exceptions thrown from the DNS library module.
Definition: exceptions/exceptions.h:23
isc::dhcp::Network::allowClientClass
void allowClientClass(const isc::dhcp::ClientClass &class_name)
Sets the supported class to class class_name.
Definition: network.cc:85
isc::dhcp::Subnet::toText
virtual std::string toText() const
Returns textual representation of the subnet (e.g.
Definition: subnet.cc:139
isc::dhcp::CfgMACSource
Wrapper class that holds MAC/hardware address sources.
Definition: cfg_mac_source.h:25
isc::dhcp::Pools4ListParser::parse
void parse(PoolStoragePtr pools, data::ConstElementPtr pools_list)
parses the actual structure
Definition: dhcp_parsers.cc:475
isc::util
Definition: edns.h:19
isc::dhcp::SubnetConfigParser::subnet_
isc::dhcp::SubnetPtr subnet_
Pointer to the created subnet object.
Definition: dhcp_parsers.h:512
isc::dhcp::PdPoolParser::PdPoolParser
PdPoolParser()
Constructor.
Definition: dhcp_parsers.cc:943
isc
Defines the logger used by the top-level component of kea-dhcp-ddns.
Definition: agent_parser.cc:144
isc::dhcp::D2ClientConfigParser::parse
D2ClientConfigPtr parse(isc::data::ConstElementPtr d2_client_cfg)
Parses a given dhcp-ddns element into D2ClientConfig.
Definition: dhcp_parsers.cc:1291
isc::dhcp::D2ClientConfig::ReplaceClientNameMode
ReplaceClientNameMode
Defines the client name replacement modes.
Definition: d2_client_cfg.h:72
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::dhcp::PoolParser::parse
virtual void parse(PoolStoragePtr pools, isc::data::ConstElementPtr pool_structure, const uint16_t address_family)
parses the actual structure
Definition: dhcp_parsers.cc:312
strutil.h
isc::dhcp::Subnet4ConfigParser::parse
Subnet4Ptr parse(data::ConstElementPtr subnet)
Parses a single IPv4 subnet configuration and adds to the Configuration Manager.
Definition: dhcp_parsers.cc:624
hex.h
isc::data::SimpleParser::getUint8
uint8_t getUint8(ConstElementPtr scope, const std::string &name)
Get an uint8_t value.
Definition: lib/cc/simple_parser.h:257
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:192
LOG_DEBUG
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
isc::InvalidParameter
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
Definition: exceptions/exceptions.h:124
dhcpsrv_log.h
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::dhcp::D2ClientConfig
Acts as a storage vault for D2 client configuration.
Definition: d2_client_cfg.h:53
isc::dhcp::Subnets4ListConfigParser::parse
size_t parse(SrvConfigPtr cfg, data::ConstElementPtr subnets_list)
parses contents of the list
Definition: dhcp_parsers.cc:869
cfg_mac_source.h
isc::dhcp::PoolStoragePtr
boost::shared_ptr< PoolStorage > PoolStoragePtr
Definition: dhcp_parsers.h:264
isc::dhcp::PoolStorage
std::vector< PoolPtr > PoolStorage
a collection of pools
Definition: dhcp_parsers.h:263
isc::dhcp::Subnet4ConfigParser
This class parses a single IPv4 subnet.
Definition: dhcp_parsers.h:530
isc::dhcp::IfaceMgr::instance
static IfaceMgr & instance()
IfaceMgr is a singleton class.
Definition: iface_mgr.cc:53
host_reservations_list_parser.h
isc::dhcp::Pkt4::MAX_SNAME_LEN
static const size_t MAX_SNAME_LEN
length of the SNAME field in DHCPv4 message
Definition: pkt4.h:45
isc::dhcp::CfgMACSource::clear
void clear()
Removes any configured MAC/Hardware address sources.
Definition: cfg_mac_source.h:68
cfg_option.h
isc::dhcp::Triplet::unspecified
bool unspecified() const
Check if the value has been specified.
Definition: triplet.h:128
isc::dhcp::Subnet4Ptr
boost::shared_ptr< Subnet4 > Subnet4Ptr
A pointer to a Subnet4 object.
Definition: subnet.h:464
isc::dhcp_ddns::FMT_JSON
@ FMT_JSON
Definition: ncr_msg.h:61
isc::dhcp::PdPoolParser::parse
void parse(PoolStoragePtr pools, data::ConstElementPtr pd_pool_)
Builds a prefix delegation pool from the given configuration.
Definition: dhcp_parsers.cc:947
isc::dhcp::PoolPtr
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
Definition: pool.h:405
isc::dhcp::CfgMACSource::add
void add(uint32_t source)
Adds additional MAC/hardware address acquisition.
Definition: cfg_mac_source.cc:57
isc::dhcp::CfgIface
Represents selection of interfaces for DHCP server.
Definition: cfg_iface.h:130
isc::dhcp::Network::HR_ALL
@ HR_ALL
Both out-of-pool and in-pool reservations are allowed.
Definition: network.h:112
isc::dhcp::Subnet6ConfigParser::parse
Subnet6Ptr parse(data::ConstElementPtr subnet)
Parses a single IPv6 subnet configuration and adds to the Configuration Manager.
Definition: dhcp_parsers.cc:1047
isc::dhcp::OptionDefinitionTuple
std::pair< isc::dhcp::OptionDefinitionPtr, std::string > OptionDefinitionTuple
Definition: dhcp_parsers.h:223
LOG_WARN
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
isc::dhcp::OptionDataListParser
Parser for option data values within a subnet.
Definition: option_data_parser.h:163
isc::dhcp::Subnet6
A configuration holder for IPv6 subnet.
Definition: subnet.h:636
isc::dhcp::D2ClientConfigPtr
boost::shared_ptr< D2ClientConfig > D2ClientConfigPtr
Defines a pointer for D2ClientConfig instances.
Definition: d2_client_cfg.h:323
isc::dhcp::Subnet6ConfigParser::initSubnet
void initSubnet(isc::data::ConstElementPtr params, isc::asiolink::IOAddress addr, uint8_t len)
Instantiates the IPv6 Subnet based on a given IPv6 address and prefix length.
Definition: dhcp_parsers.cc:1104
isc::dhcp::Subnet4ConfigParser::initSubnet
void initSubnet(data::ConstElementPtr params, asiolink::IOAddress addr, uint8_t len)
Instantiates the IPv4 Subnet based on a given IPv4 address and prefix length.
Definition: dhcp_parsers.cc:668
isc::dhcp::Network::HR_DISABLED
@ HR_DISABLED
None - host reservation is disabled.
Definition: network.h:95
isc::dhcp_ddns::NCR_UDP
@ NCR_UDP
Definition: ncr_io.h:67
isc::dhcp::HostReservationsListParser
Parser for a list of host reservations for a subnet.
Definition: host_reservations_list_parser.h:25
isc::dhcp::Subnet6ConfigParser::Subnet6ConfigParser
Subnet6ConfigParser()
Constructor.
Definition: dhcp_parsers.cc:1042
isc::data::SimpleParser::getUint32
uint32_t getUint32(isc::data::ConstElementPtr scope, const std::string &name)
Returns a value converted to uint32_t.
Definition: lib/cc/simple_parser.h:231
isc::dhcp::Pkt4::MAX_FILE_LEN
static const size_t MAX_FILE_LEN
length of the FILE field in DHCPv4 message
Definition: pkt4.h:48
isc::dhcp::CfgMgr::getStagingCfg
SrvConfigPtr getStagingCfg()
Returns a pointer to the staging configuration.
Definition: cfgmgr.cc:160
isc::dhcp::D2ClientConfigParser::setAllDefaults
static size_t setAllDefaults(isc::data::ConstElementPtr d2_config)
Sets all defaults for D2 client configuration.
Definition: dhcp_parsers.cc:1450
isc::dhcp::Network::RelayInfo
Holds optional information about relay.
Definition: network.h:59
isc::data::SimpleParser::getBoolean
static bool getBoolean(isc::data::ConstElementPtr scope, const std::string &name)
Returns a boolean parameter from a scope.
Definition: lib/cc/simple_parser.cc:58
isc::dhcp_ddns::stringToNcrFormat
NameChangeFormat stringToNcrFormat(const std::string &fmt_str)
Function which converts labels to NameChangeFormat enum values.
Definition: ncr_msg.cc:27
isc::dhcp_ddns::ncrProtocolToString
std::string ncrProtocolToString(NameChangeProtocol protocol)
Function which converts NameChangeProtocol enums to text labels.
Definition: ncr_io.cc:30
cfgmgr.h
isc::dhcp::Network::getCfgOption
CfgOptionPtr getCfgOption()
Returns pointer to the option data configuration for this subnet.
Definition: network.h:303
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::dhcp::Subnet6Ptr
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
Definition: subnet.h:629
isc::dhcp::PdPoolsListParser::parse
void parse(PoolStoragePtr pools, data::ConstElementPtr pd_pool_list)
Parse configuration entries.
Definition: dhcp_parsers.cc:1032
isc::dhcp::Option::V6
@ V6
Definition: option.h:67
isc::dhcp::PoolParser::poolMaker
virtual PoolPtr poolMaker(isc::asiolink::IOAddress &addr, uint32_t len, int32_t ptype=0)=0
Creates a Pool object given a IPv4 prefix and the prefix length.
isc::dhcp::Pool6Parser
Parser for IPv6 pool definitions.
Definition: dhcp_parsers.h:592
isc::dhcp::Network::HRMode
HRMode
Specifies allowed host reservation mode.
Definition: network.h:91
isc::dhcp::OptionPtr
boost::shared_ptr< Option > OptionPtr
Definition: option.h:37
isc::dhcp::Pool6
Pool information for IPv6 addresses and prefixes.
Definition: pool.h:272
isc::dhcp::Subnet4ConfigParser::Subnet4ConfigParser
Subnet4ConfigParser()
Constructor.
Definition: dhcp_parsers.cc:619
isc::dhcp::Pools6ListParser
Specialization of the pool list parser for DHCPv6.
Definition: dhcp_parsers.h:617
isc::dhcp::SubnetConfigParser::parse
SubnetPtr parse(isc::data::ConstElementPtr subnet)
parses a subnet description and returns Subnet{4,6} structure
Definition: dhcp_parsers.cc:492
isc::data::SimpleParser::getPosition
static const data::Element::Position & getPosition(const std::string &name, const data::ConstElementPtr parent)
Utility method that returns position of an element.
Definition: lib/cc/simple_parser.cc:88
isc::dhcp::CfgOptionPtr
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
Definition: cfg_option.h:497
isc::dhcp::Option::Universe
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:67
isc::data::ElementPtr
boost::shared_ptr< Element > ElementPtr
Definition: data.h:20
isc::dhcp::SrvConfig
Specifies current DHCP configuration.
Definition: srv_config.h:44
isc::dhcp::Network6::setInterfaceId
void setInterfaceId(const OptionPtr &ifaceid)
sets interface-id option (if defined)
Definition: network.h:463
isc::dhcp::Pool4Parser::poolMaker
PoolPtr poolMaker(asiolink::IOAddress &addr, uint32_t len, int32_t ignored)
Creates a Pool4 object given a IPv4 prefix and the prefix length.
Definition: dhcp_parsers.cc:463
isc::data::ConstElementPtr
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
isc::dhcp::SubnetConfigParser
this class parses a single subnet
Definition: dhcp_parsers.h:453
isc::dhcp::SubnetID
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)
Definition: lease.h:24
isc::dhcp::OptionDefParser
Parser for a single option definition.
Definition: dhcp_parsers.h:228
isc::data::SimpleParser::getString
static std::string getString(isc::data::ConstElementPtr scope, const std::string &name)
Returns a string parameter from a scope.
Definition: lib/cc/simple_parser.cc:24
isc::dhcp::D2ClientConfigParser::D2_CLIENT_CONFIG_DEFAULTS
static const isc::data::SimpleDefaults D2_CLIENT_CONFIG_DEFAULTS
Defaults for the D2 client configuration.
Definition: dhcp_parsers.h:810
isc::dhcp::SrvConfigPtr
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
Definition: srv_config.h:707
isc::dhcp::RelayInfoParser
parser for additional relay information
Definition: dhcp_parsers.h:389
isc::dhcp::Option
Definition: option.h:58
isc::dhcp::SubnetConfigParser::options_
CfgOptionPtr options_
Pointer to the options configuration.
Definition: dhcp_parsers.h:521
isc::dhcp::D2ClientError
An exception that is thrown if an error occurs while configuring the D2 DHCP DDNS client.
Definition: d2_client_cfg.h:34
isc::dhcp_ddns::ncrFormatToString
std::string ncrFormatToString(NameChangeFormat format)
Function which converts NameChangeFormat enums to text labels.
Definition: ncr_msg.cc:36
isc::dhcp_ddns::stringToNcrProtocol
NameChangeProtocol stringToNcrProtocol(const std::string &protocol_str)
Function which converts labels to NameChangeProtocol enum values.
Definition: ncr_io.cc:17
isc::dhcp::Subnets6ListConfigParser::parse
size_t parse(SrvConfigPtr cfg, data::ConstElementPtr subnets_list)
parses contents of the list
Definition: dhcp_parsers.cc:1223
isc::dhcp::HostReservationsListParser::parse
void parse(const SubnetID &subnet_id, isc::data::ConstElementPtr hr_list, HostCollection &hosts_list)
Parses a list of host reservation entries for a subnet.
Definition: host_reservations_list_parser.h:39
isc::dhcp::Option::V4
@ V4
Definition: option.h:67
LOG_INFO
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition: macros.h:20
isc::dhcp::dhcpsrv_logger
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition: dhcpsrv_log.h:56
host_reservation_parser.h
isc::dhcp::Network::requireClientClass
void requireClientClass(const isc::dhcp::ClientClass &class_name)
Adds class class_name to classes required to be evaluated.
Definition: network.cc:90
isc::dhcp::Triplet< uint32_t >
isc::dhcp_ddns::NameChangeFormat
NameChangeFormat
Defines the list of data wire formats supported.
Definition: ncr_msg.h:60
isc::dhcp::Pools4ListParser
Specialization of the pool list parser for DHCPv4.
Definition: dhcp_parsers.h:369
isc::dhcp::Subnet4Collection
boost::multi_index_container< Subnet4Ptr, boost::multi_index::indexed_by< boost::multi_index::random_access< boost::multi_index::tag< SubnetRandomAccessIndexTag > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetServerIdIndexTag >, boost::multi_index::const_mem_fun< Network4, asiolink::IOAddress, &Network4::getServerId > > >> Subnet4Collection
A collection of Subnet4 objects.
Definition: subnet.h:798
isc::dhcp_ddns::NameChangeProtocol
NameChangeProtocol
Defines the list of socket protocols supported.
Definition: ncr_io.h:66
isc::dhcp::SubnetConfigParser::SubnetConfigParser
SubnetConfigParser(uint16_t family)
constructor
Definition: dhcp_parsers.cc:484
isc::dhcp::HostCollection
std::vector< HostPtr > HostCollection
Collection of the Host objects.
Definition: host.h:734