|
@@ -1,4 +1,4 @@
|
|
|
-// 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);
|
|
|
|