return bytes;
}
-static ssize_t
+static size_t
dhcp_envoption1(char **env, const char *prefix,
const struct dhcp_opt *opt, int vname, const uint8_t *od, int ol,
const char *ifname)
if (len < 0)
return 0;
if (vname)
- e = strlen(opt->v.var);
+ e = strlen(opt->v.var) + 1;
else
e = 0;
- e += strlen(prefix) + len + 4;
+ if (prefix)
+ e += strlen(prefix);
+ e += len + 4;
+ if (env == NULL)
+ return e;
v = val = *env = malloc(e);
if (v == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
v += snprintf(val, e, "%s=", prefix);
if (len != 0)
print_option(v, len, opt->type, ol, od, ifname);
- return len;
+ return e;
}
ssize_t
int eos, eol, ov;
struct dhcp_opt *eopt, *oopt;
char *pfx;
- const char *p;
/* If no embedded or encapsulated options, it's easy */
if (opt->embopts_len == 0 && opt->encopts_len == 0) {
- if (env)
- dhcp_envoption1(&env[0], prefix, opt, 1, od, ol,
- ifname);
- return 1;
+ if (dhcp_envoption1(env == NULL ? NULL : &env[0],
+ prefix, opt, 1, od, ol, ifname))
+ return 1;
+ return 0;
}
/* Create a new prefix based on the option */
opt->v.var, ++opt->index);
else
snprintf(pfx, e, "%s_%s", prefix, opt->v.var);
- p = pfx;
} else
- p = pfx = NULL;
+ pfx = NULL;
/* Embedded options are always processed first as that
* is a fixed layout */
n = 0;
-
for (i = 0, eopt = opt->embopts; i < opt->embopts_len; i++, eopt++) {
e = dhcp_optlen(eopt, ol);
if (e == 0)
/* Report error? */
return 0;
- if (env) {
- /* Use the option prefix if the embedded option
- * name is different.
- * This avoids new_fqdn_fqdn which would be silly. */
- ov = strcmp(opt->v.var, eopt->v.var);
- dhcp_envoption1(&env[n], p, eopt, ov, od, e, ifname);
- }
- n++;
+ /* Use the option prefix if the embedded option
+ * name is different.
+ * This avoids new_fqdn_fqdn which would be silly. */
+ ov = strcmp(opt->v.var, eopt->v.var);
+ if (dhcp_envoption1(env == NULL ? NULL : &env[n],
+ pfx, eopt, ov, od, e, ifname))
+ n++;
od += e;
ol -= e;
}
eopt = oopt;
}
n += dhcp_envoption(
- env == NULL ? NULL : &env[n], p,
+ env == NULL ? NULL : &env[n], pfx,
ifname, eopt,
dgetopt, eod, eol);
break;
const struct dhcp6_option *o;
size_t i, n;
uint16_t ol, oc;
- char **ep, *v, *val, *pfx;
+ char *v, *val, *pfx;
const struct ipv6_addr *ap;
state = D6_CSTATE(ifp);
n = 0;
- ep = env;
ifo = ifp->options;
/* Zero our indexes */
i++, opt++)
if (opt->option == oc)
break;
- if (opt == NULL) {
+ if (i == ifo->dhcp6_override_len) {
for (i = 0, opt = dhcp6_opts;
i < dhcp6_opts_len;
i++, opt++)
if (opt->option == oc)
break;
+ if (i == dhcp6_opts_len)
+ opt = NULL;
}
if (opt) {
n += dhcp_envoption(env == NULL ? NULL : &env[n],
* and it's easier for shell scripts to see which addresses have
* been added */
if (TAILQ_FIRST(&state->addrs)) {
- if (env == NULL)
- n++;
- else {
+ if (env) {
if (ifo->ia_type == D6_OPTION_IA_PD) {
i = strlen(prefix) +
strlen("_dhcp6_prefix=");
TAILQ_FOREACH(ap, &state->addrs, next) {
i += strlen(ap->saddr) + 1;
}
- v = val = *ep++ = malloc(i);
+ v = val = env[n] = malloc(i);
if (v == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
return -1;
TAILQ_FOREACH(ap, &state->addrs, next) {
i += strlen(ap->saddr) + 1;
}
- v = val = *ep++ = malloc(i);
+ v = val = env[n] = malloc(i);
if (v == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
return -1;
*--v = '\0';
}
}
+ n++;
}
return n;