}
}
if (dhcp && iface->state->old) {
- e = configure_env(NULL, NULL, iface->state->old, ifo);
+ e = configure_env(NULL, NULL, iface->state->old, iface);
if (e > 0) {
env = xrealloc(env, sizeof(char *) * (elen + e + 1));
elen += configure_env(env + elen, "old",
- iface->state->old, ifo);
+ iface->state->old, iface);
}
append_config(&env, &elen, "old",
(const char *const *)ifo->config);
dumplease:
if (dhcp && iface->state->new) {
- e = configure_env(NULL, NULL, iface->state->new, ifo);
+ e = configure_env(NULL, NULL, iface->state->new, iface);
if (e > 0) {
env = xrealloc(env, sizeof(char *) * (elen + e + 1));
elen += configure_env(env + elen, "new",
- iface->state->new, ifo);
+ iface->state->new, iface);
}
append_config(&env, &elen, "new",
(const char *const *)ifo->config);
}
ssize_t
-print_option(char *s, ssize_t len, int type, int dl, const uint8_t *data)
+print_option(char *s, ssize_t len, int type, int dl, const uint8_t *data,
+ const char *ifname)
{
const uint8_t *e, *t;
uint16_t u16;
struct in_addr addr;
ssize_t bytes = 0;
ssize_t l;
- char *tmp, ntopbuf[INET6_ADDRSTRLEN];
- const char *addr6;
+ char *tmp;
if (type & RFC3397) {
l = decode_rfc3397(NULL, 0, dl, data);
data += sizeof(u16);
dl -= sizeof(u16);
if (dl)
- l += print_option(s, len, STRING, dl, data);
+ l += print_option(s, len, STRING, dl, data, ifname);
return l;
}
+ if (type & IPV6) {
+ }
+
if (!s) {
if (type & UINT8)
l = 3;
l = 16;
dl /= 4;
} else if (type & IPV6) {
- l = INET6_ADDRSTRLEN;
- dl /= 16;
+ e = data + dl;
+ l = 0;
+ while (data < e) {
+ if (l)
+ l++; /* space */
+ l += ipv6_printaddr(NULL, 0, data, ifname);
+ data += 16;
+ }
+ return l + 1;
} else if (type & BINHEX) {
l = 2;
} else {
l = snprintf(s, len, "%s", inet_ntoa(addr));
data += sizeof(addr.s_addr);
} else if (type & IPV6) {
- addr6 = inet_ntop(AF_INET6, data,
- ntopbuf, sizeof(ntopbuf));
- l = snprintf(s, len, "%s", addr6);
+ l = ipv6_printaddr(s, len, data, ifname);
data += 16;
} else if (type & BINHEX) {
l = snprintf(s, len, "%.2x", data[0]);
ssize_t
configure_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
- const struct if_options *ifo)
+ const struct interface *ifp)
{
+ const struct if_options *ifo;
const uint8_t *p;
int pl;
struct in_addr addr;
char cidr[4];
uint8_t overl = 0;
+ ifo = ifp->state->options;
get_option_uint8(&overl, dhcp, DHO_OPTIONSOVERLOADED);
if (!env) {
p += 3;
pl -= 3;
}
- len = print_option(NULL, 0, opt->type, pl, p);
+ len = print_option(NULL, 0, opt->type, pl, p, ifp->name);
if (len < 0)
return -1;
e = strlen(prefix) + strlen(opt->var) + len + 4;
v = val = *ep++ = xmalloc(e);
v += snprintf(val, e, "%s_%s=", prefix, opt->var);
if (len != 0)
- print_option(v, len, opt->type, pl, p);
+ print_option(v, len, opt->type, pl, p, ifp->name);
}
return ep - env;
struct rt *get_option_routes(const struct dhcp_message *, const char *,
unsigned long long *);
ssize_t decode_rfc3397(char *, ssize_t, int, const uint8_t *);
-ssize_t print_string(char *s, ssize_t len, int dl, const uint8_t *data);
-ssize_t print_option(char *s, ssize_t len, int type, int dl,
- const uint8_t *data);
+ssize_t print_string(char *, ssize_t, int, const uint8_t *);
+ssize_t print_option(char *, ssize_t, int, int, const uint8_t *, const char *);
ssize_t configure_env(char **, const char *, const struct dhcp_message *,
- const struct if_options *);
+ const struct interface *);
int dhcp_message_add_addr(struct dhcp_message *, uint8_t, struct in_addr);
ssize_t make_message(struct dhcp_message **, const struct interface *,
state->new = NULL;
state->new_len = 0;
+ /* XXX remove this line when we fix discover stamping on assigned */
+ dhcp6_freedrop_addrs(ifp, 0);
+
if (dhcp6_makemessage(ifp) == -1)
syslog(LOG_ERR, "%s: dhcp6_makemessage: %m", ifp->name);
else
}
ol = ntohs(o->len);
od = D6_COPTION_DATA(o);
- len = print_option(NULL, 0, opt->type, ol, od);
+ len = print_option(NULL, 0, opt->type, ol, od, ifp->name);
if (len < 0)
return -1;
e = strlen(prefix) + 6 + strlen(opt->var) + len + 4;
v = val = *ep++ = xmalloc(e);
v += snprintf(val, e, "%s_dhcp6_%s=", prefix, opt->var);
if (len != 0)
- print_option(v, len, opt->type, ol, od);
+ print_option(v, len, opt->type, ol, od, ifp->name);
}
return 0;
}
+ssize_t
+ipv6_printaddr(char *s, ssize_t sl, const uint8_t *d, const char *ifname)
+{
+ char buf[INET6_ADDRSTRLEN];
+ const char *p;
+ ssize_t l;
+
+ p = inet_ntop(AF_INET6, d, buf, sizeof(buf));
+ if (p == NULL)
+ return -1;
+
+ l = strlen(p);
+ if (d[0] == 0xfe && (d[1] & 0xc0) == 0x80)
+ l += 1 + strlen(ifname);
+
+ if (s == NULL)
+ return l;
+
+ if (sl < l) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ s += strlcpy(s, p, sl);
+ if (d[0] == 0xfe && (d[1] & 0xc0) == 0x80) {
+ *s++ = '%';
+ s += strlcpy(s, ifname, sl);
+ }
+ *s = '\0';
+ return l;
+}
+
struct in6_addr *
ipv6_linklocal(const char *ifname)
{
TAILQ_HEAD(rt6head, rt6);
int ipv6_init(void);
+ssize_t ipv6_printaddr(char *, ssize_t, const uint8_t *, const char *);
struct in6_addr *ipv6_linklocal(const char *);
int ipv6_makeaddr(struct in6_addr *, const char *, const struct in6_addr *, int);
int ipv6_makeprefix(struct in6_addr *, const struct in6_addr *, int);
nd_opt_rdnss_lifetime);
op += sizeof(rdnss->nd_opt_rdnss_lifetime);
l = 0;
- for (n = ndo->nd_opt_len - 1; n > 1; n -= 2) {
- memcpy(&addr.s6_addr, op, sizeof(addr.s6_addr));
- cbp = inet_ntop(AF_INET6, &addr,
- ntopbuf, INET6_ADDRSTRLEN);
- if (cbp == NULL) {
- syslog(LOG_ERR,
- "%s: invalid RDNSS address",
- ifp->name);
- } else {
- if (opt) {
- l = strlen(opt);
- opt = xrealloc(opt,
- l + strlen(cbp) + 2);
- opt[l] = ' ';
- strcpy(opt + l + 1, cbp);
- } else
- opt = xstrdup(cbp);
- if (lifetime > 0)
- has_dns = 1;
- }
- op += sizeof(addr.s6_addr);
+ for (n = ndo->nd_opt_len - 1; n > 1; n -= 2,
+ op += sizeof(addr.s6_addr))
+ {
+ l += ipv6_printaddr(NULL, 0, op, ifp->name) + 1;
+ }
+ op = (uint8_t *)ndo;
+ op += offsetof(struct nd_opt_rdnss,
+ nd_opt_rdnss_lifetime);
+ op += sizeof(rdnss->nd_opt_rdnss_lifetime);
+ tmp = opt = malloc(l);
+ for (n = ndo->nd_opt_len - 1; n > 1; n -= 2,
+ op += sizeof(addr.s6_addr))
+ {
+ tmp += ipv6_printaddr(tmp, l, op, ifp->name);
+ *tmp++ = ' ';
+ if (lifetime > 0)
+ has_dns = 1;
}
+ (*--tmp) = '\0';
break;
case ND_OPT_DNSSL: