summaryrefslogtreecommitdiffstats
path: root/lib/libc/net
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2014-07-03 15:56:30 +0000
committerume <ume@FreeBSD.org>2014-07-03 15:56:30 +0000
commite6568c7ce07545364f2ff59ddc355d2fb581da7c (patch)
tree1c864f41a29f067a14b6fadbab1fd8bf19ca7cb6 /lib/libc/net
parentae7f3947da353afd9f1cae6fc79782260a040376 (diff)
downloadFreeBSD-src-e6568c7ce07545364f2ff59ddc355d2fb581da7c.zip
FreeBSD-src-e6568c7ce07545364f2ff59ddc355d2fb581da7c.tar.gz
MFC r267912, r267915:
- Exclude loopback address rather than loopback interface. - style(9) Spotted by: melifaro
Diffstat (limited to 'lib/libc/net')
-rw-r--r--lib/libc/net/getaddrinfo.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c
index 77568a5..b4c1a33 100644
--- a/lib/libc/net/getaddrinfo.c
+++ b/lib/libc/net/getaddrinfo.c
@@ -1532,7 +1532,7 @@ find_afd(int af)
}
/*
- * post-2553: AI_ADDRCONFIG check. Determines which address families are
+ * RFC 3493: AI_ADDRCONFIG check. Determines which address families are
* configured on the local system and correlates with pai->ai_family value.
* If an address family is not configured on the system, it will not be
* queried for. For this purpose, loopback addresses are not considered
@@ -1545,24 +1545,40 @@ static int
addrconfig(struct addrinfo *pai)
{
struct ifaddrs *ifaddrs, *ifa;
+ struct sockaddr_in *sin;
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+#endif
int seen_inet = 0, seen_inet6 = 0;
if (getifaddrs(&ifaddrs) != 0)
- return 0;
+ return (0);
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL || (ifa->ifa_flags & IFF_UP) == 0)
continue;
- if ((ifa->ifa_flags & IFT_LOOP) != 0)
- continue;
switch (ifa->ifa_addr->sa_family) {
case AF_INET:
+ if (seen_inet)
+ continue;
+ sin = (struct sockaddr_in *)(ifa->ifa_addr);
+ if (IN_LOOPBACK(htonl(sin->sin_addr.s_addr)))
+ continue;
seen_inet = 1;
break;
#ifdef INET6
case AF_INET6:
- if (!seen_inet6 && !is_ifdisabled(ifa->ifa_name))
- seen_inet6 = 1;
+ if (seen_inet6)
+ continue;
+ sin6 = (struct sockaddr_in6 *)(ifa->ifa_addr);
+ if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
+ continue;
+ if ((ifa->ifa_flags & IFT_LOOP) != 0 &&
+ IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
+ continue;
+ if (is_ifdisabled(ifa->ifa_name))
+ continue;
+ seen_inet6 = 1;
break;
#endif
}
@@ -1571,16 +1587,16 @@ addrconfig(struct addrinfo *pai)
switch(pai->ai_family) {
case AF_INET6:
- return seen_inet6;
+ return (seen_inet6);
case AF_INET:
- return seen_inet;
+ return (seen_inet);
case AF_UNSPEC:
if (seen_inet == seen_inet6)
- return seen_inet;
+ return (seen_inet);
pai->ai_family = seen_inet ? AF_INET : AF_INET6;
- return 1;
+ return (1);
}
- return 1;
+ return (1);
}
#ifdef INET6
@@ -1591,12 +1607,12 @@ is_ifdisabled(char *name)
int fd;
if ((fd = _socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0)) < 0)
- return -1;
+ return (-1);
memset(&nd, 0, sizeof(nd));
strlcpy(nd.ifname, name, sizeof(nd.ifname));
if (_ioctl(fd, SIOCGIFINFO_IN6, &nd) < 0) {
_close(fd);
- return -1;
+ return (-1);
}
_close(fd);
return ((nd.ndi.flags & ND6_IFF_IFDISABLED) != 0);
OpenPOWER on IntegriCloud