diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-25 03:15:24 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-25 03:15:24 +0000 |
| commit | 72e76044cfda377486a5199a0d35d71edf669a42 (patch) | |
| tree | 69e3f0f81955aae4e82d4073b8067b9bc3f9bd44 | |
| parent | a8875efa8506e52ffb24db833e32ab8cfb9bceef (diff) | |
| download | busybox-w32-72e76044cfda377486a5199a0d35d71edf669a42.tar.gz busybox-w32-72e76044cfda377486a5199a0d35d71edf669a42.tar.bz2 busybox-w32-72e76044cfda377486a5199a0d35d71edf669a42.zip | |
dhcpc: cope with buggy DHCP servers which send oversized packets
(Cristian Ionescu-Idbohrn <cristian.ionescu-idbohrn@axis.com>)
| -rw-r--r-- | networking/udhcp/Config.in | 22 | ||||
| -rw-r--r-- | networking/udhcp/common.h | 6 | ||||
| -rw-r--r-- | networking/udhcp/options.c | 2 |
3 files changed, 27 insertions, 3 deletions
diff --git a/networking/udhcp/Config.in b/networking/udhcp/Config.in index 734db65cc..1aef69ba7 100644 --- a/networking/udhcp/Config.in +++ b/networking/udhcp/Config.in | |||
| @@ -82,3 +82,25 @@ config FEATURE_RFC3397 | |||
| 82 | help | 82 | help |
| 83 | If selected, both client and server will support passing of domain | 83 | If selected, both client and server will support passing of domain |
| 84 | search lists via option 119, specified in RFC3397. | 84 | search lists via option 119, specified in RFC3397. |
| 85 | |||
| 86 | config UDHCPC_SLACK_FOR_BUGGY_SERVERS | ||
| 87 | int "DHCP options slack buffer size" | ||
| 88 | default 80 | ||
| 89 | range 0 924 | ||
| 90 | depends on APP_UDHCPD || APP_UDHCPC | ||
| 91 | help | ||
| 92 | Some buggy DHCP servers will send DHCP offer packets with option | ||
| 93 | field larger than we expect (which might also be considered a | ||
| 94 | buffer overflow attempt). These packets are normally discarded. | ||
| 95 | If circumstances beyond your control force you to support such | ||
| 96 | servers, this may help. The upper limit (924) makes dhcpc accept | ||
| 97 | even 1500 byte packets (maximum-sized ethernet packets). | ||
| 98 | |||
| 99 | This options does not make dhcp[cd] emit non-standard | ||
| 100 | sized packets. | ||
| 101 | |||
| 102 | Known buggy DHCP servers: | ||
| 103 | 3Com OfficeConnect Remote 812 ADSL Router: | ||
| 104 | seems to confuse maximum allowed UDP packet size with | ||
| 105 | maximum size of entire IP packet, and sends packets which are | ||
| 106 | 28 bytes too large. | ||
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index 4f2d31c98..eecb72ca2 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
| @@ -21,6 +21,8 @@ extern const uint8_t MAC_BCAST_ADDR[6]; /* six all-ones */ | |||
| 21 | #include <netinet/udp.h> | 21 | #include <netinet/udp.h> |
| 22 | #include <netinet/ip.h> | 22 | #include <netinet/ip.h> |
| 23 | 23 | ||
| 24 | #define DHCP_OPTIONS_BUFSIZE 308 | ||
| 25 | |||
| 24 | struct dhcpMessage { | 26 | struct dhcpMessage { |
| 25 | uint8_t op; | 27 | uint8_t op; |
| 26 | uint8_t htype; | 28 | uint8_t htype; |
| @@ -37,7 +39,7 @@ struct dhcpMessage { | |||
| 37 | uint8_t sname[64]; | 39 | uint8_t sname[64]; |
| 38 | uint8_t file[128]; | 40 | uint8_t file[128]; |
| 39 | uint32_t cookie; | 41 | uint32_t cookie; |
| 40 | uint8_t options[308]; /* 312 - cookie */ | 42 | uint8_t options[DHCP_OPTIONS_BUFSIZE + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS]; |
| 41 | } ATTRIBUTE_PACKED; | 43 | } ATTRIBUTE_PACKED; |
| 42 | 44 | ||
| 43 | struct udp_dhcp_packet { | 45 | struct udp_dhcp_packet { |
| @@ -49,7 +51,7 @@ struct udp_dhcp_packet { | |||
| 49 | /* Let's see whether compiler understood us right */ | 51 | /* Let's see whether compiler understood us right */ |
| 50 | struct BUG_bad_sizeof_struct_udp_dhcp_packet { | 52 | struct BUG_bad_sizeof_struct_udp_dhcp_packet { |
| 51 | char BUG_bad_sizeof_struct_udp_dhcp_packet | 53 | char BUG_bad_sizeof_struct_udp_dhcp_packet |
| 52 | [sizeof(struct udp_dhcp_packet) != 576 ? -1 : 1]; | 54 | [(sizeof(struct udp_dhcp_packet) != 576 + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS) ? -1 : 1]; |
| 53 | }; | 55 | }; |
| 54 | 56 | ||
| 55 | void udhcp_init_header(struct dhcpMessage *packet, char type); | 57 | void udhcp_init_header(struct dhcpMessage *packet, char type); |
diff --git a/networking/udhcp/options.c b/networking/udhcp/options.c index 2b4f1644f..6744e2ad0 100644 --- a/networking/udhcp/options.c +++ b/networking/udhcp/options.c | |||
| @@ -145,7 +145,7 @@ int add_option_string(uint8_t *optionptr, uint8_t *string) | |||
| 145 | int end = end_option(optionptr); | 145 | int end = end_option(optionptr); |
| 146 | 146 | ||
| 147 | /* end position + string length + option code/length + end option */ | 147 | /* end position + string length + option code/length + end option */ |
| 148 | if (end + string[OPT_LEN] + 2 + 1 >= 308) { | 148 | if (end + string[OPT_LEN] + 2 + 1 >= DHCP_OPTIONS_BUFSIZE) { |
| 149 | bb_error_msg("option 0x%02x did not fit into the packet", | 149 | bb_error_msg("option 0x%02x did not fit into the packet", |
| 150 | string[OPT_CODE]); | 150 | string[OPT_CODE]); |
| 151 | return 0; | 151 | return 0; |
