diff options
Diffstat (limited to 'networking/udhcp/common.c')
-rw-r--r-- | networking/udhcp/common.c | 74 |
1 files changed, 48 insertions, 26 deletions
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index f2d6907ad..31e525cb0 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -49,6 +49,7 @@ const struct dhcp_optflag dhcp_optflags[] = { | |||
49 | { OPTION_U32 , 0x33 }, /* DHCP_LEASE_TIME */ | 49 | { OPTION_U32 , 0x33 }, /* DHCP_LEASE_TIME */ |
50 | { OPTION_IP , 0x36 }, /* DHCP_SERVER_ID */ | 50 | { OPTION_IP , 0x36 }, /* DHCP_SERVER_ID */ |
51 | { OPTION_STRING , 0x38 }, /* DHCP_ERR_MESSAGE */ | 51 | { OPTION_STRING , 0x38 }, /* DHCP_ERR_MESSAGE */ |
52 | { OPTION_STRING , 0x3c }, /* DHCP_VENDOR */ | ||
52 | //TODO: must be combined with 'sname' and 'file' handling: | 53 | //TODO: must be combined with 'sname' and 'file' handling: |
53 | { OPTION_STRING_HOST , 0x42 }, /* DHCP_TFTP_SERVER_NAME */ | 54 | { OPTION_STRING_HOST , 0x42 }, /* DHCP_TFTP_SERVER_NAME */ |
54 | { OPTION_STRING , 0x43 }, /* DHCP_BOOT_FILE */ | 55 | { OPTION_STRING , 0x43 }, /* DHCP_BOOT_FILE */ |
@@ -83,7 +84,6 @@ const struct dhcp_optflag dhcp_optflags[] = { | |||
83 | { OPTION_U8 , 0x35 }, /* DHCP_MESSAGE_TYPE */ | 84 | { OPTION_U8 , 0x35 }, /* DHCP_MESSAGE_TYPE */ |
84 | { OPTION_U16 , 0x39 }, /* DHCP_MAX_SIZE */ | 85 | { OPTION_U16 , 0x39 }, /* DHCP_MAX_SIZE */ |
85 | //looks like these opts will work just fine even without these defs: | 86 | //looks like these opts will work just fine even without these defs: |
86 | // { OPTION_STRING , 0x3c }, /* DHCP_VENDOR */ | ||
87 | // /* not really a string: */ | 87 | // /* not really a string: */ |
88 | // { OPTION_STRING , 0x3d }, /* DHCP_CLIENT_ID */ | 88 | // { OPTION_STRING , 0x3d }, /* DHCP_CLIENT_ID */ |
89 | { 0, 0 } /* zeroed terminating entry */ | 89 | { 0, 0 } /* zeroed terminating entry */ |
@@ -120,6 +120,7 @@ const char dhcp_option_strings[] ALIGN1 = | |||
120 | "lease" "\0" /* DHCP_LEASE_TIME */ | 120 | "lease" "\0" /* DHCP_LEASE_TIME */ |
121 | "serverid" "\0" /* DHCP_SERVER_ID */ | 121 | "serverid" "\0" /* DHCP_SERVER_ID */ |
122 | "message" "\0" /* DHCP_ERR_MESSAGE */ | 122 | "message" "\0" /* DHCP_ERR_MESSAGE */ |
123 | "vendor" "\0" /* DHCP_VENDOR */ | ||
123 | "tftp" "\0" /* DHCP_TFTP_SERVER_NAME*/ | 124 | "tftp" "\0" /* DHCP_TFTP_SERVER_NAME*/ |
124 | "bootfile" "\0" /* DHCP_BOOT_FILE */ | 125 | "bootfile" "\0" /* DHCP_BOOT_FILE */ |
125 | // "userclass" "\0" /* DHCP_USER_CLASS */ | 126 | // "userclass" "\0" /* DHCP_USER_CLASS */ |
@@ -184,6 +185,13 @@ const uint8_t dhcp_option_lengths[] ALIGN1 = { | |||
184 | */ | 185 | */ |
185 | }; | 186 | }; |
186 | 187 | ||
188 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | ||
189 | void FAST_FUNC log1s(const char *msg) | ||
190 | { | ||
191 | if (dhcp_verbose >= 1) | ||
192 | bb_simple_info_msg(msg); | ||
193 | } | ||
194 | #endif | ||
187 | 195 | ||
188 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 | 196 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 |
189 | static void log_option(const char *pfx, const uint8_t *opt) | 197 | static void log_option(const char *pfx, const uint8_t *opt) |
@@ -420,6 +428,40 @@ int FAST_FUNC udhcp_str2nip(const char *str, void *arg) | |||
420 | return 1; | 428 | return 1; |
421 | } | 429 | } |
422 | 430 | ||
431 | void* FAST_FUNC udhcp_insert_new_option( | ||
432 | struct option_set **opt_list, | ||
433 | unsigned code, | ||
434 | unsigned length, | ||
435 | bool dhcpv6) | ||
436 | { | ||
437 | IF_NOT_UDHCPC6(bool dhcpv6 = 0;) | ||
438 | struct option_set *new, **curr; | ||
439 | |||
440 | log2("attaching option %02x to list", code); | ||
441 | new = xmalloc(sizeof(*new)); | ||
442 | if (!dhcpv6) { | ||
443 | new->data = xzalloc(length + OPT_DATA); | ||
444 | new->data[OPT_CODE] = code; | ||
445 | new->data[OPT_LEN] = length; | ||
446 | } else { | ||
447 | new->data = xzalloc(length + D6_OPT_DATA); | ||
448 | new->data[D6_OPT_CODE] = code >> 8; | ||
449 | new->data[D6_OPT_CODE + 1] = code & 0xff; | ||
450 | new->data[D6_OPT_LEN] = length >> 8; | ||
451 | new->data[D6_OPT_LEN + 1] = length & 0xff; | ||
452 | } | ||
453 | |||
454 | curr = opt_list; | ||
455 | //FIXME: DHCP6 codes > 255!! | ||
456 | while (*curr && (*curr)->data[OPT_CODE] < code) | ||
457 | curr = &(*curr)->next; | ||
458 | |||
459 | new->next = *curr; | ||
460 | *curr = new; | ||
461 | |||
462 | return new->data; | ||
463 | } | ||
464 | |||
423 | /* udhcp_str2optset: | 465 | /* udhcp_str2optset: |
424 | * Parse string option representation to binary form and add it to opt_list. | 466 | * Parse string option representation to binary form and add it to opt_list. |
425 | * Called to parse "udhcpc -x OPTNAME:OPTVAL" | 467 | * Called to parse "udhcpc -x OPTNAME:OPTVAL" |
@@ -459,32 +501,12 @@ static NOINLINE void attach_option( | |||
459 | 501 | ||
460 | existing = udhcp_find_option(*opt_list, optflag->code); | 502 | existing = udhcp_find_option(*opt_list, optflag->code); |
461 | if (!existing) { | 503 | if (!existing) { |
462 | struct option_set *new, **curr; | ||
463 | |||
464 | /* make a new option */ | 504 | /* make a new option */ |
465 | log2("attaching option %02x to list", optflag->code); | 505 | uint8_t *p = udhcp_insert_new_option(opt_list, optflag->code, length, dhcpv6); |
466 | new = xmalloc(sizeof(*new)); | 506 | if (!dhcpv6) |
467 | if (!dhcpv6) { | 507 | memcpy(p + OPT_DATA, buffer, length); |
468 | new->data = xmalloc(length + OPT_DATA); | 508 | else |
469 | new->data[OPT_CODE] = optflag->code; | 509 | memcpy(p + D6_OPT_DATA, buffer, length); |
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; | 510 | goto ret; |
489 | } | 511 | } |
490 | 512 | ||