diff options
author | Tomek Mrugalski <tomasz@isc.org> | 2016-08-24 13:17:19 +0200 |
---|---|---|
committer | Tomek Mrugalski <tomasz@isc.org> | 2016-08-24 13:17:19 +0200 |
commit | 9134e71011c9e0b55ac118c2c8811c08e3911c32 (patch) | |
tree | b89edd288982d535e3e6a9ed6c0db0f67778909a | |
parent | [master] Fixed recently introduced cpp-check (diff) | |
download | kea-9134e71011c9e0b55ac118c2c8811c08e3911c32.tar.xz kea-9134e71011c9e0b55ac118c2c8811c08e3911c32.zip |
[4626] Prototype implementation for fields storage done.
-rw-r--r-- | src/bin/dhcp4/dhcp4_srv.cc | 45 | ||||
-rw-r--r-- | src/bin/dhcp4/dhcp4_srv.h | 11 | ||||
-rw-r--r-- | src/lib/dhcpsrv/client_class_def.cc | 5 | ||||
-rw-r--r-- | src/lib/dhcpsrv/client_class_def.h | 36 |
4 files changed, 95 insertions, 2 deletions
diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 1ef9d7f0f8..aabcda6697 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -1927,6 +1927,51 @@ Dhcpv4Srv::adjustRemoteAddr(Dhcpv4Exchange& ex) { } } +void +Dhcpv4Srv::setFixedFields(Dhcpv4Exchange& ex) { + Pkt4Ptr query = ex.getQuery(); + Pkt4Ptr response = ex.getResponse(); + + const ClientClasses classes = query->getClasses(); + if (classes.empty()) { + return; + } + + // Let's get class definitions + const ClientClassDefMapPtr& defs = CfgMgr::instance().getCurrentCfg()-> + getClientClassDictionary()->getClasses(); + + // Now we need to iterate over the classes assigned to the + // query packet and find corresponding class defintions for it. + for (ClientClasses::const_iterator name = classes.begin(); + name != classes.end(); ++name) { + + ClientClassDefMap::const_iterator cl = defs->find(*name); + if (cl == defs->end()) { + // Let's skip classes that don't have definitions. Currently + // these are automatic classes VENDOR_CLASS_something, but there + // may be other classes assigned under other circumstances, e.g. + // by hooks. + continue; + } + + IOAddress next_server = cl->second->getNextServer(); + if (!next_server.isV4Zero()) { + response->setSiaddr(next_server); + } + + const vector<uint8_t>& sname = cl->second->getSname(); + if (!sname.empty()) { + response->setSname(&sname[0], sname.size()); + } + + const vector<uint8_t>& filename = cl->second->getFilename(); + if (!filename.empty()) { + response->setFile(&filename[0], filename.size()); + } + } +} + OptionPtr Dhcpv4Srv::getNetmaskOption(const Subnet4Ptr& subnet) { diff --git a/src/bin/dhcp4/dhcp4_srv.h b/src/bin/dhcp4/dhcp4_srv.h index 516ec9921f..813e66635c 100644 --- a/src/bin/dhcp4/dhcp4_srv.h +++ b/src/bin/dhcp4/dhcp4_srv.h @@ -513,6 +513,17 @@ protected: /// @param ex DHCPv4 exchange holding the client's message to be checked. void appendBasicOptions(Dhcpv4Exchange& ex); + /// @brief Sets fixed fields of the outgoing packet. + /// + /// If the incoming packets belongs to a class and that class defines + /// next-server, server-hostname or boot-file-name, we need to set the + /// siaddr, sname or filename fields in the outgoing packet. This + /// is what this method does. + /// + /// @param ex DHCPv4 exchange holding the client's message and the server's + /// response to be adjusted. + void setFixedFields(Dhcpv4Exchange& ex); + /// @brief Processes Client FQDN and Hostname Options sent by a client. /// /// Client may send Client FQDN or Hostname option to communicate its name diff --git a/src/lib/dhcpsrv/client_class_def.cc b/src/lib/dhcpsrv/client_class_def.cc index 467be6c971..69a1350a55 100644 --- a/src/lib/dhcpsrv/client_class_def.cc +++ b/src/lib/dhcpsrv/client_class_def.cc @@ -15,7 +15,8 @@ namespace dhcp { ClientClassDef::ClientClassDef(const std::string& name, const ExpressionPtr& match_expr, const CfgOptionPtr& cfg_option) - : name_(name), match_expr_(match_expr), cfg_option_(cfg_option) { + : name_(name), match_expr_(match_expr), cfg_option_(cfg_option), + next_server_(asiolink::IOAddress("0.0.0.0")) { // Name can't be blank if (name_.empty()) { @@ -33,7 +34,7 @@ ClientClassDef::ClientClassDef(const std::string& name, ClientClassDef::ClientClassDef(const ClientClassDef& rhs) : name_(rhs.name_), match_expr_(ExpressionPtr()), - cfg_option_(new CfgOption()) { + cfg_option_(new CfgOption()), next_server_(asiolink::IOAddress("0.0.0.0")) { if (rhs.match_expr_) { match_expr_.reset(new Expression()); diff --git a/src/lib/dhcpsrv/client_class_def.h b/src/lib/dhcpsrv/client_class_def.h index 0d3b3c2d72..7d005783cd 100644 --- a/src/lib/dhcpsrv/client_class_def.h +++ b/src/lib/dhcpsrv/client_class_def.h @@ -106,6 +106,24 @@ public: /// @brief Provides a convenient text representation of the class friend std::ostream& operator<<(std::ostream& os, const ClientClassDef& x); + /// @brief returns next-server value + /// @return next-server value + asiolink::IOAddress getNextServer() const { + return (next_server_); + } + + /// @brief returns server-hostname value + /// @return the vector that contains server-hostname (may be empty if not defined) + const std::vector<uint8_t>& getSname() const { + return (sname_); + } + + /// @brief returns boot-file-name value + /// @return the vector that contains boot-file-name (may be empty if not defined) + const std::vector<uint8_t>& getFilename() const { + return (filename_); + } + private: /// @brief Unique text identifier by which this class is known. std::string name_; @@ -116,6 +134,24 @@ private: /// @brief The option data configuration for this class CfgOptionPtr cfg_option_; + + /// @brief Next server field + /// If set by the next-server parameter, this value will be set + /// in the siaddr field of the DHCPv4 packet. + asiolink::IOAddress next_server_; + + /// @brief server-hostname + /// If set by the server-hostname parameter, this value will be + /// set in the sname field of the DHCPv4 packet. + /// This can be up to 64 octets long. + std::vector<uint8_t> sname_; + + /// @brief boot-file-name + /// If set by the boot-file-name parameter, this value will be + /// set in the file field of the DHCPv4 packet. + /// This can be up to 128 octets long. + std::vector<uint8_t> filename_; + }; /// @brief a pointer to an ClientClassDef |