From: Tomek Mrugalski Date: Wed, 24 Aug 2016 12:30:16 +0000 (+0200) Subject: [4626] class parser updated to handle next-server, server-name and boot-file-name X-Git-Tag: trac4631_base~1^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5fbda6985b30f8f2fd19bd71c87b437b5fb2fa2;p=thirdparty%2Fkea.git [4626] class parser updated to handle next-server, server-name and boot-file-name --- diff --git a/src/lib/dhcpsrv/client_class_def.cc b/src/lib/dhcpsrv/client_class_def.cc index 69a1350a55..7709804e32 100644 --- a/src/lib/dhcpsrv/client_class_def.cc +++ b/src/lib/dhcpsrv/client_class_def.cc @@ -115,8 +115,14 @@ ClientClassDictionary::~ClientClassDictionary() { void ClientClassDictionary::addClass(const std::string& name, const ExpressionPtr& match_expr, - const CfgOptionPtr& cfg_option) { + const CfgOptionPtr& cfg_option, + asiolink::IOAddress next_server, + const std::vector& sname, + const std::vector& filename) { ClientClassDefPtr cclass(new ClientClassDef(name, match_expr, cfg_option)); + cclass->setNextServer(next_server); + cclass->setSname(sname); + cclass->setFilename(filename); addClass(cclass); } diff --git a/src/lib/dhcpsrv/client_class_def.h b/src/lib/dhcpsrv/client_class_def.h index 7d005783cd..36d1237807 100644 --- a/src/lib/dhcpsrv/client_class_def.h +++ b/src/lib/dhcpsrv/client_class_def.h @@ -112,6 +112,27 @@ public: return (next_server_); } + /// @brief sets the next-server value + /// + /// @param addr the value to be set + void setNextServer(const asiolink::IOAddress& addr) { + next_server_ = addr; + } + + /// @brief sets the server-name value + /// + /// @param sname the value to be set + void setSname(const std::vector& sname) { + sname_ = sname; + } + + /// @brief sets the boot-file-name value + /// + /// @param filename the value to be set + void setFilename(const std::vector& filename) { + filename_ = filename; + } + /// @brief returns server-hostname value /// @return the vector that contains server-hostname (may be empty if not defined) const std::vector& getSname() const { @@ -183,12 +204,18 @@ public: /// @param name Name to assign to this class /// @param match_expr Expression the class will use to determine membership /// @param options Collection of options members should be given + /// @param next_server next-server value for this class (optional) + /// @param sname server-name value for this class (optional) + /// @param filename boot-file-name value for this class (optional) /// /// @throw DuplicateClientClassDef if class already exists within the /// dictionary. See @ref dhcp::ClientClassDef::ClientClassDef() for /// others. void addClass(const std::string& name, const ExpressionPtr& match_expr, - const CfgOptionPtr& options); + const CfgOptionPtr& options, + asiolink::IOAddress next_server = asiolink::IOAddress("0.0.0.0"), + const std::vector& sname = std::vector(), + const std::vector& filename = std::vector()); /// @brief Adds a new class to the list /// diff --git a/src/lib/dhcpsrv/parsers/client_class_def_parser.cc b/src/lib/dhcpsrv/parsers/client_class_def_parser.cc index 36017ee4c7..b7e40e9690 100644 --- a/src/lib/dhcpsrv/parsers/client_class_def_parser.cc +++ b/src/lib/dhcpsrv/parsers/client_class_def_parser.cc @@ -9,10 +9,14 @@ #include #include #include +#include +#include #include using namespace isc::data; +using namespace isc::asiolink; +using namespace std; /// @file client_class_def.cc /// @@ -73,6 +77,11 @@ ClientClassDefParser::ClientClassDefParser(const std::string&, void ClientClassDefParser::build(ConstElementPtr class_def_cfg) { + + IOAddress next_server("0.0.0.0"); + std::vector sname; + std::vector filename; + // Parse the elements that make up the option definition. BOOST_FOREACH(ConfigPair param, class_def_cfg->mapValue()) { std::string entry(param.first); @@ -92,6 +101,36 @@ ClientClassDefParser::build(ConstElementPtr class_def_cfg) { opts_parser.reset(new OptionDataListParser(entry, options_, family)); parser = opts_parser; + } else if (entry == "next-server") { + // Let's parse the next-server field + try { + next_server = IOAddress(param.second->stringValue()); + } catch (const IOError& ex) { + isc_throw(DhcpConfigError, "Invalid next-server value specified: '" + << param.second << "'"); + } + if (next_server.getFamily() != AF_INET) { + isc_throw(DhcpConfigError, "Invalid next-server value: '" + << param.second << "', must be IPv4 address"); + } + } else if (entry == "server-hostname") { + string tmp = param.second->stringValue(); + if (tmp.length() > Pkt4::MAX_SNAME_LEN) { + isc_throw(DhcpConfigError, "server-hostname must be at most " + << Pkt4::MAX_SNAME_LEN << " bytes long, it is " + << tmp.length()); + } + sname = vector(tmp.begin(), tmp.end()); + + } else if (entry == "boot-file-name") { + string tmp = param.second->stringValue(); + if (tmp.length() > Pkt4::MAX_FILE_LEN) { + isc_throw(DhcpConfigError, "boot-file-name must be at most " + << Pkt4::MAX_FILE_LEN << " bytes long, it is " + << tmp.length()); + } + filename = vector(tmp.begin(), tmp.end()); + } else { isc_throw(DhcpConfigError, "invalid parameter '" << entry << "' (" << param.second->getPosition() << ")");