diff options
author | Nigel Hathaway <Nigel.Hathaway@ubiquisys.com> | 2011-04-26 02:38:29 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-04-26 02:38:29 +0200 |
commit | c37d4c67e85782001953a8bae8a9c65ccdcb2f88 (patch) | |
tree | 341888f2fca67e16a7981bacc2dbe7f77abaff4e | |
parent | b83c9704128dd106071184e4b00335a3b8486857 (diff) | |
download | busybox-w32-c37d4c67e85782001953a8bae8a9c65ccdcb2f88.tar.gz busybox-w32-c37d4c67e85782001953a8bae8a9c65ccdcb2f88.tar.bz2 busybox-w32-c37d4c67e85782001953a8bae8a9c65ccdcb2f88.zip |
dhcpc: export unrecognized options in "optNN=XXXXXXXXX" form
function old new delta
udhcp_run_script 609 818 +209
Signed-off-by: Nigel Hathaway <Nigel.Hathaway@ubiquisys.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/udhcp/dhcpc.c | 57 |
1 files changed, 47 insertions, 10 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index ca82d37e6..510c3a1d0 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -300,6 +300,14 @@ static char **fill_envp(struct dhcp_packet *packet) | |||
300 | uint8_t *temp; | 300 | uint8_t *temp; |
301 | uint8_t overload = 0; | 301 | uint8_t overload = 0; |
302 | 302 | ||
303 | #define BITMAP unsigned | ||
304 | #define BBITS (sizeof(BITMAP) * 8) | ||
305 | #define BMASK(i) (1 << (i & (sizeof(BITMAP) * 8 - 1))) | ||
306 | #define FOUND_OPTS(i) (found_opts[(unsigned)i / BBITS]) | ||
307 | BITMAP found_opts[256 / BBITS]; | ||
308 | |||
309 | memset(found_opts, 0, sizeof(found_opts)); | ||
310 | |||
303 | /* We need 6 elements for: | 311 | /* We need 6 elements for: |
304 | * "interface=IFACE" | 312 | * "interface=IFACE" |
305 | * "ip=N.N.N.N" from packet->yiaddr | 313 | * "ip=N.N.N.N" from packet->yiaddr |
@@ -311,18 +319,21 @@ static char **fill_envp(struct dhcp_packet *packet) | |||
311 | envc = 6; | 319 | envc = 6; |
312 | /* +1 element for each option, +2 for subnet option: */ | 320 | /* +1 element for each option, +2 for subnet option: */ |
313 | if (packet) { | 321 | if (packet) { |
314 | for (i = 0; dhcp_optflags[i].code; i++) { | 322 | /* note: do not search for "pad" (0) and "end" (255) options */ |
315 | if (udhcp_get_option(packet, dhcp_optflags[i].code)) { | 323 | for (i = 1; i < 255; i++) { |
316 | if (dhcp_optflags[i].code == DHCP_SUBNET) | 324 | temp = udhcp_get_option(packet, i); |
325 | if (temp) { | ||
326 | if (i == DHCP_OPTION_OVERLOAD) | ||
327 | overload = *temp; | ||
328 | else if (i == DHCP_SUBNET) | ||
317 | envc++; /* for mton */ | 329 | envc++; /* for mton */ |
318 | envc++; | 330 | envc++; |
331 | /*if (i != DHCP_MESSAGE_TYPE)*/ | ||
332 | FOUND_OPTS(i) |= BMASK(i); | ||
319 | } | 333 | } |
320 | } | 334 | } |
321 | temp = udhcp_get_option(packet, DHCP_OPTION_OVERLOAD); | ||
322 | if (temp) | ||
323 | overload = *temp; | ||
324 | } | 335 | } |
325 | curr = envp = xzalloc(sizeof(char *) * envc); | 336 | curr = envp = xzalloc(sizeof(envp[0]) * envc); |
326 | 337 | ||
327 | *curr = xasprintf("interface=%s", client_config.interface); | 338 | *curr = xasprintf("interface=%s", client_config.interface); |
328 | putenv(*curr++); | 339 | putenv(*curr++); |
@@ -337,12 +348,16 @@ static char **fill_envp(struct dhcp_packet *packet) | |||
337 | opt_name = dhcp_option_strings; | 348 | opt_name = dhcp_option_strings; |
338 | i = 0; | 349 | i = 0; |
339 | while (*opt_name) { | 350 | while (*opt_name) { |
340 | temp = udhcp_get_option(packet, dhcp_optflags[i].code); | 351 | uint8_t code = dhcp_optflags[i].code; |
341 | if (!temp) | 352 | BITMAP *found_ptr = &FOUND_OPTS(code); |
353 | BITMAP found_mask = BMASK(code); | ||
354 | if (!(*found_ptr & found_mask)) | ||
342 | goto next; | 355 | goto next; |
356 | *found_ptr &= ~found_mask; /* leave only unknown options */ | ||
357 | temp = udhcp_get_option(packet, code); | ||
343 | *curr = xmalloc_optname_optval(temp, &dhcp_optflags[i], opt_name); | 358 | *curr = xmalloc_optname_optval(temp, &dhcp_optflags[i], opt_name); |
344 | putenv(*curr++); | 359 | putenv(*curr++); |
345 | if (dhcp_optflags[i].code == DHCP_SUBNET) { | 360 | if (code == DHCP_SUBNET) { |
346 | /* Subnet option: make things like "$ip/$mask" possible */ | 361 | /* Subnet option: make things like "$ip/$mask" possible */ |
347 | uint32_t subnet; | 362 | uint32_t subnet; |
348 | move_from_unaligned32(subnet, temp); | 363 | move_from_unaligned32(subnet, temp); |
@@ -368,6 +383,28 @@ static char **fill_envp(struct dhcp_packet *packet) | |||
368 | *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname); | 383 | *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname); |
369 | putenv(*curr++); | 384 | putenv(*curr++); |
370 | } | 385 | } |
386 | /* Handle unknown options */ | ||
387 | for (i = 0; i < 256;) { | ||
388 | BITMAP bitmap = FOUND_OPTS(i); | ||
389 | if (!bitmap) { | ||
390 | i += BBITS; | ||
391 | continue; | ||
392 | } | ||
393 | if (bitmap & BMASK(i)) { | ||
394 | unsigned len, ofs; | ||
395 | |||
396 | temp = udhcp_get_option(packet, i); | ||
397 | /* udhcp_get_option returns ptr to data portion, | ||
398 | * need to go back to get len | ||
399 | */ | ||
400 | len = temp[-OPT_DATA + OPT_LEN]; | ||
401 | *curr = xmalloc(sizeof("optNNN=") + 1 + len*2); | ||
402 | ofs = sprintf(*curr, "opt%u=", i); | ||
403 | bin2hex(*curr + ofs, (void*) temp, len)[0] = '\0'; | ||
404 | putenv(*curr++); | ||
405 | } | ||
406 | i++; | ||
407 | } | ||
371 | return envp; | 408 | return envp; |
372 | } | 409 | } |
373 | 410 | ||