Mercurial > hg > dhcpcd
changeset 1804:b3ac4d025b78 draft
Set %interface for exported IPv6 link local addresses.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Sat, 24 Nov 2012 20:17:33 +0000 |
| parents | 9507b4c2b0ee |
| children | 725417fae1e5 |
| files | ipv6.c ipv6.h ipv6rs.c |
| diffstat | 3 files changed, 51 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/ipv6.c Fri Nov 16 20:50:18 2012 +0000 +++ b/ipv6.c Sat Nov 24 20:17:33 2012 +0000 @@ -79,6 +79,38 @@ return socket_afnet6; } +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) {
--- a/ipv6.h Fri Nov 16 20:50:18 2012 +0000 +++ b/ipv6.h Sat Nov 24 20:17:33 2012 +0000 @@ -65,6 +65,7 @@ extern int socket_afnet6; int ipv6_open(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_mask(struct in6_addr *, int);
--- a/ipv6rs.c Fri Nov 16 20:50:18 2012 +0000 +++ b/ipv6rs.c Sat Nov 24 20:17:33 2012 +0000 @@ -629,28 +629,25 @@ 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:
