udhcpc: support option 0x79 (static routes) (part of bug 341)
No binary (build failed)
—
(log yok)
| @@ -48,6 +48,7 @@ const struct dhcp_option dhcp_options[] = { | |
| #if ENABLE_FEATURE_UDHCP_RFC3397 | |
| { OPTION_STR1035 | OPTION_LIST , 0x77 }, /* search */ | |
| #endif | |
| + | { OPTION_STATIC_ROUTES , 0x79 }, /* DHCP_STATIC_ROUTES */ |
| /* MSIE's "Web Proxy Autodiscovery Protocol" support */ | |
| { OPTION_STRING , 0xfc }, /* wpad */ | |
| @@ -97,6 +98,7 @@ const char dhcp_option_strings[] ALIGN1 = | |
| #if ENABLE_FEATURE_UDHCP_RFC3397 | |
| "search" "\0" | |
| #endif | |
| + | "staticroutes" "\0" /* DHCP_STATIC_ROUTES */ |
| /* MSIE's "Web Proxy Autodiscovery Protocol" support */ | |
| "wpad" "\0" | |
| ; | |
| @@ -116,6 +118,8 @@ const uint8_t dhcp_option_lengths[] ALIGN1 = { | |
| [OPTION_S16] = 2, | |
| [OPTION_U32] = 4, | |
| [OPTION_S32] = 4, | |
| + | /* Just like OPTION_STRING, we use minimum length here */ |
| + | [OPTION_STATIC_ROUTES] = 5, |
| }; | |
| @@ -20,6 +20,7 @@ enum { | |
| OPTION_S16, | |
| OPTION_U32, | |
| OPTION_S32, | |
| + | OPTION_STATIC_ROUTES, |
| }; | |
| /* Client requests this option by default */ | |
| @@ -68,6 +69,7 @@ enum { | |
| #define DHCP_VENDOR 0x3c | |
| #define DHCP_CLIENT_ID 0x3d | |
| #define DHCP_FQDN 0x51 | |
| + | #define DHCP_STATIC_ROUTES 0x79 |
| #define DHCP_END 0xFF | |
| /* Offsets in option byte sequence */ | |
| #define OPT_CODE 0 | |
| @@ -17,6 +17,7 @@ | |
| static const uint8_t len_of_option_as_string[] = { | |
| [OPTION_IP] = sizeof("255.255.255.255 "), | |
| [OPTION_IP_PAIR] = sizeof("255.255.255.255 ") * 2, | |
| + | [OPTION_STATIC_ROUTES]= sizeof("255.255.255.255/32 255.255.255.255 "), |
| [OPTION_STRING] = 1, | |
| #if ENABLE_FEATURE_UDHCP_RFC3397 | |
| [OPTION_STR1035] = 1, | |
| @@ -51,7 +52,7 @@ static int mton(uint32_t mask) | |
| /* Create "opt_name=opt_value" string */ | |
| - | static char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_option *type_p, const char *opt_name) |
| + | static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_option *type_p, const char *opt_name) |
| { | |
| unsigned upper_length; | |
| int len, type, optlen; | |
| @@ -106,6 +107,50 @@ static char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_option *t | |
| memcpy(dest, option, len); | |
| dest[len] = '\0'; | |
| return ret; /* Short circuit this case */ | |
| + | case OPTION_STATIC_ROUTES: { |
| + | /* Option binary format: |
| + | * mask [one byte, 0..32] |
| + | * ip [big endian, 0..4 bytes depending on mask] |
| + | * router [big endian, 4 bytes] |
| + | * may be repeated |
| + | * |
| + | * We convert it to a string "IP/MASK ROUTER IP2/MASK2 ROUTER2" |
| + | */ |
| + | const char *pfx = ""; |
| + | |
| + | while (len >= 1 + 4) { /* mask + 0-byte ip + router */ |
| + | uint32_t nip; |
| + | uint8_t *p; |
| + | unsigned mask; |
| + | int bytes; |
| + | |
| + | mask = *option++; |
| + | if (mask > 32) |
| + | break; |
| + | len--; |
| + | |
| + | nip = 0; |
| + | p = (void*) &nip; |
| + | bytes = (mask + 7) / 8; /* 0 -> 0, 1..8 -> 1, 9..16 -> 2 etc */ |
| + | while (--bytes >= 0) { |
| + | *p++ = *option++; |
| + | len--; |
| + | } |
| + | if (len < 4) |
| + | break; |
| + | |
| + | /* print ip/mask */ |
| + | dest += sprint_nip(dest, pfx, (void*) &nip); |
| + | pfx = " "; |
| + | dest += sprintf(dest, "/%u ", mask); |
| + | /* print router */ |
| + | dest += sprint_nip(dest, "", option); |
| + | option += 4; |
| + | len -= 4; |
| + | } |
| + | |
| + | return ret; |
| + | } |
| #if ENABLE_FEATURE_UDHCP_RFC3397 | |
| case OPTION_STR1035: | |
| /* unpack option into dest; use ret for prefix (i.e., "optname=") */ | |