diff options
-rw-r--r-- | networking/udhcp/options.c | 4 | ||||
-rw-r--r-- | networking/udhcp/options.h | 2 | ||||
-rw-r--r-- | networking/udhcp/script.c | 47 |
3 files changed, 52 insertions, 1 deletions
diff --git a/networking/udhcp/options.c b/networking/udhcp/options.c index 76d6e3737..ddb894432 100644 --- a/networking/udhcp/options.c +++ b/networking/udhcp/options.c @@ -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, }; diff --git a/networking/udhcp/options.h b/networking/udhcp/options.h index 9e624318f..aeed36907 100644 --- a/networking/udhcp/options.h +++ b/networking/udhcp/options.h @@ -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 diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c index 94dabf4d1..f315008a3 100644 --- a/networking/udhcp/script.c +++ b/networking/udhcp/script.c @@ -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=") */ |