aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/dhcpc.c
diff options
context:
space:
mode:
authorNigel Hathaway <Nigel.Hathaway@ubiquisys.com>2011-04-26 02:38:29 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-04-26 02:38:29 +0200
commitc37d4c67e85782001953a8bae8a9c65ccdcb2f88 (patch)
tree341888f2fca67e16a7981bacc2dbe7f77abaff4e /networking/udhcp/dhcpc.c
parentb83c9704128dd106071184e4b00335a3b8486857 (diff)
downloadbusybox-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>
Diffstat (limited to 'networking/udhcp/dhcpc.c')
-rw-r--r--networking/udhcp/dhcpc.c57
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