/* 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,
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]);
}
/* 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;
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) {
int i, j;
char **envp;
char *var;
+ const char *opt_name;
uint8_t *temp;
- struct in_addr subnet;
char over = 0;
if (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"));
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);