diff options
Diffstat (limited to 'networking/udhcp/script.c')
-rw-r--r-- | networking/udhcp/script.c | 99 |
1 files changed, 39 insertions, 60 deletions
diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c index 1c6f1bd33..2eb4459dd 100644 --- a/networking/udhcp/script.c +++ b/networking/udhcp/script.c @@ -37,8 +37,6 @@ #include "options.h" #include "debug.h" -#include "config.h" - /* get a rough idea of how long an option will be (rounding up...) */ static int max_option_length[] = { [OPTION_IP] = sizeof("255.255.255.255 "), @@ -60,41 +58,22 @@ static int upper_length(int length, struct dhcp_option *option) } -static int sprintip(char *dest, char *pre, unsigned char *ip) { - return sprintf(dest, "%s%d.%d.%d.%d ", pre, ip[0], ip[1], ip[2], ip[3]); -} - -#ifdef CONFIG_FEATURE_UDHCPC_IP -/* convert a netmask (255.255.255.0) into the length (24) */ -static int inet_ntom (const char *src, short *dst) +static int sprintip(char *dest, char *pre, unsigned char *ip) { - in_addr_t mask, num; - - mask = ntohl(*(unsigned int *)src); - - for (num = mask; num & 1; num >>= 1); - - if (num != 0 && mask != 0) - { - for (num = ~mask; num & 1; num >>= 1); - if (num) - return 0; - } - - for (num = 0; mask; mask <<= 1) - num++; + return sprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]); +} - *dst = num; - return 1; +/* really simple implementation, just count the bits */ +static int mton(struct in_addr *mask) +{ + int i; + /* note: mask will always be in network byte order, so + * there are no endian issues */ + for (i = 31; i >= 0 && !((mask->s_addr >> i) & 1); i--); + return i + 1; } -static int sprintprefix(char *dest, char *pre, unsigned char *ip) { - short sdest = 0; - inet_ntom(ip, &sdest); - return sprintf(dest, "%s%hd ", pre, sdest); -} -#endif /* Fill dest with the text of option 'option'. */ static void fill_options(char *dest, unsigned char *option, struct dhcp_option *type_p) @@ -117,41 +96,30 @@ static void fill_options(char *dest, unsigned char *option, struct dhcp_option * *(dest++) = '/'; option += 4; optlen = 4; -#ifndef CONFIG_FEATURE_UDHCPC_IP case OPTION_IP: /* Works regardless of host byte order. */ -#endif dest += sprintip(dest, "", option); break; -#ifdef CONFIG_FEATURE_UDHCPC_IP - case OPTION_IP: /* Works regardless of host byte order. */ - if (type_p->flags & OPTION_PREFIX) { - dest += sprintprefix(dest, "", option); - } else { - dest += sprintip(dest, "", option); - } - break; -#endif case OPTION_BOOLEAN: - dest += sprintf(dest, *option ? "yes " : "no "); + dest += sprintf(dest, *option ? "yes" : "no"); break; case OPTION_U8: - dest += sprintf(dest, "%u ", *option); + dest += sprintf(dest, "%u", *option); break; case OPTION_U16: memcpy(&val_u16, option, 2); - dest += sprintf(dest, "%u ", ntohs(val_u16)); + dest += sprintf(dest, "%u", ntohs(val_u16)); break; case OPTION_S16: memcpy(&val_s16, option, 2); - dest += sprintf(dest, "%d ", ntohs(val_s16)); + dest += sprintf(dest, "%d", ntohs(val_s16)); break; case OPTION_U32: memcpy(&val_u32, option, 4); - dest += sprintf(dest, "%lu ", (unsigned long) ntohl(val_u32)); + dest += sprintf(dest, "%lu", (unsigned long) ntohl(val_u32)); break; case OPTION_S32: memcpy(&val_s32, option, 4); - dest += sprintf(dest, "%ld ", (long) ntohl(val_s32)); + dest += sprintf(dest, "%ld", (long) ntohl(val_s32)); break; case OPTION_STRING: memcpy(dest, option, len); @@ -161,6 +129,7 @@ static void fill_options(char *dest, unsigned char *option, struct dhcp_option * option += optlen; len -= optlen; if (len <= 0) break; + dest += sprintf(dest, " "); } } @@ -186,6 +155,7 @@ static char **fill_envp(struct dhcpMessage *packet) int i, j; char **envp; unsigned char *temp; + struct in_addr subnet; char over = 0; if (packet == NULL) @@ -202,23 +172,32 @@ static char **fill_envp(struct dhcpMessage *packet) } envp = xmalloc((num_options + 5) * sizeof(char *)); - envp[0] = xmalloc(sizeof("interface=") + strlen(client_config.interface)); + j = 0; + envp[j++] = xmalloc(sizeof("interface=") + strlen(client_config.interface)); sprintf(envp[0], "interface=%s", client_config.interface); - envp[1] = find_env("PATH", "PATH=/bin:/usr/bin:/sbin:/usr/sbin"); - envp[2] = find_env("HOME", "HOME=/"); + envp[j++] = find_env("PATH", "PATH=/bin:/usr/bin:/sbin:/usr/sbin"); + envp[j++] = find_env("HOME", "HOME=/"); if (packet == NULL) { - envp[3] = NULL; + envp[j++] = NULL; return envp; } - envp[3] = xmalloc(sizeof("ip=255.255.255.255")); - sprintip(envp[3], "ip=", (unsigned char *) &packet->yiaddr); - for (i = 0, j = 4; options[i].code; i++) { - if ((temp = get_option(packet, options[i].code))) { - envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2], &options[i]) + strlen(options[i].name) + 2); - fill_options(envp[j], temp, &options[i]); - j++; + envp[j] = xmalloc(sizeof("ip=255.255.255.255")); + sprintip(envp[j++], "ip=", (unsigned char *) &packet->yiaddr); + + + for (i = 0; options[i].code; i++) { + if (!(temp = get_option(packet, options[i].code))) + continue; + envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2], &options[i]) + strlen(options[i].name) + 2); + fill_options(envp[j++], temp, &options[i]); + + /* Fill in a subnet bits option for things like /24 */ + if (options[i].code == DHCP_SUBNET) { + envp[j] = xmalloc(sizeof("mask=32")); + memcpy(&subnet, temp, 4); + sprintf(envp[j++], "mask=%d", mton(&subnet)); } } if (packet->siaddr) { |