From db8b2c57affd4305b681f301aac63e6b2c56bb2a Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Sat, 12 Jul 2008 00:55:18 +0000 Subject: [PATCH] Use all local addresses except loopback addresses, even if a non-loopback address appears on a loopback interface. This might happen if that's how your VPN code makes your local address visible. Use a variant of Apple's patch, extended to handle the other variations of local address determination. ticket: 6017 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20513 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/os/localaddr.c | 43 ++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/lib/krb5/os/localaddr.c b/src/lib/krb5/os/localaddr.c index 55180808e..0ca3a3208 100644 --- a/src/lib/krb5/os/localaddr.c +++ b/src/lib/krb5/os/localaddr.c @@ -174,6 +174,23 @@ void printaddr (struct sockaddr *sa) } #endif +static int +is_loopback_address(struct sockaddr *sa) +{ + switch (sa->sa_family) { + case AF_INET: { + struct sockaddr_in *s4 = (struct sockaddr_in *)sa; + return s4->sin_addr.s_addr == htonl(INADDR_LOOPBACK); + } + case AF_INET6: { + struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)sa; + return IN6_IS_ADDR_LOOPBACK(&s6->sin6_addr); + } + default: + return 0; + } +} + #ifdef HAVE_IFADDRS_H #include @@ -437,12 +454,6 @@ foreach_localaddr (/*@null@*/ void *data, #endif if ((ifp->ifa_flags & IFF_UP) == 0) continue; - if (ifp->ifa_flags & IFF_LOOPBACK) { - /* Pretend it's not up, so the second pass will skip - it. */ - ifp->ifa_flags &= ~IFF_UP; - continue; - } if (ifp->ifa_addr == NULL) { /* Can't use an interface without an address. Linux apparently does this sometimes. [RT ticket 1770 from @@ -455,13 +466,17 @@ foreach_localaddr (/*@null@*/ void *data, ifp->ifa_flags &= ~IFF_UP; continue; } + if (is_loopback_address(ifp->ifa_addr)) { + /* Pretend it's not up, so the second pass will skip + it. */ + ifp->ifa_flags &= ~IFF_UP; + continue; + } /* If this address is a duplicate, punt. */ match = 0; for (ifp2 = ifp_head; ifp2 && ifp2 != ifp; ifp2 = ifp2->ifa_next) { if ((ifp2->ifa_flags & IFF_UP) == 0) continue; - if (ifp2->ifa_flags & IFF_LOOPBACK) - continue; if (addr_eq (ifp->ifa_addr, ifp2->ifa_addr)) { match = 1; ifp->ifa_flags &= ~IFF_UP; @@ -585,13 +600,11 @@ foreach_localaddr (/*@null@*/ void *data, } /*@=moduncon@*/ -#ifdef IFF_LOOPBACK /* None of the current callers want loopback addresses. */ - if (lifreq.lifr_flags & IFF_LOOPBACK) { + if (is_loopback_address((struct sockaddr *)&lifr->lifr_addr)) { Tprintf ((" loopback\n")); goto skip; } -#endif /* Ignore interfaces that are down. */ if ((lifreq.lifr_flags & IFF_UP) == 0) { Tprintf ((" down\n")); @@ -758,13 +771,11 @@ foreach_localaddr (/*@null@*/ void *data, } /*@=moduncon@*/ -#ifdef IFF_LOOPBACK /* None of the current callers want loopback addresses. */ - if (lifreq.iflr_flags & IFF_LOOPBACK) { + if (is_loopback_address(&lifr->iflr_addr)) { Tprintf ((" loopback\n")); goto skip; } -#endif /* Ignore interfaces that are down. */ if ((lifreq.iflr_flags & IFF_UP) == 0) { Tprintf ((" down\n")); @@ -975,13 +986,11 @@ foreach_localaddr (/*@null@*/ void *data, } /*@=moduncon@*/ -#ifdef IFF_LOOPBACK /* None of the current callers want loopback addresses. */ - if (ifreq.ifr_flags & IFF_LOOPBACK) { + if (is_loopback_address(&ifreq.ifr_addr)) { Tprintf ((" loopback\n")); goto skip; } -#endif /* Ignore interfaces that are down. */ if ((ifreq.ifr_flags & IFF_UP) == 0) { Tprintf ((" down\n")); -- 2.26.2