13#include <boost/lexical_cast.hpp>
15#include <sys/socket.h>
32const std::set<std::string>&
33getSupportedParams4(
const bool identifiers_only =
false) {
35 static std::set<std::string> identifiers_set;
37 static std::set<std::string> params_set;
40 if (identifiers_set.empty()) {
41 identifiers_set.insert(
"hw-address");
42 identifiers_set.insert(
"duid");
43 identifiers_set.insert(
"circuit-id");
44 identifiers_set.insert(
"client-id");
45 identifiers_set.insert(
"flex-id");
48 if (params_set.empty()) {
49 params_set = identifiers_set;
50 params_set.insert(
"hostname");
51 params_set.insert(
"ip-address");
52 params_set.insert(
"option-data");
53 params_set.insert(
"next-server");
54 params_set.insert(
"server-hostname");
55 params_set.insert(
"boot-file-name");
56 params_set.insert(
"client-classes");
57 params_set.insert(
"user-context");
59 return (identifiers_only ? identifiers_set : params_set);
70const std::set<std::string>&
71getSupportedParams6(
const bool identifiers_only =
false) {
73 static std::set<std::string> identifiers_set;
75 static std::set<std::string> params_set;
78 if (identifiers_set.empty()) {
79 identifiers_set.insert(
"hw-address");
80 identifiers_set.insert(
"duid");
81 identifiers_set.insert(
"flex-id");
84 if (params_set.empty()) {
85 params_set = identifiers_set;
86 params_set.insert(
"hostname");
87 params_set.insert(
"ip-addresses");
88 params_set.insert(
"prefixes");
89 params_set.insert(
"option-data");
90 params_set.insert(
"client-classes");
91 params_set.insert(
"user-context");
93 return (identifiers_only ? identifiers_set : params_set);
104 bool encapsulate_options) {
105 return (
parseInternal(subnet_id, reservation_data, encapsulate_options));
112 std::string identifier;
113 std::string identifier_name;
114 std::string hostname;
121 for (
auto const& element : reservation_data->mapValue()) {
125 " parameter '" << element.first <<
"'");
129 if (!identifier.empty()) {
131 <<
"' and '" << identifier_name
132 <<
"' are mutually exclusive");
134 identifier = element.second->stringValue();
135 identifier_name = element.first;
137 }
else if (element.first ==
"hostname") {
138 hostname = element.second->stringValue();
139 }
else if (element.first ==
"user-context") {
140 user_context = element.second;
145 if (identifier_name.empty()) {
149 std::ostringstream s;
151 if (s.tellp() != std::streampos(0)) {
157 " be specified for host reservation: "
163 host.reset(
new Host(identifier, identifier_name, SUBNET_ID_UNUSED,
164 SUBNET_ID_UNUSED,
IOAddress(
"0.0.0.0"), hostname));
168 host->setContext(user_context);
170 }
catch (
const std::exception& ex) {
173 << reservation_data->getPosition() <<
")");
192 bool encapsulate_options) {
194 encapsulate_options);
196 host->setIPv4SubnetID(subnet_id);
198 for (
auto const& element : reservation_data->mapValue()) {
202 if (element.first ==
"option-data") {
209 parser.
parse(cfg_option, element.second, encapsulate_options);
215 if (element.first ==
"ip-address") {
216 host->setIPv4Reservation(
IOAddress(element.second->
218 }
else if (element.first ==
"next-server") {
219 host->setNextServer(
IOAddress(element.second->stringValue()));
221 }
else if (element.first ==
"server-hostname") {
222 host->setServerHostname(element.second->stringValue());
224 }
else if (element.first ==
"boot-file-name") {
225 host->setBootFileName(element.second->stringValue());
227 }
else if (element.first ==
"client-classes") {
228 for (
auto const& class_element : element.second->listValue()) {
229 host->addClientClass4(class_element->stringValue());
233 }
catch (
const std::exception& ex) {
236 << element.second->getPosition() <<
")");
244const std::set<std::string>&
246 return (getSupportedParams4(identifiers_only));
252 bool encapsulate_options) {
254 encapsulate_options);
256 host->setIPv6SubnetID(subnet_id);
258 for (
auto const& element : reservation_data->mapValue()) {
263 if (element.first ==
"option-data") {
270 parser.
parse(cfg_option, element.second, encapsulate_options);
272 }
else if (element.first ==
"ip-addresses" || element.first ==
"prefixes") {
273 for (
auto const& prefix_element : element.second->listValue()) {
278 std::string prefix = prefix_element->stringValue();
279 uint8_t prefix_len = 128;
284 if (element.first ==
"prefixes") {
287 size_t len_pos = prefix.find(
'/');
288 if (len_pos == std::string::npos) {
290 " requires prefix length be specified"
291 " in '" << prefix <<
"'");
295 }
else if (len_pos >= prefix.length() - 1) {
297 <<
"' requires length after '/'");
306 prefix_len = boost::lexical_cast<unsigned int>(prefix.substr(len_pos + 1));
308 }
catch (
const boost::bad_lexical_cast&) {
310 << prefix.substr(len_pos + 1)
314 if ((prefix_len == 0) || (prefix_len > 128)) {
316 "'prefix-len' value must be in range of [1..128]");
321 prefix.erase(len_pos);
326 if (prefix_len != 128) {
329 if (first_address != addr) {
331 <<
" exceeds prefix/prefix-len pair: " << first_address
332 <<
"/" <<
static_cast<uint32_t
>(prefix_len));
338 host->addReservation(
IPv6Resrv(resrv_type,
342 }
catch (
const std::exception& ex) {
345 << prefix_element->getPosition() <<
")");
349 }
else if (element.first ==
"client-classes") {
351 for (
auto const& class_element : element.second->listValue()) {
352 host->addClientClass6(class_element->stringValue());
354 }
catch (
const std::exception& ex) {
357 << element.second->getPosition() <<
")");
365const std::set<std::string>&
367 return (getSupportedParams6(identifiers_only));
384 for (
auto const& element : ids_list->listValue()) {
385 std::string id_name = element->stringValue();
387 if (id_name !=
"auto") {
400 " no other values can be specified within '"
401 "host-reservation-identifiers' list");
406 for (
unsigned int i = 0;
409 std::string supported_id_name =
417 }
catch (
const std::exception& ex) {
420 << element->getPosition() <<
")");
427 " be empty (" << ids_list->getPosition() <<
")");
439 return (getSupportedParams4(
true).count(id_name) > 0);
449 return (getSupportedParams6(
true).count(id_name) > 0);
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
The IOAddress class represents an IP addresses (version agnostic)
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getStagingCfg()
Returns a pointer to the staging configuration.
To be removed. Please use ConfigError instead.
HostReservationIdsParser4()
Constructor.
virtual bool isSupportedIdentifier(const std::string &id_name) const
Checks if specified identifier name is supported for DHCPv4.
HostReservationIdsParser6()
Constructor.
virtual bool isSupportedIdentifier(const std::string &id_name) const
Checks if specified identifier name is supported for DHCPv6.
Parser for a list of host identifiers.
CfgHostOperationsPtr staging_cfg_
Pointer to the object holding configuration.
virtual bool isSupportedIdentifier(const std::string &id_name) const =0
Checks if specified identifier name is supported in the context of the parser.
HostReservationIdsParser()
Constructor.
void parse(isc::data::ConstElementPtr ids_list)
Parses a list of host identifiers.
virtual void parseInternal(isc::data::ConstElementPtr ids_list)
Parses a list of host identifiers.
virtual const std::set< std::string > & getSupportedParameters(const bool identifiers_only) const
Returns set of the supported parameters for DHCPv4.
virtual HostPtr parseInternal(const SubnetID &subnet_id, isc::data::ConstElementPtr reservation_data, bool encapsulate_options)
Parses a single host reservation for DHCPv4.
virtual HostPtr parseInternal(const SubnetID &subnet_id, isc::data::ConstElementPtr reservation_data, bool encapsulate_options)
Parses a single host reservation for DHCPv6.
virtual const std::set< std::string > & getSupportedParameters(const bool identifiers_only) const
Returns set of the supported parameters for DHCPv6.
virtual HostPtr parse(const SubnetID &subnet_id, isc::data::ConstElementPtr reservation_data, bool encapsulate_options=true) final
Parses a single entry for host reservation.
virtual bool isIdentifierParameter(const std::string ¶m_name) const
Checks if the specified parameter is a host identifier.
virtual const std::set< std::string > & getSupportedParameters(const bool identifiers_only) const =0
Returns set of the supported parameters.
virtual HostPtr parseInternal(const SubnetID &subnet_id, isc::data::ConstElementPtr reservation_data, bool encapsulate_options)
Parses a single entry for host reservation.
virtual bool isSupportedParameter(const std::string ¶m_name) const
Checks if the specified parameter is supported by the parser.
Represents a device with IPv4 and/or IPv6 reservations.
IdentifierType
Type of the host identifier.
static const IdentifierType LAST_IDENTIFIER_TYPE
Constant pointing to the last identifier of the IdentifierType enumeration.
static std::string getIdentifierName(const IdentifierType &type)
Returns name of the identifier of a specified type.
IPv6 reservation for a host.
Type
Type of the reservation.
Parser for option data values within a subnet.
void parse(const CfgOptionPtr &cfg, isc::data::ConstElementPtr option_data_list, bool encapsulate=true)
Parses a list of options, instantiates them and stores in cfg.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
IOAddress firstAddrInPrefix(const IOAddress &prefix, uint8_t len)
This code is based on similar code from the Dibbler project.
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
boost::shared_ptr< Host > HostPtr
Pointer to the Host object.
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Defines the logger used by the top-level component of kea-lfc.