CfgMgr::instance().addSubnet4(subnet_);
}
+ /// @brief Add 'Paramter Request List' option to the packet.
+ ///
+ /// This function PRL option comprising the following
+ /// option codes:
+ /// - 5 - Name Server
+ /// - 15 - Domain Name
+ /// - 7 - Log Server
+ /// - 8 - Quotes Server
+ /// - 9 - LPR Server
+ ///
+ /// @param pkt packet to add PRL option to.
+ void addPrlOption(Pkt4Ptr& pkt) {
+
+ OptionUint8ArrayPtr option_prl =
+ OptionUint8ArrayPtr(new OptionUint8Array(Option::V4,
+ DHO_DHCP_PARAMETER_REQUEST_LIST));
+
+ std::vector<uint8_t> opts;
+ // Let's request options that have been configured for the subnet.
+ opts.push_back(DHO_DOMAIN_NAME_SERVERS);
+ opts.push_back(DHO_DOMAIN_NAME);
+ opts.push_back(DHO_LOG_SERVERS);
+ opts.push_back(DHO_COOKIE_SERVERS);
+ // Let's also request the option that hasn't been configured. In such
+ // case server should ignore request for this particular option.
+ opts.push_back(DHO_LPR_SERVERS);
+ // Put the requested option codes into the 'Parameter Request List'.
+ option_prl->setValues(opts);
+ // And add 'Parameter Request List' option into the DISCOVER packet.
+ pkt->addOption(option_prl);
+ }
+
+ /// @brief Configures options being requested in the PRL option.
+ ///
+ /// The lpr-servers option is NOT configured here altough it is
+ /// added to the 'Parameter Request List' option in the
+ /// \ref addPrlOption. When requested option is not configured
+ /// the server should not return it in its rensponse. The goal
+ /// of not configuring the requested option is to verify that
+ /// the server will not return it.
+ void configureRequestedOptions() {
+ // dns-servers
+ Option4AddrLstPtr
+ option_dns_servers(new Option4AddrLst(DHO_DOMAIN_NAME_SERVERS));
+ option_dns_servers->addAddress(IOAddress("192.0.2.1"));
+ option_dns_servers->addAddress(IOAddress("192.0.2.100"));
+ ASSERT_NO_THROW(subnet_->addOption(option_dns_servers, false, "dhcp4"));
+
+ // domain-name
+ OptionDefinition def("domain-name", DHO_DOMAIN_NAME, OPT_FQDN_TYPE);
+ boost::shared_ptr<OptionCustom>
+ option_domain_name(new OptionCustom(def, Option::V4));
+ option_domain_name->writeFqdn("example.com");
+ subnet_->addOption(option_domain_name, false, "dhcp4");
+
+ // log-servers
+ Option4AddrLstPtr option_log_servers(new Option4AddrLst(DHO_LOG_SERVERS));
+ option_log_servers->addAddress(IOAddress("192.0.2.2"));
+ option_log_servers->addAddress(IOAddress("192.0.2.10"));
+ ASSERT_NO_THROW(subnet_->addOption(option_log_servers, false, "dhcp4"));
+
+ // cookie-servers
+ Option4AddrLstPtr option_cookie_servers(new Option4AddrLst(DHO_COOKIE_SERVERS));
+ option_cookie_servers->addAddress(IOAddress("192.0.2.1"));
+ ASSERT_NO_THROW(subnet_->addOption(option_cookie_servers, false, "dhcp4"));
+ }
+
/// @brief checks that the response matches request
/// @param q query (client's message)
/// @param a answer (server's message)
EXPECT_EQ(q->getIndex(), a->getIndex());
EXPECT_EQ(q->getGiaddr(), a->getGiaddr());
- // Check that bare minimum of required options are there
+ // Check that bare minimum of required options are there.
+ // We don't check options requested by a client. Those
+ // are checked elsewhere.
EXPECT_TRUE(a->getOption(DHO_SUBNET_MASK));
EXPECT_TRUE(a->getOption(DHO_ROUTERS));
EXPECT_TRUE(a->getOption(DHO_DHCP_SERVER_IDENTIFIER));
EXPECT_TRUE(a->getOption(DHO_DHCP_LEASE_TIME));
EXPECT_TRUE(a->getOption(DHO_SUBNET_MASK));
EXPECT_TRUE(a->getOption(DHO_ROUTERS));
- EXPECT_TRUE(a->getOption(DHO_DOMAIN_NAME));
- EXPECT_TRUE(a->getOption(DHO_DOMAIN_NAME_SERVERS));
// Check that something is offered
EXPECT_TRUE(a->getYiaddr().toText() != "0.0.0.0");
}
+ /// @brief Check that requested options are present.
+ ///
+ /// @param pkt packet to be checked.
+ void optionsCheck(const Pkt4Ptr& pkt) {
+ // Check that the requested and configured options are returned
+ // in the ACK message.
+ EXPECT_TRUE(pkt->getOption(DHO_DOMAIN_NAME))
+ << "domain-name not present in the response";
+ EXPECT_TRUE(pkt->getOption(DHO_DOMAIN_NAME_SERVERS))
+ << "dns-servers not present in the response";
+ EXPECT_TRUE(pkt->getOption(DHO_LOG_SERVERS))
+ << "log-servers not present in the response";
+ EXPECT_TRUE(pkt->getOption(DHO_COOKIE_SERVERS))
+ << "cookie-servers not present in the response";
+ // Check that the requested but not configured options are not
+ // returned in the ACK message.
+ EXPECT_FALSE(pkt->getOption(DHO_LPR_SERVERS))
+ << "domain-name present in the response but it is"
+ << " expected not to be present";
+ }
+
/// @brief generates client-id option
///
/// Generate client-id option of specified length
pkt->setRemotePort(DHCP4_SERVER_PORT);
// We are going to test that certain options are returned
- // in the OFFER message when requested using 'Parameter
- // Request List' option. Let's configure those options that
- // are returned when requested.
-
- // dns-servers
- OptionPtr option_dns_servers(new Option4AddrLst(DHO_DOMAIN_NAME_SERVERS));
- ASSERT_NO_THROW(subnet_->addOption(option_dns_servers, false, "dhcp4"));
- // domain-name
- OptionDefinition def("domain-name", DHO_DOMAIN_NAME, OPT_FQDN_TYPE);
- boost::shared_ptr<OptionCustom>
- option_domain_name(new OptionCustom(def, Option::V4));
- option_domain_name->writeFqdn("example.com");
- OptionPtr opt_domain = boost::dynamic_pointer_cast<Option>(option_domain_name);
- subnet_->addOption(opt_domain, false, "dhcp4");
- // log-servers
- OptionPtr option_log_servers(new Option4AddrLst(DHO_LOG_SERVERS));
- ASSERT_NO_THROW(subnet_->addOption(option_log_servers, false, "dhcp4"));
- // cookie-servers
- OptionPtr option_cookie_servers(new Option4AddrLst(DHO_COOKIE_SERVERS));
- ASSERT_NO_THROW(subnet_->addOption(option_cookie_servers, false, "dhcp4"));
-
- // Add 'Parameter Request List' option. In this option we are going
- // specify which options we request to be retured in the OFFER
- // message.
- OptionUint8ArrayPtr option_prl =
- OptionUint8ArrayPtr(new OptionUint8Array(Option::V4,
- DHO_DHCP_PARAMETER_REQUEST_LIST));
-
- std::vector<uint8_t> opts;
- // Let's request options that have been configured for the subnet.
- opts.push_back(DHO_DOMAIN_NAME_SERVERS);
- opts.push_back(DHO_DOMAIN_NAME);
- opts.push_back(DHO_LOG_SERVERS);
- opts.push_back(DHO_COOKIE_SERVERS);
- // Let's also request the option that hasn't been configured. In such
- // case server should ignore request for this particular option.
- opts.push_back(DHO_LPR_SERVERS);
- // Put the requested option codes into the 'Parameter Request List'.
- option_prl->setValues(opts);
- // And add 'Parameter Request List' option into the DISCOVER packet.
- pkt->addOption(option_prl);
+ // (or not returned) in the OFFER message when requested
+ // using 'Parameter Request List' option. Let's configure
+ // those options that are returned when requested.
+ configureRequestedOptions();
// Should not throw
EXPECT_NO_THROW(
messageCheck(pkt, offer);
+ // We did not request any options so they should not be present
+ // in the OFFER.
+ EXPECT_FALSE(offer->getOption(DHO_DOMAIN_NAME));
+ EXPECT_FALSE(offer->getOption(DHO_DOMAIN_NAME_SERVERS));
+ EXPECT_FALSE(offer->getOption(DHO_LOG_SERVERS));
+ EXPECT_FALSE(offer->getOption(DHO_COOKIE_SERVERS));
+ EXPECT_FALSE(offer->getOption(DHO_LPR_SERVERS));
+
+ // Add 'Parameter Request List' option.
+ addPrlOption(pkt);
+
+ // Now repeat the test but request some options.
+ EXPECT_NO_THROW(
+ offer = srv->processDiscover(pkt);
+ );
+
+ // Should return something
+ ASSERT_TRUE(offer);
+
+ EXPECT_EQ(DHCPOFFER, offer->getType());
+
+ // This is relayed message. It should be sent back to relay address.
+ EXPECT_EQ(pkt->getGiaddr(), offer->getRemoteAddr());
+
+ messageCheck(pkt, offer);
+
+ // Check that the requested options are returned.
+ optionsCheck(offer);
+
// Now repeat the test for directly sent message
pkt->setHops(0);
pkt->setGiaddr(IOAddress("0.0.0.0"));
messageCheck(pkt, offer);
- // Check that the requested and configured options are returned
- // in the OFFER message.
- EXPECT_TRUE(offer->getOption(DHO_LOG_SERVERS));
- EXPECT_TRUE(offer->getOption(DHO_COOKIE_SERVERS));
- // Check that the requested but not configured options are not
- // returned in the OFFER message.
- EXPECT_FALSE(offer->getOption(DHO_LPR_SERVERS));
+ // Check that the requested options are returned.
+ optionsCheck(offer);
delete srv;
}
req->setRemoteAddr(IOAddress("192.0.2.56"));
req->setGiaddr(IOAddress("192.0.2.67"));
+ // We are going to test that certain options are returned
+ // in the ACK message when requested using 'Parameter
+ // Request List' option. Let's configure those options that
+ // are returned when requested.
+ configureRequestedOptions();
+
// Should not throw
ASSERT_NO_THROW(
ack = srv->processRequest(req);
messageCheck(req, ack);
+ // We did not request any options so they should not be present
+ // in the ACK.
+ EXPECT_FALSE(ack->getOption(DHO_DOMAIN_NAME));
+ EXPECT_FALSE(ack->getOption(DHO_DOMAIN_NAME_SERVERS));
+ EXPECT_FALSE(ack->getOption(DHO_LOG_SERVERS));
+ EXPECT_FALSE(ack->getOption(DHO_COOKIE_SERVERS));
+ EXPECT_FALSE(ack->getOption(DHO_LPR_SERVERS));
+
+ // Add 'Parameter Request List' option.
+ addPrlOption(req);
+
+ // Repeat the test but request some options.
+ ASSERT_NO_THROW(
+ ack = srv->processRequest(req);
+ );
+
+ // Should return something
+ ASSERT_TRUE(ack);
+
+ EXPECT_EQ(DHCPACK, ack->getType());
+
+ // This is relayed message. It should be sent back to relay address.
+ EXPECT_EQ(req->getGiaddr(), ack->getRemoteAddr());
+
+ // Check that the requested options are returned.
+ optionsCheck(ack);
+
// Now repeat the test for directly sent message
req->setHops(0);
req->setGiaddr(IOAddress("0.0.0.0"));
messageCheck(req, ack);
+ // Check that the requested options are returned.
+ optionsCheck(ack);
+
delete srv;
}