diff options
author | Klemens Nanni <kn@cvs.openbsd.org> | 2021-11-16 16:30:43 +0000 |
---|---|---|
committer | Klemens Nanni <kn@cvs.openbsd.org> | 2021-11-16 16:30:43 +0000 |
commit | 6004ccbae4530f504f193ca36ccdc347f94ead2b (patch) | |
tree | acdcd2d0f666ff117718d163b4f2a7a9bbdbac84 /sbin/unwind | |
parent | b40962c7657dbdf8fcd684e64c8fcb88f0dfa3b0 (diff) |
Install missing scope identifier for IPv6 link-local addresses
RTM_PROPOSAL's list of IP addresses does not contain scope IDs by design.
This is not a problem as the proposal is always bound to an interface,
as long as we use it...
Fill in the scope ID for link-local IPs and replace inet_ntop(3) usage with
getnameinfo(3) in the IPv6 case such that it actually turns up in the string
representation.
This is the unwind specific fix to ensure working IPv6LL; libunbound still
requires another fix.
This commit is the equivalent of sbin/resolvd/resolvd.c revision 1.20
"Install missing scope identifier for IPv6 link-local addresses".
OK florian
Diffstat (limited to 'sbin/unwind')
-rw-r--r-- | sbin/unwind/resolver.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/sbin/unwind/resolver.c b/sbin/unwind/resolver.c index 42730213f9b..1d7019c0851 100644 --- a/sbin/unwind/resolver.c +++ b/sbin/unwind/resolver.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolver.c,v 1.150 2021/10/23 07:25:20 florian Exp $ */ +/* $OpenBSD: resolver.c,v 1.151 2021/11/16 16:30:42 kn Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -1994,8 +1994,10 @@ replace_autoconf_forwarders(struct imsg_rdns_proposal *rdns_proposal) } for (i = 0; i < rdns_count; i++) { + struct sockaddr_storage ss; + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss; struct in_addr addr4; - struct in6_addr addr6; + int err; switch (af) { case AF_INET: @@ -2007,12 +2009,23 @@ replace_autoconf_forwarders(struct imsg_rdns_proposal *rdns_proposal) INET6_ADDRSTRLEN); break; case AF_INET6: - memcpy(&addr6, src, sizeof(struct in6_addr)); + memset(&ss, 0, sizeof(ss)); + memcpy(&sin6->sin6_addr, src, sizeof(sin6->sin6_addr)); src += sizeof(struct in6_addr); - if (IN6_IS_ADDR_LOOPBACK(&addr6)) + if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) continue; - ns = inet_ntop(af, &addr6, ntopbuf, - INET6_ADDRSTRLEN); + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + sin6->sin6_scope_id = rdns_proposal->if_index; + ss.ss_len = sizeof(*sin6); + ss.ss_family = af; + if ((err = getnameinfo((struct sockaddr *)&ss, ss.ss_len, + ntopbuf, sizeof(ntopbuf), + NULL, 0, NI_NUMERICHOST)) != 0) { + log_warnx("getnameinfo: %s", gai_strerror(err)); + continue; + } + ns = ntopbuf; + break; } if ((uw_forwarder = calloc(1, sizeof(struct uw_forwarder))) == |