X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=networking%2Fudhcp%2Fscript.c;h=71f0333280bdbc2b8f6882c4c5129819973fc9f3;hb=3718832a1542f7bf786a1678741b8566ad3a35c6;hp=98706a592977e9d3c406bf29f55758e4270103a0;hpb=fbd2918f5c91723063ed698026217a77a0fe565b;p=oweals%2Fbusybox.git diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c index 98706a592..71f033328 100644 --- a/networking/udhcp/script.c +++ b/networking/udhcp/script.c @@ -14,7 +14,7 @@ /* get a rough idea of how long an option will be (rounding up...) */ -static const int max_option_length[] = { +static const uint8_t max_option_length[] = { [OPTION_IP] = sizeof("255.255.255.255 "), [OPTION_IP_PAIR] = sizeof("255.255.255.255 ") * 2, [OPTION_STRING] = 1, @@ -33,7 +33,7 @@ static const int max_option_length[] = { static inline int upper_length(int length, int opt_index) { return max_option_length[opt_index] * - (length / option_lengths[opt_index]); + (length / dhcp_option_lengths[opt_index]); } @@ -44,19 +44,20 @@ static int sprintip(char *dest, const char *pre, const uint8_t *ip) /* really simple implementation, just count the bits */ -static int mton(struct in_addr *mask) +static int mton(uint32_t mask) { - int i; - unsigned long bits = ntohl(mask->s_addr); - /* too bad one can't check the carry bit, etc in c bit - * shifting */ - for (i = 0; i < 32 && !((bits >> i) & 1); i++); - return 32 - i; + int i = 0; + mask = ntohl(mask); /* 111110000-like bit pattern */ + while (mask) { + i++; + mask <<= 1; + } + return i; } /* Allocate and fill with the text of option 'option'. */ -static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p) +static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p, const char *opt_name) { int len, type, optlen; uint16_t val_u16; @@ -67,10 +68,10 @@ static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p) len = option[OPT_LEN - 2]; type = type_p->flags & TYPE_MASK; - optlen = option_lengths[type]; + optlen = dhcp_option_lengths[type]; - dest = ret = xmalloc(upper_length(len, type) + strlen(type_p->name) + 2); - dest += sprintf(ret, "%s=", type_p->name); + dest = ret = xmalloc(upper_length(len, type) + strlen(opt_name) + 2); + dest += sprintf(ret, "%s=", opt_name); for (;;) { switch (type) { @@ -132,8 +133,8 @@ static char **fill_envp(struct dhcpMessage *packet) int i, j; char **envp; char *var; + const char *opt_name; uint8_t *temp; - struct in_addr subnet; char over = 0; if (packet) { @@ -171,17 +172,23 @@ static char **fill_envp(struct dhcpMessage *packet) envp[j] = xmalloc(sizeof("ip=255.255.255.255")); sprintip(envp[j++], "ip=", (uint8_t *) &packet->yiaddr); - for (i = 0; dhcp_options[i].code; i++) { + opt_name = dhcp_option_strings; + i = 0; + while (*opt_name) { temp = get_option(packet, dhcp_options[i].code); if (!temp) - continue; - envp[j++] = alloc_fill_opts(temp, &dhcp_options[i]); + goto next; + envp[j++] = alloc_fill_opts(temp, &dhcp_options[i], opt_name); /* Fill in a subnet bits option for things like /24 */ if (dhcp_options[i].code == DHCP_SUBNET) { + uint32_t subnet; memcpy(&subnet, temp, 4); - envp[j++] = xasprintf("mask=%d", mton(&subnet)); + envp[j++] = xasprintf("mask=%d", mton(subnet)); } + next: + opt_name += strlen(opt_name) + 1; + i++; } if (packet->siaddr) { envp[j] = xmalloc(sizeof("siaddr=255.255.255.255")); @@ -225,7 +232,7 @@ void udhcp_run_script(struct dhcpMessage *packet, const char *name) name, NULL, envp); bb_perror_msg_and_die("script %s failed", client_config.script); } - waitpid(pid, NULL, 0); + safe_waitpid(pid, NULL, 0); for (curr = envp; *curr; curr++) free(*curr); free(envp);