aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp/common.c')
-rw-r--r--networking/udhcp/common.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index e5fd74f91..fc4de5716 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -272,6 +272,15 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code)
272 goto complain; /* complain and return NULL */ 272 goto complain; /* complain and return NULL */
273 273
274 if (optionptr[OPT_CODE] == code) { 274 if (optionptr[OPT_CODE] == code) {
275 if (optionptr[OPT_LEN] == 0) {
276 /* So far no valid option with length 0 known.
277 * Having this check means that searching
278 * for DHCP_MESSAGE_TYPE need not worry
279 * that returned pointer might be unsafe
280 * to dereference.
281 */
282 goto complain; /* complain and return NULL */
283 }
275 log_option("option found", optionptr); 284 log_option("option found", optionptr);
276 return optionptr + OPT_DATA; 285 return optionptr + OPT_DATA;
277 } 286 }
@@ -289,6 +298,16 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code)
289 return NULL; 298 return NULL;
290} 299}
291 300
301uint8_t* FAST_FUNC udhcp_get_option32(struct dhcp_packet *packet, int code)
302{
303 uint8_t *r = udhcp_get_option(packet, code);
304 if (r) {
305 if (r[-OPT_DATA + OPT_LEN] != 4)
306 r = NULL;
307 }
308 return r;
309}
310
292/* Return the position of the 'end' option (no bounds checking) */ 311/* Return the position of the 'end' option (no bounds checking) */
293int FAST_FUNC udhcp_end_option(uint8_t *optionptr) 312int FAST_FUNC udhcp_end_option(uint8_t *optionptr)
294{ 313{
@@ -403,6 +422,7 @@ static NOINLINE void attach_option(
403 if (errno) 422 if (errno)
404 bb_error_msg_and_die("malformed hex string '%s'", buffer); 423 bb_error_msg_and_die("malformed hex string '%s'", buffer);
405 length = end - allocated; 424 length = end - allocated;
425 buffer = allocated;
406 } 426 }
407#if ENABLE_FEATURE_UDHCP_RFC3397 427#if ENABLE_FEATURE_UDHCP_RFC3397
408 if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_DNS_STRING) { 428 if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_DNS_STRING) {
@@ -422,15 +442,14 @@ static NOINLINE void attach_option(
422 new->data = xmalloc(length + OPT_DATA); 442 new->data = xmalloc(length + OPT_DATA);
423 new->data[OPT_CODE] = optflag->code; 443 new->data[OPT_CODE] = optflag->code;
424 new->data[OPT_LEN] = length; 444 new->data[OPT_LEN] = length;
425 memcpy(new->data + OPT_DATA, (allocated ? allocated : buffer), 445 memcpy(new->data + OPT_DATA, buffer, length);
426 length);
427 } else { 446 } else {
428 new->data = xmalloc(length + D6_OPT_DATA); 447 new->data = xmalloc(length + D6_OPT_DATA);
429 new->data[D6_OPT_CODE] = optflag->code >> 8; 448 new->data[D6_OPT_CODE] = optflag->code >> 8;
430 new->data[D6_OPT_CODE + 1] = optflag->code & 0xff; 449 new->data[D6_OPT_CODE + 1] = optflag->code & 0xff;
431 new->data[D6_OPT_LEN] = length >> 8; 450 new->data[D6_OPT_LEN] = length >> 8;
432 new->data[D6_OPT_LEN + 1] = length & 0xff; 451 new->data[D6_OPT_LEN + 1] = length & 0xff;
433 memcpy(new->data + D6_OPT_DATA, (allocated ? allocated : buffer), 452 memcpy(new->data + D6_OPT_DATA, buffer,
434 length); 453 length);
435 } 454 }
436 455
@@ -453,6 +472,8 @@ static NOINLINE void attach_option(
453 /* actually 255 is ok too, but adding a space can overlow it */ 472 /* actually 255 is ok too, but adding a space can overlow it */
454 473
455 existing->data = xrealloc(existing->data, OPT_DATA + 1 + old_len + length); 474 existing->data = xrealloc(existing->data, OPT_DATA + 1 + old_len + length);
475// So far dhcp_optflags[] has no OPTION_STRING[_HOST] | OPTION_LIST items
476#if 0
456 if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING 477 if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING
457 || (optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING_HOST 478 || (optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING_HOST
458 ) { 479 ) {
@@ -460,7 +481,9 @@ static NOINLINE void attach_option(
460 existing->data[OPT_DATA + old_len] = ' '; 481 existing->data[OPT_DATA + old_len] = ' ';
461 old_len++; 482 old_len++;
462 } 483 }
463 memcpy(existing->data + OPT_DATA + old_len, (allocated ? allocated : buffer), length); 484#endif
485
486 memcpy(existing->data + OPT_DATA + old_len, buffer, length);
464 existing->data[OPT_LEN] = old_len + length; 487 existing->data[OPT_LEN] = old_len + length;
465 } /* else, ignore the data, we could put this in a second option in the future */ 488 } /* else, ignore the data, we could put this in a second option in the future */
466 } /* else, ignore the new data */ 489 } /* else, ignore the new data */
@@ -534,7 +557,7 @@ int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg,
534 if (retval) 557 if (retval)
535 retval = udhcp_str2nip(val, buffer + 4); 558 retval = udhcp_str2nip(val, buffer + 4);
536 break; 559 break;
537case_OPTION_STRING: 560 case_OPTION_STRING:
538 case OPTION_STRING: 561 case OPTION_STRING:
539 case OPTION_STRING_HOST: 562 case OPTION_STRING_HOST:
540#if ENABLE_FEATURE_UDHCP_RFC3397 563#if ENABLE_FEATURE_UDHCP_RFC3397