}
}
- // Step 1: try to set values using HR.
- /// @todo: Merge Marcin's code here.
-
- // Step 2: if step 1 failed, try to set the values based on classes.
- 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;
+ void
+ Dhcpv4Srv::setFixedFields(Dhcpv4Exchange& ex) {
+ Pkt4Ptr query = ex.getQuery();
+ Pkt4Ptr response = ex.getResponse();
+
- IOAddress next_server = cl->second->getNextServer();
- if (!next_server.isV4Zero()) {
- response->setSiaddr(next_server);
- }
++ // Step 1: Start with fixed fields defined on subnet level.
++ Subnet4Ptr subnet = ex.getContext()->subnet_;
++ if (subnet) {
++ IOAddress subnet_next_server = subnet->getSiaddr();
++ if (!subnet_next_server.isV4Zero()) {
++ response->setSiaddr(subnet_next_server);
+ }
++ }
+
- const string& sname = cl->second->getSname();
- if (!sname.empty()) {
- // Converting string to (const uint8_t*, size_t len) format is
- // tricky. reineterpret_cast is not the most elegant solution,
- // but it does avoid us making unnecessary copy. We will convert
- // sname and file fields in Pkt4 to string one day and live
- // will be easier.
- response->setSname(reinterpret_cast<const uint8_t*>(sname.c_str()),
- sname.size());
- }
++ // Step 2: Try to set the values based on classes.
++ // Any values defined in classes will override those from subnet level.
++ const ClientClasses classes = query->getClasses();
++ if (!classes.empty()) {
++
++ // 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;
++ }
+
- const string& filename = cl->second->getFilename();
- if (!filename.empty()) {
- // Converting string to (const uint8_t*, size_t len) format is
- // tricky. reineterpret_cast is not the most elegant solution,
- // but it does avoid us making unnecessary copy. We will convert
- // sname and file fields in Pkt4 to string one day and live
- // will be easier.
- response->setFile(reinterpret_cast<const uint8_t*>(filename.c_str()),
- filename.size());
++ IOAddress next_server = cl->second->getNextServer();
++ if (!next_server.isV4Zero()) {
++ response->setSiaddr(next_server);
++ }
+
- // Step 3: Finally, set the values based on subnet values.
- /// @todo implement this.
-
- /// @todo: We need to implement some kind of logic here that only
- /// the values that are not set yet in previous steps are overwritten.
++ const string& sname = cl->second->getSname();
++ if (!sname.empty()) {
++ // Converting string to (const uint8_t*, size_t len) format is
++ // tricky. reineterpret_cast is not the most elegant solution,
++ // but it does avoid us making unnecessary copy. We will convert
++ // sname and file fields in Pkt4 to string one day and live
++ // will be easier.
++ response->setSname(reinterpret_cast<const uint8_t*>(sname.c_str()),
++ sname.size());
++ }
++
++ const string& filename = cl->second->getFilename();
++ if (!filename.empty()) {
++ // Converting string to (const uint8_t*, size_t len) format is
++ // tricky. reineterpret_cast is not the most elegant solution,
++ // but it does avoid us making unnecessary copy. We will convert
++ // sname and file fields in Pkt4 to string one day and live
++ // will be easier.
++ response->setFile(reinterpret_cast<const uint8_t*>(filename.c_str()),
++ filename.size());
++ }
+ }
+ }
+
++ // Step 3: try to set values using HR. Any values coming from there will override
++ // the subnet or class values.
++ ex.setReservedMessageFields();
+ }
OptionPtr
Dhcpv4Srv::getNetmaskOption(const Subnet4Ptr& subnet) {