Hi,
If the dhclient receives an OFFER or ACK, that does not contain all required
parameters, a DECLINE is send. This DECLINE has the 'Requested IP Address'
(DHO_DHCP_REQUESTET_ADDRESS) set to 0 instead of using the client IP address
(yiaddr) from the packet. As far as I see it, the 'Requested IP Address' is the
address the dhclient is declining, so the yiaddr would make more sense than 0.
This happens in dhclient.c::packet_to_lease() and only if not all required
parameters are in the packet. For all other cases the 'Requested IP Address' of
the DECLINE is set to the yiaddr from the OFFER / ACK packet. My fix would be
to store (and check) the yiaddr from the packet before the first jump to the
decline label occurs. I have included a diff below.
Best Regards,
Dominik
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c
index 007358c5008..b287c19a3b2 100644
--- a/sbin/dhclient/dhclient.c
+++ b/sbin/dhclient/dhclient.c
@@ -1257,18 +1257,6 @@ packet_to_lease(struct interface_info *ifi, struct
option_data *options)
options[i].len = 0;
}
- /*
- * If this lease doesn't supply a required parameter, decline it.
- */
- for (i = 0; i < config->required_option_count; i++) {
- if (lease->options[config->required_options[i]].len == 0) {
- name = code_to_name(config->required_options[i]);
- log_warnx("%s: %s required but missing", log_procname,
- name);
- goto decline;
- }
- }
-
/*
* If this lease is trying to sell us an address we are already
* using, decline it.
@@ -1282,6 +1270,18 @@ packet_to_lease(struct interface_info *ifi, struct
option_data *options)
goto decline;
}
+ /*
+ * If this lease doesn't supply a required parameter, decline it.
+ */
+ for (i = 0; i < config->required_option_count; i++) {
+ if (lease->options[config->required_options[i]].len == 0) {
+ name = code_to_name(config->required_options[i]);
+ log_warnx("%s: %s required but missing", log_procname,
+ name);
+ goto decline;
+ }
+ }
+
/* Save the siaddr (a.k.a. next-server) info. */
lease->next_server.s_addr = packet->siaddr.s_addr;