rsp->setSiaddr(IOAddress::IPV4_ZERO_ADDRESS());
}
+ // try to get the 'Parameter Request List' option which holds the
+ // codes of requested options.
+ OptionUint8ArrayPtr option_prl = boost::dynamic_pointer_cast<
+ OptionUint8Array>(query->getOption(DHO_DHCP_PARAMETER_REQUEST_LIST));
+ // If there is no PRL option in the message from the client then
+ // there is nothing to do.
+ if (!option_prl) {
+ return (true);
+ }
+ // Get the codes of requested options.
+ const std::vector<uint8_t>& requested_opts = option_prl->getValues();
+
// Process each class in the packet
const ClientClasses& classes = query->getClasses();
for (ClientClasses::const_iterator cclass = classes.begin();
// Not found
continue;
}
- // Get the configured options of this class
- const OptionContainerPtr& options = ccdef->getCfgOption()->getAll("dhcp4");
- if (!options || options->empty()) {
- continue;
- }
- // Go through each OptionDescriptor
- for (OptionContainer::const_iterator desc = options->begin();
- desc != options->end(); ++desc) {
- OptionPtr opt = desc->option_;
- // Add the option if it doesn't exist yet
- if (!rsp->getOption(opt->getType())) {
- rsp->addOption(opt);
- }
- }
+ // For each requested option code get the instance of the option
+ // in the class to be returned to the client.
+ for (std::vector<uint8_t>::const_iterator opt = requested_opts.begin();
+ opt != requested_opts.end(); ++opt) {
+ if (!rsp->getOption(*opt)) {
+ OptionDescriptor desc = ccdef->getCfgOption()->get("dhcp4", *opt);
+ if (desc.option_) {
+ rsp->addOption(desc.option_);
+ }
+ }
+ }
}
return (true);
query1->setRemoteAddr(IOAddress("192.0.2.1"));
Pkt4Ptr query2(new Pkt4(DHCPDISCOVER, 1234));
query2->setRemoteAddr(IOAddress("192.0.2.1"));
+ Pkt4Ptr query3(new Pkt4(DHCPDISCOVER, 1234));
+ query3->setRemoteAddr(IOAddress("192.0.2.1"));
- // Create and add a host-name option to the first query
+ // Create and add a PRL option to the first 2 queries
+ OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
+ DHO_DHCP_PARAMETER_REQUEST_LIST));
+ ASSERT_TRUE(prl);
+ prl->addValue(DHO_IP_FORWARDING);
+ query1->addOption(prl);
+ query2->addOption(prl);
+
+ // Create and add a host-name option to the first and last queries
OptionStringPtr hostname(new OptionString(Option::V4, 12, "foo"));
ASSERT_TRUE(hostname);
query1->addOption(hostname);
+ query3->addOption(hostname);
// Classify packets
srv.classifyPacket(query1);
srv.classifyPacket(query2);
+ srv.classifyPacket(query3);
- // The first packet (and only the first) should be in the router class
+ // Packets at the exception of the second should be in the router class
EXPECT_TRUE(query1->inClass("router"));
EXPECT_FALSE(query2->inClass("router"));
+ EXPECT_TRUE(query3->inClass("router"));
Dhcpv4Exchange ex1 = createExchange(query1);
Pkt4Ptr response1 = ex1.getResponse();
Dhcpv4Exchange ex2 = createExchange(query2);
Pkt4Ptr response2 = ex2.getResponse();
+ Dhcpv4Exchange ex3 = createExchange(query3);
+ Pkt4Ptr response3 = ex3.getResponse();
// Classification processing should add an ip-forwarding option
srv.classSpecificProcessing(ex1);
srv.classSpecificProcessing(ex2);
OptionPtr opt2 = response2->getOption(DHO_IP_FORWARDING);
EXPECT_FALSE(opt2);
+
+ // But only for the first exchange
+ srv.classSpecificProcessing(ex3);
+ OptionPtr opt3 = response3->getOption(DHO_IP_FORWARDING);
+ EXPECT_FALSE(opt3);
}
// Checks subnet options have the priority over class options