summaryrefslogtreecommitdiff
path: root/sbin/unwind
diff options
context:
space:
mode:
authorKlemens Nanni <kn@cvs.openbsd.org>2021-11-16 16:30:43 +0000
committerKlemens Nanni <kn@cvs.openbsd.org>2021-11-16 16:30:43 +0000
commit6004ccbae4530f504f193ca36ccdc347f94ead2b (patch)
treeacdcd2d0f666ff117718d163b4f2a7a9bbdbac84 /sbin/unwind
parentb40962c7657dbdf8fcd684e64c8fcb88f0dfa3b0 (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.c25
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))) ==