20 #include <boost/foreach.hpp>
32 OptionDataParser::OptionDataParser(
const uint16_t address_family,
34 : address_family_(address_family), cfg_option_def_(cfg_option_def) {
37 std::pair<OptionDescriptor, std::string>
41 if (address_family_ == AF_INET) {
48 std::pair<OptionDescriptor, std::string> opt = createOption(single_option);
50 if (!opt.first.option_) {
53 "parser logic error: no option has been configured and"
54 " thus there is nothing to commit. Has build() been called?");
66 }
catch (
const std::exception&) {
72 if (address_family_ == AF_INET &&
73 code > std::numeric_limits<uint8_t>::max()) {
74 isc_throw(DhcpConfigError,
"invalid option code '" << code
75 <<
"', it must not be greater than '"
76 << static_cast<int>(std::numeric_limits<uint8_t>::max())
80 }
else if (address_family_ == AF_INET6 &&
81 code > std::numeric_limits<uint16_t>::max()) {
82 isc_throw(DhcpConfigError,
"invalid option code '" << code
83 <<
"', it must not exceed '"
84 << std::numeric_limits<uint16_t>::max()
103 if (name.find(
" ") != std::string::npos) {
104 isc_throw(DhcpConfigError,
"invalid option name '" << name
105 <<
"', space character is not allowed ("
128 bool csv_format =
true;
130 csv_format =
getBoolean(parent,
"csv-format");
141 std::string space = address_family_ == AF_INET ?
152 isc_throw(DhcpConfigError,
"invalid option space name '"
158 <<
"' option space name is reserved for DHCPv4 server");
161 (address_family_ == AF_INET)) {
163 <<
"' option space name is reserved for DHCPv6 server");
166 }
catch (
const std::exception& ex) {
168 isc_throw(DhcpConfigError, ex.what() <<
" ("
177 bool persist =
false;
188 template<
typename SearchKey>
190 OptionDataParser::findOptionDefinition(
const std::string& option_space,
191 const SearchKey& search_key)
const {
193 if (cfg_option_def_) {
195 def = cfg_option_def_->get(option_space, search_key);
235 std::pair<OptionDescriptor, std::string>
244 std::string data_param = extractData(option_data);
245 std::string space_param = extractSpace(option_data);
250 isc_throw(DhcpConfigError,
"option data configuration requires one of"
251 " 'code' or 'name' parameters to be specified"
252 <<
" (" << option_data->getPosition() <<
")");
258 findOptionDefinition(space_param, name_param) :
259 findOptionDefinition(space_param, code_param);
266 if (!csv_format_param.
unspecified() && csv_format_param) {
267 isc_throw(DhcpConfigError,
"definition for the option '"
268 << space_param <<
"." << name_param
269 <<
"' having code '" << code_param
270 <<
"' does not exist ("
277 isc_throw(DhcpConfigError,
"definition for the option '"
278 << space_param <<
"." << name_param
279 <<
"' does not exist ("
286 std::vector<uint8_t> binary;
287 std::vector<std::string> data_tokens;
291 if (def && (csv_format_param.
unspecified() || csv_format_param)) {
308 if (binary.empty()) {
312 isc_throw(DhcpConfigError,
"option data is not a valid"
313 <<
" string of hexadecimal digits: " << data_param
320 OptionDescriptor desc(
false);
328 OptionPtr option(
new Option(universe, static_cast<uint16_t>(code_param),
331 desc.option_ = option;
332 desc.persistent_ = !persist_param.
unspecified() && persist_param;
336 if (!name_param.
unspecified() && (def->getName() != name_param.
get())) {
337 isc_throw(DhcpConfigError,
"specified option name '"
338 << name_param <<
"' does not match the "
339 <<
"option definition: '" << space_param
340 <<
"." << def->getName() <<
"' ("
348 bool use_csv = csv_format_param.
unspecified() || csv_format_param;
350 def->optionFactory(universe, def->getCode(), data_tokens) :
351 def->optionFactory(universe, def->getCode(), binary);
352 desc.option_ = option;
353 desc.persistent_ = !persist_param.
unspecified() && persist_param;
355 desc.formatted_value_ = data_param;
358 isc_throw(DhcpConfigError,
"option data does not match"
359 <<
" option definition (space: " << space_param
360 <<
", code: " << def->getCode() <<
"): "
369 if (desc.option_->getType() ==
DHO_PAD) {
370 isc_throw(DhcpConfigError,
"invalid option code '0': "
371 <<
"reserved for PAD ("
372 << option_data->getPosition() <<
")");
373 }
else if (desc.option_->getType() ==
DHO_END) {
374 isc_throw(DhcpConfigError,
"invalid option code '255': "
375 <<
"reserved for END ("
376 << option_data->getPosition() <<
")");
382 if (desc.option_->getType() == 0) {
383 isc_throw(DhcpConfigError,
"invalid option code '0': "
384 <<
"reserved value ("
385 << option_data->getPosition() <<
")");
392 desc.setContext(user_context);
396 return make_pair(desc, space_param);
402 const uint16_t address_family,
404 : address_family_(address_family), cfg_option_def_(cfg_option_def) {
412 std::pair<OptionDescriptor, std::string> option =
413 option_parser.
parse(data);
415 cfg->add(option.first, option.second);
static bool getBoolean(isc::data::ConstElementPtr scope, const std::string &name)
Returns a boolean parameter from a scope.
static OptionDefinitionPtr getRuntimeOptionDef(const std::string &space, const uint16_t code)
Returns runtime (non-standard) option definition by space and option code.
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
static int64_t getInteger(isc::data::ConstElementPtr scope, const std::string &name)
Returns an integer parameter from a scope.
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.
std::pair< OptionDescriptor, std::string > parse(isc::data::ConstElementPtr single_option)
Parses ElementPtr containing option definition.
static bool validateName(const std::string &name)
Checks that the provided option space name is valid.
boost::shared_ptr< Option > OptionPtr
Universe
defines option universe DHCPv4 or DHCPv6
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
void decodeFormattedHexString(const std::string &hex_string, std::vector< uint8_t > &binary)
Converts a formatted string of hexadecimal digits into a vector.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< const Element > ConstElementPtr
static std::string getString(isc::data::ConstElementPtr scope, const std::string &name)
Returns a string parameter from a scope.
vector< string > tokens(const std::string &text, const std::string &delim, bool escape)
Split String into Tokens.
static OptionDefinitionPtr getOptionDef(const std::string &space, const uint16_t code)
Return the first option definition matching a particular option code.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
static const isc::data::SimpleKeywords OPTION6_PARAMETERS
This table defines all option parameters.
std::vector< uint8_t > quotedStringToBinary(const std::string "ed_string)
Converts a string in quotes into vector.
static const data::Element::Position & getPosition(const std::string &name, const data::ConstElementPtr parent)
Utility method that returns position of an element.
This is a base class for exceptions thrown from the DNS library module.
Defines the logger used by the top-level component of kea-dhcp-ddns.
T get() const
Retrieves the encapsulated value.
#define DHCP6_OPTION_SPACE
A generic exception that is thrown if a function is called in a prohibited way.
#define DHCP4_OPTION_SPACE
global std option spaces
static void checkKeywords(const SimpleKeywords &keywords, isc::data::ConstElementPtr scope)
Checks acceptable keywords with their expected type.
Parser for option data value.
static OptionDefinitionPtr getLastResortOptionDef(const std::string &space, const uint16_t code)
Returns last resort option definition by space and option code.
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
OptionDataListParser(const uint16_t address_family, CfgOptionDefPtr cfg_option_def=CfgOptionDefPtr())
Constructor.
static uint32_t optionSpaceToVendorId(const std::string &option_space)
Converts option space name to vendor id.
static const isc::data::SimpleKeywords OPTION4_PARAMETERS
This table defines all option parameters.
static OptionDefinitionPtr getVendorOptionDef(const Option::Universe u, const uint32_t vendor_id, const uint16_t code)
Returns vendor option definition for a given vendor-id and code.