aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael McTernan <Michael.McTernan.2001@cs.bris.ac.uk>2011-12-16 17:10:09 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2011-12-16 17:10:09 +0100
commitee0f444f11504e47fc0f3ab6bc2bf95defb6e6ae (patch)
tree28afb5beb270a80183fdc5b90848e322cb99abf8
parent7b57ff4436f3e672076e6f5440954a958ba04ab3 (diff)
downloadbusybox-w32-ee0f444f11504e47fc0f3ab6bc2bf95defb6e6ae.tar.gz
busybox-w32-ee0f444f11504e47fc0f3ab6bc2bf95defb6e6ae.tar.bz2
busybox-w32-ee0f444f11504e47fc0f3ab6bc2bf95defb6e6ae.zip
udhcp: finish support of classless static routes (now the correct patch!)
Signed-off-by: Michael McTernan <Michael.McTernan.2001@cs.bris.ac.uk> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/udhcp/common.c55
1 files changed, 37 insertions, 18 deletions
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index cf6b1ca91..ae0e0d306 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -57,13 +57,13 @@ const struct dhcp_optflag dhcp_optflags[] = {
57 { OPTION_DNS_STRING | OPTION_LIST , 0x77 }, /* DHCP_DOMAIN_SEARCH */ 57 { OPTION_DNS_STRING | OPTION_LIST , 0x77 }, /* DHCP_DOMAIN_SEARCH */
58 { OPTION_SIP_SERVERS , 0x78 }, /* DHCP_SIP_SERVERS */ 58 { OPTION_SIP_SERVERS , 0x78 }, /* DHCP_SIP_SERVERS */
59#endif 59#endif
60 { OPTION_STATIC_ROUTES , 0x79 }, /* DHCP_STATIC_ROUTES */ 60 { OPTION_STATIC_ROUTES | OPTION_LIST , 0x79 }, /* DHCP_STATIC_ROUTES */
61#if ENABLE_FEATURE_UDHCP_8021Q 61#if ENABLE_FEATURE_UDHCP_8021Q
62 { OPTION_U16 , 0x84 }, /* DHCP_VLAN_ID */ 62 { OPTION_U16 , 0x84 }, /* DHCP_VLAN_ID */
63 { OPTION_U8 , 0x85 }, /* DHCP_VLAN_PRIORITY */ 63 { OPTION_U8 , 0x85 }, /* DHCP_VLAN_PRIORITY */
64#endif 64#endif
65 { OPTION_6RD , 0xd4 }, /* DHCP_6RD */ 65 { OPTION_6RD , 0xd4 }, /* DHCP_6RD */
66 { OPTION_STATIC_ROUTES , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ 66 { OPTION_STATIC_ROUTES | OPTION_LIST , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */
67 { OPTION_STRING , 0xfc }, /* DHCP_WPAD */ 67 { OPTION_STRING , 0xfc }, /* DHCP_WPAD */
68 68
69 /* Options below have no match in dhcp_option_strings[], 69 /* Options below have no match in dhcp_option_strings[],
@@ -123,8 +123,6 @@ const char dhcp_option_strings[] ALIGN1 =
123// is not handled yet by "string->option" conversion code: 123// is not handled yet by "string->option" conversion code:
124 "sipsrv" "\0" /* DHCP_SIP_SERVERS */ 124 "sipsrv" "\0" /* DHCP_SIP_SERVERS */
125#endif 125#endif
126// doesn't work in udhcpd.conf since OPTION_STATIC_ROUTES
127// is not handled yet by "string->option" conversion code:
128 "staticroutes" "\0"/* DHCP_STATIC_ROUTES */ 126 "staticroutes" "\0"/* DHCP_STATIC_ROUTES */
129#if ENABLE_FEATURE_UDHCP_8021Q 127#if ENABLE_FEATURE_UDHCP_8021Q
130 "vlanid" "\0" /* DHCP_VLAN_ID */ 128 "vlanid" "\0" /* DHCP_VLAN_ID */
@@ -338,7 +336,8 @@ int FAST_FUNC udhcp_str2nip(const char *str, void *arg)
338 lsa = host_and_af2sockaddr(str, 0, AF_INET); 336 lsa = host_and_af2sockaddr(str, 0, AF_INET);
339 if (!lsa) 337 if (!lsa)
340 return 0; 338 return 0;
341 *(uint32_t*)arg = lsa->u.sin.sin_addr.s_addr; 339 /* arg maybe unaligned */
340 move_to_unaligned32((uint32_t*)arg, lsa->u.sin.sin_addr.s_addr);
342 free(lsa); 341 free(lsa);
343 return 1; 342 return 1;
344} 343}
@@ -437,13 +436,14 @@ static NOINLINE void attach_option(
437int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg) 436int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg)
438{ 437{
439 struct option_set **opt_list = arg; 438 struct option_set **opt_list = arg;
440 char *opt, *val, *endptr; 439 char *opt, *val;
441 char *str; 440 char *str;
442 const struct dhcp_optflag *optflag; 441 const struct dhcp_optflag *optflag;
443 struct dhcp_optflag bin_optflag; 442 struct dhcp_optflag bin_optflag;
444 unsigned optcode; 443 unsigned optcode;
445 int retval, length; 444 int retval, length;
446 char buffer[8] ALIGNED(4); 445 /* IP_PAIR needs 8 bytes, STATIC_ROUTES needs 9 max */
446 char buffer[9] ALIGNED(4);
447 uint16_t *result_u16 = (uint16_t *) buffer; 447 uint16_t *result_u16 = (uint16_t *) buffer;
448 uint32_t *result_u32 = (uint32_t *) buffer; 448 uint32_t *result_u32 = (uint32_t *) buffer;
449 449
@@ -501,34 +501,53 @@ int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg)
501// break; 501// break;
502// } 502// }
503 case OPTION_U8: 503 case OPTION_U8:
504 buffer[0] = strtoul(val, &endptr, 0); 504 buffer[0] = bb_strtou32(val, NULL, 0);
505 retval = (endptr[0] == '\0'); 505 retval = (errno == 0);
506 break; 506 break;
507 /* htonX are macros in older libc's, using temp var 507 /* htonX are macros in older libc's, using temp var
508 * in code below for safety */ 508 * in code below for safety */
509 /* TODO: use bb_strtoX? */ 509 /* TODO: use bb_strtoX? */
510 case OPTION_U16: { 510 case OPTION_U16: {
511 unsigned long tmp = strtoul(val, &endptr, 0); 511 uint32_t tmp = bb_strtou32(val, NULL, 0);
512 *result_u16 = htons(tmp); 512 *result_u16 = htons(tmp);
513 retval = (endptr[0] == '\0' /*&& tmp < 0x10000*/); 513 retval = (errno == 0 /*&& tmp < 0x10000*/);
514 break; 514 break;
515 } 515 }
516// case OPTION_S16: { 516// case OPTION_S16: {
517// long tmp = strtol(val, &endptr, 0); 517// long tmp = bb_strtoi32(val, NULL, 0);
518// *result_u16 = htons(tmp); 518// *result_u16 = htons(tmp);
519// retval = (endptr[0] == '\0'); 519// retval = (errno == 0);
520// break; 520// break;
521// } 521// }
522 case OPTION_U32: { 522 case OPTION_U32: {
523 unsigned long tmp = strtoul(val, &endptr, 0); 523 uint32_t tmp = bb_strtou32(val, NULL, 0);
524 *result_u32 = htonl(tmp); 524 *result_u32 = htonl(tmp);
525 retval = (endptr[0] == '\0'); 525 retval = (errno == 0);
526 break; 526 break;
527 } 527 }
528 case OPTION_S32: { 528 case OPTION_S32: {
529 long tmp = strtol(val, &endptr, 0); 529 int32_t tmp = bb_strtoi32(val, NULL, 0);
530 *result_u32 = htonl(tmp); 530 *result_u32 = htonl(tmp);
531 retval = (endptr[0] == '\0'); 531 retval = (errno == 0);
532 break;
533 }
534 case OPTION_STATIC_ROUTES: {
535 /* Input: "a.b.c.d/m" */
536 /* Output: mask(1 byte),pfx(0-4 bytes),gw(4 bytes) */
537 unsigned mask;
538 char *slash = strchr(val, '/');
539 if (slash) {
540 *slash = '\0';
541 retval = udhcp_str2nip(val, buffer + 1);
542 buffer[0] = mask = bb_strtou(slash + 1, NULL, 10);
543 val = strtok(NULL, ", \t/-");
544 if (!val || mask > 32 || errno)
545 retval = 0;
546 if (retval) {
547 length = ((mask + 7) >> 3) + 5;
548 retval = udhcp_str2nip(val, buffer + (length - 4));
549 }
550 }
532 break; 551 break;
533 } 552 }
534 case OPTION_BIN: /* handled in attach_option() */ 553 case OPTION_BIN: /* handled in attach_option() */
@@ -539,7 +558,7 @@ int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg)
539 } 558 }
540 if (retval) 559 if (retval)
541 attach_option(opt_list, optflag, opt, length); 560 attach_option(opt_list, optflag, opt, length);
542 } while (retval && optflag->flags & OPTION_LIST); 561 } while (retval && (optflag->flags & OPTION_LIST));
543 562
544 return retval; 563 return retval;
545} 564}