dhcpc: cope with buggy DHCP servers which send oversized packets
authorDenis Vlasenko <vda.linux@googlemail.com>
Sun, 25 Nov 2007 03:15:24 +0000 (03:15 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sun, 25 Nov 2007 03:15:24 +0000 (03:15 -0000)
(Cristian Ionescu-Idbohrn <cristian.ionescu-idbohrn@axis.com>)

networking/udhcp/Config.in
networking/udhcp/common.h
networking/udhcp/options.c

index 734db65ccff42356056cff7924e01ff539c82240..1aef69ba70f4a1d7aa3aabe3509a27405883442a 100644 (file)
@@ -82,3 +82,25 @@ config FEATURE_RFC3397
        help
          If selected, both client and server will support passing of domain
          search lists via option 119, specified in RFC3397.
+
+config UDHCPC_SLACK_FOR_BUGGY_SERVERS
+       int "DHCP options slack buffer size"
+       default 80
+       range 0 924
+       depends on APP_UDHCPD || APP_UDHCPC
+       help
+         Some buggy DHCP servers will send DHCP offer packets with option
+         field larger than we expect (which might also be considered a
+         buffer overflow attempt). These packets are normally discarded.
+         If circumstances beyond your control force you to support such
+         servers, this may help. The upper limit (924) makes dhcpc accept
+         even 1500 byte packets (maximum-sized ethernet packets).
+
+         This options does not make dhcp[cd] emit non-standard
+         sized packets.
+
+         Known buggy DHCP servers:
+         3Com OfficeConnect Remote 812 ADSL Router:
+           seems to confuse maximum allowed UDP packet size with
+           maximum size of entire IP packet, and sends packets which are
+           28 bytes too large.
index 4f2d31c980de0f5fc342e7d7472b6dd6e9118895..eecb72ca259c5a9267d160cbb084743602820b85 100644 (file)
@@ -21,6 +21,8 @@ extern const uint8_t MAC_BCAST_ADDR[6]; /* six all-ones */
 #include <netinet/udp.h>
 #include <netinet/ip.h>
 
+#define DHCP_OPTIONS_BUFSIZE 308
+
 struct dhcpMessage {
        uint8_t op;
        uint8_t htype;
@@ -37,7 +39,7 @@ struct dhcpMessage {
        uint8_t sname[64];
        uint8_t file[128];
        uint32_t cookie;
-       uint8_t options[308]; /* 312 - cookie */
+       uint8_t options[DHCP_OPTIONS_BUFSIZE + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS];
 } ATTRIBUTE_PACKED;
 
 struct udp_dhcp_packet {
@@ -49,7 +51,7 @@ struct udp_dhcp_packet {
 /* Let's see whether compiler understood us right */
 struct BUG_bad_sizeof_struct_udp_dhcp_packet {
        char BUG_bad_sizeof_struct_udp_dhcp_packet
-                [sizeof(struct udp_dhcp_packet) != 576 ? -1 : 1];
+               [(sizeof(struct udp_dhcp_packet) != 576 + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS) ? -1 : 1];
 };
 
 void udhcp_init_header(struct dhcpMessage *packet, char type);
index 2b4f1644f03f60ea63c61ca91e7c5b0f1d35fc6e..6744e2ad0e1924b0ded286455c29ea05af0b6a6b 100644 (file)
@@ -145,7 +145,7 @@ int add_option_string(uint8_t *optionptr, uint8_t *string)
        int end = end_option(optionptr);
 
        /* end position + string length + option code/length + end option */
-       if (end + string[OPT_LEN] + 2 + 1 >= 308) {
+       if (end + string[OPT_LEN] + 2 + 1 >= DHCP_OPTIONS_BUFSIZE) {
                bb_error_msg("option 0x%02x did not fit into the packet",
                                string[OPT_CODE]);
                return 0;