udhcpc: ignore zero-length DHCP options
Discovered that the DHCP server on a TrendNet router (unknown model) provides a zero-length option 12 (Host Name) in the DHCP ACK message. This has the effect of causing udhcpc to drop the rest of the options, including option 51 (IP Address Lease Time), 3 (Router), and 6 (Domain Name Server), most importantly leaving the OpenWrt device with no default gateway. The TrendNet behavior violates RFC 2132, which in Section 3.14 declares that option 12 has a minimum length of 1 octet. It is perhaps not a cosmic coincidence that I found this behavior on Pi Day. This patch allows zero length options without bailing out, by simply skipping them. function old new delta udhcp_scan_options 183 172 -11 Signed-off-by: Russell Senior <russell@personaltelco.net> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
f26e5634b1
commit
1c461df70a
@ -273,17 +273,27 @@ uint8_t* FAST_FUNC udhcp_scan_options(struct dhcp_packet *packet, struct dhcp_sc
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scan_state->rem <= OPT_LEN)
|
if (scan_state->rem <= OPT_LEN) /* [len] byte exists? */
|
||||||
goto complain; /* complain and return NULL */
|
goto complain; /* no, complain and return NULL */
|
||||||
len = 2 + scan_state->optionptr[OPT_LEN];
|
len = scan_state->optionptr[OPT_LEN];
|
||||||
|
/* Skip options with zero length.
|
||||||
|
* Users report that DHCP server on a TrendNet router (unknown model)
|
||||||
|
* provides a zero-length option 12 (Host Name)
|
||||||
|
* (this violates RFC 2132 section 3.14).
|
||||||
|
*/
|
||||||
|
if (len == 0) {
|
||||||
|
scan_state->rem -= OPT_LEN;
|
||||||
|
scan_state->optionptr += OPT_LEN;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
len += OPT_LEN;
|
||||||
scan_state->rem -= len;
|
scan_state->rem -= len;
|
||||||
/* So far no valid option with length 0 known. */
|
if (scan_state->rem < 0) /* option is longer than options field? */
|
||||||
if (scan_state->rem < 0 || scan_state->optionptr[OPT_LEN] == 0)
|
goto complain; /* yes, complain and return NULL */
|
||||||
goto complain; /* complain and return NULL */
|
|
||||||
|
|
||||||
if (scan_state->optionptr[OPT_CODE] == DHCP_OPTION_OVERLOAD) {
|
if (scan_state->optionptr[OPT_CODE] == DHCP_OPTION_OVERLOAD) {
|
||||||
if (len >= 3)
|
/* len is known to be >= 3 now, [data] byte exists */
|
||||||
scan_state->overload |= scan_state->optionptr[OPT_DATA];
|
scan_state->overload |= scan_state->optionptr[OPT_DATA];
|
||||||
} else {
|
} else {
|
||||||
uint8_t *return_ptr = scan_state->optionptr;
|
uint8_t *return_ptr = scan_state->optionptr;
|
||||||
scan_state->optionptr += len;
|
scan_state->optionptr += len;
|
||||||
|
Loading…
Reference in New Issue
Block a user