13#include <boost/lexical_cast.hpp> 
   15#include <sys/socket.h> 
   35const std::set<std::string>&
 
   36getSupportedParams4(
const bool identifiers_only = 
false) {
 
   38    static std::set<std::string> identifiers_set;
 
   40    static std::set<std::string> params_set;
 
   43    if (identifiers_set.empty()) {
 
   44        identifiers_set.insert(
"hw-address");
 
   45        identifiers_set.insert(
"duid");
 
   46        identifiers_set.insert(
"circuit-id");
 
   47        identifiers_set.insert(
"client-id");
 
   48        identifiers_set.insert(
"flex-id");
 
   51    if (params_set.empty()) {
 
   52        params_set = identifiers_set;
 
   53        params_set.insert(
"hostname");
 
   54        params_set.insert(
"ip-address");
 
   55        params_set.insert(
"option-data");
 
   56        params_set.insert(
"next-server");
 
   57        params_set.insert(
"server-hostname");
 
   58        params_set.insert(
"boot-file-name");
 
   59        params_set.insert(
"client-classes");
 
   60        params_set.insert(
"user-context");
 
   62    return (identifiers_only ? identifiers_set : params_set);
 
   73const std::set<std::string>&
 
   74getSupportedParams6(
const bool identifiers_only = 
false) {
 
   76    static std::set<std::string> identifiers_set;
 
   78    static std::set<std::string> params_set;
 
   81    if (identifiers_set.empty()) {
 
   82        identifiers_set.insert(
"hw-address");
 
   83        identifiers_set.insert(
"duid");
 
   84        identifiers_set.insert(
"flex-id");
 
   87    if (params_set.empty()) {
 
   88        params_set = identifiers_set;
 
   89        params_set.insert(
"hostname");
 
   90        params_set.insert(
"ip-addresses");
 
   91        params_set.insert(
"prefixes");
 
   92        params_set.insert(
"excluded-prefixes");
 
   93        params_set.insert(
"option-data");
 
   94        params_set.insert(
"client-classes");
 
   95        params_set.insert(
"user-context");
 
   97    return (identifiers_only ? identifiers_set : params_set);
 
  108parsePrefix(std::string prefix, 
IOAddress& addr, uint8_t& len, std::string msg) {
 
  111    size_t len_pos  = prefix.find(
'/');
 
  112    if (len_pos == std::string::npos) {
 
  114                  << 
"be specified in '" << prefix << 
"'");
 
  115    } 
else if (len_pos >= prefix.length() - 1) {
 
  119                  << 
"' requires length after '/'");
 
  127    unsigned int prefix_len = len;
 
  129        prefix_len = boost::lexical_cast<unsigned int>(prefix.substr(len_pos + 1));
 
  130    } 
catch (
const boost::bad_lexical_cast&) {
 
  132                  << prefix.substr(len_pos + 1) << 
"' is invalid");
 
  134    if ((prefix_len == 0) || (prefix_len > 128)) {
 
  136                  "'prefix-len' value must be in range of [1..128]");
 
  138    len = 
static_cast<uint8_t
>(prefix_len);
 
  142    prefix.erase(len_pos);
 
  147        if (first_address != addr) {
 
  148            isc_throw(BadValue, 
"Prefix address: " << addr
 
  149                      << 
" exceeds prefix/prefix-len pair: " << first_address
 
  150                      << 
"/" << prefix_len);
 
  160                             bool encapsulate_options) {
 
  161    return (
parseInternal(subnet_id, reservation_data, encapsulate_options));
 
 
  168    std::string identifier;
 
  169    std::string identifier_name;
 
  170    std::string hostname;
 
  177        for (
auto const& element : reservation_data->mapValue()) {
 
  181                          " parameter '" << element.first << 
"'");
 
  185                if (!identifier.empty()) {
 
  187                              << 
"' and '" << identifier_name
 
  188                              << 
"' are mutually exclusive");
 
  190                identifier = element.second->stringValue();
 
  191                identifier_name = element.first;
 
  193            } 
else if (element.first == 
"hostname") {
 
  194                hostname = element.second->stringValue();
 
  195            } 
else if (element.first == 
"user-context") {
 
  196                user_context = element.second;
 
  201        if (identifier_name.empty()) {
 
  205            std::ostringstream s;
 
  207                if (s.tellp() != std::streampos(0)) {
 
  213                      " be specified for host reservation: " 
  219        host.reset(
new Host(identifier, identifier_name, SUBNET_ID_UNUSED,
 
  220                            SUBNET_ID_UNUSED, 
IOAddress(
"0.0.0.0"), hostname));
 
  224            host->setContext(user_context);
 
  226    } 
catch (
const std::exception& ex) {
 
  229                  << reservation_data->getPosition() << 
")");
 
 
  248                                      bool encapsulate_options) {
 
  250                                                        encapsulate_options);
 
  252    host->setIPv4SubnetID(subnet_id);
 
  254    for (
auto const& element : reservation_data->mapValue()) {
 
  258        if (element.first == 
"option-data") {
 
  265            parser.
parse(cfg_option, element.second, encapsulate_options);
 
  271                if (element.first == 
"ip-address") {
 
  272                    host->setIPv4Reservation(
IOAddress(element.second->
 
  274                } 
else if (element.first == 
"next-server") {
 
  275                    host->setNextServer(
IOAddress(element.second->stringValue()));
 
  277                } 
else if (element.first == 
"server-hostname") {
 
  278                    host->setServerHostname(element.second->stringValue());
 
  280                } 
else if (element.first == 
"boot-file-name") {
 
  281                    host->setBootFileName(element.second->stringValue());
 
  283                } 
else if (element.first == 
"client-classes") {
 
  284                    for (
auto const& class_element : element.second->listValue()) {
 
  285                        host->addClientClass4(class_element->stringValue());
 
  289            } 
catch (
const std::exception& ex) {
 
  292                          << element.second->getPosition() << 
")");
 
 
  300const std::set<std::string>&
 
  302    return (getSupportedParams4(identifiers_only));
 
 
  308                                      bool encapsulate_options) {
 
  310                                                        encapsulate_options);
 
  312    host->setIPv6SubnetID(subnet_id);
 
  317    ConstElementPtr excluded_prefixes = reservation_data->get(
"excluded-prefixes");
 
  318    ConstElementPtr client_classes = reservation_data->get(
"client-classes");
 
  331        parser.
parse(cfg_option, option_data, encapsulate_options);
 
  335        for (
size_t idx = 0; idx < ip_addresses->size(); ++idx) {
 
  340                std::string addr = element->stringValue();
 
  344            } 
catch (
const std::exception& ex) {
 
  347                          << element->getPosition() << 
")");
 
  352    if (excluded_prefixes) {
 
  355                      "requires the 'prefixes' parameter");
 
  357        if (excluded_prefixes->size() != prefixes->size()) {
 
  359                      "does not match the 'prefixes' parameter: " 
  360                      << excluded_prefixes->size() << 
" != " 
  361                      << prefixes->size());
 
  366        for (
size_t idx = 0; idx < prefixes->size(); ++idx) {
 
  369                std::string prefix = element->stringValue();
 
  371                uint8_t prefix_len(128);
 
  372                parsePrefix(prefix, addr, prefix_len, 
"prefix reservation");
 
  374                std::string exclude(
"");
 
  375                if (excluded_prefixes) {
 
  376                    element = excluded_prefixes->get(idx);
 
  377                    exclude = element->stringValue();
 
  379                if (!exclude.empty()) {
 
  381                    uint8_t excluded_prefix_len(0);
 
  382                    parsePrefix(exclude, excluded_prefix, excluded_prefix_len,
 
  388                host->addReservation(res);
 
  389            } 
catch (
const std::exception& ex) {
 
  392                          << element->getPosition() << 
")");
 
  397    if (client_classes) {
 
  399            for (
auto const& class_element : client_classes->listValue()) {
 
  400                host->addClientClass6(class_element->stringValue());
 
  402        } 
catch (
const std::exception& ex) {
 
  405                      << client_classes->getPosition() << 
")");
 
 
  412const std::set<std::string>&
 
  414    return (getSupportedParams6(identifiers_only));
 
 
  431    for (
auto const& element : ids_list->listValue()) {
 
  432        std::string id_name = element->stringValue();
 
  434            if (id_name != 
"auto") {
 
  447                              " no other values can be specified within '" 
  448                              "host-reservation-identifiers' list");
 
  453                for (
unsigned int i = 0;
 
  456                    std::string supported_id_name =
 
  464        } 
catch (
const std::exception& ex) {
 
  467                      << element->getPosition() << 
")");
 
  474                  " be empty (" << ids_list->getPosition() << 
")");
 
 
  486    return (getSupportedParams4(
true).count(id_name) > 0);
 
 
  496    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...
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.
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.
void setPDExclude(const asiolink::IOAddress &excluded_prefix, const uint8_t excluded_prefix_len)
Sets the Prefix Exclude option.
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.