diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-28 19:23:12 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-28 19:23:12 +0000 |
commit | 35ff74676b54b1cae5a6324d2517568393fedbc8 (patch) | |
tree | b913eda3005954aec3543cc07d3f86baeeb6429a | |
parent | 41f5add965163607b5921aa224b9ba6fa3debc05 (diff) | |
download | busybox-w32-35ff74676b54b1cae5a6324d2517568393fedbc8.tar.gz busybox-w32-35ff74676b54b1cae5a6324d2517568393fedbc8.tar.bz2 busybox-w32-35ff74676b54b1cae5a6324d2517568393fedbc8.zip |
dhcpc: let server know we don't like oversized packets.
add TODO comment
-rw-r--r-- | networking/udhcp/Config.in | 1 | ||||
-rw-r--r-- | networking/udhcp/clientpacket.c | 3 | ||||
-rw-r--r-- | networking/udhcp/files.c | 6 | ||||
-rw-r--r-- | networking/udhcp/options.c | 68 | ||||
-rw-r--r-- | networking/udhcp/options.h | 4 | ||||
-rw-r--r-- | networking/udhcp/script.c | 23 |
6 files changed, 58 insertions, 47 deletions
diff --git a/networking/udhcp/Config.in b/networking/udhcp/Config.in index 1aef69ba7..242a9f3b8 100644 --- a/networking/udhcp/Config.in +++ b/networking/udhcp/Config.in | |||
@@ -104,3 +104,4 @@ config UDHCPC_SLACK_FOR_BUGGY_SERVERS | |||
104 | seems to confuse maximum allowed UDP packet size with | 104 | seems to confuse maximum allowed UDP packet size with |
105 | maximum size of entire IP packet, and sends packets which are | 105 | maximum size of entire IP packet, and sends packets which are |
106 | 28 bytes too large. | 106 | 28 bytes too large. |
107 | Seednet (ISP) VDSL: sends packets 2 bytes too big. | ||
diff --git a/networking/udhcp/clientpacket.c b/networking/udhcp/clientpacket.c index 4a5c627f4..406fe340a 100644 --- a/networking/udhcp/clientpacket.c +++ b/networking/udhcp/clientpacket.c | |||
@@ -96,6 +96,9 @@ int send_discover(uint32_t xid, uint32_t requested) | |||
96 | if (requested) | 96 | if (requested) |
97 | add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); | 97 | add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); |
98 | 98 | ||
99 | /* Explicitly saying that we want RFC-compliant packets helps | ||
100 | * some buggy DHCP servers to NOT send bigger packets */ | ||
101 | add_simple_option(packet.options, DHCP_MAX_SIZE, htons(576)); | ||
99 | add_requests(&packet); | 102 | add_requests(&packet); |
100 | bb_info_msg("Sending discover..."); | 103 | bb_info_msg("Sending discover..."); |
101 | return udhcp_raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, | 104 | return udhcp_raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, |
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c index 59a5e4ab2..5026598d7 100644 --- a/networking/udhcp/files.c +++ b/networking/udhcp/files.c | |||
@@ -90,7 +90,7 @@ static void attach_option(struct option_set **opt_list, | |||
90 | 90 | ||
91 | existing = find_option(*opt_list, option->code); | 91 | existing = find_option(*opt_list, option->code); |
92 | if (!existing) { | 92 | if (!existing) { |
93 | DEBUG("Attaching option %s to list", option->name); | 93 | DEBUG("Attaching option %02x to list", option->code); |
94 | 94 | ||
95 | #if ENABLE_FEATURE_RFC3397 | 95 | #if ENABLE_FEATURE_RFC3397 |
96 | if ((option->flags & TYPE_MASK) == OPTION_STR1035) | 96 | if ((option->flags & TYPE_MASK) == OPTION_STR1035) |
@@ -119,7 +119,7 @@ static void attach_option(struct option_set **opt_list, | |||
119 | } | 119 | } |
120 | 120 | ||
121 | /* add it to an existing option */ | 121 | /* add it to an existing option */ |
122 | DEBUG("Attaching option %s to existing member of list", option->name); | 122 | DEBUG("Attaching option %02x to existing member of list", option->code); |
123 | if (option->flags & OPTION_LIST) { | 123 | if (option->flags & OPTION_LIST) { |
124 | #if ENABLE_FEATURE_RFC3397 | 124 | #if ENABLE_FEATURE_RFC3397 |
125 | if ((option->flags & TYPE_MASK) == OPTION_STR1035) | 125 | if ((option->flags & TYPE_MASK) == OPTION_STR1035) |
@@ -170,7 +170,7 @@ static int read_opt(const char *const_line, void *arg) | |||
170 | while (1) { | 170 | while (1) { |
171 | if (!option->code) | 171 | if (!option->code) |
172 | return 0; | 172 | return 0; |
173 | if (!strcasecmp(option->name, opt)) | 173 | if (!strcasecmp(option->opt_name, opt)) |
174 | break; | 174 | break; |
175 | option++; | 175 | option++; |
176 | } | 176 | } |
diff --git a/networking/udhcp/options.c b/networking/udhcp/options.c index 6744e2ad0..ffc0ed127 100644 --- a/networking/udhcp/options.c +++ b/networking/udhcp/options.c | |||
@@ -9,37 +9,42 @@ | |||
9 | #include "options.h" | 9 | #include "options.h" |
10 | 10 | ||
11 | 11 | ||
12 | /* supported options are easily added here */ | 12 | /* Supported options are easily added here */ |
13 | const struct dhcp_option dhcp_options[] = { | 13 | const struct dhcp_option dhcp_options[] = { |
14 | /* name[12] flags code */ | 14 | /* opt_name[12] flags code */ |
15 | {"subnet", OPTION_IP | OPTION_REQ, 0x01}, | 15 | {"subnet", OPTION_IP | OPTION_REQ, 0x01}, /* DHCP_SUBNET */ |
16 | {"timezone", OPTION_S32, 0x02}, | 16 | {"timezone", OPTION_S32, 0x02}, /* DHCP_TIME_OFFSET */ |
17 | {"router", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x03}, | 17 | {"router", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x03}, /* DHCP_ROUTER */ |
18 | {"timesvr", OPTION_IP | OPTION_LIST, 0x04}, | 18 | {"timesvr", OPTION_IP | OPTION_LIST, 0x04}, /* DHCP_TIME_SERVER */ |
19 | {"namesvr", OPTION_IP | OPTION_LIST, 0x05}, | 19 | {"namesvr", OPTION_IP | OPTION_LIST, 0x05}, /* DHCP_NAME_SERVER */ |
20 | {"dns", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x06}, | 20 | {"dns", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x06}, /* DHCP_DNS_SERVER */ |
21 | {"logsvr", OPTION_IP | OPTION_LIST, 0x07}, | 21 | {"logsvr", OPTION_IP | OPTION_LIST, 0x07}, /* DHCP_LOG_SERVER */ |
22 | {"cookiesvr", OPTION_IP | OPTION_LIST, 0x08}, | 22 | {"cookiesvr", OPTION_IP | OPTION_LIST, 0x08}, /* DHCP_COOKIE_SERVER */ |
23 | {"lprsvr", OPTION_IP | OPTION_LIST, 0x09}, | 23 | {"lprsvr", OPTION_IP | OPTION_LIST, 0x09}, /* DHCP_LPR_SERVER */ |
24 | {"hostname", OPTION_STRING | OPTION_REQ, 0x0c}, | 24 | {"hostname", OPTION_STRING | OPTION_REQ, 0x0c}, /* DHCP_HOST_NAME */ |
25 | {"bootsize", OPTION_U16, 0x0d}, | 25 | {"bootsize", OPTION_U16, 0x0d}, /* DHCP_BOOT_SIZE */ |
26 | {"domain", OPTION_STRING | OPTION_LIST | OPTION_REQ, 0x0f}, | 26 | {"domain", OPTION_STRING | OPTION_LIST | OPTION_REQ, 0x0f}, /* DHCP_DOMAIN_NAME */ |
27 | {"swapsvr", OPTION_IP, 0x10}, | 27 | {"swapsvr", OPTION_IP, 0x10}, /* DHCP_SWAP_SERVER */ |
28 | {"rootpath", OPTION_STRING, 0x11}, | 28 | {"rootpath", OPTION_STRING, 0x11}, /* DHCP_ROOT_PATH */ |
29 | {"ipttl", OPTION_U8, 0x17}, | 29 | {"ipttl", OPTION_U8, 0x17}, /* DHCP_IP_TTL */ |
30 | {"mtu", OPTION_U16, 0x1a}, | 30 | {"mtu", OPTION_U16, 0x1a}, /* DHCP_MTU */ |
31 | {"broadcast", OPTION_IP | OPTION_REQ, 0x1c}, | 31 | {"broadcast", OPTION_IP | OPTION_REQ, 0x1c}, /* DHCP_BROADCAST */ |
32 | {"nisdomain", OPTION_STRING | OPTION_REQ, 0x28}, | 32 | {"nisdomain", OPTION_STRING | OPTION_REQ, 0x28}, /* DHCP_NTP_SERVER */ |
33 | {"nissrv", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x29}, | 33 | {"nissrv", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x29}, /* DHCP_WINS_SERVER */ |
34 | {"ntpsrv", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x2a}, | 34 | {"ntpsrv", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x2a}, /* DHCP_REQUESTED_IP */ |
35 | {"wins", OPTION_IP | OPTION_LIST, 0x2c}, | 35 | {"wins", OPTION_IP | OPTION_LIST, 0x2c}, /* DHCP_LEASE_TIME */ |
36 | {"requestip", OPTION_IP, 0x32}, | 36 | {"requestip", OPTION_IP, 0x32}, /* DHCP_OPTION_OVER */ |
37 | {"lease", OPTION_U32, 0x33}, | 37 | {"lease", OPTION_U32, 0x33}, /* DHCP_MESSAGE_TYPE */ |
38 | {"dhcptype", OPTION_U8, 0x35}, | 38 | {"dhcptype", OPTION_U8, 0x35}, /* DHCP_SERVER_ID */ |
39 | {"serverid", OPTION_IP, 0x36}, | 39 | {"serverid", OPTION_IP, 0x36}, /* DHCP_PARAM_REQ */ |
40 | {"message", OPTION_STRING, 0x38}, | 40 | {"message", OPTION_STRING, 0x38}, /* DHCP_MESSAGE */ |
41 | {"vendorclass", OPTION_STRING, 0x3C}, | 41 | // TODO: 1) some options should not be parsed & passed to script - |
42 | {"clientid", OPTION_STRING, 0x3D}, | 42 | // maxsize sure should not, since it cannot appear in server responses! |
43 | // grep for opt_name is fix the mess. | ||
44 | // 2) Using fixed-sized char[] vector wastes space. | ||
45 | {"maxsize", OPTION_U16, 0x39}, /* DHCP_MAX_SIZE */ | ||
46 | {"vendorclass", OPTION_STRING, 0x3C}, /* DHCP_VENDOR */ | ||
47 | {"clientid", OPTION_STRING, 0x3D}, /* DHCP_CLIENT_ID */ | ||
43 | {"tftp", OPTION_STRING, 0x42}, | 48 | {"tftp", OPTION_STRING, 0x42}, |
44 | {"bootfile", OPTION_STRING, 0x43}, | 49 | {"bootfile", OPTION_STRING, 0x43}, |
45 | {"userclass", OPTION_STRING, 0x4D}, | 50 | {"userclass", OPTION_STRING, 0x4D}, |
@@ -48,9 +53,10 @@ const struct dhcp_option dhcp_options[] = { | |||
48 | #endif | 53 | #endif |
49 | /* MSIE's "Web Proxy Autodiscovery Protocol" support */ | 54 | /* MSIE's "Web Proxy Autodiscovery Protocol" support */ |
50 | {"wpad", OPTION_STRING, 0xfc}, | 55 | {"wpad", OPTION_STRING, 0xfc}, |
51 | {"", 0x00, 0x00} | 56 | {} /* zero-padded terminating entry */ |
52 | }; | 57 | }; |
53 | 58 | ||
59 | |||
54 | /* Lengths of the different option types */ | 60 | /* Lengths of the different option types */ |
55 | const unsigned char option_lengths[] ALIGN1 = { | 61 | const unsigned char option_lengths[] ALIGN1 = { |
56 | [OPTION_IP] = 4, | 62 | [OPTION_IP] = 4, |
diff --git a/networking/udhcp/options.h b/networking/udhcp/options.h index 33a968ce9..4bf73a17e 100644 --- a/networking/udhcp/options.h +++ b/networking/udhcp/options.h | |||
@@ -33,6 +33,7 @@ enum { | |||
33 | 33 | ||
34 | #define DHCP_MAGIC 0x63825363 | 34 | #define DHCP_MAGIC 0x63825363 |
35 | 35 | ||
36 | |||
36 | /* DHCP option codes (partial list) */ | 37 | /* DHCP option codes (partial list) */ |
37 | #define DHCP_PADDING 0x00 | 38 | #define DHCP_PADDING 0x00 |
38 | #define DHCP_SUBNET 0x01 | 39 | #define DHCP_SUBNET 0x01 |
@@ -67,7 +68,6 @@ enum { | |||
67 | #define DHCP_VENDOR 0x3c | 68 | #define DHCP_VENDOR 0x3c |
68 | #define DHCP_CLIENT_ID 0x3d | 69 | #define DHCP_CLIENT_ID 0x3d |
69 | #define DHCP_FQDN 0x51 | 70 | #define DHCP_FQDN 0x51 |
70 | |||
71 | #define DHCP_END 0xFF | 71 | #define DHCP_END 0xFF |
72 | 72 | ||
73 | 73 | ||
@@ -98,7 +98,7 @@ enum { | |||
98 | #define OPT_DATA 2 | 98 | #define OPT_DATA 2 |
99 | 99 | ||
100 | struct dhcp_option { | 100 | struct dhcp_option { |
101 | char name[12]; | 101 | char opt_name[12]; |
102 | char flags; | 102 | char flags; |
103 | uint8_t code; | 103 | uint8_t code; |
104 | }; | 104 | }; |
diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c index 68de358e5..33d96e687 100644 --- a/networking/udhcp/script.c +++ b/networking/udhcp/script.c | |||
@@ -44,14 +44,15 @@ static int sprintip(char *dest, const char *pre, const uint8_t *ip) | |||
44 | 44 | ||
45 | 45 | ||
46 | /* really simple implementation, just count the bits */ | 46 | /* really simple implementation, just count the bits */ |
47 | static int mton(struct in_addr *mask) | 47 | static int mton(uint32_t mask) |
48 | { | 48 | { |
49 | int i; | 49 | int i = 0; |
50 | unsigned long bits = ntohl(mask->s_addr); | 50 | mask = ntohl(mask); /* 111110000-like bit pattern */ |
51 | /* too bad one can't check the carry bit, etc in c bit | 51 | while (mask) { |
52 | * shifting */ | 52 | i++; |
53 | for (i = 0; i < 32 && !((bits >> i) & 1); i++); | 53 | mask <<= 1; |
54 | return 32 - i; | 54 | } |
55 | return i; | ||
55 | } | 56 | } |
56 | 57 | ||
57 | 58 | ||
@@ -69,8 +70,8 @@ static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p) | |||
69 | type = type_p->flags & TYPE_MASK; | 70 | type = type_p->flags & TYPE_MASK; |
70 | optlen = option_lengths[type]; | 71 | optlen = option_lengths[type]; |
71 | 72 | ||
72 | dest = ret = xmalloc(upper_length(len, type) + strlen(type_p->name) + 2); | 73 | dest = ret = xmalloc(upper_length(len, type) + strlen(type_p->opt_name) + 2); |
73 | dest += sprintf(ret, "%s=", type_p->name); | 74 | dest += sprintf(ret, "%s=", type_p->opt_name); |
74 | 75 | ||
75 | for (;;) { | 76 | for (;;) { |
76 | switch (type) { | 77 | switch (type) { |
@@ -133,7 +134,6 @@ static char **fill_envp(struct dhcpMessage *packet) | |||
133 | char **envp; | 134 | char **envp; |
134 | char *var; | 135 | char *var; |
135 | uint8_t *temp; | 136 | uint8_t *temp; |
136 | struct in_addr subnet; | ||
137 | char over = 0; | 137 | char over = 0; |
138 | 138 | ||
139 | if (packet) { | 139 | if (packet) { |
@@ -179,8 +179,9 @@ static char **fill_envp(struct dhcpMessage *packet) | |||
179 | 179 | ||
180 | /* Fill in a subnet bits option for things like /24 */ | 180 | /* Fill in a subnet bits option for things like /24 */ |
181 | if (dhcp_options[i].code == DHCP_SUBNET) { | 181 | if (dhcp_options[i].code == DHCP_SUBNET) { |
182 | uint32_t subnet; | ||
182 | memcpy(&subnet, temp, 4); | 183 | memcpy(&subnet, temp, 4); |
183 | envp[j++] = xasprintf("mask=%d", mton(&subnet)); | 184 | envp[j++] = xasprintf("mask=%d", mton(subnet)); |
184 | } | 185 | } |
185 | } | 186 | } |
186 | if (packet->siaddr) { | 187 | if (packet->siaddr) { |