Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/external/bsd/dhcpcd/dist/src/if-options.c,v rcsdiff: /ftp/cvs/cvsroot/src/external/bsd/dhcpcd/dist/src/if-options.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.4.2.5 retrieving revision 1.5 diff -u -p -r1.4.2.5 -r1.5 --- src/external/bsd/dhcpcd/dist/src/if-options.c 2019/05/05 08:24:04 1.4.2.5 +++ src/external/bsd/dhcpcd/dist/src/if-options.c 2017/09/19 19:19:21 1.5 @@ -1,6 +1,6 @@ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2019 Roy Marples + * Copyright (c) 2006-2017 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -207,12 +207,11 @@ const struct option cf_options[] = { {NULL, 0, NULL, '\0'} }; -static const char *default_script = SCRIPT; - static char * -add_environ(char ***array, const char *value, int uniq) +add_environ(struct if_options *ifo, const char *value, int uniq) { - char **newlist, **list = *array; + char **newlist; + char **lst = ifo->environ; size_t i = 0, l, lv; char *match = NULL, *p, *n; @@ -230,8 +229,8 @@ add_environ(char ***array, const char *v *p++ = '\0'; l = strlen(match); - while (list && list[i]) { - if (match && strncmp(list[i], match, l) == 0) { + while (lst && lst[i]) { + if (match && strncmp(lst[i], match, l) == 0) { if (uniq) { n = strdup(value); if (n == NULL) { @@ -239,25 +238,25 @@ add_environ(char ***array, const char *v free(match); return NULL; } - free(list[i]); - list[i] = n; + free(lst[i]); + lst[i] = n; } else { /* Append a space and the value to it */ - l = strlen(list[i]); + l = strlen(lst[i]); lv = strlen(p); - n = realloc(list[i], l + lv + 2); + n = realloc(lst[i], l + lv + 2); if (n == NULL) { logerr(__func__); free(match); return NULL; } - list[i] = n; - list[i][l] = ' '; - memcpy(list[i] + l + 1, p, lv); - list[i][l + lv + 1] = '\0'; + lst[i] = n; + lst[i][l] = ' '; + memcpy(lst[i] + l + 1, p, lv); + lst[i][l + lv + 1] = '\0'; } free(match); - return list[i]; + return lst[i]; } i++; } @@ -268,7 +267,7 @@ add_environ(char ***array, const char *v logerr(__func__); return NULL; } - newlist = reallocarray(list, i + 2, sizeof(char *)); + newlist = reallocarray(lst, i + 2, sizeof(char *)); if (newlist == NULL) { logerr(__func__); free(n); @@ -276,31 +275,26 @@ add_environ(char ***array, const char *v } newlist[i] = n; newlist[i + 1] = NULL; - *array = newlist; + ifo->environ = newlist; return newlist[i]; } -#define PARSE_STRING 0 -#define PARSE_STRING_NULL 1 -#define PARSE_HWADDR 2 -#define parse_string(a, b, c) parse_str((a), (b), (c), PARSE_STRING) -#define parse_hwaddr(a, b, c) parse_str((a), (b), (c), PARSE_HWADDR) +#define parse_string(buf, len, arg) parse_string_hwaddr(buf, len, arg, 0) static ssize_t -parse_str(char *sbuf, size_t slen, const char *str, int flags) +parse_string_hwaddr(char *sbuf, size_t slen, const char *str, int clid) { size_t l; - const char *p, *end; - int i; + const char *p; + int i, punt_last = 0; char c[4], cmd; - end = str + strlen(str); /* If surrounded by quotes then it's a string */ if (*str == '"') { - p = end - 1; - if (*p == '"') { - str++; - end = p; - } + str++; + l = strlen(str); + p = str + l - 1; + if (*p == '"') + punt_last = 1; } else { l = (size_t)hwaddr_aton(NULL, str); if ((ssize_t) l != -1 && l > 1) { @@ -317,13 +311,13 @@ parse_str(char *sbuf, size_t slen, const l = 0; /* If processing a string on the clientid, first byte should be * 0 to indicate a non hardware type */ - if (flags == PARSE_HWADDR && *str) { + if (clid && *str) { if (sbuf) *sbuf++ = 0; l++; } c[3] = '\0'; - while (str < end) { + while (*str) { if (++l > slen && sbuf) { errno = ENOBUFS; return -1; @@ -391,8 +385,11 @@ parse_str(char *sbuf, size_t slen, const str++; } } - if (flags == PARSE_STRING_NULL && sbuf) - *sbuf = '\0'; + if (punt_last) { + if (sbuf) + *--sbuf = '\0'; + l--; + } return (ssize_t)l; } @@ -544,7 +541,6 @@ set_option_space(struct dhcpcd_ctx *ctx, return arg + strlen("nd_"); } -#ifdef DHCP6 if (strncmp(arg, "dhcp6_", strlen("dhcp6_")) == 0) { *d = ctx->dhcp6_opts; *dl = ctx->dhcp6_opts_len; @@ -557,7 +553,6 @@ set_option_space(struct dhcpcd_ctx *ctx, return arg + strlen("dhcp6_"); } #endif -#endif #ifdef INET *d = ctx->dhcp_opts; @@ -657,7 +652,7 @@ parse_option(struct dhcpcd_ctx *ctx, con int e, i, t; long l; unsigned long u; - char *p = NULL, *bp, *fp, *np; + char *p = NULL, *bp, *fp, *np, **nconf; ssize_t s; struct in_addr addr, addr2; in_addr_t *naddr; @@ -711,33 +706,17 @@ parse_option(struct dhcpcd_ctx *ctx, con break; case 'c': ARG_REQUIRED; - if (ifo->script != default_script) - free(ifo->script); - s = parse_str(NULL, 0, arg, PARSE_STRING_NULL); - if (s == 0) { - ifo->script = NULL; - break; - } - dl = (size_t)s; - if (s == -1 || (ifo->script = malloc(dl)) == NULL) { - ifo->script = NULL; + free(ifo->script); + ifo->script = strdup(arg); + if (ifo->script == NULL) logerr(__func__); - return -1; - } - parse_str(ifo->script, dl, arg, PARSE_STRING_NULL); - if (ifo->script[0] == '\0' || - strcmp(ifo->script, "/dev/null") == 0) - { - free(ifo->script); - ifo->script = NULL; - } break; case 'd': ifo->options |= DHCPCD_DEBUG; break; case 'e': ARG_REQUIRED; - add_environ(&ifo->environ, arg, 1); + add_environ(ifo, arg, 1); break; case 'h': if (!arg) { @@ -836,21 +815,8 @@ parse_option(struct dhcpcd_ctx *ctx, con break; case 's': if (arg && *arg != '\0') { - /* Strip out a broadcast address */ - p = strchr(arg, '/'); - if (p != NULL) { - p = strchr(p + 1, '/'); - if (p != NULL) - *p = '\0'; - } - i = parse_addr(&ifo->req_addr, &ifo->req_mask, arg); - if (p != NULL) { - /* Ensure the original string is preserved */ - *p++ = '/'; - if (i == 0) - i = parse_addr(&ifo->req_brd, NULL, p); - } - if (i != 0) + if (parse_addr(&ifo->req_addr, &ifo->req_mask, arg) + != 0) return -1; } else { ifo->req_addr.s_addr = 0; @@ -988,7 +954,7 @@ parse_option(struct dhcpcd_ctx *ctx, con return -1; } snprintf(p, dl, "skip_hooks=%s", arg); - add_environ(&ifo->environ, p, 0); + add_environ(ifo, p, 0); free(p); break; case 'D': @@ -1025,8 +991,8 @@ parse_option(struct dhcpcd_ctx *ctx, con /* Strings have a type of 0 */; ifo->clientid[1] = 0; if (arg) - s = parse_hwaddr((char *)ifo->clientid + 1, - CLIENTID_MAX_LEN, arg); + s = parse_string_hwaddr((char *)ifo->clientid + 1, + CLIENTID_MAX_LEN, arg, 1); else s = 0; if (s == -1) { @@ -1094,11 +1060,6 @@ parse_option(struct dhcpcd_ctx *ctx, con { if (parse_addr(&ifo->req_mask, NULL, p) != 0) return -1; - } else if (strncmp(arg, "broadcast_address=", - strlen("broadcast_address=")) == 0) - { - if (parse_addr(&ifo->req_brd, NULL, p) != 0) - return -1; } else if (strncmp(arg, "routes=", strlen("routes=")) == 0 || strncmp(arg, "static_routes=", strlen("static_routes=")) == 0 || @@ -1107,8 +1068,14 @@ parse_option(struct dhcpcd_ctx *ctx, con strncmp(arg, "ms_classless_static_routes=", strlen("ms_classless_static_routes=")) == 0) { + struct interface *ifp; struct in_addr addr3; + ifp = if_find(ctx->ifaces, ifname); + if (ifp == NULL) { + logerrx("static routes require an interface"); + return -1; + } fp = np = strwhite(p); if (np == NULL) { logerrx("all routes need a gateway"); @@ -1122,7 +1089,7 @@ parse_option(struct dhcpcd_ctx *ctx, con *fp = ' '; return -1; } - if ((rt = rt_new0(ctx)) == NULL) { + if ((rt = rt_new(ifp)) == NULL) { *fp = ' '; return -1; } @@ -1131,18 +1098,23 @@ parse_option(struct dhcpcd_ctx *ctx, con sa_in_init(&rt->rt_gateway, &addr3); TAILQ_INSERT_TAIL(&ifo->routes, rt, rt_next); *fp = ' '; - add_environ(&ifo->config, arg, 0); } else if (strncmp(arg, "routers=", strlen("routers=")) == 0) { + struct interface *ifp; + + ifp = if_find(ctx->ifaces, ifname); + if (ifp == NULL) { + logerrx("static routes require an interface"); + return -1; + } if (parse_addr(&addr, NULL, p) == -1) return -1; - if ((rt = rt_new0(ctx)) == NULL) + if ((rt = rt_new(ifp)) == NULL) return -1; addr2.s_addr = INADDR_ANY; sa_in_init(&rt->rt_dest, &addr2); sa_in_init(&rt->rt_netmask, &addr2); sa_in_init(&rt->rt_gateway, &addr); TAILQ_INSERT_TAIL(&ifo->routes, rt, rt_next); - add_environ(&ifo->config, arg, 0); } else if (strncmp(arg, "interface_mtu=", strlen("interface_mtu=")) == 0 || strncmp(arg, "mtu=", strlen("mtu=")) == 0) @@ -1170,8 +1142,40 @@ parse_option(struct dhcpcd_ctx *ctx, con } else ifo->req_prefix_len = 128; } - } else - add_environ(&ifo->config, arg, 1); + } else { + dl = 0; + if (ifo->config != NULL) { + while (ifo->config[dl] != NULL) { + if (strncmp(ifo->config[dl], arg, + (size_t)(p - arg)) == 0) + { + p = strdup(arg); + if (p == NULL) { + logerr(__func__); + return -1; + } + free(ifo->config[dl]); + ifo->config[dl] = p; + return 1; + } + dl++; + } + } + p = strdup(arg); + if (p == NULL) { + logerr(__func__); + return -1; + } + nconf = reallocarray(ifo->config, dl+2, sizeof(char *)); + if (nconf == NULL) { + logerr(__func__); + free(p); + return -1; + } + ifo->config = nconf; + ifo->config[dl] = p; + ifo->config[dl + 1] = NULL; + } break; case 'W': if (parse_addr(&addr, &addr2, arg) != 0) @@ -1320,7 +1324,7 @@ parse_option(struct dhcpcd_ctx *ctx, con return -1; #else if (ifname == NULL) { - logerrx("IA PD must belong in an " + logerr("IA PD must belong in an " "interface block"); return -1; } @@ -1351,7 +1355,6 @@ parse_option(struct dhcpcd_ctx *ctx, con for (sl = 0; sl < ifo->ia_len; sl++) { if ((arg == NULL && !ifo->ia[sl].iaid_set) || (arg != NULL && ifo->ia[sl].iaid_set && - ifo->ia[sl].ia_type == (uint16_t)i && ifo->ia[sl].iaid[0] == iaid[0] && ifo->ia[sl].iaid[1] == iaid[1] && ifo->ia[sl].iaid[2] == iaid[2] && @@ -1361,6 +1364,10 @@ parse_option(struct dhcpcd_ctx *ctx, con break; } } + if (ia && ia->ia_type != (uint16_t)i) { + logerrx("Cannot mix IA for the same IAID"); + break; + } if (ia == NULL) { ia = reallocarray(ifo->ia, ifo->ia_len + 1, sizeof(*ifo->ia)); @@ -1411,13 +1418,9 @@ parse_option(struct dhcpcd_ctx *ctx, con ia->sla = NULL; #endif } - -#ifdef SMALL - break; -#else if (ia->ia_type != D6_OPTION_IA_PD) break; - +#ifndef SMALL for (p = fp; p; p = fp) { fp = strwhite(p); if (fp) { @@ -1842,7 +1845,6 @@ err_sla: logerrx("invalid code: %s", arg); return -1; } - fp = strskipwhite(fp); if (fp) { s = parse_string(NULL, 0, fp); if (s == -1) { @@ -1905,32 +1907,12 @@ err_sla: } if (fp) *fp++ = '\0'; - if (ifo->auth.protocol == AUTH_PROTO_TOKEN) { - np = strchr(arg, '/'); - if (np) { - if (fp == NULL || np < fp) - *np++ = '\0'; - else - np = NULL; - } - if (parse_uint32(&ifo->auth.token_snd_secretid, - arg) == -1) - logerrx("%s: not a number", arg); - else - ifo->auth.token_rcv_secretid = - ifo->auth.token_snd_secretid; - if (np && - parse_uint32(&ifo->auth.token_rcv_secretid, - np) == -1) - logerrx("%s: not a number", arg); - } else { - if (strcasecmp(arg, "hmacmd5") == 0 || - strcasecmp(arg, "hmac-md5") == 0) - ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; - else { - logerrx("%s: unsupported algorithm", arg); - return 1; - } + if (strcasecmp(arg, "hmacmd5") == 0 || + strcasecmp(arg, "hmac-md5") == 0) + ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; + else { + logerrx("%s: unsupported algorithm", arg); + return 1; } arg = fp; if (arg == NULL) { @@ -2005,7 +1987,7 @@ err_sla: arg = fp; fp = strend(arg); if (fp == NULL) { - logerrx("authtoken requies an expiry date"); + logerrx("authtoken requies an an expiry date"); free(token->realm); free(token); return -1; @@ -2266,7 +2248,6 @@ default_config(struct dhcpcd_ctx *ctx) ifo->options |= DHCPCD_IF_UP | DHCPCD_LINK | DHCPCD_INITIAL_DELAY; ifo->timeout = DEFAULT_TIMEOUT; ifo->reboot = DEFAULT_REBOOT; - ifo->script = UNCONST(default_script); ifo->metric = -1; ifo->auth.options |= DHCPCD_AUTH_REQUIRE; TAILQ_INIT(&ifo->routes); @@ -2368,7 +2349,7 @@ read_config(struct dhcpcd_ctx *ctx, buf = malloc(buflen); if (buf == NULL) { logerr(__func__); - free_options(ctx, ifo); + free_options(ifo); return NULL; } ldop = edop = NULL; @@ -2382,7 +2363,7 @@ read_config(struct dhcpcd_ctx *ctx, if (nbuf == NULL) { logerr(__func__); free(buf); - free_options(ctx, ifo); + free_options(ifo); return NULL; } buf = nbuf; @@ -2426,10 +2407,8 @@ read_config(struct dhcpcd_ctx *ctx, #ifdef INET6 ctx->nd_opts = ifo->nd_override; ctx->nd_opts_len = ifo->nd_override_len; -#ifdef DHCP6 ctx->dhcp6_opts = ifo->dhcp6_override; ctx->dhcp6_opts_len = ifo->dhcp6_override_len; -#endif #else for (i = 0, opt = ifo->nd_override; i < ifo->nd_override_len; @@ -2548,7 +2527,7 @@ read_config(struct dhcpcd_ctx *ctx, free(buf); if (profile && !have_profile) { - free_options(ctx, ifo); + free_options(ifo); errno = ENOENT; return NULL; } @@ -2593,7 +2572,7 @@ add_options(struct dhcpcd_ctx *ctx, cons } void -free_options(struct dhcpcd_ctx *ctx, struct if_options *ifo) +free_options(struct if_options *ifo) { size_t i; struct dhcp_opt *opt; @@ -2615,9 +2594,8 @@ free_options(struct dhcpcd_ctx *ctx, str free(ifo->config[i++]); free(ifo->config); } - rt_headclear0(ctx, &ifo->routes, AF_UNSPEC); - if (ifo->script != default_script) - free(ifo->script); + rt_headclear(&ifo->routes, AF_UNSPEC); + free(ifo->script); free(ifo->arping); free(ifo->blacklist); free(ifo->fallback);