summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2002-02-10 07:07:19 +0000
committerKen Raeburn <raeburn@mit.edu>2002-02-10 07:07:19 +0000
commit1baed0756ffc9695aebca5e3f68c85d3790d5c23 (patch)
tree71ae39edf1a00163ad0382b3cd4197041e73c247 /src
parent4df3816b982e8fc1893a492e02182570dcf34789 (diff)
downloadkrb5-1baed0756ffc9695aebca5e3f68c85d3790d5c23.tar.gz
krb5-1baed0756ffc9695aebca5e3f68c85d3790d5c23.tar.xz
krb5-1baed0756ffc9695aebca5e3f68c85d3790d5c23.zip
get local ipv6 addresses on linux
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14138 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/lib/krb5/os/ChangeLog9
-rw-r--r--src/lib/krb5/os/localaddr.c91
2 files changed, 99 insertions, 1 deletions
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 <raeburn@mit.edu>
+
+ * 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 <raeburn@mit.edu>
* 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 <stddef.h>
#include <ctype.h>
+#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 */