From e20183da23270383e37f5a86f462a68329aed6b6 Mon Sep 17 00:00:00 2001 From: Ted Percival Date: Fri, 4 Dec 2009 13:50:29 -0700 Subject: [PATCH] Fix roken getifaddrs for IPv4 & IPv6 on HP-UX & Solaris HP-UX only returns IPv6 addresses using SIOCGLIFCONF, SIOCGIFCONF has to be used for IPv4 addresses. Solaris uses the same code as described in the comments, which should correctly detect all addresses when running in a zone. Signed-off-by: Love Hornquist Astrand --- lib/roken/getifaddrs.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/lib/roken/getifaddrs.c b/lib/roken/getifaddrs.c index 0ba1b29cf..019a43342 100644 --- a/lib/roken/getifaddrs.c +++ b/lib/roken/getifaddrs.c @@ -1165,9 +1165,43 @@ rk_getifaddrs(struct ifaddrs **ifap) sizeof(struct in6_ifreq)); #endif #if defined(HAVE_IPV6) && defined(SIOCGLIFCONF) && defined(SIOCGLIFFLAGS) - if (ret) - ret = getlifaddrs2 (ifap, AF_INET6, SIOCGLIFCONF, SIOCGLIFFLAGS, + /* Do IPv6 and IPv4 queries separately then join the result. + * + * HP-UX only returns IPv6 addresses using SIOCGLIFCONF, + * SIOCGIFCONF has to be used for IPv4 addresses. The result is then + * merged. + * + * Solaris needs particular care, because a SIOCGLIFCONF lookup using + * AF_UNSPEC can fail in a Zone requiring an AF_INET lookup, so we just + * do them separately the same as for HP-UX. See + * http://repo.or.cz/w/heimdal.git/commitdiff/76afc31e9ba2f37e64c70adc006ade9e37e9ef73 + */ + if (ret) { + int v6err, v4err; + struct ifaddrs *v6addrs, *v4addrs; + + v6err = getlifaddrs2 (&v6addrs, AF_INET6, SIOCGLIFCONF, SIOCGLIFFLAGS, sizeof(struct lifreq)); + v4err = getifaddrs2 (&v4addrs, AF_INET, SIOCGIFCONF, SIOCGIFFLAGS, + sizeof(struct ifreq)); + if (v6err) + v6addrs = NULL; + if (v4err) + v4addrs = NULL; + + if (v6addrs) { + if (v4addrs) + *ifap = append_ifaddrs(v6addrs, v4addrs); + else + *ifap = v6addrs; + } else if (v4addrs) { + *ifap = v4addrs; + } else { + *ifap = NULL; + } + + ret = (v6err || v4err) ? -1 : 0; + } #endif #if defined(HAVE_IPV6) && defined(SIOCGIFCONF) if (ret)