diff options
Diffstat (limited to 'networking/udhcp/script.c')
-rw-r--r-- | networking/udhcp/script.c | 283 |
1 files changed, 0 insertions, 283 deletions
diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c deleted file mode 100644 index 400fd2b..0000000 --- a/networking/udhcp/script.c +++ /dev/null @@ -1,283 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* script.c - * - * Functions to call the DHCP client notification scripts - * - * Russ Dill <Russ.Dill@asu.edu> July 2001 - * - * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. - */ - -#include "common.h" -#include "dhcpc.h" -#include "options.h" - - -/* get a rough idea of how long an option will be (rounding up...) */ -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, -#endif - [OPTION_BOOLEAN] = sizeof("yes "), - [OPTION_U8] = sizeof("255 "), - [OPTION_U16] = sizeof("65535 "), - [OPTION_S16] = sizeof("-32768 "), - [OPTION_U32] = sizeof("4294967295 "), - [OPTION_S32] = sizeof("-2147483684 "), -}; - - -/* note: ip is a pointer to an IP in network order, possibly misaliged */ -static int sprint_nip(char *dest, const char *pre, const uint8_t *ip) -{ - return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); -} - - -/* really simple implementation, just count the bits */ -static int mton(uint32_t mask) -{ - int i = 0; - mask = ntohl(mask); /* 111110000-like bit pattern */ - while (mask) { - i++; - mask <<= 1; - } - return i; -} - - -/* Create "opt_name=opt_value" string */ -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; - uint16_t val_u16; - int16_t val_s16; - uint32_t val_u32; - int32_t val_s32; - char *dest, *ret; - - /* option points to OPT_DATA, need to go back and get OPT_LEN */ - len = option[OPT_LEN - OPT_DATA]; - type = type_p->flags & OPTION_TYPE_MASK; - optlen = dhcp_option_lengths[type]; - upper_length = len_of_option_as_string[type] * (len / optlen); - - dest = ret = xmalloc(upper_length + strlen(opt_name) + 2); - dest += sprintf(ret, "%s=", opt_name); - - while (len >= optlen) { - switch (type) { - case OPTION_IP_PAIR: - dest += sprint_nip(dest, "", option); - *dest++ = '/'; - option += 4; - optlen = 4; - case OPTION_IP: - dest += sprint_nip(dest, "", option); -// TODO: it can be a list only if (type_p->flags & OPTION_LIST). -// Should we bail out/warn if we see multi-ip option which is -// not allowed to be such? For example, DHCP_BROADCAST... - break; - case OPTION_BOOLEAN: - dest += sprintf(dest, *option ? "yes" : "no"); - break; - case OPTION_U8: - dest += sprintf(dest, "%u", *option); - break; - case OPTION_U16: - move_from_unaligned16(val_u16, option); - dest += sprintf(dest, "%u", ntohs(val_u16)); - break; - case OPTION_S16: - move_from_unaligned16(val_s16, option); - dest += sprintf(dest, "%d", ntohs(val_s16)); - break; - case OPTION_U32: - move_from_unaligned32(val_u32, option); - dest += sprintf(dest, "%lu", (unsigned long) ntohl(val_u32)); - break; - case OPTION_S32: - move_from_unaligned32(val_s32, option); - dest += sprintf(dest, "%ld", (long) ntohl(val_s32)); - break; - case OPTION_STRING: - 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=") */ - dest = dname_dec(option, len, ret); - if (dest) { - free(ret); - return dest; - } - /* error. return "optname=" string */ - return ret; -#endif - } - option += optlen; - len -= optlen; - if (len <= 0) - break; - *dest++ = ' '; - *dest = '\0'; - } - return ret; -} - - -/* put all the parameters into the environment */ -static char **fill_envp(struct dhcp_packet *packet) -{ - int num_options = 0; - int i; - char **envp, **curr; - const char *opt_name; - uint8_t *temp; - uint8_t over = 0; - - if (packet) { - for (i = 0; dhcp_options[i].code; i++) { - if (get_option(packet, dhcp_options[i].code)) { - num_options++; - if (dhcp_options[i].code == DHCP_SUBNET) - num_options++; /* for mton */ - } - } - if (packet->siaddr_nip) - num_options++; - temp = get_option(packet, DHCP_OPTION_OVERLOAD); - if (temp) - over = *temp; - if (!(over & FILE_FIELD) && packet->file[0]) - num_options++; - if (!(over & SNAME_FIELD) && packet->sname[0]) - num_options++; - } - - curr = envp = xzalloc(sizeof(char *) * (num_options + 3)); - *curr = xasprintf("interface=%s", client_config.interface); - putenv(*curr++); - - if (packet == NULL) - return envp; - - *curr = xmalloc(sizeof("ip=255.255.255.255")); - sprint_nip(*curr, "ip=", (uint8_t *) &packet->yiaddr); - putenv(*curr++); - - opt_name = dhcp_option_strings; - i = 0; - while (*opt_name) { - temp = get_option(packet, dhcp_options[i].code); - if (!temp) - goto next; - *curr = xmalloc_optname_optval(temp, &dhcp_options[i], opt_name); - putenv(*curr++); - - /* Fill in a subnet bits option for things like /24 */ - if (dhcp_options[i].code == DHCP_SUBNET) { - uint32_t subnet; - move_from_unaligned32(subnet, temp); - *curr = xasprintf("mask=%d", mton(subnet)); - putenv(*curr++); - } - next: - opt_name += strlen(opt_name) + 1; - i++; - } - if (packet->siaddr_nip) { - *curr = xmalloc(sizeof("siaddr=255.255.255.255")); - sprint_nip(*curr, "siaddr=", (uint8_t *) &packet->siaddr_nip); - putenv(*curr++); - } - if (!(over & FILE_FIELD) && packet->file[0]) { - /* watch out for invalid packets */ - *curr = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file); - putenv(*curr++); - } - if (!(over & SNAME_FIELD) && packet->sname[0]) { - /* watch out for invalid packets */ - *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname); - putenv(*curr++); - } - return envp; -} - - -/* Call a script with a par file and env vars */ -void FAST_FUNC udhcp_run_script(struct dhcp_packet *packet, const char *name) -{ - char **envp, **curr; - char *argv[3]; - - if (client_config.script == NULL) - return; - - envp = fill_envp(packet); - - /* call script */ - log1("Executing %s %s", client_config.script, name); - argv[0] = (char*) client_config.script; - argv[1] = (char*) name; - argv[2] = NULL; - spawn_and_wait(argv); - - for (curr = envp; *curr; curr++) { - log2(" %s", *curr); - bb_unsetenv(*curr); - free(*curr); - } - free(envp); -} |