diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-26 09:32:09 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-26 09:32:09 +0100 |
commit | 7724c766bdfba5f3af5cdf5d869bcf03f45149e3 (patch) | |
tree | d1cb0db7b683bdc9c9ecb954cc83dea7d53ae440 | |
parent | a8f6b9998727ad67db4b812270a1bbceea011dde (diff) | |
download | busybox-w32-7724c766bdfba5f3af5cdf5d869bcf03f45149e3.tar.gz busybox-w32-7724c766bdfba5f3af5cdf5d869bcf03f45149e3.tar.bz2 busybox-w32-7724c766bdfba5f3af5cdf5d869bcf03f45149e3.zip |
udhcp: pass pointer to whole packet to "add option" functions
This is needed for "overflow option" support
function old new delta
udhcp_find_option - 34 +34
udhcp_add_binary_option 94 106 +12
write_leases 227 223 -4
udhcp_init_header 86 82 -4
send_release 104 99 -5
init_packet 87 81 -6
add_client_options 160 154 -6
add_server_options 100 92 -8
udhcpd_main 1964 1954 -10
udhcpc_main 2859 2837 -22
find_option 34 - -34
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 1/8 up/down: 46/-99) Total: -53 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/udhcp/common.c | 16 | ||||
-rw-r--r-- | networking/udhcp/common.h | 6 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 26 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.c | 10 | ||||
-rw-r--r-- | networking/udhcp/files.c | 9 | ||||
-rw-r--r-- | networking/udhcp/leases.c | 1 | ||||
-rw-r--r-- | networking/udhcp/packet.c | 2 | ||||
-rw-r--r-- | networking/udhcp/socket.c | 1 |
8 files changed, 37 insertions, 34 deletions
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index bc458ac7a..9316774ff 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -226,14 +226,16 @@ int FAST_FUNC udhcp_end_option(uint8_t *optionptr) | |||
226 | /* Add an option (supplied in binary form) to the options. | 226 | /* Add an option (supplied in binary form) to the options. |
227 | * Option format: [code][len][data1][data2]..[dataLEN] | 227 | * Option format: [code][len][data1][data2]..[dataLEN] |
228 | */ | 228 | */ |
229 | void FAST_FUNC udhcp_add_binary_option(uint8_t *optionptr, uint8_t *addopt) | 229 | void FAST_FUNC udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt) |
230 | { | 230 | { |
231 | unsigned len; | 231 | unsigned len; |
232 | uint8_t *optionptr = packet->options; | ||
232 | unsigned end = udhcp_end_option(optionptr); | 233 | unsigned end = udhcp_end_option(optionptr); |
233 | 234 | ||
234 | /* end position + option code/length + addopt length + end option */ | ||
235 | len = OPT_DATA + addopt[OPT_LEN]; | 235 | len = OPT_DATA + addopt[OPT_LEN]; |
236 | /* end position + (option code/length + addopt length) + end option */ | ||
236 | if (end + len + 1 >= DHCP_OPTIONS_BUFSIZE) { | 237 | if (end + len + 1 >= DHCP_OPTIONS_BUFSIZE) { |
238 | //TODO: learn how to use overflow option if we exhaust packet->options[] | ||
237 | bb_error_msg("option 0x%02x did not fit into the packet", | 239 | bb_error_msg("option 0x%02x did not fit into the packet", |
238 | addopt[OPT_CODE]); | 240 | addopt[OPT_CODE]); |
239 | return; | 241 | return; |
@@ -243,8 +245,8 @@ void FAST_FUNC udhcp_add_binary_option(uint8_t *optionptr, uint8_t *addopt) | |||
243 | optionptr[end + len] = DHCP_END; | 245 | optionptr[end + len] = DHCP_END; |
244 | } | 246 | } |
245 | 247 | ||
246 | /* Add a one to four byte option to a packet */ | 248 | /* Add an one to four byte option to a packet */ |
247 | void FAST_FUNC udhcp_add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data) | 249 | void FAST_FUNC udhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code, uint32_t data) |
248 | { | 250 | { |
249 | const struct dhcp_option *dh; | 251 | const struct dhcp_option *dh; |
250 | 252 | ||
@@ -259,7 +261,7 @@ void FAST_FUNC udhcp_add_simple_option(uint8_t *optionptr, uint8_t code, uint32_ | |||
259 | data <<= 8 * (4 - len); | 261 | data <<= 8 * (4 - len); |
260 | /* Assignment is unaligned! */ | 262 | /* Assignment is unaligned! */ |
261 | move_to_unaligned32(&option[OPT_DATA], data); | 263 | move_to_unaligned32(&option[OPT_DATA], data); |
262 | udhcp_add_binary_option(optionptr, option); | 264 | udhcp_add_binary_option(packet, option); |
263 | return; | 265 | return; |
264 | } | 266 | } |
265 | } | 267 | } |
@@ -268,7 +270,7 @@ void FAST_FUNC udhcp_add_simple_option(uint8_t *optionptr, uint8_t code, uint32_ | |||
268 | } | 270 | } |
269 | 271 | ||
270 | /* Find option 'code' in opt_list */ | 272 | /* Find option 'code' in opt_list */ |
271 | struct option_set* FAST_FUNC find_option(struct option_set *opt_list, uint8_t code) | 273 | struct option_set* FAST_FUNC udhcp_find_option(struct option_set *opt_list, uint8_t code) |
272 | { | 274 | { |
273 | while (opt_list && opt_list->data[OPT_CODE] < code) | 275 | while (opt_list && opt_list->data[OPT_CODE] < code) |
274 | opt_list = opt_list->next; | 276 | opt_list = opt_list->next; |
@@ -307,7 +309,7 @@ static NOINLINE void attach_option( | |||
307 | char *allocated = NULL; | 309 | char *allocated = NULL; |
308 | #endif | 310 | #endif |
309 | 311 | ||
310 | existing = find_option(*opt_list, option->code); | 312 | existing = udhcp_find_option(*opt_list, option->code); |
311 | if (!existing) { | 313 | if (!existing) { |
312 | log2("Attaching option %02x to list", option->code); | 314 | log2("Attaching option %02x to list", option->code); |
313 | #if ENABLE_FEATURE_UDHCP_RFC3397 | 315 | #if ENABLE_FEATURE_UDHCP_RFC3397 |
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index cc0cab6e4..bb7541f6e 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
@@ -172,13 +172,13 @@ extern const uint8_t dhcp_option_lengths[]; | |||
172 | 172 | ||
173 | uint8_t *udhcp_get_option(struct dhcp_packet *packet, int code) FAST_FUNC; | 173 | uint8_t *udhcp_get_option(struct dhcp_packet *packet, int code) FAST_FUNC; |
174 | int udhcp_end_option(uint8_t *optionptr) FAST_FUNC; | 174 | int udhcp_end_option(uint8_t *optionptr) FAST_FUNC; |
175 | void udhcp_add_binary_option(uint8_t *optionptr, uint8_t *addopt) FAST_FUNC; | 175 | void udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt) FAST_FUNC; |
176 | void udhcp_add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data) FAST_FUNC; | 176 | void udhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code, uint32_t data) FAST_FUNC; |
177 | #if ENABLE_FEATURE_UDHCP_RFC3397 | 177 | #if ENABLE_FEATURE_UDHCP_RFC3397 |
178 | char *dname_dec(const uint8_t *cstr, int clen, const char *pre) FAST_FUNC; | 178 | char *dname_dec(const uint8_t *cstr, int clen, const char *pre) FAST_FUNC; |
179 | uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen) FAST_FUNC; | 179 | uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen) FAST_FUNC; |
180 | #endif | 180 | #endif |
181 | struct option_set *find_option(struct option_set *opt_list, uint8_t code) FAST_FUNC; | 181 | struct option_set *udhcp_find_option(struct option_set *opt_list, uint8_t code) FAST_FUNC; |
182 | 182 | ||
183 | 183 | ||
184 | // RFC 2131 Table 5: Fields and options used by DHCP clients | 184 | // RFC 2131 Table 5: Fields and options used by DHCP clients |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 2c7608048..717c92c6b 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -319,22 +319,22 @@ static void init_packet(struct dhcp_packet *packet, char type) | |||
319 | udhcp_init_header(packet, type); | 319 | udhcp_init_header(packet, type); |
320 | memcpy(packet->chaddr, client_config.client_mac, 6); | 320 | memcpy(packet->chaddr, client_config.client_mac, 6); |
321 | if (client_config.clientid) | 321 | if (client_config.clientid) |
322 | udhcp_add_binary_option(packet->options, client_config.clientid); | 322 | udhcp_add_binary_option(packet, client_config.clientid); |
323 | if (client_config.hostname) | 323 | if (client_config.hostname) |
324 | udhcp_add_binary_option(packet->options, client_config.hostname); | 324 | udhcp_add_binary_option(packet, client_config.hostname); |
325 | if (client_config.fqdn) | 325 | if (client_config.fqdn) |
326 | udhcp_add_binary_option(packet->options, client_config.fqdn); | 326 | udhcp_add_binary_option(packet, client_config.fqdn); |
327 | if (type != DHCPDECLINE | 327 | if (type != DHCPDECLINE |
328 | && type != DHCPRELEASE | 328 | && type != DHCPRELEASE |
329 | && client_config.vendorclass | 329 | && client_config.vendorclass |
330 | ) { | 330 | ) { |
331 | udhcp_add_binary_option(packet->options, client_config.vendorclass); | 331 | udhcp_add_binary_option(packet, client_config.vendorclass); |
332 | } | 332 | } |
333 | } | 333 | } |
334 | 334 | ||
335 | static void add_client_options(struct dhcp_packet *packet) | 335 | static void add_client_options(struct dhcp_packet *packet) |
336 | { | 336 | { |
337 | /* Add am "param req" option with the list of options we'd like to have | 337 | /* Add a "param req" option with the list of options we'd like to have |
338 | * from stubborn DHCP servers. Pull the data from the struct in common.c. | 338 | * from stubborn DHCP servers. Pull the data from the struct in common.c. |
339 | * No bounds checking because it goes towards the head of the packet. */ | 339 | * No bounds checking because it goes towards the head of the packet. */ |
340 | uint8_t c; | 340 | uint8_t c; |
@@ -361,7 +361,7 @@ static void add_client_options(struct dhcp_packet *packet) | |||
361 | { | 361 | { |
362 | struct option_set *curr = client_config.options; | 362 | struct option_set *curr = client_config.options; |
363 | while (curr) { | 363 | while (curr) { |
364 | udhcp_add_binary_option(packet->options, curr->data); | 364 | udhcp_add_binary_option(packet, curr->data); |
365 | curr = curr->next; | 365 | curr = curr->next; |
366 | } | 366 | } |
367 | // if (client_config.sname) | 367 | // if (client_config.sname) |
@@ -405,10 +405,10 @@ static int send_discover(uint32_t xid, uint32_t requested) | |||
405 | init_packet(&packet, DHCPDISCOVER); | 405 | init_packet(&packet, DHCPDISCOVER); |
406 | packet.xid = xid; | 406 | packet.xid = xid; |
407 | if (requested) | 407 | if (requested) |
408 | udhcp_add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); | 408 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); |
409 | /* Explicitly saying that we want RFC-compliant packets helps | 409 | /* Explicitly saying that we want RFC-compliant packets helps |
410 | * some buggy DHCP servers to NOT send bigger packets */ | 410 | * some buggy DHCP servers to NOT send bigger packets */ |
411 | udhcp_add_simple_option(packet.options, DHCP_MAX_SIZE, htons(576)); | 411 | udhcp_add_simple_option(&packet, DHCP_MAX_SIZE, htons(576)); |
412 | add_client_options(&packet); | 412 | add_client_options(&packet); |
413 | 413 | ||
414 | bb_info_msg("Sending discover..."); | 414 | bb_info_msg("Sending discover..."); |
@@ -426,8 +426,8 @@ static int send_select(uint32_t xid, uint32_t server, uint32_t requested) | |||
426 | 426 | ||
427 | init_packet(&packet, DHCPREQUEST); | 427 | init_packet(&packet, DHCPREQUEST); |
428 | packet.xid = xid; | 428 | packet.xid = xid; |
429 | udhcp_add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); | 429 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); |
430 | udhcp_add_simple_option(packet.options, DHCP_SERVER_ID, server); | 430 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); |
431 | add_client_options(&packet); | 431 | add_client_options(&packet); |
432 | 432 | ||
433 | addr.s_addr = requested; | 433 | addr.s_addr = requested; |
@@ -461,8 +461,8 @@ static int send_decline(uint32_t xid, uint32_t server, uint32_t requested) | |||
461 | 461 | ||
462 | init_packet(&packet, DHCPDECLINE); | 462 | init_packet(&packet, DHCPDECLINE); |
463 | packet.xid = xid; | 463 | packet.xid = xid; |
464 | udhcp_add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); | 464 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); |
465 | udhcp_add_simple_option(packet.options, DHCP_SERVER_ID, server); | 465 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); |
466 | 466 | ||
467 | bb_info_msg("Sending decline..."); | 467 | bb_info_msg("Sending decline..."); |
468 | return raw_bcast_from_client_config_ifindex(&packet); | 468 | return raw_bcast_from_client_config_ifindex(&packet); |
@@ -478,7 +478,7 @@ static int send_release(uint32_t server, uint32_t ciaddr) | |||
478 | packet.xid = random_xid(); | 478 | packet.xid = random_xid(); |
479 | packet.ciaddr = ciaddr; | 479 | packet.ciaddr = ciaddr; |
480 | 480 | ||
481 | udhcp_add_simple_option(packet.options, DHCP_SERVER_ID, server); | 481 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); |
482 | 482 | ||
483 | bb_info_msg("Sending release..."); | 483 | bb_info_msg("Sending release..."); |
484 | return udhcp_send_kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT); | 484 | return udhcp_send_kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT); |
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 32f351f52..4ab32de90 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c | |||
@@ -93,7 +93,7 @@ static void init_packet(struct dhcp_packet *packet, struct dhcp_packet *oldpacke | |||
93 | packet->flags = oldpacket->flags; | 93 | packet->flags = oldpacket->flags; |
94 | packet->gateway_nip = oldpacket->gateway_nip; | 94 | packet->gateway_nip = oldpacket->gateway_nip; |
95 | packet->ciaddr = oldpacket->ciaddr; | 95 | packet->ciaddr = oldpacket->ciaddr; |
96 | udhcp_add_simple_option(packet->options, DHCP_SERVER_ID, server_config.server_nip); | 96 | udhcp_add_simple_option(packet, DHCP_SERVER_ID, server_config.server_nip); |
97 | } | 97 | } |
98 | 98 | ||
99 | /* Fill options field, siaddr_nip, and sname and boot_file fields. | 99 | /* Fill options field, siaddr_nip, and sname and boot_file fields. |
@@ -105,7 +105,7 @@ static void add_server_options(struct dhcp_packet *packet) | |||
105 | 105 | ||
106 | while (curr) { | 106 | while (curr) { |
107 | if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) | 107 | if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) |
108 | udhcp_add_binary_option(packet->options, curr->data); | 108 | udhcp_add_binary_option(packet, curr->data); |
109 | curr = curr->next; | 109 | curr = curr->next; |
110 | } | 110 | } |
111 | 111 | ||
@@ -194,7 +194,7 @@ static void send_offer(struct dhcp_packet *oldpacket, uint32_t static_lease_nip, | |||
194 | } | 194 | } |
195 | 195 | ||
196 | lease_time_sec = select_lease_time(oldpacket); | 196 | lease_time_sec = select_lease_time(oldpacket); |
197 | udhcp_add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_sec)); | 197 | udhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec)); |
198 | add_server_options(&packet); | 198 | add_server_options(&packet); |
199 | 199 | ||
200 | addr.s_addr = packet.yiaddr; | 200 | addr.s_addr = packet.yiaddr; |
@@ -224,7 +224,7 @@ static void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) | |||
224 | packet.yiaddr = yiaddr; | 224 | packet.yiaddr = yiaddr; |
225 | 225 | ||
226 | lease_time_sec = select_lease_time(oldpacket); | 226 | lease_time_sec = select_lease_time(oldpacket); |
227 | udhcp_add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_sec)); | 227 | udhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec)); |
228 | 228 | ||
229 | add_server_options(&packet); | 229 | add_server_options(&packet); |
230 | 230 | ||
@@ -324,7 +324,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
324 | 324 | ||
325 | bb_info_msg("%s (v"BB_VER") started", applet_name); | 325 | bb_info_msg("%s (v"BB_VER") started", applet_name); |
326 | 326 | ||
327 | option = find_option(server_config.options, DHCP_LEASE_TIME); | 327 | option = udhcp_find_option(server_config.options, DHCP_LEASE_TIME); |
328 | server_config.max_lease_sec = DEFAULT_LEASE_TIME; | 328 | server_config.max_lease_sec = DEFAULT_LEASE_TIME; |
329 | if (option) { | 329 | if (option) { |
330 | move_from_unaligned32(server_config.max_lease_sec, option->data + OPT_DATA); | 330 | move_from_unaligned32(server_config.max_lease_sec, option->data + OPT_DATA); |
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c index 1f25bb105..cf55a6b5c 100644 --- a/networking/udhcp/files.c +++ b/networking/udhcp/files.c | |||
@@ -167,10 +167,11 @@ void FAST_FUNC write_leases(void) | |||
167 | close(fd); | 167 | close(fd); |
168 | 168 | ||
169 | if (server_config.notify_file) { | 169 | if (server_config.notify_file) { |
170 | // TODO: vfork-based child creation | 170 | char *argv[3]; |
171 | char *cmd = xasprintf("%s %s", server_config.notify_file, server_config.lease_file); | 171 | argv[0] = server_config.notify_file; |
172 | system(cmd); | 172 | argv[1] = server_config.lease_file; |
173 | free(cmd); | 173 | argv[2] = NULL; |
174 | spawn_and_wait(argv); | ||
174 | } | 175 | } |
175 | } | 176 | } |
176 | 177 | ||
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c index efe67cf5d..81acb9910 100644 --- a/networking/udhcp/leases.c +++ b/networking/udhcp/leases.c | |||
@@ -163,6 +163,7 @@ uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac) | |||
163 | 163 | ||
164 | lease = find_lease_by_nip(nip); | 164 | lease = find_lease_by_nip(nip); |
165 | if (!lease) { | 165 | if (!lease) { |
166 | //TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping! | ||
166 | if (nobody_responds_to_arp(nip, safe_mac)) | 167 | if (nobody_responds_to_arp(nip, safe_mac)) |
167 | return nip; | 168 | return nip; |
168 | } else { | 169 | } else { |
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index 5b113bc10..ecdbec7f3 100644 --- a/networking/udhcp/packet.c +++ b/networking/udhcp/packet.c | |||
@@ -33,7 +33,7 @@ void FAST_FUNC udhcp_init_header(struct dhcp_packet *packet, char type) | |||
33 | packet->cookie = htonl(DHCP_MAGIC); | 33 | packet->cookie = htonl(DHCP_MAGIC); |
34 | if (DHCP_END != 0) | 34 | if (DHCP_END != 0) |
35 | packet->options[0] = DHCP_END; | 35 | packet->options[0] = DHCP_END; |
36 | udhcp_add_simple_option(packet->options, DHCP_MESSAGE_TYPE, type); | 36 | udhcp_add_simple_option(packet, DHCP_MESSAGE_TYPE, type); |
37 | } | 37 | } |
38 | 38 | ||
39 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 | 39 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 |
diff --git a/networking/udhcp/socket.c b/networking/udhcp/socket.c index a0ffbf893..469b36202 100644 --- a/networking/udhcp/socket.c +++ b/networking/udhcp/socket.c | |||
@@ -24,7 +24,6 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <net/if.h> | 26 | #include <net/if.h> |
27 | //#include <features.h> | ||
28 | #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined _NEWLIB_VERSION | 27 | #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined _NEWLIB_VERSION |
29 | #include <netpacket/packet.h> | 28 | #include <netpacket/packet.h> |
30 | #include <net/ethernet.h> | 29 | #include <net/ethernet.h> |