mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-29 13:28:14 +00:00
The DHCP server now responds to DHCPLEASEQUERY messages from agents using
IP addresses not covered by a subnet in configuration. Server also returns vendor-class-id option, if client sent it. [ISC-Bugs #21094]
This commit is contained in:
parent
023fbaa03e
commit
656b1ecebe
7
RELNOTES
7
RELNOTES
@ -99,6 +99,13 @@ work on other platforms. Please report any problems and suggested fixes to
|
|||||||
OMAPI as a domain name, the syntax written to disk is now correctly parsed
|
OMAPI as a domain name, the syntax written to disk is now correctly parsed
|
||||||
upon restart. [ISC-Bugs #22266]
|
upon restart. [ISC-Bugs #22266]
|
||||||
|
|
||||||
|
- The DHCP server now responds to DHCPLEASEQUERY messages from agents using
|
||||||
|
IP addresses not covered by a subnet in configuration. Whether or not to
|
||||||
|
respond to such an agent is still governed by the 'allow leasequery;'
|
||||||
|
configuration parameter, in the case of an agent not covered by a configured
|
||||||
|
subnet the root configuration area is examined. Server now also returns
|
||||||
|
vendor-class-id option, if client sent it. [ISC-Bugs #21094]
|
||||||
|
|
||||||
Changes since 4.2.0
|
Changes since 4.2.0
|
||||||
|
|
||||||
- Documentation cleanup covering multiple tickets
|
- Documentation cleanup covering multiple tickets
|
||||||
|
@ -2329,6 +2329,20 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
|
|||||||
option_chain_head_reference (< -> agent_options,
|
option_chain_head_reference (< -> agent_options,
|
||||||
lease -> agent_options, MDL);
|
lease -> agent_options, MDL);
|
||||||
|
|
||||||
|
/* Save the vendor-class-identifier for DHCPLEASEQUERY. */
|
||||||
|
oc = lookup_option(&dhcp_universe, packet->options,
|
||||||
|
DHO_VENDOR_CLASS_IDENTIFIER);
|
||||||
|
if (oc != NULL &&
|
||||||
|
evaluate_option_cache(&d1, packet, NULL, NULL, packet->options,
|
||||||
|
NULL, &lease->scope, oc, MDL)) {
|
||||||
|
if (d1.len != 0) {
|
||||||
|
bind_ds_value(&lease->scope, "vendor-class-identifier",
|
||||||
|
&d1);
|
||||||
|
}
|
||||||
|
|
||||||
|
data_string_forget(&d1, MDL);
|
||||||
|
}
|
||||||
|
|
||||||
/* If we got relay agent information options from the packet, then
|
/* If we got relay agent information options from the packet, then
|
||||||
* cache them for renewal in case the relay agent can't supply them
|
* cache them for renewal in case the relay agent can't supply them
|
||||||
* when the client unicasts. The options may be from an addressed
|
* when the client unicasts. The options may be from an addressed
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
.\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see
|
.\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see
|
||||||
.\" ``http://www.nominum.com''.
|
.\" ``http://www.nominum.com''.
|
||||||
.\"
|
.\"
|
||||||
.\" $Id: dhcpd.leases.5,v 1.15 2009/11/24 02:06:57 sar Exp $
|
.\" $Id: dhcpd.leases.5,v 1.16 2011/04/22 13:21:35 tomasz Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH dhcpd.leases 5
|
.TH dhcpd.leases 5
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@ -241,6 +241,11 @@ variable will record the name that the DHCP server used for the PTR
|
|||||||
record. The name to which the PTR record points will be either the
|
record. The name to which the PTR record points will be either the
|
||||||
\fIddns-fwd-name\fR or the \fIddns-client-fqdn\fR.
|
\fIddns-fwd-name\fR or the \fIddns-client-fqdn\fR.
|
||||||
.PP
|
.PP
|
||||||
|
.B The \fIvendor-class-identifier\fB variable
|
||||||
|
.PP
|
||||||
|
The server retains the client-supplied Vendor Class Identifier option
|
||||||
|
for informational purposes, and to render them in DHCPLEASEQUERY responses.
|
||||||
|
.PP
|
||||||
.B on \fIevents\fB { \fIstatements...\fB }
|
.B on \fIevents\fB { \fIstatements...\fB }
|
||||||
The \fBon\fI statement records a list of statements to execute if a
|
The \fBon\fI statement records a list of statements to execute if a
|
||||||
certain event occurs. The possible events that can occur for an
|
certain event occurs. The possible events that can occur for an
|
||||||
|
@ -17,9 +17,6 @@
|
|||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: RFC4388 specifies that the server SHOULD store the
|
|
||||||
* vendor-class-id.
|
|
||||||
*
|
|
||||||
* TODO: RFC4388 specifies that the server SHOULD return the same
|
* TODO: RFC4388 specifies that the server SHOULD return the same
|
||||||
* options it would for a DHCREQUEST message, if no Parameter
|
* options it would for a DHCREQUEST message, if no Parameter
|
||||||
* Request List option (option 55) is passed. We do not do that.
|
* Request List option (option 55) is passed. We do not do that.
|
||||||
@ -145,6 +142,7 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
|
|||||||
unsigned char dhcpMsgType;
|
unsigned char dhcpMsgType;
|
||||||
const char *dhcp_msg_type_name;
|
const char *dhcp_msg_type_name;
|
||||||
struct subnet *subnet;
|
struct subnet *subnet;
|
||||||
|
struct group *relay_group;
|
||||||
struct option_state *options;
|
struct option_state *options;
|
||||||
struct option_cache *oc;
|
struct option_cache *oc;
|
||||||
int allow_leasequery;
|
int allow_leasequery;
|
||||||
@ -180,23 +178,26 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up our options, scope, and, um... stuff.
|
* Initially we use the 'giaddr' subnet options scope to determine if
|
||||||
* This is basically copied from dhcpinform() in dhcp.c.
|
* the giaddr-identified relay agent is permitted to perform a
|
||||||
|
* leasequery. The subnet is not required, and may be omitted, in
|
||||||
|
* which case we are essentially interrogating the root options class
|
||||||
|
* to find a globally permit.
|
||||||
*/
|
*/
|
||||||
gip.len = sizeof(packet->raw->giaddr);
|
gip.len = sizeof(packet->raw->giaddr);
|
||||||
memcpy(gip.iabuf, &packet->raw->giaddr, sizeof(packet->raw->giaddr));
|
memcpy(gip.iabuf, &packet->raw->giaddr, sizeof(packet->raw->giaddr));
|
||||||
|
|
||||||
subnet = NULL;
|
subnet = NULL;
|
||||||
find_subnet(&subnet, gip, MDL);
|
find_subnet(&subnet, gip, MDL);
|
||||||
if (subnet == NULL) {
|
if (subnet != NULL)
|
||||||
log_info("%s: unknown subnet for address %s",
|
relay_group = subnet->group;
|
||||||
msgbuf, piaddr(gip));
|
else
|
||||||
return;
|
relay_group = root_group;
|
||||||
}
|
|
||||||
|
subnet_dereference(&subnet, MDL);
|
||||||
|
|
||||||
options = NULL;
|
options = NULL;
|
||||||
if (!option_state_allocate(&options, MDL)) {
|
if (!option_state_allocate(&options, MDL)) {
|
||||||
subnet_dereference(&subnet, MDL);
|
|
||||||
log_error("No memory for option state.");
|
log_error("No memory for option state.");
|
||||||
log_info("%s: out of memory, no reply sent", msgbuf);
|
log_info("%s: out of memory, no reply sent", msgbuf);
|
||||||
return;
|
return;
|
||||||
@ -209,8 +210,9 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
|
|||||||
packet->options,
|
packet->options,
|
||||||
options,
|
options,
|
||||||
&global_scope,
|
&global_scope,
|
||||||
subnet->group,
|
relay_group,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
for (i=packet->class_count-1; i>=0; i--) {
|
for (i=packet->class_count-1; i>=0; i--) {
|
||||||
execute_statements_in_scope(NULL,
|
execute_statements_in_scope(NULL,
|
||||||
packet,
|
packet,
|
||||||
@ -220,11 +222,9 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
|
|||||||
options,
|
options,
|
||||||
&global_scope,
|
&global_scope,
|
||||||
packet->classes[i]->group,
|
packet->classes[i]->group,
|
||||||
subnet->group);
|
relay_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
subnet_dereference(&subnet, MDL);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Because LEASEQUERY has some privacy concerns, default to deny.
|
* Because LEASEQUERY has some privacy concerns, default to deny.
|
||||||
*/
|
*/
|
||||||
@ -385,6 +385,30 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
|
|||||||
|
|
||||||
if (dhcpMsgType == DHCPLEASEACTIVE)
|
if (dhcpMsgType == DHCPLEASEACTIVE)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* RFC 4388 uses the PRL to request options for the agent to
|
||||||
|
* receive that are "about" the client. It is confusing
|
||||||
|
* because in some cases it wants to know what was sent to
|
||||||
|
* the client (lease times, adjusted), and in others it wants
|
||||||
|
* to know information the client sent. You're supposed to
|
||||||
|
* know this on a case-by-case basis.
|
||||||
|
*
|
||||||
|
* "Name servers", "domain name", and the like from the relay
|
||||||
|
* agent's scope seems less than useful. Our options are to
|
||||||
|
* restart the option cache from the lease's best point of view
|
||||||
|
* (execute statements from the lease pool's group), or to
|
||||||
|
* simply restart the option cache from empty.
|
||||||
|
*
|
||||||
|
* I think restarting the option cache from empty best
|
||||||
|
* approaches RFC 4388's intent; specific options are included.
|
||||||
|
*/
|
||||||
|
option_state_dereference(&options, MDL);
|
||||||
|
|
||||||
|
if (!option_state_allocate(&options, MDL)) {
|
||||||
|
log_error("%s: out of memory, no reply sent", msgbuf);
|
||||||
|
lease_dereference(&lease, MDL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the hardware address fields.
|
* Set the hardware address fields.
|
||||||
@ -430,7 +454,11 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
|
|||||||
(lease_duration / 8);
|
(lease_duration / 8);
|
||||||
|
|
||||||
if (time_renewal > cur_time) {
|
if (time_renewal > cur_time) {
|
||||||
|
if (time_renewal < cur_time)
|
||||||
|
time_renewal = 0;
|
||||||
|
else
|
||||||
time_renewal = htonl(time_renewal - cur_time);
|
time_renewal = htonl(time_renewal - cur_time);
|
||||||
|
|
||||||
if (!add_option(options,
|
if (!add_option(options,
|
||||||
DHO_DHCP_RENEWAL_TIME,
|
DHO_DHCP_RENEWAL_TIME,
|
||||||
&time_renewal,
|
&time_renewal,
|
||||||
@ -445,6 +473,7 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
|
|||||||
|
|
||||||
if (time_rebinding > cur_time) {
|
if (time_rebinding > cur_time) {
|
||||||
time_rebinding = htonl(time_rebinding - cur_time);
|
time_rebinding = htonl(time_rebinding - cur_time);
|
||||||
|
|
||||||
if (!add_option(options,
|
if (!add_option(options,
|
||||||
DHO_DHCP_REBINDING_TIME,
|
DHO_DHCP_REBINDING_TIME,
|
||||||
&time_rebinding,
|
&time_rebinding,
|
||||||
@ -458,6 +487,14 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lease->ends > cur_time) {
|
if (lease->ends > cur_time) {
|
||||||
|
if (time_expiry < cur_time) {
|
||||||
|
log_error("Impossible condition at %s:%d.",
|
||||||
|
MDL);
|
||||||
|
|
||||||
|
option_state_dereference(&options, MDL);
|
||||||
|
lease_dereference(&lease, MDL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
time_expiry = htonl(lease->ends - cur_time);
|
time_expiry = htonl(lease->ends - cur_time);
|
||||||
if (!add_option(options,
|
if (!add_option(options,
|
||||||
DHO_DHCP_LEASE_TIME,
|
DHO_DHCP_LEASE_TIME,
|
||||||
@ -471,9 +508,38 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Supply the Vendor-Class-Identifier. */
|
||||||
|
if (lease->scope != NULL) {
|
||||||
|
struct data_string vendor_class;
|
||||||
|
|
||||||
|
memset(&vendor_class, 0, sizeof(vendor_class));
|
||||||
|
|
||||||
|
if (find_bound_string(&vendor_class, lease->scope,
|
||||||
|
"vendor-class-identifier")) {
|
||||||
|
if (!add_option(options,
|
||||||
|
DHO_VENDOR_CLASS_IDENTIFIER,
|
||||||
|
(void *)vendor_class.data,
|
||||||
|
vendor_class.len)) {
|
||||||
|
option_state_dereference(&options,
|
||||||
|
MDL);
|
||||||
|
lease_dereference(&lease, MDL);
|
||||||
|
log_error("%s: error adding vendor "
|
||||||
|
"class identifier, no reply "
|
||||||
|
"sent", msgbuf);
|
||||||
|
data_string_forget(&vendor_class, MDL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data_string_forget(&vendor_class, MDL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the relay agent info.
|
* Set the relay agent info.
|
||||||
|
*
|
||||||
|
* Note that because agent info is appended without regard
|
||||||
|
* to the PRL in cons_options(), this will be sent as the
|
||||||
|
* last option in the packet whether it is listed on PRL or
|
||||||
|
* not.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (lease->agent_options != NULL) {
|
if (lease->agent_options != NULL) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user