Commit a0ac798d authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[2591] Append requested options to the OFFER message.

parent 2443a6fc
// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
......@@ -17,6 +17,7 @@
#include <dhcp/iface_mgr.h>
#include <dhcp/option4_addrlst.h>
#include <dhcp/option_int.h>
#include <dhcp/option_int_array.h>
#include <dhcp/pkt4.h>
#include <dhcp/duid.h>
#include <dhcp/hwaddr.h>
......@@ -233,18 +234,41 @@ void Dhcpv4Srv::appendDefaultOptions(Pkt4Ptr& msg, uint8_t msg_type) {
}
void Dhcpv4Srv::appendRequestedOptions(Pkt4Ptr& msg) {
OptionPtr opt;
void Dhcpv4Srv::appendRequestedOptions(const Pkt4Ptr& question, Pkt4Ptr& msg) {
// Get the subnet relevant for the client. We will need it
// to get the options associated with it.
Subnet4Ptr subnet = selectSubnet(question);
// If we can't find the subnet for the client there is no way
// to get the options to be sent to a client. We don't log an
// error because it will be logged by the assignLease method
// anyway.
if (!subnet) {
return;
}
// Domain name (type 15)
vector<uint8_t> domain(HARDCODED_DOMAIN_NAME.begin(), HARDCODED_DOMAIN_NAME.end());
opt = OptionPtr(new Option(Option::V4, DHO_DOMAIN_NAME, domain));
msg->addOption(opt);
// TODO: Add Option_String class
// try to get the 'Parameter Request List' option which holds the
// codes of requested options.
OptionUint8ArrayPtr option_prl = boost::dynamic_pointer_cast<
OptionUint8Array>(question->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;
}
// DNS servers (type 6)
opt = OptionPtr(new Option4AddrLst(DHO_DOMAIN_NAME_SERVERS, IOAddress(HARDCODED_DNS_SERVER)));
msg->addOption(opt);
// Get the codes of requested options.
const std::vector<uint8_t>& requested_opts = option_prl->getValues();
// For each requested option code get the instance of the option
// to be returned to the client.
for (std::vector<uint8_t>::const_iterator opt = requested_opts.begin();
opt != requested_opts.end(); ++opt) {
Subnet::OptionDescriptor desc =
subnet->getOptionDescriptor("dhcp4", *opt);
if (desc.option) {
msg->addOption(desc.option);
}
}
}
void Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
......@@ -358,7 +382,7 @@ Pkt4Ptr Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
copyDefaultFields(discover, offer);
appendDefaultOptions(offer, DHCPOFFER);
appendRequestedOptions(offer);
appendRequestedOptions(discover, offer);
assignLease(discover, offer);
......@@ -371,7 +395,7 @@ Pkt4Ptr Dhcpv4Srv::processRequest(Pkt4Ptr& request) {
copyDefaultFields(request, ack);
appendDefaultOptions(ack, DHCPACK);
appendRequestedOptions(ack);
appendRequestedOptions(request, ack);
assignLease(request, ack);
......
// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
......@@ -173,8 +173,9 @@ protected:
/// This method assigns options that were requested by client
/// (sent in PRL) or are enforced by server.
///
/// @param question DISCOVER or REQUEST message from a client.
/// @param msg outgoing message (options will be added here)
void appendRequestedOptions(Pkt4Ptr& msg);
void appendRequestedOptions(const Pkt4Ptr& question, Pkt4Ptr& msg);
/// @brief Assigns a lease and appends corresponding options
///
......
......@@ -19,6 +19,7 @@
#include <dhcp/dhcp4.h>
#include <dhcp/option.h>
#include <dhcp/option4_addrlst.h>
#include <dhcp/option_custom.h>
#include <dhcp/option_int_array.h>
#include <dhcp4/dhcp4_srv.h>
#include <dhcp4/dhcp4_log.h>
......@@ -318,8 +319,21 @@ TEST_F(Dhcpv4SrvTest, processDiscover) {
// 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"));
......@@ -332,6 +346,8 @@ TEST_F(Dhcpv4SrvTest, processDiscover) {
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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment