From: Ken Raeburn Date: Sun, 10 Feb 2002 07:07:19 +0000 (+0000) Subject: get local ipv6 addresses on linux X-Git-Tag: krb5-1.3-alpha1~884 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=1baed0756ffc9695aebca5e3f68c85d3790d5c23;p=krb5.git get local ipv6 addresses on linux git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14138 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog index b0fa0bc7f..dc12af652 100644 --- a/src/lib/krb5/os/ChangeLog +++ b/src/lib/krb5/os/ChangeLog @@ -1,3 +1,12 @@ +2002-02-10 Ken Raeburn + + * localaddr.c (LINUX_IPV6_HACK) [__linux__&& KRB5_USE_INET6]: + Define macro. + (get_linux_ipv6_addrs) [LINUX_IPV6_HACK]: New function, reads + addresses from /proc/net/if_inet6. + (foreach_localaddr) [!HAVE_IFADDRS_H && !SIOCGLIFNUM && + LINUX_IPV6_HACK]: Include ipv6 addresses. + 2002-01-09 Ken Raeburn * hst_realm.c (EAFNOSUPPORT): On Windows, translate to diff --git a/src/lib/krb5/os/localaddr.c b/src/lib/krb5/os/localaddr.c index fc40d7e9e..e315a7696 100644 --- a/src/lib/krb5/os/localaddr.c +++ b/src/lib/krb5/os/localaddr.c @@ -42,6 +42,10 @@ #include #include +#if defined(__linux__) && defined(KRB5_USE_INET6) +#define LINUX_IPV6_HACK +#endif + #if defined(TEST) || defined(DEBUG) # define FAI_PREFIX krb5int # include "fake-addrinfo.c" @@ -268,6 +272,68 @@ get_lifconf (int af, int s, size_t *lenp, /*@out@*/ char *buf) } #endif +#ifdef LINUX_IPV6_HACK +/* Hack workaround until they get a real interface for this. */ +struct linux_ipv6_addr_list { + struct sockaddr_in6 addr; + struct linux_ipv6_addr_list *next; +}; +static struct linux_ipv6_addr_list * +get_linux_ipv6_addrs () +{ + struct linux_ipv6_addr_list *lst = 0; + FILE *f; + + /* _PATH_PROCNET_IFINET6 */ + f = fopen("/proc/net/if_inet6", "r"); + if (f) { + char ifname[21]; + int idx, pfxlen, scope, dadstat; + struct in6_addr a6; + struct linux_ipv6_addr_list *nw; + int i, addrbyte[16]; + + while (fscanf(f, + "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x" + " %2x %2x %2x %2x %20s\n", + &addrbyte[0], &addrbyte[1], &addrbyte[2], &addrbyte[3], + &addrbyte[4], &addrbyte[5], &addrbyte[6], &addrbyte[7], + &addrbyte[8], &addrbyte[9], &addrbyte[10], &addrbyte[11], + &addrbyte[12], &addrbyte[13], &addrbyte[14], + &addrbyte[15], + &idx, &pfxlen, &scope, &dadstat, ifname) != EOF) { + for (i = 0; i < 16; i++) + a6.s6_addr[i] = addrbyte[i]; + if (scope != 0) + continue; +#if 0 + switch (scope) { + case 0: + default: + break; + case IPV6_ADDR_LINKLOCAL: + case IPV6_ADDR_SITELOCAL: + case IPV6_ADDR_COMPATv4: + case IPV6_ADDR_LOOPBACK: + continue; + } +#endif + nw = malloc (sizeof (struct linux_ipv6_addr_list)); + if (nw == 0) + continue; + memset (nw, 0, sizeof (*nw)); + nw->addr.sin6_addr = a6; + nw->addr.sin6_family = AF_INET6; + /* Ignore other fields, we don't actually use them here. */ + nw->next = lst; + lst = nw; + } + fclose (f); + } + return lst; +} +#endif + /* Return value is errno if internal stuff failed, otherwise zero, even in the case where a called function terminated the iteration. @@ -508,6 +574,10 @@ punt: #ifdef SIOCGIFNUM int numifs = -1; #endif +#ifdef LINUX_IPV6_HACK + struct linux_ipv6_addr_list *linux_ipv6_addrs = get_linux_ipv6_addrs (); + struct linux_ipv6_addr_list *lx_v6; +#endif s = socket (USE_AF, USE_TYPE, USE_PROTO); if (s < 0) @@ -622,12 +692,18 @@ punt: /*@=moduncon@*/ } +#ifdef LINUX_IPV6_HACK + for (lx_v6 = linux_ipv6_addrs; lx_v6; lx_v6 = lx_v6->next) + if ((*pass1fn) (data, (struct sockaddr *) &lx_v6->addr)) + goto punt; +#endif + /*@-moduncon@*/ if (betweenfn != NULL && (*betweenfn)(data)) goto punt; /*@=moduncon@*/ - if (pass2fn) + if (pass2fn) { for (i = 0; i < n; i+= ifreq_size(*ifr) ) { ifr = (struct ifreq *)((caddr_t) buf+i); @@ -640,11 +716,24 @@ punt: goto punt; /*@=moduncon@*/ } +#ifdef LINUX_IPV6_HACK + for (lx_v6 = linux_ipv6_addrs; lx_v6; lx_v6 = lx_v6->next) + if ((*pass2fn) (data, (struct sockaddr *) &lx_v6->addr)) + goto punt; +#endif + } punt: /*@-moduncon@*/ closesocket(s); /*@=moduncon@*/ free (buf); +#ifdef LINUX_IPV6_HACK + while (linux_ipv6_addrs) { + lx_v6 = linux_ipv6_addrs->next; + free (linux_ipv6_addrs); + linux_ipv6_addrs = lx_v6; + } +#endif return retval; #endif /* not HAVE_IFADDRS_H */