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: