diff options
Diffstat (limited to 'networking/udhcp/common.c')
-rw-r--r-- | networking/udhcp/common.c | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index f2d6907ad..684d76b2b 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -420,6 +420,43 @@ int FAST_FUNC udhcp_str2nip(const char *str, void *arg) | |||
420 | return 1; | 420 | return 1; |
421 | } | 421 | } |
422 | 422 | ||
423 | void* FAST_FUNC udhcp_insert_new_option( | ||
424 | struct option_set **opt_list, | ||
425 | unsigned code, | ||
426 | const void *buffer, | ||
427 | unsigned length, | ||
428 | bool dhcpv6) | ||
429 | { | ||
430 | IF_NOT_UDHCPC6(bool dhcpv6 = 0;) | ||
431 | struct option_set *new, **curr; | ||
432 | |||
433 | log2("attaching option %02x to list", code); | ||
434 | new = xmalloc(sizeof(*new)); | ||
435 | if (!dhcpv6) { | ||
436 | new->data = xmalloc(length + OPT_DATA); | ||
437 | new->data[OPT_CODE] = code; | ||
438 | new->data[OPT_LEN] = length; | ||
439 | memcpy(new->data + OPT_DATA, buffer, length); | ||
440 | } else { | ||
441 | new->data = xmalloc(length + D6_OPT_DATA); | ||
442 | new->data[D6_OPT_CODE] = code >> 8; | ||
443 | new->data[D6_OPT_CODE + 1] = code & 0xff; | ||
444 | new->data[D6_OPT_LEN] = length >> 8; | ||
445 | new->data[D6_OPT_LEN + 1] = length & 0xff; | ||
446 | memcpy(new->data + D6_OPT_DATA, buffer, length); | ||
447 | } | ||
448 | |||
449 | curr = opt_list; | ||
450 | //FIXME: DHCP6 codes > 255!! | ||
451 | while (*curr && (*curr)->data[OPT_CODE] < code) | ||
452 | curr = &(*curr)->next; | ||
453 | |||
454 | new->next = *curr; | ||
455 | *curr = new; | ||
456 | |||
457 | return new->data; | ||
458 | } | ||
459 | |||
423 | /* udhcp_str2optset: | 460 | /* udhcp_str2optset: |
424 | * Parse string option representation to binary form and add it to opt_list. | 461 | * Parse string option representation to binary form and add it to opt_list. |
425 | * Called to parse "udhcpc -x OPTNAME:OPTVAL" | 462 | * Called to parse "udhcpc -x OPTNAME:OPTVAL" |
@@ -459,32 +496,8 @@ static NOINLINE void attach_option( | |||
459 | 496 | ||
460 | existing = udhcp_find_option(*opt_list, optflag->code); | 497 | existing = udhcp_find_option(*opt_list, optflag->code); |
461 | if (!existing) { | 498 | if (!existing) { |
462 | struct option_set *new, **curr; | ||
463 | |||
464 | /* make a new option */ | 499 | /* make a new option */ |
465 | log2("attaching option %02x to list", optflag->code); | 500 | udhcp_insert_new_option(opt_list, optflag->code, buffer, length, dhcpv6); |
466 | new = xmalloc(sizeof(*new)); | ||
467 | if (!dhcpv6) { | ||
468 | new->data = xmalloc(length + OPT_DATA); | ||
469 | new->data[OPT_CODE] = optflag->code; | ||
470 | new->data[OPT_LEN] = length; | ||
471 | memcpy(new->data + OPT_DATA, buffer, length); | ||
472 | } else { | ||
473 | new->data = xmalloc(length + D6_OPT_DATA); | ||
474 | new->data[D6_OPT_CODE] = optflag->code >> 8; | ||
475 | new->data[D6_OPT_CODE + 1] = optflag->code & 0xff; | ||
476 | new->data[D6_OPT_LEN] = length >> 8; | ||
477 | new->data[D6_OPT_LEN + 1] = length & 0xff; | ||
478 | memcpy(new->data + D6_OPT_DATA, buffer, | ||
479 | length); | ||
480 | } | ||
481 | |||
482 | curr = opt_list; | ||
483 | while (*curr && (*curr)->data[OPT_CODE] < optflag->code) | ||
484 | curr = &(*curr)->next; | ||
485 | |||
486 | new->next = *curr; | ||
487 | *curr = new; | ||
488 | goto ret; | 501 | goto ret; |
489 | } | 502 | } |
490 | 503 | ||