123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- #include <dhcpsrv/parsers/simple_parser.h>
- #include <boost/foreach.hpp>
- #include <boost/lexical_cast.hpp>
- #include <cc/data.h>
- #include <string>
- using namespace std;
- using namespace isc::data;
- namespace isc {
- namespace dhcp {
- /// This table defines default values for option definitions in DHCPv4
- const SimpleDefaults OPTION4_DEF_DEFAULTS = {
- { "record-types", Element::string, ""},
- { "space", Element::string, "dhcp4"},
- { "array", Element::boolean, "false"},
- { "encapsulate", Element::string, "" }
- };
- /// This table defines default values for option definitions in DHCPv6
- const SimpleDefaults OPTION6_DEF_DEFAULTS = {
- { "record-types", Element::string, ""},
- { "space", Element::string, "dhcp6"},
- { "array", Element::boolean, "false"},
- { "encapsulate", Element::string, "" }
- };
- /// This table defines default values for options in DHCPv4
- const SimpleDefaults OPTION4_DEFAULTS = {
- { "space", Element::string, "dhcp4"},
- { "csv-format", Element::boolean, "true"},
- { "encapsulate", Element::string, "" }
- };
- /// This table defines default values for options in DHCPv6
- const SimpleDefaults OPTION6_DEFAULTS = {
- { "space", Element::string, "dhcp6"},
- { "csv-format", Element::boolean, "true"},
- { "encapsulate", Element::string, "" }
- };
- /// This table defines default values for DHCPv4
- const SimpleDefaults GLOBAL4_DEFAULTS = {
- { "renew-timer", Element::integer, "900" },
- { "rebind-timer", Element::integer, "1800" },
- { "valid-lifetime", Element::integer, "7200" }
- };
- /// This table defines default values for both DHCPv4 and DHCPv6
- const SimpleDefaults GLOBAL6_DEFAULTS = {
- { "renew-timer", Element::integer, "900" },
- { "rebind-timer", Element::integer, "1800" },
- { "preferred-lifetime", Element::integer, "3600" },
- { "valid-lifetime", Element::integer, "7200" }
- };
- /// This list defines parameters that can be inherited from the global
- /// scope to subnet scope.
- const ParamsList INHERIT_GLOBAL_TO_SUBNET = {
- "renew-timer",
- "rebind-timer",
- "preferred-lifetime",
- "valid-lifetime"
- };
- std::string
- SimpleParser::getString(isc::data::ConstElementPtr scope, const std::string& name) {
- ConstElementPtr x = scope->get(name);
- if (!x) {
- isc_throw(BadValue, "Element " << name << " not found");
- }
- if (x->getType() != Element::string) {
- isc_throw(BadValue, "Element " << name << " found, but is not a string");
- }
- return (x->stringValue());
- }
- int64_t
- SimpleParser::getInteger(isc::data::ConstElementPtr scope, const std::string& name) {
- ConstElementPtr x = scope->get(name);
- if (!x) {
- isc_throw(BadValue, "Element " << name << " not found");
- }
- if (x->getType() != Element::integer) {
- isc_throw(BadValue, "Element " << name << " found, but is not an integer");
- }
- return (x->intValue());
- }
- bool
- SimpleParser::getBoolean(isc::data::ConstElementPtr scope, const std::string& name) {
- ConstElementPtr x = scope->get(name);
- if (!x) {
- isc_throw(BadValue, "Element " << name << " not found");
- }
- if (x->getType() != Element::boolean) {
- isc_throw(BadValue, "Element " << name << " found, but is not a boolean");
- }
- return (x->boolValue());
- }
- const data::Element::Position&
- SimpleParser::getPosition(const std::string& name, const data::ConstElementPtr parent) const {
- if (!parent) {
- return (data::Element::ZERO_POSITION());
- }
- ConstElementPtr elem = parent->get(name);
- if (!elem) {
- return (data::Element::ZERO_POSITION());
- }
- return (elem->getPosition());
- }
- size_t SimpleParser::setDefaults(isc::data::ElementPtr scope,
- const SimpleDefaults& default_values) {
- size_t cnt = 0;
- // This is the position representing a default value. As the values
- // we're inserting here are not present in whatever the config file
- // came from, we need to make sure it's clearly labeled as default.
- const Element::Position pos("<default-value>", 0, 0);
- // Let's go over all parameters we have defaults for.
- BOOST_FOREACH(SimpleDefault def_value, default_values) {
- // Try if such a parameter is there. If it is, let's
- // skip it, because user knows best *cough*.
- ConstElementPtr x = scope->get(string(def_value.name_));
- if (x) {
- // There is such a value already, skip it.
- continue;
- }
- // There isn't such a value defined, let's create the default
- // value...
- switch (def_value.type_) {
- case Element::string: {
- x.reset(new StringElement(def_value.value_, pos));
- break;
- }
- case Element::integer: {
- int int_value = boost::lexical_cast<int>(def_value.value_);
- x.reset(new IntElement(int_value, pos));
- break;
- }
- case Element::boolean: {
- bool bool_value;
- if (def_value.value_ == string("true")) {
- bool_value = true;
- } else if (def_value.value_ == string("false")) {
- bool_value = false;
- } else {
- isc_throw(BadValue, "Internal error. Boolean value specified as "
- << def_value.value_ << ", expected true or false");
- }
- x.reset(new BoolElement(bool_value, pos));
- break;
- }
- case Element::real: {
- double dbl_value = boost::lexical_cast<double>(def_value.value_);
- x.reset(new DoubleElement(dbl_value, pos));
- break;
- }
- default:
- // No default values for null, list or map
- isc_throw(BadValue, "Internal error. Incorrect default value type.");
- }
- // ... and insert it into the provided Element tree.
- scope->set(def_value.name_, x);
- cnt++;
- }
- return (cnt);
- }
- size_t SimpleParser::setGlobalDefaults(isc::data::ElementPtr global, bool v6) {
- return (setDefaults(global, v6 ? GLOBAL6_DEFAULTS : GLOBAL4_DEFAULTS));
- }
- size_t SimpleParser::setOptionDefaults(isc::data::ElementPtr option, bool v6) {
- return (setDefaults(option, v6?OPTION6_DEFAULTS : OPTION4_DEFAULTS));
- }
- size_t SimpleParser::setOptionListDefaults(isc::data::ElementPtr option_list, bool v6) {
- size_t cnt = 0;
- BOOST_FOREACH(ElementPtr single_option, option_list->listValue()) {
- cnt += setOptionDefaults(single_option, v6);
- }
- return (cnt);
- }
- size_t SimpleParser::setOptionDefDefaults(isc::data::ElementPtr option_def, bool v6) {
- return (setDefaults(option_def, v6? OPTION6_DEF_DEFAULTS : OPTION4_DEF_DEFAULTS));
- }
- size_t SimpleParser::setOptionDefListDefaults(isc::data::ElementPtr option_def_list,
- bool v6) {
- size_t cnt = 0;
- BOOST_FOREACH(ElementPtr single_def, option_def_list->listValue()) {
- cnt += setOptionDefDefaults(single_def, v6);
- }
- return (cnt);
- }
- size_t SimpleParser::setAllDefaults(isc::data::ElementPtr global, bool v6) {
- size_t cnt = 0;
- // Set global defaults first.
- /// @todo: Uncomment as part of the ticket 5019 work.
- //cnt = setGlobalDefaults(global, v6);
- // Now set option defintion defaults for each specified option definition
- ConstElementPtr option_defs = global->get("option-def");
- if (option_defs) {
- BOOST_FOREACH(ElementPtr single_def, option_defs->listValue()) {
- cnt += setOptionDefDefaults(single_def, v6);
- }
- }
- ConstElementPtr options = global->get("option-data");
- if (options) {
- BOOST_FOREACH(ElementPtr single_option, options->listValue()) {
- cnt += setOptionDefaults(single_option, v6);
- }
- //setOptionListDefaults(options);
- }
- return (cnt);
- }
- size_t
- SimpleParser::deriveParams(isc::data::ConstElementPtr parent,
- isc::data::ElementPtr child,
- const ParamsList& params) {
- if ( (parent->getType() != Element::map) ||
- (child->getType() != Element::map)) {
- return (0);
- }
- size_t cnt = 0;
- BOOST_FOREACH(string param, params) {
- ConstElementPtr x = parent->get(param);
- if (!x) {
- // Parent doesn't define this parameter, so there's
- // nothing to derive from
- continue;
- }
- if (child->get(param)) {
- // Child defines this parameter already. There's
- // nothing to do here.
- continue;
- }
- // Copy the parameters to the child scope.
- child->set(param, x);
- cnt++;
- }
- return (cnt);
- }
- size_t
- SimpleParser::inheritGlobalToSubnet(isc::data::ConstElementPtr global,
- isc::data::ElementPtr subnet) {
- return deriveParams(global, subnet, INHERIT_GLOBAL_TO_SUBNET);
- }
- }; // end of isc::dhcp namespace
- }; // end of isc namespace
|