12 #include <boost/foreach.hpp>
13 #include <boost/lexical_cast.hpp>
15 #include <sys/socket.h>
32 const std::set<std::string>&
33 getSupportedParams4(
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);
70 const std::set<std::string>&
71 getSupportedParams6(
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);
102 HostReservationParser::parse(
const SubnetID& subnet_id,
104 return (parseInternal(subnet_id, reservation_data));
108 HostReservationParser::parseInternal(
const SubnetID&,
110 std::string identifier;
111 std::string identifier_name;
112 std::string hostname;
119 BOOST_FOREACH(
auto element, reservation_data->mapValue()) {
121 if (!isSupportedParameter(element.first)) {
123 " parameter '" << element.first <<
"'");
126 if (isIdentifierParameter(element.first)) {
127 if (!identifier.empty()) {
129 <<
"' and '" << identifier_name
130 <<
"' are mutually exclusive");
132 identifier = element.second->stringValue();
133 identifier_name = element.first;
135 }
else if (element.first ==
"hostname") {
136 hostname = element.second->stringValue();
137 }
else if (element.first ==
"user-context") {
138 user_context = element.second;
143 if (identifier_name.empty()) {
147 std::ostringstream s;
148 BOOST_FOREACH(std::string param_name, getSupportedParameters(
true)) {
149 if (s.tellp() != std::streampos(0)) {
155 " be specified for host reservation: "
161 host.reset(
new Host(identifier, identifier_name, SUBNET_ID_UNUSED,
162 SUBNET_ID_UNUSED,
IOAddress(
"0.0.0.0"), hostname));
166 host->setContext(user_context);
168 }
catch (
const std::exception& ex) {
171 << reservation_data->getPosition() <<
")");
178 HostReservationParser::isIdentifierParameter(
const std::string& param_name)
const {
179 return (getSupportedParameters(
true).count(param_name) > 0);
183 HostReservationParser::isSupportedParameter(
const std::string& param_name)
const {
184 return (getSupportedParameters(
false).count(param_name) > 0);
188 HostReservationParser4::parseInternal(
const SubnetID& subnet_id,
190 HostPtr host = HostReservationParser::parseInternal(subnet_id, reservation_data);
192 host->setIPv4SubnetID(subnet_id);
194 BOOST_FOREACH(
auto element, reservation_data->mapValue()) {
198 if (element.first ==
"option-data") {
205 parser.
parse(cfg_option, element.second);
211 if (element.first ==
"ip-address") {
212 host->setIPv4Reservation(
IOAddress(element.second->
214 }
else if (element.first ==
"next-server") {
215 host->setNextServer(
IOAddress(element.second->stringValue()));
217 }
else if (element.first ==
"server-hostname") {
218 host->setServerHostname(element.second->stringValue());
220 }
else if (element.first ==
"boot-file-name") {
221 host->setBootFileName(element.second->stringValue());
223 }
else if (element.first ==
"client-classes") {
225 element.second->listValue()) {
226 host->addClientClass4(class_element->stringValue());
230 }
catch (
const std::exception& ex) {
233 << element.second->getPosition() <<
")");
241 const std::set<std::string>&
242 HostReservationParser4::getSupportedParameters(
const bool identifiers_only)
const {
243 return (getSupportedParams4(identifiers_only));
247 HostReservationParser6::parseInternal(
const SubnetID& subnet_id,
249 HostPtr host = HostReservationParser::parseInternal(subnet_id, reservation_data);
251 host->setIPv6SubnetID(subnet_id);
253 BOOST_FOREACH(
auto element, reservation_data->mapValue()) {
258 if (element.first ==
"option-data") {
265 parser.
parse(cfg_option, element.second);
267 }
else if (element.first ==
"ip-addresses" || element.first ==
"prefixes") {
269 element.second->listValue()) {
274 std::string prefix = prefix_element->stringValue();
275 uint8_t prefix_len = 128;
280 if (element.first ==
"prefixes") {
283 size_t len_pos = prefix.find(
'/');
284 if (len_pos == std::string::npos) {
286 " requires prefix length be specified"
287 " in '" << prefix <<
"'");
291 }
else if (len_pos >= prefix.length() - 1) {
293 <<
"' requires length after '/'");
302 prefix_len = boost::lexical_cast<
303 unsigned int>(prefix.substr(len_pos + 1));
305 }
catch (
const boost::bad_lexical_cast&) {
307 << prefix.substr(len_pos + 1)
313 prefix.erase(len_pos);
316 resrv_type = IPv6Resrv::TYPE_PD;
320 host->addReservation(
IPv6Resrv(resrv_type,
324 }
catch (
const std::exception& ex) {
327 << prefix_element->getPosition() <<
")");
332 }
else if (element.first ==
"client-classes") {
335 element.second->listValue()) {
336 host->addClientClass6(class_element->stringValue());
338 }
catch (
const std::exception& ex) {
341 << element.second->getPosition() <<
")");
349 const std::set<std::string>&
350 HostReservationParser6::getSupportedParameters(
const bool identifiers_only)
const {
351 return (getSupportedParams6(identifiers_only));
354 HostReservationIdsParser::HostReservationIdsParser()
369 std::string id_name = element->stringValue();
371 if (id_name !=
"auto") {
384 " no other values can be specified within '"
385 "host-reservation-identifiers' list");
390 for (
unsigned int i = 0;
393 std::string supported_id_name =
401 }
catch (
const std::exception& ex) {
404 << element->getPosition() <<
")");
411 " be empty (" << ids_list->getPosition() <<
")");
423 return (getSupportedParams4(
true).count(id_name) > 0);
433 return (getSupportedParams6(
true).count(id_name) > 0);
void parse(const CfgOptionPtr &cfg, isc::data::ConstElementPtr option_data_list)
Parses a list of options, instantiates them and stores in cfg.
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
boost::shared_ptr< Host > HostPtr
Pointer to the Host object.
static CfgMgr & instance()
returns a single instance of Configuration Manager
static std::string getIdentifierName(const IdentifierType &type)
Returns name of the identifier of a specified type.
IPv6 reservation for a host.
void parse(isc::data::ConstElementPtr ids_list)
Parses a list of host identifiers.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
To be removed. Please use ConfigError instead.
HostReservationIdsParser6()
Constructor.
boost::shared_ptr< const Element > ConstElementPtr
Parser for option data values within a subnet.
Represents a device with IPv4 and/or IPv6 reservations.
Type
Type of the reservation.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Parser for a list of host identifiers.
Defines the logger used by the top-level component of kea-dhcp-ddns.
virtual bool isSupportedIdentifier(const std::string &id_name) const =0
Checks if specified identifier name is supported in the context of the parser.
HostReservationIdsParser4()
Constructor.
CfgHostOperationsPtr staging_cfg_
Pointer to the object holding configuration.
virtual void parseInternal(isc::data::ConstElementPtr ids_list)
Parses a list of host identifiers.
The IOAddress class represents an IP addresses (version agnostic)
static const IdentifierType LAST_IDENTIFIER_TYPE
Constant pointing to the last identifier of the IdentifierType enumeration.
virtual bool isSupportedIdentifier(const std::string &id_name) const
Checks if specified identifier name is supported for DHCPv6.
virtual bool isSupportedIdentifier(const std::string &id_name) const
Checks if specified identifier name is supported for DHCPv4.
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)
SrvConfigPtr getStagingCfg()
Returns a pointer to the staging configuration.