add support for IPv6 scope ids
diff --git a/CREDITS b/CREDITS
index 2c8c22a..fbb414b 100644
--- a/CREDITS
+++ b/CREDITS
@@ -9,6 +9,7 @@
porting to new systems:
Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+ Arkadiusz Miskiewicz <misiek@pld.org.pl>
Marty Leisner <leisner@sdsp.mc.xerox.com>
Lupe Christoph <lupe@alanya.isar.muc.de>
Thanh Ma <tma@encore.com>
diff --git a/ChangeLog b/ChangeLog
index 96f23bc..c27e8cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2001-02-16 Wichert Akkerman <wakkerma@debian.org>
+ * CREDITS: add Arkadiusz Miskiewicz <misiek@pld.org.pl> who
+ submitted the IP6 scope ID updates
+ * acconfig.h: add HAVE_SIN6_SCOPE_ID and HAVE_SIN6_SCOPE_ID_LINUX
+ * aclocal.m4: add AC_SIN6_SCOPE_ID to check if sin6_scope_id is
+ available
+ * configure.in: check for if_indextoname function and sin6_scope_id
+ * net.c: teach printsock about IP6 scope ids
+
+2001-02-16 Wichert Akkerman <wakkerma@debian.org>
+
* configure.in: test for netinet/tcp.h and netinet/udp.h existance
* net.c: include netinet/tcp.h and netinet/udp.h if they exist
* Makefile.in: use @mandir@ and @bindir@
diff --git a/NEWS b/NEWS
index 2f7f1e1..109c8a6 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@
==============
* Linux/ia64 port added
* The usual Linux syscall updates (includes 32bit uid/gid support),
+* Support IPv6 scope ids
see ChangeLog for details
Changes in 4.2
diff --git a/acconfig.h b/acconfig.h
index b86ddfa..67bdf91 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -77,3 +77,9 @@
/* Define if yor compilers know abuot long long */
#undef HAVE_LONG_LONG
+
+/* Define if struct sockaddr_in6 contains sin6_scope_id field. */
+#undef HAVE_SIN6_SCOPE_ID
+
+/* Define if linux struct sockaddr_in6 contains sin6_scope_id fiels. */
+#undef HAVE_SIN6_SCOPE_ID_LINUX
diff --git a/aclocal.m4 b/aclocal.m4
index 6854e87..93d880e 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -314,3 +314,30 @@
AC_DEFINE(HAVE_LONG_LONG)
fi
])
+
+dnl ### A macro to determine whether sin6_scope_id is available.
+AC_DEFUN(AC_SIN6_SCOPE_ID,
+[AC_MSG_CHECKING(for sin6_scope_id in sockaddr_in6)
+AC_CACHE_VAL(ac_cv_have_sin6_scope_id,
+[AC_TRY_COMPILE([#include <netinet/in.h>],
+[ struct sockaddr_in6 s; s.sin6_scope_id = 0; ],
+ac_cv_have_sin6_scope_id=yes,
+ac_cv_have_sin6_scope_id=no)])
+AC_MSG_RESULT($ac_cv_have_sin6_scope_id)
+if test "$ac_cv_have_sin6_scope_id" = "yes" ; then
+ AC_DEFINE(HAVE_SIN6_SCOPE_ID)
+else
+ AC_MSG_CHECKING(for sin6_scope_id in linux sockaddr_in6)
+ AC_CACHE_VAL(ac_cv_have_sin6_scope_id_linux,
+ [AC_TRY_COMPILE([#include <linux/in6.h>],
+ [ struct sockaddr_in6 s; s.sin6_scope_id = 0; ],
+ ac_cv_have_sin6_scope_id_linux=yes,
+ ac_cv_have_sin6_scope_id_linux=no)])
+ AC_MSG_RESULT($ac_cv_have_sin6_scope_id_linux)
+ if test "$ac_cv_have_sin6_scope_id_linux" = "yes" ; then
+ AC_DEFINE(HAVE_SIN6_SCOPE_ID)
+ AC_DEFINE(HAVE_SIN6_SCOPE_ID_LINUX)
+ fi
+fi
+])
+
diff --git a/configure.in b/configure.in
index 1d29ece..8f60482 100644
--- a/configure.in
+++ b/configure.in
@@ -146,11 +146,12 @@
AC_HEADER_MAJOR
AC_SIG_ATOMIC_T
AC_STAT64
+AC_SIN6_SCOPE_ID
AC_LONG_LONG
if test x$OPSYS != xLINUX; then
AC_CHECK_LIB(nsl, main)
fi
-AC_CHECK_FUNCS(sigaction strerror strsignal pread sys_siglist _sys_siglist getdents mctl putpmsg prctl sendmsg inet_ntop)
+AC_CHECK_FUNCS(sigaction strerror strsignal pread sys_siglist _sys_siglist getdents mctl putpmsg prctl sendmsg inet_ntop if_indextoname)
AC_CHECK_HEADERS(sys/reg.h sys/filio.h sys/acl.h sys/asynch.h sys/door.h sys/stream.h sys/tiuser.h sys/sysconfig.h asm/sigcontext.h ioctls.h sys/ioctl.h sys/ptrace.h termio.h linux/ptrace.h asm/reg.h linux/icmp.h linux/in6.h sys/uio.h linux/netlink.h linux/if_packet.h sys/poll.h sys/vfs.h netinet/tcp.h netinet/udp.h)
AC_DECL_SYS_ERRLIST
AC_DECL_SYS_SIGLIST
diff --git a/net.c b/net.c
index 066965a..05ac089 100644
--- a/net.c
+++ b/net.c
@@ -35,6 +35,13 @@
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
+
+#if defined(HAVE_SIN6_SCOPE_ID_LINUX)
+#define in6_addr in6_addr_libc
+#define ipv6_mreq ipv6_mreq_libc
+#define sockaddr_in6 sockaddr_in6_libc
+#endif
+
#include <netinet/in.h>
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
@@ -43,6 +50,7 @@
#include <netinet/udp.h>
#endif
#include <arpa/inet.h>
+#include <net/if.h>
#if defined(LINUX)
#include <asm/types.h>
#if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC__ + __GLIBC_MINOR__ >= 3)
@@ -52,9 +60,25 @@
#endif
#endif /* LINUX */
-#if defined (__GLIBC__) && ((__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))
+#if defined (__GLIBC__) && (((__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1)) || defined(HAVE_SIN6_SCOPE_ID_LINUX))
#if defined(HAVE_LINUX_IN6_H)
+#if defined(HAVE_SIN6_SCOPE_ID_LINUX)
+#undef in6_addr
+#undef ipv6_mreq
+#undef sockaddr_in6
+#define in6_addr in6_addr_kernel
+#define ipv6_mreq ipv6_mreq_kernel
+#define sockaddr_in6 sockaddr_in6_kernel
+#endif
#include <linux/in6.h>
+#if defined(HAVE_SIN6_SCOPE_ID_LINUX)
+#undef in6_addr
+#undef ipv6_mreq
+#undef sockaddr_in6
+#define in6_addr in6_addr_libc
+#define ipv6_mreq ipv6_mreq_libc
+#define sockaddr_in6 sockaddr_in6_kernel
+#endif
#endif
#endif
@@ -603,9 +627,30 @@
#ifdef HAVE_INET_NTOP
case AF_INET6:
inet_ntop(AF_INET6, &addrbuf.sa6.sin6_addr, string_addr, sizeof(string_addr));
- tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=htonl(%u)}",
- ntohs(addrbuf.sa6.sin6_port), string_addr, ntohl(addrbuf.sa6.sin6_flowinfo));
- break;
+ tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=%u",
+ ntohs(addrbuf.sa6.sin6_port), string_addr,
+ addrbuf.sa6.sin6_flowinfo);
+#ifdef HAVE_SIN6_SCOPE_ID
+ {
+#if defined(HAVE_IF_INDEXTONAME) && defined(IN6_IS_ADDR_LINKLOCAL) && defined(IN6_IS_ADDR_MC_LINKLOCAL)
+ int numericscope = 0;
+ if (IN6_IS_ADDR_LINKLOCAL (&addrbuf.sa6.sin6_addr)
+ || IN6_IS_ADDR_MC_LINKLOCAL (&addrbuf.sa6.sin6_addr)) {
+ char scopebuf[IFNAMSIZ + 1];
+
+ if (if_indextoname (addrbuf.sa6.sin6_scope_id, scopebuf) == NULL)
+ numericscope++;
+ else
+ tprintf(", sin6_scope_id=if_nametoindex(\"%s\")", scopebuf);
+ } else
+ numericscope++;
+
+ if (numericscope)
+#endif
+ tprintf(", sin6_scope_id=%u", addrbuf.sa6.sin6_scope_id);
+ }
+#endif
+ break;
#endif
#if defined(AF_IPX) && defined(linux)
case AF_IPX: