Index: /trunk/Makefile.in
===================================================================
--- /trunk/Makefile.in	(revision 294)
+++ /trunk/Makefile.in	(revision 295)
@@ -124,5 +124,5 @@
 	sh_processcheck.h sh_portcheck.h sh_pthread.h sh_string.h \
 	sh_log_check.h sh_log_evalrule.h sh_log_correlate.h \
-	sh_log_mark.h sh_log_repeat.h sh_inotify.h sh_registry.h
+	sh_log_mark.h sh_log_repeat.h sh_inotify.h sh_registry.h sh_ipvx.h
 
 
@@ -166,4 +166,5 @@
 	$(srcsrc)/sh_inotify.c $(srcsrc)/sh_log_repeat.c \
 	$(srcsrc)/sh_audit.c $(srcsrc)/sh_registry.c \
+	$(srcsrc)/sh_ipvx.c \
 	$(srcsrc)/t-test1.c
 
@@ -185,5 +186,5 @@
 	sh_log_correlate.o sh_log_mark.o sh_log_repeat.o \
 	sh_pthread.o sh_string.o sh_inotify.o dnmalloc.o \
-	sh_audit.o sh_registry.o
+	sh_audit.o sh_registry.o sh_ipvx.o
 
 KERN = kern_head.h kern_head.c
@@ -1689,5 +1690,5 @@
 
 samhain.o: $(srcsrc)/samhain.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_getopt.h $(srcinc)/sh_readconf.h $(srcinc)/sh_hash.h $(srcinc)/sh_nmail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_mem.h $(srcinc)/sh_forward.h $(srcinc)/sh_tools.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h sh_MK.h $(srcinc)/sh_schedule.h 
-sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/zAVLTree.h $(srcinc)/sh_ignore.h 
+sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/zAVLTree.h $(srcinc)/sh_ignore.h 
 sh_utils.o: $(srcsrc)/sh_utils.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_entropy.h $(srcinc)/sh_pthread.h 
 sh_error.o: $(srcsrc)/sh_error.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_database.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_nmail.h $(srcinc)/sh_forward.h $(srcinc)/sh_prelude.h $(srcinc)/sh_pthread.h $(srcinc)/sh_tools.h $(srcinc)/sh_extern.h 
@@ -1701,8 +1702,8 @@
 sh_tiger2_64.o: $(srcsrc)/sh_tiger2_64.c Makefile config_xor.h 
 sh_hash.o: $(srcsrc)/sh_hash.c Makefile config_xor.h $(srcinc)/sh_hash.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_ignore.h $(srcinc)/sh_pthread.h $(srcinc)/sh_forward.h $(srcinc)/sh_hash.h 
-sh_mail.o: $(srcsrc)/sh_mail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_pthread.h $(srcinc)/sh_filter.h $(srcinc)/sh_mail_int.h $(srcinc)/sh_nmail.h $(srcinc)/sh_static.h $(srcinc)/sh_tools.h 
+sh_mail.o: $(srcsrc)/sh_mail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_pthread.h $(srcinc)/sh_filter.h $(srcinc)/sh_mail_int.h $(srcinc)/sh_nmail.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_static.h $(srcinc)/sh_tools.h 
 sh_mem.o: $(srcsrc)/sh_mem.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_pthread.h 
 sh_entropy.o: $(srcsrc)/sh_entropy.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_calls.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
-sh_forward.o: $(srcsrc)/sh_forward.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_forward.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_nmail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/rijndael-api-fst.h $(srcinc)/sh_readconf.h $(srcinc)/zAVLTree.h $(srcinc)/sh_extern.h 
+sh_forward.o: $(srcsrc)/sh_forward.c Makefile config_xor.h $(srcinc)/sh_ipvx.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_forward.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_nmail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/rijndael-api-fst.h $(srcinc)/sh_readconf.h $(srcinc)/zAVLTree.h $(srcinc)/sh_extern.h 
 sh_modules.o: $(srcsrc)/sh_modules.c Makefile config_xor.h $(srcinc)/sh_modules.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utmp.h $(srcinc)/sh_mounts.h $(srcinc)/sh_userfiles.h $(srcinc)/sh_kern.h $(srcinc)/sh_suidchk.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_portcheck.h $(srcinc)/sh_logmon.h $(srcinc)/sh_registry.h 
 sh_utmp.o: $(srcsrc)/sh_utmp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_utmp.h $(srcinc)/sh_pthread.h $(srcinc)/sh_inotify.h 
@@ -1711,9 +1712,9 @@
 sh_srp.o: $(srcsrc)/sh_srp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mem.h $(srcinc)/sh_utils.h $(srcinc)/sh_srp.h $(srcinc)/bignum.h $(srcinc)/CuTest.h 
 sh_fifo.o: $(srcsrc)/sh_fifo.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_mem.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h $(srcinc)/sh_fifo.h 
-sh_tools.o: $(srcsrc)/sh_tools.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_mem.h $(srcinc)/sh_error.h $(srcinc)/sh_tools.h $(srcinc)/sh_utils.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/rijndael-api-fst.h $(srcinc)/rijndael-api-fst.h 
+sh_tools.o: $(srcsrc)/sh_tools.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_mem.h $(srcinc)/sh_error.h $(srcinc)/sh_tools.h $(srcinc)/sh_utils.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/sh_ipvx.h $(srcinc)/rijndael-api-fst.h $(srcinc)/rijndael-api-fst.h 
 sh_html.o: $(srcsrc)/sh_html.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_forward.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_html.h $(srcinc)/zAVLTree.h 
 sh_gpg.o: $(srcsrc)/sh_gpg.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h 
 sh_cat.o: $(srcsrc)/sh_cat.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_cat.h 
-sh_calls.o: $(srcsrc)/sh_calls.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_calls.h 
+sh_calls.o: $(srcsrc)/sh_calls.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_calls.h $(srcinc)/sh_ipvx.h 
 sh_extern.o: $(srcsrc)/sh_extern.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/sh_filter.h $(srcinc)/sh_static.h 
 sh_database.o: $(srcsrc)/sh_database.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h 
@@ -1748,10 +1749,10 @@
 sh_async.o: $(srcsrc)/sh_async.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_calls.h $(srcinc)/sh_error.h 
 sh_processcheck.o: $(srcsrc)/sh_processcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_modules.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
-sh_portcheck.o: $(srcsrc)/sh_portcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_mem.h $(srcinc)/sh_calls.h $(srcinc)/sh_utils.h $(srcinc)/sh_modules.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
+sh_portcheck.o: $(srcsrc)/sh_portcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_mem.h $(srcinc)/sh_calls.h $(srcinc)/sh_utils.h $(srcinc)/sh_modules.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/sh_ipvx.h $(srcinc)/CuTest.h 
 sh_pthread.o: $(srcsrc)/sh_pthread.c Makefile config_xor.h $(srcinc)/sh_pthread.h $(srcinc)/sh_calls.h $(srcinc)/sh_modules.h 
 sh_string.o: $(srcsrc)/sh_string.c Makefile config_xor.h $(srcinc)/sh_string.h $(srcinc)/sh_mem.h $(srcinc)/CuTest.h 
 dnmalloc.o: $(srcsrc)/dnmalloc.c Makefile config.h 
 t-test1.o: $(srcsrc)/t-test1.c Makefile config.h $(srcinc)/malloc.h 
-sh_port2proc.o: $(srcsrc)/sh_port2proc.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error_min.h $(srcinc)/sh_pthread.h 
+sh_port2proc.o: $(srcsrc)/sh_port2proc.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error_min.h $(srcinc)/sh_pthread.h $(srcinc)/sh_ipvx.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h 
 sh_log_parse_syslog.o: $(srcsrc)/sh_log_parse_syslog.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_log_check.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h 
 sh_log_parse_pacct.o: $(srcsrc)/sh_log_parse_pacct.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_log_check.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h 
@@ -1767,5 +1768,6 @@
 sh_log_repeat.o: $(srcsrc)/sh_log_repeat.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h 
 sh_log_parse_generic.o: $(srcsrc)/sh_log_parse_generic.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_log_check.h $(srcinc)/sh_string.h 
-sh_login_track.o: $(srcsrc)/sh_login_track.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_string.h $(srcinc)/sh_tools.h $(srcinc)/sh_error_min.h $(srcinc)/CuTest.h $(srcinc)/CuTest.h 
+sh_login_track.o: $(srcsrc)/sh_login_track.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_string.h $(srcinc)/sh_tools.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_error_min.h $(srcinc)/CuTest.h $(srcinc)/CuTest.h 
 sh_audit.o: $(srcsrc)/sh_audit.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_utils.h 
 sh_registry.o: $(srcsrc)/sh_registry.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_modules.h $(srcinc)/sh_hash.h $(srcinc)/sh_tiger.h 
+sh_ipvx.o: $(srcsrc)/sh_ipvx.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_ipvx.h 
Index: /trunk/acconfig.h
===================================================================
--- /trunk/acconfig.h	(revision 294)
+++ /trunk/acconfig.h	(revision 295)
@@ -363,4 +363,7 @@
 /* Define if your struct utmp has ut_addr.    */
 #undef HAVE_UTADDR
+
+/* Define if your struct utmp has ut_addr_v6  */
+#undef HAVE_UTADDR_V6
 
 /* Define if your includes are broken.        */
Index: /trunk/aclocal.m4
===================================================================
--- /trunk/aclocal.m4	(revision 294)
+++ /trunk/aclocal.m4	(revision 295)
@@ -409,5 +409,5 @@
 x_libraries=NONE
 DESTDIR=
-SH_ENABLE_OPTS="ssp db-reload xml-log message-queue login-watch process-check port-check mounts-check logfile-monitor userfiles debug ptrace static network udp nocl stealth micro-stealth install-name identity khide suidcheck base largefile mail external-scripts encrypt srp dnmalloc"
+SH_ENABLE_OPTS="ssp db-reload xml-log message-queue login-watch process-check port-check mounts-check logfile-monitor userfiles debug ptrace static network udp nocl stealth micro-stealth install-name identity khide suidcheck base largefile mail external-scripts encrypt srp dnmalloc ipv6"
 SH_WITH_OPTS="prelude libprelude-prefix database libwrap cflags libs console altconsole timeserver alttimeserver rnd egd-socket port logserver altlogserver kcheck gpg keyid checksum fp recipient sender trusted tmp-dir config-file log-file pid-file state-dir data-file html-file"
 
Index: /trunk/configure.ac
===================================================================
--- /trunk/configure.ac	(revision 294)
+++ /trunk/configure.ac	(revision 295)
@@ -247,4 +247,5 @@
   		AC_EGREP_HEADER(ut_host, utmpx.h, AC_DEFINE(HAVE_UTHOST) )
   		AC_EGREP_HEADER(ut_addr, utmpx.h, AC_DEFINE(HAVE_UTADDR) )
+  		AC_EGREP_HEADER(ut_addr_v6, utmpx.h, AC_DEFINE(HAVE_UTADDR_V6) )
   		AC_EGREP_HEADER(ut_xtime,utmpx.h, AC_DEFINE(HAVE_UTXTIME) )
   		AC_EGREP_HEADER(ut_type, utmpx.h, AC_DEFINE(HAVE_UTTYPE) )
@@ -369,4 +370,5 @@
 	strptime basename sched_yield hasmntopt \
 	inet_aton gethostbyname setutent setrlimit gethostname uname \
+	getaddrinfo getnameinfo \
 	initgroups getpagesize \
 	ttyname fchmod writev mmap tzset \
@@ -1575,8 +1577,25 @@
                 fi
                 mydebugit="yes"
+	elif test "x${enable_debug}" = "xgdb"; then
+                if test "x${myneedg3}" = "xyes"; then
+                        mydebugdef="-g3"
+                else
+                        mydebugdef="-g"
+                fi
+		mydebugit="yes"
         fi
         ]
 )
 AC_SUBST(mydebugdef)
+
+
+AC_ARG_ENABLE(ipv6,
+        [  --disable-ipv6			disable ipv6 support],
+        [
+        if test "x${enable_ipv6}" = xno; then
+		AC_DEFINE(USE_IPV4,1,[Define if you do not want IPv6])
+        fi
+        ]
+)
 
 if test "x${dnmalloc_ok}" = "xyes"; then
Index: /trunk/depend.dep
===================================================================
--- /trunk/depend.dep	(revision 294)
+++ /trunk/depend.dep	(revision 295)
@@ -2,5 +2,5 @@
 # DO NOT DELETE THIS LINE
 samhain.o: $(srcsrc)/samhain.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_files.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_getopt.h $(srcinc)/sh_readconf.h $(srcinc)/sh_hash.h $(srcinc)/sh_nmail.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_mem.h $(srcinc)/sh_forward.h $(srcinc)/sh_tools.h $(srcinc)/sh_hash.h $(srcinc)/sh_extern.h $(srcinc)/sh_modules.h $(srcinc)/sh_ignore.h $(srcinc)/sh_prelink.h sh_MK.h $(srcinc)/sh_schedule.h 
-sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/zAVLTree.h $(srcinc)/sh_ignore.h 
+sh_unix.o: $(srcsrc)/sh_unix.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_hash.h $(srcinc)/sh_tools.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_tiger.h $(srcinc)/sh_prelink.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_prelude.h $(srcinc)/zAVLTree.h $(srcinc)/sh_ignore.h 
 sh_utils.o: $(srcsrc)/sh_utils.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_entropy.h $(srcinc)/sh_pthread.h 
 sh_error.o: $(srcsrc)/sh_error.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_database.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_nmail.h $(srcinc)/sh_forward.h $(srcinc)/sh_prelude.h $(srcinc)/sh_pthread.h $(srcinc)/sh_tools.h $(srcinc)/sh_extern.h 
@@ -14,8 +14,8 @@
 sh_tiger2_64.o: $(srcsrc)/sh_tiger2_64.c Makefile config_xor.h 
 sh_hash.o: $(srcsrc)/sh_hash.c Makefile config_xor.h $(srcinc)/sh_hash.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_gpg.h $(srcinc)/sh_unix.h $(srcinc)/sh_files.h $(srcinc)/sh_ignore.h $(srcinc)/sh_pthread.h $(srcinc)/sh_forward.h $(srcinc)/sh_hash.h 
-sh_mail.o: $(srcsrc)/sh_mail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_pthread.h $(srcinc)/sh_filter.h $(srcinc)/sh_mail_int.h $(srcinc)/sh_nmail.h $(srcinc)/sh_static.h $(srcinc)/sh_tools.h 
+sh_mail.o: $(srcsrc)/sh_mail.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mail.h $(srcinc)/sh_utils.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_pthread.h $(srcinc)/sh_filter.h $(srcinc)/sh_mail_int.h $(srcinc)/sh_nmail.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_static.h $(srcinc)/sh_tools.h 
 sh_mem.o: $(srcsrc)/sh_mem.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h $(srcinc)/sh_mem.h $(srcinc)/sh_pthread.h 
 sh_entropy.o: $(srcsrc)/sh_entropy.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_calls.h $(srcinc)/sh_pthread.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
-sh_forward.o: $(srcsrc)/sh_forward.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_forward.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_nmail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/rijndael-api-fst.h $(srcinc)/sh_readconf.h $(srcinc)/zAVLTree.h $(srcinc)/sh_extern.h 
+sh_forward.o: $(srcsrc)/sh_forward.c Makefile config_xor.h $(srcinc)/sh_ipvx.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_forward.h $(srcinc)/sh_srp.h $(srcinc)/sh_fifo.h $(srcinc)/sh_tools.h $(srcinc)/sh_entropy.h $(srcinc)/sh_html.h $(srcinc)/sh_nmail.h $(srcinc)/sh_socket.h $(srcinc)/sh_static.h $(srcinc)/rijndael-api-fst.h $(srcinc)/sh_readconf.h $(srcinc)/zAVLTree.h $(srcinc)/sh_extern.h 
 sh_modules.o: $(srcsrc)/sh_modules.c Makefile config_xor.h $(srcinc)/sh_modules.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utmp.h $(srcinc)/sh_mounts.h $(srcinc)/sh_userfiles.h $(srcinc)/sh_kern.h $(srcinc)/sh_suidchk.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_portcheck.h $(srcinc)/sh_logmon.h $(srcinc)/sh_registry.h 
 sh_utmp.o: $(srcsrc)/sh_utmp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_modules.h $(srcinc)/sh_utmp.h $(srcinc)/sh_pthread.h $(srcinc)/sh_inotify.h 
@@ -24,9 +24,9 @@
 sh_srp.o: $(srcsrc)/sh_srp.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_mem.h $(srcinc)/sh_utils.h $(srcinc)/sh_srp.h $(srcinc)/bignum.h $(srcinc)/CuTest.h 
 sh_fifo.o: $(srcsrc)/sh_fifo.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_mem.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h $(srcinc)/sh_fifo.h 
-sh_tools.o: $(srcsrc)/sh_tools.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_mem.h $(srcinc)/sh_error.h $(srcinc)/sh_tools.h $(srcinc)/sh_utils.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/rijndael-api-fst.h $(srcinc)/rijndael-api-fst.h 
+sh_tools.o: $(srcsrc)/sh_tools.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_mem.h $(srcinc)/sh_error.h $(srcinc)/sh_tools.h $(srcinc)/sh_utils.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/sh_ipvx.h $(srcinc)/rijndael-api-fst.h $(srcinc)/rijndael-api-fst.h 
 sh_html.o: $(srcsrc)/sh_html.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_forward.h $(srcinc)/sh_error.h $(srcinc)/sh_unix.h $(srcinc)/sh_utils.h $(srcinc)/sh_html.h $(srcinc)/zAVLTree.h 
 sh_gpg.o: $(srcsrc)/sh_gpg.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h 
 sh_cat.o: $(srcsrc)/sh_cat.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_cat.h 
-sh_calls.o: $(srcsrc)/sh_calls.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_calls.h 
+sh_calls.o: $(srcsrc)/sh_calls.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_calls.h $(srcinc)/sh_ipvx.h 
 sh_extern.o: $(srcsrc)/sh_extern.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/sh_filter.h $(srcinc)/sh_static.h 
 sh_database.o: $(srcsrc)/sh_database.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h 
@@ -58,5 +58,5 @@
 sh_prelink.o: $(srcsrc)/sh_prelink.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_tiger.h $(srcinc)/sh_extern.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h 
 sh_static.o: $(srcsrc)/sh_static.c Makefile config_xor.h $(srcinc)/sh_pthread.h 
-sh_portcheck.o: $(srcsrc)/sh_portcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_mem.h $(srcinc)/sh_calls.h $(srcinc)/sh_utils.h $(srcinc)/sh_modules.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
+sh_portcheck.o: $(srcsrc)/sh_portcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_mem.h $(srcinc)/sh_calls.h $(srcinc)/sh_utils.h $(srcinc)/sh_modules.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/sh_ipvx.h $(srcinc)/CuTest.h 
 sh_processcheck.o: $(srcsrc)/sh_processcheck.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_modules.h $(srcinc)/sh_processcheck.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/sh_pthread.h $(srcinc)/CuTest.h 
 sh_prelude_old.o: $(srcsrc)/sh_prelude_old.c Makefile config_xor.h $(srcinc)/slib.h $(srcinc)/sh_mem.h $(srcinc)/sh_cat.h $(srcinc)/sh_error_min.h $(srcinc)/sh_prelude.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h 
@@ -68,5 +68,5 @@
 dnmalloc-portable.o: $(srcsrc)/dnmalloc-portable.c Makefile config.h 
 dnmalloc.o: $(srcsrc)/dnmalloc.c Makefile config.h 
-sh_port2proc.o: $(srcsrc)/sh_port2proc.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error_min.h $(srcinc)/sh_pthread.h 
+sh_port2proc.o: $(srcsrc)/sh_port2proc.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error_min.h $(srcinc)/sh_pthread.h $(srcinc)/sh_ipvx.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h 
 sh_log_parse_syslog.o: $(srcsrc)/sh_log_parse_syslog.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_log_check.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h 
 sh_log_parse_pacct.o: $(srcsrc)/sh_log_parse_pacct.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_log_check.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h 
@@ -82,5 +82,6 @@
 sh_log_repeat.o: $(srcsrc)/sh_log_repeat.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_string.h $(srcinc)/sh_log_check.h $(srcinc)/sh_log_evalrule.h 
 sh_log_parse_generic.o: $(srcsrc)/sh_log_parse_generic.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_log_check.h $(srcinc)/sh_string.h 
-sh_login_track.o: $(srcsrc)/sh_login_track.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_string.h $(srcinc)/sh_tools.h $(srcinc)/sh_error_min.h $(srcinc)/CuTest.h $(srcinc)/CuTest.h 
+sh_login_track.o: $(srcsrc)/sh_login_track.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_string.h $(srcinc)/sh_tools.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_error_min.h $(srcinc)/CuTest.h $(srcinc)/CuTest.h 
 sh_audit.o: $(srcsrc)/sh_audit.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_extern.h $(srcinc)/sh_utils.h 
 sh_registry.o: $(srcsrc)/sh_registry.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_modules.h $(srcinc)/sh_hash.h $(srcinc)/sh_tiger.h 
+sh_ipvx.o: $(srcsrc)/sh_ipvx.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/sh_utils.h $(srcinc)/sh_ipvx.h 
Index: /trunk/depend.sum
===================================================================
--- /trunk/depend.sum	(revision 294)
+++ /trunk/depend.sum	(revision 295)
@@ -1,1 +1,1 @@
-2205834486
+1732172137
Index: /trunk/docs/Changelog
===================================================================
--- /trunk/docs/Changelog	(revision 294)
+++ /trunk/docs/Changelog	(revision 295)
@@ -1,3 +1,4 @@
 2.8.0:
+	* Support IPv6
 	* Add registry checking
 	* Use auditd records to find out who did it
Index: /trunk/include/samhain.h
===================================================================
--- /trunk/include/samhain.h	(revision 294)
+++ /trunk/include/samhain.h	(revision 295)
@@ -34,4 +34,28 @@
  **************************************************/
 
+/* IPv6 */
+#if defined(HAVE_GETNAMEINFO) && defined(HAVE_GETADDRINFO)
+
+#if defined(SH_COMPILE_STATIC) && defined(__linux__)
+#undef USE_IPVX
+#define SH_SOCKMAX 1
+#else
+
+#if defined(USE_IPV4)
+#undef USE_IPVX
+#else
+#define USE_IPVX 1
+#endif
+
+#define SH_SOCKMAX 8
+#endif
+
+#else
+#undef USE_IPVX
+#define SH_SOCKMAX 1
+#endif
+
+/* end IPv6 */
+
 #define REPLACE_OLD
 
@@ -39,5 +63,5 @@
  * IPv6 is 8 groups of 4 hex digits seperated by colons.
  */
-#define SH_IP_BUF        40
+#define SH_IP_BUF        48
 #define SH_MINIBUF       64
 #define SH_BUFSIZE     1024
Index: /trunk/include/sh_calls.h
===================================================================
--- /trunk/include/sh_calls.h	(revision 294)
+++ /trunk/include/sh_calls.h	(revision 295)
@@ -35,7 +35,9 @@
 int sh_aud_set_functions(const char * str_s);
 
+#ifdef SH_IPVX_H
+long int retry_accept(const char * file, int line, 
+		      int fd, struct sh_sockaddr *serv_addr, int * addrlen);
+#endif
 
-long int retry_accept(const char * file, int line, 
-		      int fd, struct sockaddr *serv_addr, int * addrlen);
 long int retry_stat (const char * file, int line, 
 		     const char *file_name, struct stat *buf);
Index: /trunk/include/sh_ipvx.h
===================================================================
--- /trunk/include/sh_ipvx.h	(revision 295)
+++ /trunk/include/sh_ipvx.h	(revision 295)
@@ -0,0 +1,75 @@
+#ifndef SH_IPVX_H
+#define SH_IPVX_H
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#if defined(USE_IPVX)
+#define SH_SSP_LEN(a) ((a)->ss_family == AF_INET) ? \
+	sizeof(struct sockaddr_in) : \
+	sizeof(struct sockaddr_in6)
+
+#define SH_SS_LEN(a) ((a).ss_family == AF_INET) ? \
+	sizeof(struct sockaddr_in) : \
+	sizeof(struct sockaddr_in6)
+#else
+#define SH_SSP_LEN(a) sizeof(struct sockaddr_in)
+#define SH_SS_LEN(a)  sizeof(struct sockaddr_in)
+#endif
+
+struct sh_sockaddr {
+  int ss_family;
+
+  struct sockaddr_in  sin;
+#if defined(USE_IPVX)
+  struct sockaddr_in6 sin6;
+#endif
+};
+
+/* Cast a sockaddress
+ */
+struct sockaddr * sh_ipvx_sockaddr_cast (struct sh_sockaddr * ss);
+
+/* Compare with any_address
+ */
+int sh_ipvx_isany (struct sh_sockaddr * a);
+
+/* Compare two addresses
+ */
+int sh_ipvx_cmp(struct sh_sockaddr * a, struct sh_sockaddr * b);
+
+/* Set the port
+ */
+int sh_ipvx_set_port(struct sh_sockaddr * ss, int port);
+
+/* Save a sockaddress
+ */
+void sh_ipvx_save(struct sh_sockaddr * ss, int sa_family, struct sockaddr * sa);
+
+/* Determine whether the given address is numeric
+ */
+int sh_ipvx_is_numeric (const char * addr);
+
+/* Convert a network address to an ascii numeric address
+ */
+int sh_ipvx_ntoa (char * name, size_t name_size, struct sh_sockaddr * ss);
+
+/* Convert an ascii numeric address to a network address
+ */
+int sh_ipvx_aton (const char * name, struct sh_sockaddr * ss);
+
+/* Try to find canonical hostname
+ */
+char * sh_ipvx_canonical(const char * hostname, char * numeric, size_t nlen);
+
+/* Convert address to hostname
+ */
+char * sh_ipvx_addrtoname(struct sh_sockaddr * ss);
+
+/* Try a reverse lookup
+ */
+int sh_ipvx_reverse_check_ok (char * peer, int port, struct sh_sockaddr * ss);
+#endif
Index: /trunk/include/sh_tools.h
===================================================================
--- /trunk/include/sh_tools.h	(revision 294)
+++ /trunk/include/sh_tools.h	(revision 295)
@@ -28,5 +28,5 @@
  */
 char * sh_tools_safe_name(const char * str, int flag);
-int is_numeric (const char * address);
+
 int connect_port (char * address, int port, 
 		  char * ecall, int * errnum, char * errmsg, int errsiz);
Index: /trunk/src/cutest_sh_tools.c
===================================================================
--- /trunk/src/cutest_sh_tools.c	(revision 294)
+++ /trunk/src/cutest_sh_tools.c	(revision 295)
@@ -6,4 +6,5 @@
 #include "samhain.h"
 #include "sh_tools.h"
+#include "sh_ipvx.h"
 
 void Test_sh_tools_safe_name_01(CuTest *tc) {
@@ -106,12 +107,12 @@
   char* input  = strdup("hello world");
 
-  CuAssertTrue(tc, !is_numeric(input));
+  CuAssertTrue(tc, !sh_ipvx_is_numeric(input));
 
   input  = strdup("127.0.0.1");
-  CuAssertTrue(tc, is_numeric(input));
+  CuAssertTrue(tc, sh_ipvx_is_numeric(input));
   input  = strdup("127.0.0.de");
-  CuAssertTrue(tc, !is_numeric(input));
+  CuAssertTrue(tc, !sh_ipvx_is_numeric(input));
   input  = strdup("127");
-  CuAssertTrue(tc, is_numeric(input));
+  CuAssertTrue(tc, sh_ipvx_is_numeric(input));
 }
 
Index: /trunk/src/sh_audit.c
===================================================================
--- /trunk/src/sh_audit.c	(revision 294)
+++ /trunk/src/sh_audit.c	(revision 295)
@@ -276,7 +276,7 @@
   for (i = 0; i < 4; ++i)
     {
-      if (0 == access(_(actl_paths[i]), F_OK))
-	{
-	  if (0 == access(_(actl_paths[i]), X_OK))
+      if (0 == access(_(actl_paths[i]), F_OK))/* flawfinder: ignore */
+	{
+	  if (0 == access(_(actl_paths[i]), X_OK))/* flawfinder: ignore */
 	    {
 	      actl_pnum = i;
Index: /trunk/src/sh_calls.c
===================================================================
--- /trunk/src/sh_calls.c	(revision 294)
+++ /trunk/src/sh_calls.c	(revision 295)
@@ -51,4 +51,5 @@
 #include "sh_error.h"
 #include "sh_calls.h"
+#include "sh_ipvx.h"
 
 #undef  FIL__
@@ -134,5 +135,5 @@
 }
 
-static struct in_addr bind_addr;
+static struct sh_sockaddr bind_addr;
 static int        use_bind_addr = 0;
 
@@ -147,8 +148,12 @@
     reject = 1;
 
-  if (0 == /*@-unrecog@*/inet_aton(str, &bind_addr)/*@+unrecog@*/) 
-    {
-      return -1;
-    }
+#if defined(USE_IPVX)
+  if (0 == sh_ipvx_aton(str, &bind_addr)) 
+    return -1;
+#else
+  if (0 == inet_aton(str, &(bind_addr.sin.sin_addr))) 
+    return -1;
+#endif
+
   use_bind_addr = 1;
   return 0;
@@ -161,5 +166,4 @@
   int error;
   long int val_retry = 0;
-  static struct sockaddr_in new_addr;
   char errbuf[SH_ERRBUF_SIZE];
 
@@ -170,10 +174,7 @@
   if (0 != use_bind_addr) 
     {
-      memcpy(&new_addr.sin_addr, &bind_addr, sizeof(struct in_addr));
-      new_addr.sin_family = AF_INET;
-      
-      val_retry = /*@-unrecog@*/bind(sockfd, 
-				     (struct sockaddr*)&new_addr, 
-				     sizeof(struct sockaddr_in))/*@+unrecog@*/;
+      int slen = SH_SS_LEN(bind_addr);
+
+      val_retry = bind(sockfd, sh_ipvx_sockaddr_cast(&bind_addr), slen);
     }
 
@@ -181,6 +182,5 @@
     {
       do {
-	val_retry = 
-	  /*@-unrecog@*/connect(sockfd, serv_addr, addrlen)/*@+unrecog@*/;
+	val_retry = connect(sockfd, serv_addr, addrlen);
       } while (val_retry < 0 && (errno == EINTR || errno == EINPROGRESS));
     }
@@ -188,20 +188,19 @@
   error = errno;
   if (val_retry != 0) {
-    /* ugly cast back to struct sockaddr_in :-(
-     */
+    long eport;
+    char eaddr[SH_IP_BUF];
+
+    struct sh_sockaddr ss;
+    sh_ipvx_save(&ss, serv_addr->sa_family, serv_addr);
+    sh_ipvx_ntoa(eaddr, sizeof(eaddr), &ss);
+    
+    if (serv_addr->sa_family == AF_INET)
+      eport = (long) ntohs(((struct sockaddr_in *)serv_addr)->sin_port);
+    else
+      eport = (long) ntohs(((struct sockaddr_in6 *)serv_addr)->sin6_port);
+
     sh_error_handle ((-1), file, line, error, MSG_ERR_CONNECT, 
 		     sh_error_message(error, errbuf, sizeof(errbuf)),
-		     (long) sockfd,
-		     /*@-unrecog -type@*/
-		     (long) ntohs(((struct sockaddr_in *)serv_addr)->sin_port),
-		     /*@+unrecog +type@*/
-#ifdef HAVE_INET_ATON
-		     /*@-unrecog -type@*/
-		     inet_ntoa( ((struct sockaddr_in *)serv_addr)->sin_addr )
-		     /*@+unrecog +type@*/
-#else
-		     _("unknown")
-#endif
-		     );
+		     (long) sockfd, eport, eaddr);
   }
   errno = error;    
@@ -210,11 +209,12 @@
 
 long int retry_accept(const char * file, int line, int fd, 
-		      struct sockaddr *serv_addr, int * addrlen)
+		      struct sh_sockaddr *serv_addr, int * addrlen)
 {
   int  error;
   long int val_retry = -1;
   char errbuf[SH_ERRBUF_SIZE];
-
-  ACCEPT_TYPE_ARG3 my_addrlen = (ACCEPT_TYPE_ARG3) *addrlen;
+  struct sockaddr_storage ss;
+
+  ACCEPT_TYPE_ARG3 my_addrlen = sizeof(ss);
 
   errno              = 0;
@@ -223,6 +223,7 @@
 
   do {
-    val_retry = /*@-unrecog@*/accept(fd, serv_addr, &my_addrlen)/*@+unrecog@*/;
+    val_retry = accept(fd, (struct sockaddr *)&ss, &my_addrlen);
   } while (val_retry < 0 && errno == EINTR);
+
   *addrlen = (int) my_addrlen;
   error = errno;
@@ -232,5 +233,8 @@
 		       (long) fd );
   }
-  errno = error;    
+  errno = error;
+
+  sh_ipvx_save(serv_addr, ss.ss_family, (struct sockaddr *) &ss);
+
   SL_RETURN(val_retry, _("retry_accept"));
 }
Index: /trunk/src/sh_forward.c
===================================================================
--- /trunk/src/sh_forward.c	(revision 294)
+++ /trunk/src/sh_forward.c	(revision 295)
@@ -121,4 +121,5 @@
 #endif
 
+#include "sh_ipvx.h"
 #include "samhain.h"
 #include "sh_tiger.h"
@@ -239,5 +240,5 @@
        * --> last part must be kept
        */
-      if (0 != is_numeric(name))
+      if (0 != sh_ipvx_is_numeric(name))
 	{
 	  SL_RETURN( name, _("sh_strip_domain"));
@@ -2187,5 +2188,5 @@
   char            FileType[5];
 
-  struct sockaddr_in addr_peer;
+  struct sh_sockaddr addr_peer;
 } sh_conn_t;
 
@@ -2592,14 +2593,12 @@
 #endif
 
-int check_addr (const char * claim, struct sockaddr_in addr_peer)
+int check_addr (const char * claim, struct sh_sockaddr * addr_peer)
 {
   char               h_name[MAXHOSTNAMELEN + 1];
   char               h_peer[MAXHOSTNAMELEN + 1];
-  char               h_peer_IP[16];
-  char               tmp_peer_IP[16];
-  struct hostent   * he;
-  char            ** p = NULL;
-  int                i;
-  int                flag = 0;
+  char               h_peer_IP[SH_IP_BUF];
+  char               tmp_peer_IP[SH_IP_BUF];
+  char             * canonical;
+  char               numeric[SH_IP_BUF];
 
   SL_ENTER(_("check_addr"));
@@ -2614,21 +2613,12 @@
   /* Make sure we have the canonical name for the client
    */
-  he = sh_gethostbyname (claim);
-
-  if (he != NULL && he->h_name != NULL)
-    {
-      if (NULL == strchr(he->h_name, '.') && he->h_addr_list != NULL)
-	{
-	  he = sh_gethostbyaddr(he->h_addr_list[0], 
-				he->h_length, 
-				he->h_addrtype);
-	}
-    }
+  canonical = sh_ipvx_canonical(claim, numeric, sizeof(numeric));
 
   /* copy canonical name into h_name
    */
-  if (he != NULL && he->h_name != NULL)
-    {
-      sl_strlcpy(h_name, he->h_name, MAXHOSTNAMELEN + 1);
+  if (canonical != NULL)
+    {
+      sl_strlcpy(h_name, canonical, MAXHOSTNAMELEN + 1);
+      SH_FREE(canonical);
     }
   else
@@ -2642,20 +2632,17 @@
   /* get canonical name of socket peer
    */
-  he = sh_gethostbyaddr ((char *) &(addr_peer.sin_addr), 
-			 sizeof(addr_peer.sin_addr),
-			 AF_INET);
-
-  if (he != NULL && he->h_name != NULL)
-    {
-      if (0 == sl_strcmp(he->h_name, _("localhost")))
+  canonical = sh_ipvx_addrtoname(addr_peer);
+
+  if (canonical)
+    {
+      if (0 == sl_strcmp(canonical, _("localhost")))
 	sl_strlcpy(h_peer, sh.host.name, MAXHOSTNAMELEN + 1);
       else
-	sl_strlcpy(h_peer, he->h_name, MAXHOSTNAMELEN + 1);
+	sl_strlcpy(h_peer, canonical, MAXHOSTNAMELEN + 1);
+      SH_FREE(canonical);
     }
   else
     {
-      sl_strlcpy(tmp_peer_IP,
-		 inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
-		 16);
+      sh_ipvx_ntoa (tmp_peer_IP, sizeof(tmp_peer_IP), addr_peer);
       sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_RESPEER,
 		      claim, tmp_peer_IP);
@@ -2663,7 +2650,5 @@
     }
 
-  sl_strlcpy(h_peer_IP, 
-	     inet_ntoa (*(struct in_addr *) he->h_addr),
-	     16);
+  sh_ipvx_ntoa (h_peer_IP, sizeof(h_peer_IP), addr_peer);
 
 #if 0
@@ -2676,32 +2661,18 @@
   /* reverse lookup
    */
-  if (0 != sl_strncmp(_("127."), 
-		      inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
-		      4))
-    {
-      he = sh_gethostbyname(h_peer);
-      
-      if (he != NULL)
-	{
-	  for (p = he->h_addr_list; *p; ++p)
-	    {
-	      if (0 == memcmp (*p, &(addr_peer.sin_addr), 
-			       sizeof(addr_peer.sin_addr))) 
-		break;
-	    }
-	}
-      if (he == NULL || *p == NULL) 
-	{
-	  sl_strlcpy(tmp_peer_IP,
-		     inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
-		     16);
-	  sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKERS,
-			  claim, h_peer, tmp_peer_IP);
-	  SL_RETURN ((0), _("check_addr"));
-	}
-    }
-
-  sh_tolower(h_peer);
-  sh_tolower(h_name);
+  if (0 == sh_ipvx_reverse_check_ok (h_peer, ServerPort, addr_peer))
+    {
+      sh_ipvx_ntoa (tmp_peer_IP, sizeof(tmp_peer_IP), addr_peer);
+
+      sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKERS,
+		      claim, h_peer, tmp_peer_IP);
+      SL_RETURN ((0), _("check_addr"));
+    }
+
+  /* Check whether claim and peer are identical
+   */
+
+  sh_tolower(h_peer); /* Canonical name of what the peer is     */
+  sh_tolower(h_name); /* Canonical name of what the peer claims */
 
   if ((0 == sl_strcmp(h_peer, h_name)) || (0 == sl_strcmp(h_peer_IP, h_name)))
@@ -2709,7 +2680,11 @@
       SL_RETURN ((0), _("check_addr"));
     }
+#if !defined(USE_IPVX)
   else
     {
-      i = 0;
+      struct hostent   * he = sh_gethostbyname(h_peer);
+      int                i = 0;
+      int                flag = 0;
+
       while (he->h_aliases[i] != NULL)
 	{
@@ -2725,4 +2700,5 @@
 			claim, h_peer);
     }
+#endif
 
   SL_RETURN ((0), _("check_addr"));
@@ -2742,10 +2718,11 @@
 {
   client_t * this_client;
-  char       peer_ip[16];
+  char       peer_ip[SH_IP_BUF];
+  char       numerical[SH_IP_BUF];
   char       peer_name[MAXHOSTNAMELEN+1];
   char     * search_string;
-  struct sockaddr_in peer_addr;
-  struct hostent   * he;
-  char    ** p = NULL;
+
+  struct sh_sockaddr peer_addr;
+  char             * canonical;
 
   SL_ENTER(_("search_register"));
@@ -2753,51 +2730,25 @@
   if (UseSocketPeer == S_TRUE)
     {
-      peer_addr = conn->addr_peer;
-      sl_strlcpy(peer_ip, 
-		 inet_ntoa (*(struct in_addr *) &(peer_addr.sin_addr)), 16);
+      memcpy(&peer_addr, &(conn->addr_peer), sizeof(struct sh_sockaddr));
+      sh_ipvx_ntoa (peer_ip, sizeof(peer_ip), &peer_addr);
 
       /* get canonical name of socket peer
        */
-      he = sh_gethostbyaddr ((char *) &(peer_addr.sin_addr), 
-			     sizeof(peer_addr.sin_addr),
-			     AF_INET);
-
-      if (he != NULL && he->h_name != NULL)
-	{
-	  if (0 == sl_strcmp(he->h_name, _("localhost")))
+      canonical = sh_ipvx_canonical(peer_ip, numerical, sizeof(numerical));
+
+      if (canonical != NULL)
+	{
+	  if (0 == sl_strcmp(canonical, _("localhost")))
 	    sl_strlcpy(peer_name, sh.host.name, MAXHOSTNAMELEN + 1);
 	  else
-	    sl_strlcpy(peer_name, he->h_name, MAXHOSTNAMELEN + 1);
-
-	  /* Reverse lookup 
-	   */
-	  if (0 != sl_strncmp(peer_ip, _("127."), 4))
-	    {
-	      he = sh_gethostbyname(peer_name);
-	      
-	      if (he != NULL)
-	      {
-		for (p = he->h_addr_list; *p; ++p)
-		  {
-		    if (0 == memcmp (*p, &(peer_addr.sin_addr), 
-				     sizeof(peer_addr.sin_addr))) 
-		      break;
-		  }
-	      }
-	      if (he == NULL || *p == NULL) 
-	      {
-		/*
-		sh_error_handle(lookup_err, FIL__, __LINE__, 0, 
-				MSG_TCP_LOOKERS,
-				conn->buf[pos], peer_name, peer_ip);
-		*/
-		sl_strlcpy(peer_name, peer_ip, MAXHOSTNAMELEN + 1);
-	      }
-	    }
-	}
-      else
+	    sl_strlcpy(peer_name, canonical,    MAXHOSTNAMELEN + 1);
+	  SH_FREE(canonical);
+	}
+
+      if (0 == sh_ipvx_reverse_check_ok (peer_name, ServerPort, &peer_addr))
 	{
 	  sl_strlcpy(peer_name, peer_ip, MAXHOSTNAMELEN + 1);
 	}
+
       search_string = peer_name;
     }
@@ -2806,5 +2757,5 @@
       search_string = &(conn->buf[pos]);
 
-      if (0 != check_addr (search_string, conn->addr_peer))
+      if (0 != check_addr (search_string, &(conn->addr_peer)))
 	{
 	  sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
@@ -3662,5 +3613,9 @@
                    */
 #if defined(SH_WITH_SERVER) && defined(HAVE_LIBPRELUDE)
-                  sh_error_set_peer_ip( inet_ntoa (*(struct in_addr *) &(conn->addr_peer.sin_addr)) );                        
+		  {
+		    char peer_ip[SH_IP_BUF];
+		    sh_ipvx_ntoa(peer_ip, sizeof(peer_ip), conn->addr_peer); 
+		    sh_error_set_peer_ip( peer_ip );
+		  }                        
 #endif
                   sh_error_set_peer(sh_strip_domain (conn->peer));
@@ -4684,5 +4639,5 @@
   int                errflag;
   int                rc;
-  struct sockaddr_in addr;
+  struct sh_sockaddr addr;
 #ifdef SH_USE_LIBWRAP
   struct request_info request;
@@ -4697,6 +4652,5 @@
   SL_ENTER(_("sh_forward_accept"));
 
-  rc = retry_accept(FIL__, __LINE__, sock, 
-		    (struct sockaddr *) &addr, &addrlen);
+  rc = retry_accept(FIL__, __LINE__, sock, &addr, &addrlen);
 
   if (rc >= 0)
@@ -4714,11 +4668,11 @@
 
 #ifdef SH_USE_LIBWRAP
-      sl_strlcpy(daemon, SH_INSTALL_NAME, 128);
+      sl_strlcpy(daemon, SH_INSTALL_NAME, sizeof(daemon));
       request_init(&request, RQ_DAEMON, daemon, RQ_FILE, rc, 0);
       fromhost(&request);
       if (!hosts_access(&request)) 
 	{
-	  sl_strlcpy(errbuf, _("Refused connection from "), 128);
-	  sl_strlcat(errbuf,   eval_client(&request), 128);
+	  sl_strlcpy(errbuf, _("Refused connection from "), sizeof(errbuf));
+	  sl_strlcat(errbuf,   eval_client(&request), sizeof(errbuf));
 
 	  sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
@@ -4731,5 +4685,5 @@
 #endif
 
-      memcpy (&(newconn->addr_peer), &addr, sizeof(struct sockaddr_in));
+      memcpy (&(newconn->addr_peer), &addr, sizeof(struct sh_sockaddr));
 
       /* prepare for usage of connection
@@ -4781,5 +4735,5 @@
 }
 
-static struct in_addr server_interface;
+static struct sh_sockaddr server_interface;
 static int            use_server_interface = 0;
 
@@ -4791,9 +4745,11 @@
       return 0;
     }
-  if (0 == /*@-unrecog@*/inet_aton(str, &server_interface)/*@+unrecog@*/) 
+
+  if (0 == sh_ipvx_aton(str, &server_interface)) 
     {
       use_server_interface = 0;
       return -1;
     }
+
   use_server_interface = 1;
   return 0;
@@ -4882,26 +4838,95 @@
 #ifdef INET_SYSLOG
 #define INET_SUSPEND_TIME 180		/* equal to 3 minutes */
-#define SH_MINSOCK 3
+#define SH_MINSOCK_DEFAULT 3
 int create_syslog_socket (int flag);
 static int recv_syslog_socket   (int fd);
-static int syslog_sock = -1;
+static int syslog_sock[SH_SOCKMAX] = { -1 };
+static int syslog_sock_n = 0;
 #else
-#define SH_MINSOCK 2
-#endif
-
+#define SH_MINSOCK_DEFAULT 2
+#endif
+
+static int SH_MINSOCK = SH_MINSOCK_DEFAULT;
 extern int pf_unix_fd;
 
 /* the tcp socket, and the function to establish it
  */
-static int sh_tcp_sock = -1;
+static int sh_tcp_sock[SH_SOCKMAX] = { -1 };
+static int sh_tcp_sock_n = 0;
+
+static int do_socket(int domain, int type, int protocol,
+		     struct sockaddr * sa, int salen)
+{
+  int sock = -1;
+  int errnum = 0;
+  int flag   = 1; /* non-zero to enable an option */
+
+  /* create the socket, bind() it and listen()
+   */
+  if ((sock = socket(domain, type, protocol)) < 0 )
+    {
+      errnum = errno; 
+      sh_forward_printerr (_("socket"), errnum, server_port, __LINE__);
+      return -1;
+    }
+  (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
+ 
+  if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+		  (void *) &flag, sizeof(flag)) < 0 )
+    {
+      errnum = errno;
+      sh_forward_printerr (_("setsockopt"), errnum, server_port, __LINE__);
+      sl_close_fd (FIL__, __LINE__, sock);
+      return -1;
+    }
+  
+  if ( bind(sock, (struct sockaddr *) sa, salen) < 0) 
+    {
+      if (errno != EADDRINUSE)
+	{
+	  errnum = errno;
+	  sh_forward_printerr (_("bind"), errnum, server_port, __LINE__);
+	  sl_close_fd (FIL__, __LINE__, sock);
+	  return -1;
+	}
+      else
+	{
+	  sl_close_fd (FIL__, __LINE__, sock);
+	  return -2;
+	}
+    }
+  
+  if ( retry_fcntl( FIL__, __LINE__, sock, F_SETFL, O_NONBLOCK ) < 0 )
+    {
+      errnum = errno;
+      sh_forward_printerr (_("fcntl"), errnum, server_port, __LINE__);
+      sl_close_fd (FIL__, __LINE__, sock);
+      return -1;
+    }
+  
+  if ( listen(sock, 64) < 0)
+    {
+      errnum = errno;
+      sh_forward_printerr (_("listen"), errnum, server_port, __LINE__);
+      sl_close_fd (FIL__, __LINE__, sock);
+      return -1;
+    }
+
+  return sock;
+}
 
 int sh_create_tcp_socket (void)
 {
+#if defined(USE_IPVX)
+  struct addrinfo *ai;
+  struct addrinfo *p;
+  struct addrinfo hints;
+  char            port[32];
+#else
   struct sockaddr_in addr;
   int addrlen      = sizeof(addr);
+#endif
 
   int sock   = -1;
-  int errnum = 0;
-  int flag   = 1; /* non-zero to enable an option */
 
   SL_ENTER(_("sh_create_tcp_socket"));
@@ -4909,53 +4934,81 @@
   sh_forward_printerr (NULL, 0, server_port, __LINE__);
 
-  /* create the socket, bind() it and listen()
-   */
-  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
-    {
-      errnum = errno; 
-      sh_forward_printerr (_("socket"), errnum, server_port, __LINE__);
-      SL_RETURN((-1), _("sl_create_tcp_socket"));
-    }
-  (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
-  
-  if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
-		  (void *) &flag, sizeof(flag)) < 0 )
-    {
-      errnum = errno;
-      sh_forward_printerr (_("setsockopt"), errnum, server_port, __LINE__);
-      SL_RETURN((-1), _("sl_create_tcp_socket"));
-    }
-  
-  addr.sin_family      = AF_INET;
-  addr.sin_port        = htons(server_port);
+#if defined(USE_IPVX)
+  if (use_server_interface == 0)
+    {
+      memset (&hints, '\0', sizeof (hints));
+      hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
+      hints.ai_socktype = SOCK_STREAM;
+      sl_snprintf(port, sizeof(port), "%d", server_port);
+
+      if (getaddrinfo (NULL, port, &hints, &ai) != 0)
+	{
+	  int errnum = errno;
+	  sh_forward_printerr (_("getaddrinfo"), errnum, server_port, __LINE__);
+	  sl_close_fd (FIL__, __LINE__, sock);
+	  SL_RETURN((-1), _("sl_create_tcp_socket"));
+	}
+      
+      p = ai;
+      
+      while (p != NULL && sh_tcp_sock_n < SH_SOCKMAX)
+	{
+	  sock = do_socket(p->ai_family, p->ai_socktype, p->ai_protocol,
+			   p->ai_addr, p->ai_addrlen);
+	  
+	  if (sock >= 0) {
+	    if (sh_tcp_sock_n < SH_SOCKMAX) {
+	      sh_tcp_sock[sh_tcp_sock_n] = sock;
+	      ++sh_tcp_sock_n;
+	    }
+	    else {
+	      sl_close_fd (FIL__, __LINE__, sock);
+	    }    
+	  } else if (sock == -1) {
+	    freeaddrinfo (ai);
+	    goto end;
+	  }
+	  p = p->ai_next;
+	}
+      
+      freeaddrinfo (ai);
+    }
+  else
+    {
+      sh_ipvx_set_port(&server_interface, server_port);
+
+      sock = do_socket(server_interface.ss_family, SOCK_STREAM, 0, 
+		       sh_ipvx_sockaddr_cast(&server_interface), 
+		       SH_SS_LEN(server_interface));
+      
+      if (sock >= 0) {
+	sh_tcp_sock[0] = sock;
+	sh_tcp_sock_n  = 1;
+      }
+    }	       
+#else
   if (use_server_interface == 0)
     addr.sin_addr.s_addr = INADDR_ANY;
   else
-    memcpy(&addr.sin_addr, &server_interface, sizeof(struct in_addr));
+    memcpy(&addr, sh_ipvx_sockaddr_cast(&server_interface), addrlen);
+  addr.sin_family      = AF_INET;
+  addr.sin_port        = htons(server_port);
   
-  if ( bind(sock, (struct sockaddr *) &addr, addrlen) < 0) 
-    {
-      errnum = errno;
-      sh_forward_printerr (_("bind"), errnum, server_port, __LINE__);
-      SL_RETURN((-1), _("sl_create_tcp_socket"));
-    }
-  
-  if ( retry_fcntl( FIL__, __LINE__, sock, F_SETFL, O_NONBLOCK ) < 0 )
-    {
-      errnum = errno;
-      sh_forward_printerr (_("fcntl"), errnum, server_port, __LINE__);
-      SL_RETURN((-1), _("sl_create_tcp_socket"));
-    }
-  
-  if ( listen(sock, 5) < 0)
-    {
-      errnum = errno;
-      sh_forward_printerr (_("listen"), errnum, server_port, __LINE__);
-      SL_RETURN((-1), _("sl_create_tcp_socket"));
-    }
-
-  sh_tcp_sock = sock;
-
-  SL_RETURN((sock), _("sl_create_tcp_socket"));
+  sock = do_socket(AF_INET, SOCK_STREAM, 0, (struct sockaddr *) &addr, addrlen);
+
+  if (sock >= 0) {
+      sh_tcp_sock[0] = sock;
+      sh_tcp_sock_n  = 1;
+  }
+
+#endif
+
+#if defined(USE_IPVX)
+ end:
+#endif
+  if (sh_tcp_sock_n > 1)
+    SH_MINSOCK += (sh_tcp_sock_n - 1);
+
+  SL_RETURN((sh_tcp_sock_n), _("sl_create_tcp_socket"));
 }
 
@@ -4984,5 +5037,5 @@
   int                nowconn;
   int                status;
-  int                high_fd;
+  int                high_fd = -1;
   register int       i;
   long               dummy = 0;
@@ -5000,4 +5053,10 @@
 
   int setsize_fd;
+
+  int sock_tcp[2];
+  int sock_unix;
+#ifdef INET_SYSLOG
+  int sock_log[2];
+#endif
   
   SL_ENTER(_("sh_receive"));
@@ -5015,5 +5074,6 @@
       aud_exit(FIL__, __LINE__, EXIT_FAILURE);
     }
-  sock = sh_tcp_sock;
+
+  sock = sh_tcp_sock[0];
 
   /* ****************************************************************
@@ -5031,4 +5091,5 @@
    */
   maxconn    = get_open_max() - 6;
+
   /* ugly fix for FreeBSD compiler warning; casting FD_SETSIZE in the
    * conditional expression does not suppress the warning... */
@@ -5079,14 +5140,27 @@
   /* conns[0] is the listen() socket. Always in read mode.
    */
-  conns[0].fd    = sock;
-  conns[0].state = CONN_READING;
-  high_fd = sock;
+  sock = 0;
+
+  sock_tcp[0] = 0;
+  while (sock < sh_tcp_sock_n)
+    {
+      conns[sock].fd    = sh_tcp_sock[sock];
+      conns[sock].state = CONN_READING;
+      high_fd = (sh_tcp_sock[sock] > high_fd) ? sh_tcp_sock[sock] : high_fd;
+      ++sock;
+    }
+  sock_tcp[1] = sock;
   
-  conns[1].fd    = pf_unix_fd;
-  conns[1].state = CONN_READING;
+  conns[sock].fd    = pf_unix_fd;
+  conns[sock].state = CONN_READING;
   high_fd = (pf_unix_fd > high_fd) ? pf_unix_fd : high_fd;
-  
+
+  sock_unix = sock;
+
+  ++sock;
+
 #ifdef INET_SYSLOG
-  conns[2].fd = -1;
+  conns[sock].fd = -1;
+
   if ( sh_forward_printerr_final(1) < 0)
     {
@@ -5095,11 +5169,20 @@
       aud_exit(FIL__, __LINE__, EXIT_FAILURE);
     }
-  sock = syslog_sock;
-
-  if (sock >= 0)
-    {
-      conns[2].fd    = sock;
-      conns[2].state = CONN_READING;
-      high_fd = (high_fd > conns[2].fd) ? high_fd : conns[2].fd;
+
+  sock_log[0] = sock;
+  sock_log[1] = sock;
+
+  if (syslog_sock_n > 0)
+    {
+      int s2;
+      for (s2 = 0; s2 < syslog_sock_n; ++s2)
+	{
+	  conns[sock].fd    = syslog_sock[s2];
+	  conns[sock].state = CONN_READING;
+	  high_fd = (high_fd > conns[sock].fd) ? high_fd : conns[sock].fd;
+	  ++sock;
+	}
+      sock_log[1] = sock;
+
     }
 #endif
@@ -5153,4 +5236,5 @@
 
 	    (void) sh_readconf_read ();
+
 	    for (i = SH_MINSOCK; i < maxconn; ++i)
 	      if (conns[i].state != CONN_FREE   && 
@@ -5230,18 +5314,26 @@
       FD_ZERO( &readset );
       FD_ZERO( &writeset );
-      FD_SET(conns[0].fd, &readset );
-      high_fd   = conns[0].fd;
-
-      if (conns[1].fd > -1)
-	{
-	  FD_SET(conns[1].fd, &readset );
-	  high_fd   = (high_fd > conns[1].fd) ? high_fd : conns[1].fd;
+      high_fd = conns[0].fd;
+
+      for (sock = sock_tcp[0]; sock < sock_tcp[1]; ++sock)
+	{
+	  FD_SET(conns[sock].fd, &readset );
+	  high_fd   = (high_fd > conns[sock].fd) ? high_fd : conns[sock].fd;
+	}
+
+      if (conns[sock_unix].fd > -1)
+	{
+	  FD_SET(conns[sock_unix].fd, &readset );
+	  high_fd   = (high_fd > conns[sock_unix].fd) ? high_fd : conns[sock_unix].fd;
 	}
 
 #ifdef INET_SYSLOG
-      if (conns[2].fd > -1)
-	{
-	  FD_SET(conns[2].fd, &readset );
-	  high_fd   = (high_fd > conns[2].fd) ? high_fd : conns[2].fd;
+      for (sock = sock_log[0]; sock < sock_log[1]; ++sock)
+	{
+	  if (conns[sock].fd > -1)
+	    {
+	      FD_SET(conns[sock].fd, &readset );
+	      high_fd   = (high_fd > conns[sock].fd) ? high_fd : conns[sock].fd;
+	    }
 	}
 #endif
@@ -5405,36 +5497,49 @@
       /* New connection.
        */
-      if ( FD_ISSET(conns[0].fd , &readset )) /* a new connection   */
-	{
-	  --num_sel;
-	  status = 0;
-	  if (nowconn < maxconn && sig_terminate == 0 && sig_termfast == 0)
+      for (sock = sock_tcp[0]; sock < sock_tcp[1]; ++sock)
+	{
+	  if ( FD_ISSET(conns[sock].fd , &readset )) /* a new connection   */
 	    {
-	      i = SH_MINSOCK;
-	      while (i < maxconn)
+	      --num_sel;
+	      status = 0;
+	      if (nowconn < maxconn && sig_terminate == 0 && sig_termfast == 0)
 		{
-		  if (conns[i].state == CONN_FREE)
+		  /* Find a free slot to accept the connection
+		   */
+		  i = SH_MINSOCK;
+		  while (i < maxconn)
 		    {
-		      status = sh_forward_accept (conns[0].fd, &conns[i]);
-		      if (status == 0)
+		      if (conns[i].state == CONN_FREE)
 			{
-			  high_fd = 
-			    (high_fd > conns[i].fd ? high_fd : conns[i].fd);
-			  ++server_status.conn_open;
-			  ++server_status.conn_total;
-			  server_status.last = time (NULL);
+			  /* Here we run the accept() and copy the peer to
+			   * the free slot. 
+			   */
+			  status = sh_forward_accept(conns[sock].fd, &conns[i]);
+			  
+			  if (status == 0)
+			    {
+			      high_fd = 
+				(high_fd > conns[i].fd ? high_fd : conns[i].fd);
+			      ++server_status.conn_open;
+			      ++server_status.conn_total;
+			      server_status.last = time (NULL);
+			    }
+			  break;
 			}
-		      break;
+		      ++i;
 		    }
-		  ++i;
 		}
+	      /* This re-runs select to accept data on the new
+	       * connection, rather than first dealing with old
+	       * connections.
+	       */
+	      if (status == 0) 
+		continue;
 	    }
-	  if (status == 0) 
-	    continue;
 	}
       
       /* check for commands on the socket
        */
-      if (conns[1].fd > (-1) && FD_ISSET(conns[1].fd , &readset ))
+      if (conns[sock_unix].fd > (-1) && FD_ISSET(conns[sock_unix].fd , &readset ))
 	{
 	  sh_socket_poll();
@@ -5442,7 +5547,10 @@
 
 #ifdef INET_SYSLOG
-      if (conns[2].fd > (-1) && FD_ISSET(conns[2].fd , &readset ))
-	{
-	  recv_syslog_socket (conns[2].fd);
+      for (sock = sock_log[0]; sock < sock_log[1]; ++sock)
+	{
+	  if (conns[sock].fd > (-1) && FD_ISSET(conns[sock].fd , &readset ))
+	    {
+	      recv_syslog_socket (conns[sock].fd);
+	    }
 	}
 #endif
@@ -5503,27 +5611,4 @@
 
 #ifdef INET_SYSLOG
-
-#ifdef HAVE_INET_ATON
-static char * my_inet_ntoa(struct in_addr in)
-{
-  return inet_ntoa(in);
-}
-#else
-static char * my_inet_ntoa(struct in_addr in)
-{
-  unsigned char a, b, c, d;
-  static char   foo[16];
-  char          bar[4];
-  memcpy (bar, &(in.s_addr), 4); /* memory alignment (?) */
-  memcpy (&a, &bar[0], 1);
-  memcpy (&b, &bar[1], 1);
-  memcpy (&c, &bar[2], 1);
-  memcpy (&d, &bar[3], 1);
-  sprintf(foo, "%d.%d.%d.%d",                       /* known to fit  */
-	  (int) a, (int) b, (int) c, (int) d);
-  return foo;
-}
-#endif
-
 
 /* Unlike Linux / FreeBSD, most systems don't define the stuff below
@@ -5675,4 +5760,8 @@
   char errbuf[SH_ERRBUF_SIZE];
 
+  struct sh_sockaddr ss;
+  struct sockaddr * sa = (struct sockaddr *) &from;
+  char   namebuf[SH_BUFSIZE];
+
   /* The 6th argument in recvfrom is *socklen_t in Linux and *BSD, 
    * but *int everywhere else. Because socklen_t is unsigned int, there
@@ -5696,4 +5785,7 @@
   res = recvfrom(fd,  buf,  1047, 0, (struct sockaddr *) &from, &fromlen);
 
+  sh_ipvx_save(&ss, sa->sa_family, &from);
+  sh_ipvx_ntoa(namebuf, sizeof(namebuf), &ss);
+
   if (res > 0)
     {
@@ -5715,10 +5807,10 @@
 	  sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
 			  sh_error_message(res, errbuf, sizeof(errbuf)), 
-			  my_inet_ntoa(from.sin_addr));
+			  namebuf);
 	  SL_RETURN( (-1), _("recv_syslog_socket"));
 	}      
 
-      TPT(( 0, FIL__, __LINE__, _("msg=<UDP message from %s>\n"),
-	    my_inet_ntoa(from.sin_addr)));
+      TPT(( 0, FIL__, __LINE__, _("msg=<UDP message from %s>\n"), namebuf ));
+
       ptr = bptr;
       i = 0;
@@ -5775,5 +5867,5 @@
       sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
 		      sh_error_message(res, errbuf, sizeof(errbuf)), 
-		      my_inet_ntoa(from.sin_addr));
+		      namebuf);
 
       /* don't accept anything the next 2 seconds
@@ -5790,7 +5882,6 @@
 }
 
-/* callerFlag == S_TRUE means override the enable_syslog_socket flag
- */
-int create_syslog_socket (int callerFlag)
+static int do_syslog_socket(int domain, int type, int protocol,
+			    struct sockaddr * sa, int salen)
 {
   int                flag = 1;  /* non-zero to enable an option */
@@ -5798,6 +5889,63 @@
   int errnum;
   int res;
+
+  /* create the socket, bind() it and listen()
+   */
+  sock = socket(domain, type, protocol);
+
+  if (sock < 0)
+    {
+      errnum = errno; 
+      sh_forward_printerr (_("syslog socket"), errnum, 514, __LINE__);
+      return -1;
+    }
+  (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
+  
+  if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+		  (void *) &flag, sizeof(flag)) < 0 )
+    {
+      errnum = errno;
+      sh_forward_printerr (_("syslog setsockopt SO_REUSEADDR"), 
+			   errnum, 514, __LINE__);
+      return -1;
+    }
+
+#if defined(SO_BSDCOMPAT)
+  if ( setsockopt(sock, SOL_SOCKET, SO_BSDCOMPAT,
+		  (void *) &flag, sizeof(flag)) < 0 )
+    {
+      errnum = errno;
+      sh_forward_printerr (_("syslog setsockopt SO_BSDCOMPAT"), 
+			   errnum, 514, __LINE__);
+      return -1;
+    }
+#endif
+  
+  res = bind(sock, sa, salen);
+
+  if ( res < 0) 
+    {
+      errnum = errno;
+      sh_forward_printerr (_("syslog bind"), errnum, 514, __LINE__);
+      sl_close_fd(FIL__, __LINE__, sock);
+      return -1;
+    }
+  return sock;
+}
+
+/* callerFlag == S_TRUE means override the enable_syslog_socket flag
+ */
+int create_syslog_socket (int callerFlag)
+{
+  int sock;
+
+#if defined(USE_IPVX)
+  struct addrinfo *ai;
+  struct addrinfo *p;
+  struct addrinfo hints;
+#else
   struct sockaddr_in addr;
   int addrlen      = sizeof(addr);
+#endif
 
   SL_ENTER(_("create_syslog_socket"));
@@ -5811,5 +5959,5 @@
 	  TPT(( 0, FIL__, __LINE__, _("msg=<close syslog socket>\n")));
 	  sl_close_fd(FIL__, __LINE__, syslog_sock);
-	  syslog_sock = -1;
+	  syslog_sock[0] = -1;
 	}
       SL_RETURN((-1), _("create_syslog_socket"));
@@ -5818,53 +5966,58 @@
   sh_forward_printerr (NULL, 0, 514, __LINE__);
 
-  /* create the socket, bind() it and listen()
-   */
-  sock = socket(AF_INET, SOCK_DGRAM, 0);
-
-  if (sock < 0)
-    {
-      errnum = errno; 
-      sh_forward_printerr (_("syslog socket"), errnum, 514, __LINE__);
-      SL_RETURN((-1), _("create_syslog_socket"));
-    }
-  (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
-  
-  if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
-		  (void *) &flag, sizeof(flag)) < 0 )
-    {
-      errnum = errno;
-      sh_forward_printerr (_("syslog setsockopt SO_REUSEADDR"), 
-			   errnum, 514, __LINE__);
-      SL_RETURN((-1), _("create_syslog_socket"));
-    }
-
-#if defined(SO_BSDCOMPAT)
-  if ( setsockopt(sock, SOL_SOCKET, SO_BSDCOMPAT,
-		  (void *) &flag, sizeof(flag)) < 0 )
-    {
-      errnum = errno;
-      sh_forward_printerr (_("syslog setsockopt SO_BSDCOMPAT"), 
-			   errnum, 514, __LINE__);
-      SL_RETURN((-1), _("create_syslog_socket"));
-    }
-#endif
-  
+#if !defined(USE_IPVX)
+
   memset(&addr, 0, sizeof(addr));
   addr.sin_family      = AF_INET;
   addr.sin_port        = htons(514);
   
-  res = bind(sock, (struct sockaddr *) &addr, addrlen);
-
-  if ( res < 0) 
+  do_syslog_socket(AF_INET, SOCK_DGRAM, 0, (struct sockaddr *) &addr, addrlen);
+
+  if (sock >= 0) {
+    syslog_sock[0] = sock;
+    syslog_sock_n  = 1;
+  }
+
+#else
+  memset (&hints, '\0', sizeof (hints));
+  hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
+  hints.ai_socktype = SOCK_DGRAM;
+  if (getaddrinfo (NULL, "syslog", &hints, &ai) != 0)
     {
       errnum = errno;
-      sh_forward_printerr (_("syslog bind"), errnum, 514, __LINE__);
-      sl_close_fd(FIL__, __LINE__, sock);
+      sh_forward_printerr (_("getaddrinfo"), errnum, 514, __LINE__);
+      sl_close_fd (FIL__, __LINE__, sock);
       SL_RETURN((-1), _("create_syslog_socket"));
     }
-
-  syslog_sock = sock;
-
-  SL_RETURN((sock), _("create_syslog_socket"));
+  
+  p = ai;
+
+  while (p != NULL && syslog_sock_n < SH_SOCKMAX)
+    {
+      sock = do_syslog_socket(p->ai_family, p->ai_socktype, p->ai_protocol,
+			      p->ai_addr, p->ai_addrlen);
+      
+      if (sock >= 0) {
+	if (syslog_sock_n < SH_SOCKMAX) {
+	  syslog_sock[syslog_sock_n] = sock;
+	  ++syslog_sock_n;
+	}
+	else {
+	  sl_close_fd (FIL__, __LINE__, sock);
+	}    
+      } else if (sock == -1) {
+	freeaddrinfo (ai);
+	goto end;
+      }
+      p = p->ai_next;
+    }
+  freeaddrinfo (ai);
+#endif
+
+ end:
+  if (syslog_sock_n > 1)
+    SH_MINSOCK += (syslog_sock_n - 1);
+
+  SL_RETURN((syslog_sock_n), _("create_syslog_socket"));
 }
 /* #ifdef INET_SYSLOG */
Index: /trunk/src/sh_getopt.c
===================================================================
--- /trunk/src/sh_getopt.c	(revision 294)
+++ /trunk/src/sh_getopt.c	(revision 295)
@@ -400,4 +400,7 @@
 	  SH_DEFAULT_PORT, DEFAULT_IDENT); 
   ++num;
+#endif
+#if defined(USE_IPVX)
+  fputs (_(", IPv6 supported"), stdout);
 #endif
 
Index: /trunk/src/sh_ipvx.c
===================================================================
--- /trunk/src/sh_ipvx.c	(revision 295)
+++ /trunk/src/sh_ipvx.c	(revision 295)
@@ -0,0 +1,483 @@
+/* SAMHAIN file system integrity testing                                   */
+/* Copyright (C) 2010 Rainer Wichmann                                      */
+/*                                                                         */
+/*  This program is free software; you can redistribute it                 */
+/*  and/or modify                                                          */
+/*  it under the terms of the GNU General Public License as                */
+/*  published by                                                           */
+/*  the Free Software Foundation; either version 2 of the License, or      */
+/*  (at your option) any later version.                                    */
+/*                                                                         */
+/*  This program is distributed in the hope that it will be useful,        */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of         */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
+/*  GNU General Public License for more details.                           */
+/*                                                                         */
+/*  You should have received a copy of the GNU General Public License      */
+/*  along with this program; if not, write to the Free Software            */
+/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
+
+#include "config_xor.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <ctype.h>
+
+#undef  FIL__
+#define FIL__  _("sh_ipvx.c")
+
+#include "samhain.h"
+#define SH_NEED_GETHOSTBYXXX
+#include "sh_static.h"
+#include "sh_pthread.h"
+#include "sh_utils.h"
+#include "sh_ipvx.h"
+
+static int sh_ipvx_is_ipv4 (const char * addr)
+{
+  int j;
+  int len = sl_strlen(addr);
+  
+  for (j = 0; j < len; ++j)
+    if ( (addr[j] < '0' || addr[j] > '9') && addr[j] != '.')
+      return (1 == 0);
+  return (1 == 1);
+}
+
+#if defined(USE_IPVX)
+static int sh_ipvx_is_ipv6 (const char * addr)
+{
+  int j;
+  char c;
+  int len = sl_strlen(addr);
+  
+  for (j = 0; j < len; ++j) {
+    c = addr[j];
+    if (( c < '0' || c > '9' ) &&
+	( c < 'a' || c > 'f' ) &&
+	( c < 'A' || c > 'F' ) &&
+	( c != ':'))
+      return (1 == 0);
+  }
+  return (1 == 1);
+}
+#endif
+
+
+int sh_ipvx_is_numeric (const char * addr)
+{
+#if defined(USE_IPVX)
+  if (!sh_ipvx_is_ipv4(addr))
+    return sh_ipvx_is_ipv6(addr);
+  else
+    return (1 == 1);
+#else
+  return sh_ipvx_is_ipv4(addr);
+#endif
+}
+
+int sh_ipvx_isany (struct sh_sockaddr * a)
+{
+#if defined(USE_IPVX)
+  struct in6_addr anyaddr = IN6ADDR_ANY_INIT; 
+#endif
+
+  switch (a->ss_family)
+    {
+    case AF_INET:
+      if ((a->sin).sin_addr.s_addr == INADDR_ANY)
+	return 1;
+      break;
+#if defined(USE_IPVX)
+    case AF_INET6:
+      if (0 == memcmp(&((a->sin6).sin6_addr.s6_addr), &anyaddr, 16))
+	return 1;
+      break;
+#endif
+    }
+  return 0;
+}
+
+int sh_ipvx_cmp (struct sh_sockaddr * a, struct sh_sockaddr * b)
+{
+  if (a->ss_family != b->ss_family)
+    return 1;
+  
+  switch (a->ss_family)
+    {
+    case AF_INET:
+      return memcmp(&((a->sin).sin_addr.s_addr), &((b->sin).sin_addr.s_addr), 4);
+      break;
+#if defined(USE_IPVX)
+    case AF_INET6:
+      return memcmp(&((a->sin6).sin6_addr.s6_addr), &((b->sin6).sin6_addr.s6_addr), 16);
+      break;
+#endif
+    }
+  return 1;
+}
+
+int sh_ipvx_ntoa (char * name, size_t name_size, struct sh_sockaddr * ss)
+{
+#if defined(USE_IPVX)
+  int len = (ss->ss_family == AF_INET) ? 
+    sizeof(struct sockaddr_in) :
+    sizeof(struct sockaddr_in6);
+
+  int ret = getnameinfo(sh_ipvx_sockaddr_cast(ss), len,
+			name, name_size, NULL, 0, NI_NUMERICHOST);
+
+  if (ret != 0)
+    {
+      if (name_size > 7) {
+	name[0] = '0'; name[1] = '.'; name[2] = '0'; name[3] = '.'; 
+	name[4] = '0'; name[5] = '.'; name[6] = '0'; name[7] = '\0';
+      } else if (name_size > 0) {
+	name[0] = '\0';
+      }
+    } 
+  return ret;
+#else
+  char * p = inet_ntoa((ss->sin).sin_addr);
+  sl_strlcpy(name, p, name_size);
+  return 0;
+#endif
+}
+
+struct sockaddr * sh_ipvx_sockaddr_cast (struct sh_sockaddr * ss)
+{
+#if defined(USE_IPVX)
+  if (ss->ss_family == AF_INET6)
+    return (struct sockaddr *) &(ss->sin6);
+#endif
+  return (struct sockaddr *) &(ss->sin);
+}
+
+void sh_ipvx_save(struct sh_sockaddr * ss, int sa_family, struct sockaddr * sa)
+{
+  /* memset(ss, '\0', sizeof(struct sh_sockaddr)); */
+
+  switch (sa_family)
+    {
+    case AF_INET:
+      ss->ss_family = AF_INET;
+      memcpy(&(ss->sin), sa, sizeof(struct sockaddr_in));
+      break;
+#if defined(USE_IPVX)
+    case AF_INET6:
+      ss->ss_family = AF_INET6;
+      memcpy(&(ss->sin6), sa, sizeof(struct sockaddr_in6));
+      break;
+#endif
+    default:
+      break;
+    }
+  return;
+}
+
+int sh_ipvx_set_port(struct sh_sockaddr * ss, int port)
+{
+#if defined(USE_IPVX)
+
+  switch (ss->ss_family)
+    {
+    case AF_INET:
+      (ss->sin).sin_port = htons (port);
+      break;
+    case AF_INET6:
+      (ss->sin6).sin6_port = htons (port);
+      break;
+    }
+  return 0;
+#else
+  (ss->sin).sin_port = htons (port);
+  return 0;
+#endif
+}
+
+int sh_ipvx_aton (const char * name, struct sh_sockaddr * ss)
+{
+#if defined(USE_IPVX)
+  int             ret;
+  struct addrinfo hints;
+  struct addrinfo *res;
+
+  memset(&hints, '\0', sizeof(hints));
+  hints.ai_family = PF_UNSPEC;
+  hints.ai_flags  = AI_NUMERICHOST;
+  ret = getaddrinfo(name, NULL, &hints, &res);
+
+  if (ret)
+    return 0;
+
+  memset(ss, '\0', sizeof(struct sh_sockaddr));
+  switch(res->ai_family)
+    {
+    case AF_INET:
+      memcpy(&(ss->sin), res->ai_addr, sizeof(struct sockaddr_in));
+      ss->ss_family = AF_INET;
+      break;
+    case AF_INET6:
+      memcpy(&(ss->sin6), res->ai_addr, sizeof(struct sockaddr_in6));
+      ss->ss_family = AF_INET6;
+      break;
+    default:
+      return 0;
+      break;
+    }
+  return 1;
+#else
+  int ret = inet_aton(name, &((ss->sin).sin_addr));
+  ss->ss_family = AF_INET;
+  return ret;
+#endif
+}
+
+#if !defined(USE_IPVX)
+static const char * sh_ipvx_h_name (struct hostent * host_entry)
+{
+  char ** p;
+  if (strchr(host_entry->h_name, '.')) {
+    return host_entry->h_name;
+  } else {
+    for (p = host_entry->h_aliases; *p; ++p) {
+      if (strchr(*p, '.'))
+	return *p;
+    }
+  }
+  return host_entry->h_name;
+}
+#endif
+
+static char * sh_tolower (char * s)
+{
+  char * ret = s;
+  if (s)
+    {
+      for (; *s; ++s)
+	{ 
+	  *s = tolower((unsigned char) *s);
+	}
+    }
+  return ret;
+}
+
+static void * sh_dummy_out;
+
+char * sh_ipvx_canonical(const char * hostname, char * numeric, size_t nlen)
+{
+  volatile int    flag = 0;
+  char            *out = NULL;
+#if defined(USE_IPVX)
+  struct addrinfo hints;
+  struct addrinfo *res;
+  struct sockaddr *sa;
+  int             salen;
+  int             err;
+  struct sh_sockaddr  ss;
+  const char * host;
+  char hostbuf[SH_BUFSIZE];
+
+  numeric[0] = '\0';
+
+  sh_dummy_out = (void *) &out;
+ 
+  if (sh_ipvx_is_numeric(hostname))
+    {
+      sh_ipvx_aton (hostname, &ss);
+      if (0 == getnameinfo(sh_ipvx_sockaddr_cast(&ss), SH_SS_LEN(ss),
+			   hostbuf, sizeof(hostbuf), NULL, 0, NI_NAMEREQD))
+	host = hostbuf;
+      else
+	host = hostname;
+    }
+  else
+    {
+      host = hostname;
+    }
+ 
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = PF_UNSPEC;
+#if defined(AI_CANONNAME)
+  hints.ai_flags = AI_CANONNAME;
+#endif 
+
+  err = getaddrinfo(host, NULL, &hints, &res);
+  if (err == 0)
+    {
+#if defined(AI_CANONNAME)
+      if (res->ai_canonname && strlen(res->ai_canonname) > 0)
+	{
+	  out = sh_util_strdup(res->ai_canonname);
+	  sh_tolower (out);
+	  if (strchr(out, '.'))
+	    flag = 1;
+	}
+#endif
+
+      sa = res->ai_addr;
+      salen = res->ai_addrlen;
+      getnameinfo(sa, salen,
+		  numeric, nlen, NULL, 0, NI_NUMERICHOST);
+
+      if (!flag)
+	out = SH_ALLOC(SH_PATHBUF);
+
+      while (res && !flag) 
+	{
+	  sa = res->ai_addr;
+	  salen = res->ai_addrlen;
+
+	  getnameinfo(sa, salen,
+		      out, SH_PATHBUF, NULL, 0, 0);
+	  sh_tolower (out);
+	  if (strchr(out, '.'))
+	    flag = 1;
+	  
+	  res = res->ai_next;
+	}
+    }
+#else
+  struct hostent     *he;
+  struct sh_sockaddr  ss;
+  volatile int        isNum = 0;
+  struct sockaddr_in *sin;
+
+  numeric[0] = '\0';
+
+  sh_dummy_out = (void *) &out;
+
+  if (sh_ipvx_is_numeric(hostname))
+    {
+      sh_ipvx_aton (hostname, &ss);
+      isNum = 1;
+    }
+ 
+
+  SH_MUTEX_LOCK(mutex_resolv);
+
+  if (isNum == 0)
+    {
+      he = sh_gethostbyname(hostname);
+    }
+  else
+    {
+      sin = (struct sockaddr_in *) sh_ipvx_sockaddr_cast(&ss);
+      he = sh_gethostbyaddr(&(sin->sin_addr), sizeof(sin->sin_addr), AF_INET);
+    }
+
+  if (he != NULL)
+    {
+      out = sh_util_strdup(sh_ipvx_h_name(he));
+      sh_tolower (out);
+      sl_strlcpy (numeric, 
+		  inet_ntoa (*(struct in_addr *) he->h_addr), 
+		  nlen);
+      flag = 1;
+    }
+  SH_MUTEX_UNLOCK(mutex_resolv);
+#endif
+
+  if (flag)
+    return out;
+  
+  if (out)
+    SH_FREE(out);
+  if (numeric[0] == '\0')
+    sl_strlcpy (numeric, _("0.0.0.0"), nlen);
+  return NULL;
+}
+
+char * sh_ipvx_addrtoname(struct sh_sockaddr * ss)
+{
+#if defined(USE_IPVX)
+  char namebuf[SH_BUFSIZE];
+
+  if (getnameinfo(sh_ipvx_sockaddr_cast(ss), SH_SSP_LEN(ss),
+		  namebuf, sizeof(namebuf), NULL, 0, NI_NAMEREQD) != 0)
+    {
+      return NULL;
+    }
+  return sh_util_strdup(namebuf);
+#else
+  struct sockaddr_in *sin;
+  struct hostent *he;
+
+  sin = (struct sockaddr_in *) sh_ipvx_sockaddr_cast(ss);
+
+  he = sh_gethostbyaddr(&(sin->sin_addr), sizeof(sin->sin_addr), AF_INET);
+
+  if (he && he->h_name)
+    {
+      return sh_util_strdup(he->h_name);
+    }
+
+  return NULL;
+#endif
+}
+
+int sh_ipvx_reverse_check_ok (char * peer, int port, struct sh_sockaddr * ss)
+{
+#if defined(USE_IPVX)
+  struct addrinfo *res;
+  struct addrinfo hints;
+  char            sport[32];
+  struct addrinfo *p;
+
+  sl_snprintf(sport, sizeof(sport), "%d", port);
+
+  memset(&hints, '\0', sizeof(hints));
+  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_flags = AI_ADDRCONFIG;
+
+  if (getaddrinfo(peer, sport, &hints, &res) != 0)
+    {
+      return 0;
+    }
+  
+  p = res;
+  while (p != NULL)
+    {
+      if (ss->ss_family == p->ai_family)
+	{
+	  struct sh_sockaddr pp;
+
+	  char dst1[SH_IP_BUF];
+	  char dst2[SH_IP_BUF];
+
+	  sh_ipvx_save(&pp, p->ai_family, p->ai_addr);
+
+	  sh_ipvx_ntoa (dst1, sizeof(dst1), &pp);
+	  sh_ipvx_ntoa (dst2, sizeof(dst2),  ss);
+
+	  if (0 == sl_strcmp(dst1, dst2))
+	    {
+	      return 1;
+	    }
+	}
+      p = p->ai_next;
+    }
+  freeaddrinfo(res);
+#else
+  struct hostent * he;
+  char          ** p;
+  struct sockaddr_in * sin = (struct sockaddr_in *) sh_ipvx_sockaddr_cast(ss);
+
+  (void) port;
+
+  he = sh_gethostbyname(peer);
+  if (he != NULL)
+    {
+      for (p = he->h_addr_list; *p; ++p)
+	{
+	  if (0 == memcmp (*p, &(sin->sin_addr), sizeof(in_addr_t)) )
+	    return 1;
+	}
+    }
+#endif
+  return 0;
+}
Index: /trunk/src/sh_login_track.c
===================================================================
--- /trunk/src/sh_login_track.c	(revision 294)
+++ /trunk/src/sh_login_track.c	(revision 295)
@@ -33,4 +33,5 @@
 #include "sh_string.h"
 #include "sh_tools.h"
+#include "sh_ipvx.h"
 #include "sh_error_min.h"
 
@@ -809,5 +810,5 @@
   char *p, *q;
   
-  if (is_numeric(host))
+  if (sh_ipvx_is_numeric(host))
     {
       p = sh_util_strdup(host);
Index: /trunk/src/sh_mail.c
===================================================================
--- /trunk/src/sh_mail.c	(revision 294)
+++ /trunk/src/sh_mail.c	(revision 295)
@@ -62,4 +62,5 @@
 #include "sh_mail_int.h"
 #include "sh_nmail.h"
+#include "sh_ipvx.h"
 
 #undef  FIL__
@@ -1113,5 +1114,5 @@
   (void) fflush(connFile);
 
-  if (0 != is_numeric(sh.host.name))
+  if (0 != sh_ipvx_is_numeric(sh.host.name))
     {
       sl_snprintf(error_msg, sizeof(error_msg), "HELO [%s]", 
@@ -1125,5 +1126,5 @@
   report_smtp(error_msg);
 
-  if (0 != is_numeric(sh.host.name))
+  if (0 != sh_ipvx_is_numeric(sh.host.name))
     fprintf(connFile, _("HELO [%s]%c%c"), sh.host.name, 13, 10);
   else
@@ -1150,5 +1151,5 @@
     {
       (void) sl_strlcat (this_address, "@", 256);
-      if (0 != is_numeric(sh.host.name))
+      if (0 != sh_ipvx_is_numeric(sh.host.name))
 	(void) sl_strlcat (this_address, _("example.com"), 256);
       else
@@ -1866,6 +1867,6 @@
   mx     * result;
   dnsrep * retval;
+  char   * address = NULL;
   char     errmsg[128];
-  size_t   len;
 
   SL_ENTER(_("return_mx"));
@@ -1884,4 +1885,6 @@
   else
     {
+      char numeric[SH_IP_BUF];
+
       if (domain != NULL)
 	{
@@ -1904,13 +1907,11 @@
 	}
 
-      SH_MUTEX_LOCK(mutex_resolv);
-
+      retval = NULL;
       host   = NULL;
-      retval = NULL;
 
       if (domain != NULL)
-	host = /*@-unrecog@*/sh_gethostbyname (domain)/*@+unrecog@*/;
-
-      if (host)
+	address = sh_ipvx_canonical(domain, numeric, sizeof(numeric));
+
+      if (address)
 	{
 	  result       = SH_ALLOC (sizeof (mx));
@@ -1919,13 +1920,8 @@
 	  retval->count = 1;
 	  result->pref  = 0;
-	  /*@-type@*/
-	  len = strlen (host->h_name) + 1;
-	  result->address = SH_ALLOC (len);
-	  sl_strlcpy (result->address, host->h_name, len);
-	  /*@+type@*/
-	}
-      SH_MUTEX_UNLOCK(mutex_resolv);
-
-      if (!host)
+
+	  result->address = address;
+	}
+      else
 	{
 #ifdef FIL__
Index: /trunk/src/sh_port2proc.c
===================================================================
--- /trunk/src/sh_port2proc.c	(revision 294)
+++ /trunk/src/sh_port2proc.c	(revision 295)
@@ -62,4 +62,5 @@
 #include "sh_error_min.h"
 #include "sh_pthread.h"
+#include "sh_ipvx.h"
 
 #define FIL__  _("sh_port2proc.c")
@@ -325,6 +326,6 @@
 /* returns the command and fills the 'user' array 
  */
-static char * port2proc_query(char * file, int proto, 
-			      struct in_addr * saddr, int sport, 
+static char * port2proc_query(char * file, int proto, int domain,
+			      struct sh_sockaddr * saddr, int sport, 
 			      unsigned long * pid, char * user, size_t userlen)
 {
@@ -338,7 +339,9 @@
   {
     char errmsg[256];
+    char siface[SH_IP_BUF];
+    sh_ipvx_ntoa(siface, sizeof(siface), saddr);
     sl_snprintf(errmsg, sizeof(errmsg), 
 		"query, file=%s, proto=%d, port=%d, iface=%s\n",
-		file, proto, sport, inet_ntoa(*saddr));
+		file, proto, sport, siface);
     fprintf(stderr, "%s", errmsg);
   }
@@ -347,6 +350,7 @@
   if (fd)
     {
-      unsigned int n, iface, port, inode, istatus;
+      unsigned int n, i, port, niface, inode, istatus;
       char line[512];
+      char iface[SH_IP_BUF];
 
       while (NULL != fgets(line, sizeof(line), fd))
@@ -360,18 +364,45 @@
 
 	  if (5 == sscanf(line, 
-			  "%u: %X:%X %*X:%*X %X %*X:%*X %*X:%*X %*X %*d %*d %u %*s",
-			  &n, &iface, &port, &istatus, &inode))
+			  "%u: %s:%X %*X:%*X %X %*X:%*X %*X:%*X %*X %*d %*d %u %*s",
+			  &n, iface, &port, &istatus, &inode))
 	    {
-	      struct in_addr haddr;
-
-	      haddr.s_addr = (unsigned long)iface;
+	      struct sockaddr_in  addr4;
+	      struct sockaddr_in6 addr6;
+	      struct sh_sockaddr  ss;
+	      
+	      niface = 0;
+
+	      switch (domain) 
+		{
+		case AF_INET:
+		  addr4.sin_addr.s_addr = (int) strtol(iface, NULL, 16);
+		  niface = (unsigned int) addr4.sin_addr.s_addr;
+		  sh_ipvx_save(&ss, AF_INET, (struct sockaddr *)&addr4);
+		  break;
+
+		case AF_INET6:
+		  sscanf(iface, 
+			 "%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx", 
+			 &addr6.sin6_addr.s6_addr[3], &addr6.sin6_addr.s6_addr[2], &addr6.sin6_addr.s6_addr[1], &addr6.sin6_addr.s6_addr[0], 
+			 &addr6.sin6_addr.s6_addr[7], &addr6.sin6_addr.s6_addr[6], &addr6.sin6_addr.s6_addr[5], &addr6.sin6_addr.s6_addr[4], 
+			 &addr6.sin6_addr.s6_addr[11], &addr6.sin6_addr.s6_addr[10], &addr6.sin6_addr.s6_addr[9], &addr6.sin6_addr.s6_addr[8], 
+			 &addr6.sin6_addr.s6_addr[15], &addr6.sin6_addr.s6_addr[14], &addr6.sin6_addr.s6_addr[13], &addr6.sin6_addr.s6_addr[12]);
+		  
+		  for (i = 0; i < 16; ++i)
+		    {
+		      if (0 != (unsigned int) addr6.sin6_addr.s6_addr[i]) 
+			++niface;
+		    }
+		  sh_ipvx_save(&ss, AF_INET6, (struct sockaddr *)&addr6);
+		  break;
+		}
 
 #ifdef DEBUG_P2P
 	      {
-		char a[32];
-		char b[32];
-
-		sl_strlcpy(a, inet_ntoa(haddr), sizeof(a));
-		sl_strlcpy(b, inet_ntoa(*saddr), sizeof(b));
+		char a[SH_IP_BUF];
+		char b[SH_IP_BUF];
+
+		sh_ipvx_ntoa(a, sizeof(a), &ss);
+		sh_ipvx_ntoa(b, sizeof(b), &ss);
 
 		fprintf(stderr, " -> inode %u, iface/port %s,%u, status %u, searching %s,%u, %u\n", 
@@ -392,5 +423,6 @@
 #endif
 
-	      if ((proto == IPPROTO_UDP || iface == 0 || haddr.s_addr == saddr->s_addr) && port == (unsigned int)sport)
+	      if ((proto == IPPROTO_UDP || niface == 0 || 0 == sh_ipvx_cmp(&ss, saddr)) && 
+		  port == (unsigned int)sport)
 		{
 		  struct sock_store * new = socklist;
@@ -445,13 +477,22 @@
 /* returns the command and fills the 'user' array 
  */
-char * sh_port2proc_query(int proto, struct in_addr * saddr, int sport, 
+char * sh_port2proc_query(int proto, struct sh_sockaddr * saddr, int sport, 
 			  unsigned long * pid, char * user, size_t userlen)
 {
   char file[32];
-
+  char * ret;
+ 
   if (proto == IPPROTO_TCP)
     {
       sl_strlcpy(file, _("/proc/net/tcp"), sizeof(file));
-      return port2proc_query(file, proto, saddr, sport, pid, user, userlen);
+      ret = port2proc_query(file, proto, AF_INET, saddr, sport, pid, user, userlen);
+
+      if (ret[0] == '-' && ret[1] == '\0')
+	{
+	  SH_FREE(ret);
+	  sl_strlcpy(file, _("/proc/net/tcp6"), sizeof(file));
+	  ret = port2proc_query(file, proto, AF_INET6, saddr, sport, pid, user, userlen);
+	}
+      return ret;
     }
   else
@@ -459,10 +500,11 @@
       char * ret;
       sl_strlcpy(file, _("/proc/net/udp"), sizeof(file));
-      ret = port2proc_query(file, proto, saddr, sport, pid, user, userlen);
+      ret = port2proc_query(file, proto, AF_INET, saddr, sport, pid, user, userlen);
+
       if (ret[0] == '-' && ret[1] == '\0')
 	{
 	  SH_FREE(ret);
 	  sl_strlcpy(file, _("/proc/net/udp6"), sizeof(file));
-	  ret = port2proc_query(file, proto, saddr, sport, pid, user, userlen);
+	  ret = port2proc_query(file, proto, AF_INET6, saddr, sport, pid, user, userlen);
 	}
       return ret;
@@ -541,5 +583,5 @@
 
 static int       opt_4 = 1;         /* Show IPv4 sockets */
-static int       opt_6 = 0;         /* Show IPv6 sockets */
+static int       opt_6 = 1;         /* Show IPv6 sockets */
 static int       opt_c = 0;         /* Show connected sockets */
 static int       opt_l = 1;         /* Show listening sockets */
@@ -852,11 +894,13 @@
 }
 
-char * sh_port2proc_query(int proto, struct in_addr * saddr, int sport,
+char * sh_port2proc_query(int proto, struct sh_sockaddr * saddr, int sport,
 			  unsigned long * pid, char * user, size_t userlen)
 {
   int n, hash;
   struct xfile *xf;
-  struct in_addr * haddr;
+  struct in_addr  * haddr;
+  struct in6_addr * haddr6;
   struct sock * s;
+  struct in6_addr   anyaddr = IN6ADDR_ANY_INIT; 
 
   *pid = 0;
@@ -886,16 +930,34 @@
       continue;
 
-    if (s->family != AF_INET /* && s->family != AF_INET6 */)
+    if (s->family != AF_INET && s->family != AF_INET6)
       continue;
 
-    if (sport != ntohs(((struct sockaddr_in *)(&s->laddr))->sin_port))
+    if (s->family == AF_INET &&
+	(sport != ntohs(((struct sockaddr_in *)(&s->laddr))->sin_port)))
       continue;
 
-    haddr = &((struct sockaddr_in *)(&s->laddr))->sin_addr;
+    if (s->family == AF_INET6 &&
+	(sport != ntohs(((struct sockaddr_in6 *)(&s->laddr))->sin6_port)))
+      continue;
+
+    if (s->family == AF_INET)
+      haddr  = &((struct sockaddr_in  *)(&s->laddr))->sin_addr;
+    if (s->family == AF_INET6)
+      haddr6 = &((struct sockaddr_in6 *)(&s->laddr))->sin6_addr;
+    
 
     /* fprintf(stderr, "FIXME: %s\n", inet_ntoa(*haddr)); */
     /* fprintf(stderr, "FIXME: %s\n", inet_ntoa(*saddr)); */
 
-    if (haddr->s_addr == saddr->s_addr || inet_lnaof(*saddr) == INADDR_ANY || inet_lnaof(*haddr) == INADDR_ANY)
+    if ( (s->family == AF_INET && 
+	  (haddr->s_addr == (saddr->sin).sin_addr.s_addr || 
+	   sh_ipvx_isany(saddr) || 
+	   inet_lnaof(*haddr) == INADDR_ANY))
+	 ||
+	 (s->family == AF_INET6 &&
+	  (0 == memcmp(haddr6->s6_addr, &((saddr->sin6).sin6_addr.s6_addr), 16) ||
+	   0 == memcmp(haddr6->s6_addr, &(anyaddr.s6_addr), 16) ||
+	   sh_ipvx_isany(saddr) ))
+	 )
       {
 	struct sock_store try;
@@ -975,6 +1037,7 @@
 #include "samhain.h"
 #include "sh_utils.h"
-
-char * sh_port2proc_query(int proto, struct in_addr * saddr, int sport,
+#include "sh_ipvx.h"
+
+char * sh_port2proc_query(int proto, struct sh_sockaddr * saddr, int sport,
 			  unsigned long * pid, char * user, size_t userlen)
 {
Index: /trunk/src/sh_portcheck.c
===================================================================
--- /trunk/src/sh_portcheck.c	(revision 294)
+++ /trunk/src/sh_portcheck.c	(revision 295)
@@ -74,52 +74,4 @@
 /* TIME_WAIT ? 60-240 seconds */
 
-/* the size of an interface string 
- */
-#define SH_INTERFACE_SIZE 16
-
-#define SH_PORT_NOT 0
-#define SH_PORT_REQ 1
-#define SH_PORT_OPT 2
-#define SH_PORT_IGN 3
-#define SH_PORT_BLACKLIST 4
-
-#define SH_PORT_MISS 0
-#define SH_PORT_ISOK 1
-#define SH_PORT_UNKN 2
-
-#define SH_PORT_NOREPT 0
-#define SH_PORT_REPORT 1
-
-#define SH_PROTO_TCP 0
-#define SH_PROTO_UDP 1
-#define SH_PROTO_STR(a) (((a) == IPPROTO_TCP) ? _("tcp") : _("udp"))
-
-struct sh_portentry {
-  int  port;
-  char interface[SH_INTERFACE_SIZE];
-  char * service;
-  char * error;
-  int  flag;    /* required or not */
-  int  status;  /* missing or not  */
-  struct sh_portentry * next;
-};
-
-static struct sh_portentry * portlist_tcp = NULL;
-static struct sh_portentry * portlist_udp = NULL;
-
-struct sh_port {
-  int              port;
-  struct in_addr   haddr;
-  struct sh_port * next;
-};
-
-static struct sh_port * blacklist_tcp = NULL;
-static struct sh_port * blacklist_udp = NULL;
-
-#define SH_PORTCHK_INTERVAL 300
-
-static int sh_portchk_check_udp = 1;
-static int sh_portchk_active    = 1;
-static int sh_portchk_interval  = SH_PORTCHK_INTERVAL;
 #if !defined(TEST_ONLY)
 
@@ -134,4 +86,55 @@
 #include "sh_static.h"
 #include "sh_pthread.h"
+#include "sh_ipvx.h"
+
+/* the size of an interface string 
+ */
+#define SH_INTERFACE_SIZE SH_IP_BUF
+
+#define SH_PORT_NOT 0
+#define SH_PORT_REQ 1
+#define SH_PORT_OPT 2
+#define SH_PORT_IGN 3
+#define SH_PORT_BLACKLIST 4
+
+#define SH_PORT_MISS 0
+#define SH_PORT_ISOK 1
+#define SH_PORT_UNKN 2
+
+#define SH_PORT_NOREPT 0
+#define SH_PORT_REPORT 1
+
+#define SH_PROTO_TCP 0
+#define SH_PROTO_UDP 1
+#define SH_PROTO_STR(a) (((a) == IPPROTO_TCP) ? _("tcp") : _("udp"))
+
+struct sh_portentry {
+  int  port;
+  char interface[SH_INTERFACE_SIZE];
+  char * service;
+  char * error;
+  int  flag;    /* required or not */
+  int  status;  /* missing or not  */
+  struct sh_portentry * next;
+};
+
+static struct sh_portentry * portlist_tcp = NULL;
+static struct sh_portentry * portlist_udp = NULL;
+
+
+#define SH_PORTCHK_INTERVAL 300
+
+static int sh_portchk_check_udp = 1;
+static int sh_portchk_active    = 1;
+static int sh_portchk_interval  = SH_PORTCHK_INTERVAL;
+
+struct sh_port {
+  int                  port;
+  struct sh_sockaddr * paddr;
+  struct sh_port     * next;
+};
+
+static struct sh_port * blacklist_tcp = NULL;
+static struct sh_port * blacklist_udp = NULL;
 
 SH_MUTEX_STATIC(mutex_port_check, PTHREAD_MUTEX_INITIALIZER);
@@ -139,5 +142,5 @@
 static int sh_portchk_severity  = SH_ERR_SEVERE;
 
-extern char * sh_port2proc_query(int proto, struct in_addr * saddr, int sport,
+extern char * sh_port2proc_query(int proto, struct sh_sockaddr * saddr, int sport,
 				 unsigned long * pid, char * user, size_t userlen);
 extern int sh_port2proc_prepare();
@@ -168,5 +171,5 @@
 /* verify whether port/interface is blacklisted (do not check)
  */
-static int sh_portchk_is_blacklisted(int port, struct in_addr haddr, int proto);
+static int sh_portchk_is_blacklisted(int port, struct sh_sockaddr * haddr, int proto);
 
 #ifndef TEST_ONLY
@@ -379,5 +382,5 @@
 
 static void sh_portchk_add_to_list (int proto, 
-				    int port, struct in_addr haddr, 
+				    int port, struct sh_sockaddr * paddr, 
 				    char * service,
 				    int flag, int status)
@@ -390,5 +393,5 @@
 
   new->port = port;
-  sl_strlcpy (new->interface, inet_ntoa(haddr), SH_INTERFACE_SIZE);
+  sh_ipvx_ntoa(new->interface, SH_INTERFACE_SIZE, paddr);
   new->status = status;
   new->flag   = flag;
@@ -459,4 +462,5 @@
 	sh_portchk_kill_blacklist (head->next);
 
+      SH_FREE(head->paddr);
       SH_FREE(head);
     }
@@ -560,11 +564,9 @@
 
 static struct sh_portentry * sh_portchk_get_from_list (int proto, int port, 
-						       struct in_addr haddr, char * service)
+						       struct sh_sockaddr * paddr, char * service)
 {
   struct sh_portentry * portlist;
-  char iface_all[8];
-
-  sl_strlcpy (iface_all, _("0.0.0.0"), sizeof(iface_all));
-  
+  char str_addr[SH_IP_BUF];
+
   if (proto == IPPROTO_TCP)
     portlist = portlist_tcp;
@@ -572,4 +574,6 @@
     portlist = portlist_udp;
 
+  sh_ipvx_ntoa(str_addr, sizeof(str_addr), paddr);
+
   if (service)
     {
@@ -578,6 +582,6 @@
 	  if (portlist->service && 
 	      0 == strcmp(service, portlist->service) &&
-	      (0 == strcmp(portlist->interface, inet_ntoa(haddr)) ||
-	       0 == strcmp(portlist->interface, iface_all)))
+	      ( 0 == strcmp(portlist->interface, str_addr) ||
+	        sh_ipvx_isany(paddr) ))
 	    return portlist;
 	  portlist = portlist->next;
@@ -589,6 +593,6 @@
 	{
 	  if (port == portlist->port &&
-	      (0 == strcmp(portlist->interface, inet_ntoa(haddr)) ||
-	       0 == strcmp(portlist->interface, iface_all)))
+	      (0 == strcmp(portlist->interface, str_addr)  ||
+	       sh_ipvx_isany(paddr) ))
 	    return portlist;
 	  portlist = portlist->next;
@@ -599,5 +603,5 @@
       
 
-static void sh_portchk_cmp_to_list (int proto, int port, struct in_addr haddr, char * service)
+static void sh_portchk_cmp_to_list (int proto, int port, struct sh_sockaddr * paddr, char * service)
 {
   struct sh_portentry * portent;
@@ -605,5 +609,5 @@
 
   
-  portent = sh_portchk_get_from_list (proto, port, haddr, service);
+  portent = sh_portchk_get_from_list (proto, port, paddr, service);
 
   if (service)
@@ -614,12 +618,15 @@
 	  unsigned long qpid;
 	  char   user[USER_MAX];
+	  char   saddr[SH_IP_BUF];
+
+	  sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
 
 	  snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"), 
-		    inet_ntoa(haddr), port, SH_PROTO_STR(proto), service);
+		    saddr, port, SH_PROTO_STR(proto), service);
 #ifdef TEST_ONLY
 	  fprintf(stderr, _("open port: %s:%d/%s (%s)\n"), 
-		  inet_ntoa(haddr), port, SH_PROTO_STR(proto), service);
-#else
-	  path = sh_port2proc_query(proto, &haddr, port, &qpid, user, sizeof(user));
+		  saddr, port, SH_PROTO_STR(proto), service);
+#else
+	  path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
 	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0, 
@@ -631,5 +638,5 @@
 	   * was not there, thus it is not in 'required' or 'optional' list
 	   */
-	  sh_portchk_add_to_list (proto, port, haddr, service, SH_PORT_NOT, SH_PORT_ISOK);
+	  sh_portchk_add_to_list (proto, port, paddr, service, SH_PORT_NOT, SH_PORT_ISOK);
 	}
       else if (portent->status == SH_PORT_MISS && portent->flag != SH_PORT_IGN)
@@ -638,11 +645,14 @@
 	  unsigned long qpid;
 	  char   user[USER_MAX];
+	  char   saddr[SH_IP_BUF];
+
+	  sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
 
 	  snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s), was %d/%s"), 
-		    inet_ntoa(haddr), port, SH_PROTO_STR(proto), service, portent->port, SH_PROTO_STR(proto));
+		    saddr, port, SH_PROTO_STR(proto), service, portent->port, SH_PROTO_STR(proto));
 #ifdef TEST_ONLY
 	  fprintf(stderr, _("service: %s\n"), errbuf);
 #else
-	  path = sh_port2proc_query(proto, &haddr, port, &qpid, user, sizeof(user));
+	  path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
 	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0, 
@@ -659,11 +669,14 @@
 	  unsigned long qpid;
 	  char   user[USER_MAX];
+	  char   saddr[SH_IP_BUF];
+
+	  sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
 
 	  snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s), was %d/%s"), 
-		    inet_ntoa(haddr), port, SH_PROTO_STR(proto), service, portent->port, SH_PROTO_STR(proto));
+		    saddr, port, SH_PROTO_STR(proto), service, portent->port, SH_PROTO_STR(proto));
 #ifdef TEST_ONLY
 	  fprintf(stderr, _("service: %s\n"), errbuf);
 #else
-	  path = sh_port2proc_query(proto, &haddr, port, &qpid, user, sizeof(user));
+	  path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
 	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0, 
@@ -687,12 +700,15 @@
 	  unsigned long qpid;
 	  char   user[USER_MAX];
+	  char   saddr[SH_IP_BUF];
+
+	  sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
 
 	  snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"), 
-		    inet_ntoa(haddr), port, SH_PROTO_STR(proto), check_services(port, proto));
+		    saddr, port, SH_PROTO_STR(proto), check_services(port, proto));
 #ifdef TEST_ONLY
 	  fprintf(stderr, _("open port: %s:%d/%s (%s)\n"), 
-		  inet_ntoa(haddr), port, SH_PROTO_STR(proto), check_services(port, proto));
-#else
-	  path = sh_port2proc_query(proto, &haddr, port, &qpid, user, sizeof(user));
+		  saddr, port, SH_PROTO_STR(proto), check_services(port, proto));
+#else
+	  path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
 	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0, 
@@ -704,5 +720,5 @@
 	  /* was not there, thus it is not in 'required' or 'optional' list
 	   */
-	  sh_portchk_add_to_list (proto, port, haddr, service, SH_PORT_NOT, SH_PORT_ISOK);
+	  sh_portchk_add_to_list (proto, port, paddr, service, SH_PORT_NOT, SH_PORT_ISOK);
 	}
       else if (portent->status == SH_PORT_MISS && portent->flag != SH_PORT_IGN)
@@ -711,11 +727,14 @@
 	  unsigned long qpid;
 	  char   user[USER_MAX];
+	  char   saddr[SH_IP_BUF];
+
+	  sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
 
 	  snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"), 
-		    inet_ntoa(haddr), port, SH_PROTO_STR(proto), check_services(port, proto));
+		    saddr, port, SH_PROTO_STR(proto), check_services(port, proto));
 #ifdef TEST_ONLY
 	  fprintf(stderr, _("port   : %s\n"), errbuf);
 #else
-	  path = sh_port2proc_query(proto, &haddr, port, &qpid, user, sizeof(user));
+	  path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
 	  SH_MUTEX_LOCK(mutex_thread_nolog);
 	  sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0, 
@@ -799,10 +818,8 @@
 }
 
-static int check_port_udp_internal (int fd, int port, struct in_addr haddr)
-{
-  struct sockaddr_in sinr;
-  /* struct in_addr     haddr; */
+static int check_port_udp_internal (int fd, int port, struct sh_sockaddr * paddr)
+{
   int                retval;
-  char             * p;
+  char             * p = NULL;
   char               buf[8];
 #ifndef TEST_ONLY
@@ -811,13 +828,10 @@
 #endif
   char errbuf[SH_ERRBUF_SIZE];
-
-  /* inet_aton(interface, &haddr); */
-
-  sinr.sin_family = AF_INET;
-  sinr.sin_port   = htons (port);
-  sinr.sin_addr   = haddr;
+  char ipbuf[SH_IP_BUF];
+
+  sh_ipvx_set_port(paddr, port);
 
   do {
-    retval = connect(fd, (struct sockaddr *) &sinr, sizeof(sinr));
+    retval = connect(fd, sh_ipvx_sockaddr_cast(paddr), SH_SSP_LEN(paddr));
   } while (retval < 0 && (errno == EINTR || errno == EINPROGRESS));
 
@@ -828,7 +842,9 @@
 	perror(_("connect"));
 #else
+      sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
+
       nerr = errno;
       sl_snprintf(errmsg, sizeof(errmsg), _("check port: %5d/udp on %15s: %s"),
-		  port, inet_ntoa(haddr), sh_error_message(errno, errbuf, sizeof(errbuf)));
+		  port, ipbuf, sh_error_message(errno, errbuf, sizeof(errbuf)));
       SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle((-1), FIL__, __LINE__, nerr, MSG_E_SUBGEN, 
@@ -845,7 +861,8 @@
       if (retval == -1 && errno == ECONNREFUSED)
 	{
+	  sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
 	  if (portchk_debug)
 	    fprintf(stderr, _("check port: %5d/udp on %15s established/time_wait\n"),
-		    port, inet_ntoa(haddr));
+		    port, ipbuf);
 	}
       else 
@@ -859,7 +876,8 @@
 	  if (retval == -1 && errno == ECONNREFUSED)
 	    {
+	      sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
 	      if (portchk_debug)
 		fprintf(stderr, _("check port: %5d/udp on %15s established/time_wait\n"),
-			port, inet_ntoa(haddr));
+			port, ipbuf);
 	    }
 	  else if (retval != -1)
@@ -867,7 +885,10 @@
 	      /* Try to get service name from portmap
 	       */
-	      p = check_rpc_list (port, &sinr, IPPROTO_UDP);
+	      if (paddr->ss_family == AF_INET)
+		{
+		  p = check_rpc_list (port, (struct sockaddr_in *) sh_ipvx_sockaddr_cast(paddr), IPPROTO_UDP);
+		}
 	      
-	      sh_portchk_cmp_to_list (IPPROTO_UDP, port, haddr, p ? p : NULL);
+	      sh_portchk_cmp_to_list (IPPROTO_UDP, port, paddr, p ? p : NULL);
 	      
 	      /* If not an RPC service, try to get name from /etc/services
@@ -877,6 +898,9 @@
 	      
 	      if (portchk_debug)
-		fprintf(stderr, _("check port: %5d/udp on %15s open %s\n"), 
-			port, inet_ntoa(haddr), p);
+		{
+		  sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
+		  fprintf(stderr, _("check port: %5d/udp on %15s open %s\n"), 
+			  port, ipbuf, p);
+		}
 	      
 	    }
@@ -887,11 +911,9 @@
 }
 
-static int check_port_tcp_internal (int fd, int port, struct in_addr haddr)
-{
-  struct sockaddr_in sinr;
-  /* struct in_addr     haddr; */
+static int check_port_tcp_internal (int fd, int port, struct sh_sockaddr * paddr)
+{
   int                retval;
   int                flags;
-  char             * p;
+  char             * p = NULL;
 #ifndef TEST_ONLY
   char               errmsg[256];
@@ -899,13 +921,10 @@
 #endif
   char errbuf[SH_ERRBUF_SIZE];
-
-  /* inet_aton(interface, &haddr); */
-
-  sinr.sin_family = AF_INET;
-  sinr.sin_port   = htons (port);
-  sinr.sin_addr   = haddr;
+  char ipbuf[SH_IP_BUF];
+
+  sh_ipvx_set_port(paddr, port);
 
   do {
-    retval = connect(fd, (struct sockaddr *) &sinr, sizeof(sinr));
+    retval = connect(fd, sh_ipvx_sockaddr_cast(paddr), SH_SSP_LEN(paddr));
   } while (retval < 0 && (errno == EINTR || errno == EINPROGRESS));
 
@@ -913,6 +932,9 @@
     {
       if (portchk_debug)
-	fprintf(stderr, _("check port: %5d on %15s established/time_wait\n"),
-		port, inet_ntoa(haddr));
+	{
+	  sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
+	  fprintf(stderr, _("check port: %5d on %15s established/time_wait\n"),
+		  port, ipbuf);
+	}
     }
   else if (retval == -1)
@@ -922,7 +944,8 @@
 	perror(_("connect"));
 #else
+      sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
       nerr = errno;
       sl_snprintf(errmsg, sizeof(errmsg), _("check port: %5d/tcp on %15s: %s"),
-		  port, inet_ntoa(haddr), sh_error_message(errno, errbuf, sizeof(errbuf)));
+		  port, ipbuf, sh_error_message(errno, errbuf, sizeof(errbuf)));
       SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle((-1), FIL__, __LINE__, nerr, MSG_E_SUBGEN, 
@@ -935,7 +958,10 @@
       /* Try to get service name from portmap
        */
-      p = check_rpc_list (port, &sinr, IPPROTO_TCP);
-
-      sh_portchk_cmp_to_list (IPPROTO_TCP, port, haddr, p ? p : NULL);
+      if (paddr->ss_family == AF_INET)
+	{
+	  p = check_rpc_list (port, (struct sockaddr_in *) sh_ipvx_sockaddr_cast(paddr), IPPROTO_TCP);
+	}
+
+      sh_portchk_cmp_to_list (IPPROTO_TCP, port, paddr, p ? p : NULL);
 
       /* If not an RPC service, try to get name from /etc/services
@@ -945,6 +971,9 @@
 
       if (portchk_debug)
-	fprintf(stderr, _("check port: %5d on %15s open %s\n"), 
-		port, inet_ntoa(haddr), p);
+	{
+	  sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
+	  fprintf(stderr, _("check port: %5d on %15s open %s\n"), 
+		  port, ipbuf, p);
+	}
 
 #if !defined(O_NONBLOCK)
@@ -1011,5 +1040,5 @@
 
 struct portchk_interfaces {
-  struct in_addr iface[SH_IFACE_MAX];
+  struct sh_sockaddr iface[SH_IFACE_MAX];
   int            used;
 };
@@ -1026,7 +1055,13 @@
 static int sh_portchk_init_internal (void)
 {
-  struct hostent * hent;
   volatile int     i; /* might be clobbered by âlongjmpâ or âvforkâ*/
   char errbuf[256];
+#if defined(USE_IPVX)
+  struct addrinfo hints;
+  struct addrinfo *res;
+#else
+  struct hostent * hent;
+#endif
+  char ipbuf[SH_IP_BUF];
 
   if (portchk_debug)
@@ -1045,5 +1080,6 @@
       iface_initialized = 1;
     }
-	    
+
+#if !defined(USE_IPVX)
   SH_MUTEX_LOCK(mutex_resolv);
   hent = sh_gethostbyname(portchk_hostname);
@@ -1051,14 +1087,38 @@
   while (hent && hent->h_addr_list[i] && (iface_list.used < SH_IFACE_MAX))
     {
-      memcpy (&(iface_list.iface[iface_list.used].s_addr), hent->h_addr_list[i], sizeof(in_addr_t));
+      struct sockaddr_in sin;
+
+      memcpy(&(sin.sin_addr.s_addr), hent->h_addr_list[i], sizeof(in_addr_t));
+      sh_ipvx_save(&(iface_list.iface[iface_list.used]), 
+		   AF_INET, (struct sockaddr *)&sin);
       ++iface_list.used;
       ++i;
     }
   SH_MUTEX_UNLOCK(mutex_resolv);
+#else
+  memset(&hints, '\0', sizeof(hints));
+  hints.ai_family = PF_UNSPEC;
+  hints.ai_flags  = AI_ADDRCONFIG;
+
+  if (0 == getaddrinfo(portchk_hostname, NULL, &hints, &res))
+    {
+      struct addrinfo *p = res;
+
+      while ((p != NULL) && (iface_list.used < SH_IFACE_MAX))
+	{
+	  sh_ipvx_save(&(iface_list.iface[iface_list.used]), 
+		       p->ai_family, p->ai_addr);
+	  ++iface_list.used;
+	  p = p->ai_next;
+	}
+      freeaddrinfo(res);
+    } 
+#endif
 
   for (i = 0; i < iface_list.used; ++i)
     {
-      sl_snprintf(errbuf, sizeof(errbuf), _("interface: %s"), 
-		  inet_ntoa(iface_list.iface[i]));
+      sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), &(iface_list.iface[i]));
+      sl_snprintf(errbuf, sizeof(errbuf), _("interface: %s"), ipbuf);
+
       SH_MUTEX_LOCK(mutex_thread_nolog);
       sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGEN, 
@@ -1136,10 +1196,10 @@
 #endif
 
-static int check_port_generic (int port, int type, int protocol)
+static int check_port_generic (int port, int domain, int type, int protocol)
 {
   volatile int     i    =  0;
   int              sock = -1;
   int              flag =  1; /* non-zero to enable an option */
-  struct in_addr   haddr;
+  struct sh_sockaddr   paddr;
   char errbuf[SH_ERRBUF_SIZE];
 
@@ -1148,12 +1208,19 @@
   while (i < iface_list.used)
     {
-      haddr.s_addr = iface_list.iface[i].s_addr;
-
-      if (0 != sh_portchk_is_blacklisted(port, haddr, protocol))
-	{
-	  ++i; continue;
-	}
-
-      if ((sock = socket(AF_INET, type, protocol)) < 0 )
+      memcpy(&paddr, &(iface_list.iface[i]), sizeof(paddr));
+
+      if (paddr.ss_family != domain)
+	{
+	  ++i;
+	  continue;
+	}
+
+      if (0 != sh_portchk_is_blacklisted(port, &paddr, protocol))
+	{
+	  ++i; 
+	  continue;
+	}
+
+      if ((sock = socket(paddr.ss_family, type, protocol)) < 0 )
 	{
 	  ++i;
@@ -1187,7 +1254,7 @@
 
       if (protocol == IPPROTO_TCP)
-	check_port_tcp_internal(sock, port, haddr);
+	check_port_tcp_internal(sock, port, &paddr);
       else
-	check_port_udp_internal(sock, port, haddr);
+	check_port_udp_internal(sock, port, &paddr);
 
       ++i;
@@ -1199,17 +1266,17 @@
 
 
-static int check_port_udp (int port)
-{
-  return check_port_generic(port, SOCK_DGRAM, IPPROTO_UDP);
-}
-
-static int check_port_tcp (int port)
-{
-  return check_port_generic(port, SOCK_STREAM, IPPROTO_TCP);
-}
-
-
-
-static int sh_portchk_scan_ports_generic (int min_port, int max_port_arg, int type, int protocol)
+static int check_port_udp (int port, int domain)
+{
+  return check_port_generic(port, domain, SOCK_DGRAM, IPPROTO_UDP);
+}
+
+static int check_port_tcp (int port, int domain)
+{
+  return check_port_generic(port, domain, SOCK_STREAM, IPPROTO_TCP);
+}
+
+
+static int sh_portchk_scan_ports_generic (int min_port, int max_port_arg, 
+					  int domain, int type, int protocol)
 {
   /*
@@ -1224,6 +1291,12 @@
   int flag   = 1; /* non-zero to enable an option */
 
-  struct sockaddr_in addr;
-  int addrlen      = sizeof(addr);
+  struct sockaddr_in  addr4;
+  struct sockaddr_in6 addr6;
+
+  int addrlen4      = sizeof(addr4);
+  int addrlen6      = sizeof(addr6);
+
+  struct in6_addr anyaddr = IN6ADDR_ANY_INIT; 
+
   char errbuf[SH_ERRBUF_SIZE];
 
@@ -1235,5 +1308,5 @@
   for (port = min_port; port <= max_port; ++port) 
     {
-      if ((sock = socket(AF_INET, type, protocol)) < 0 )
+      if ((sock = socket(domain, type, protocol)) < 0 )
 	{
 #ifdef TEST_ONLY
@@ -1263,9 +1336,18 @@
 	}
 
-      addr.sin_family      = AF_INET;
-      addr.sin_port        = htons(port);
-      addr.sin_addr.s_addr = INADDR_ANY;
-
-      retval = bind (sock, (struct sockaddr *) &addr, addrlen);
+      if (domain == AF_INET)
+	{
+	  addr4.sin_family      = AF_INET;
+	  addr4.sin_port        = htons(port);
+	  addr4.sin_addr.s_addr = INADDR_ANY;
+	  retval = bind (sock, (struct sockaddr *) &addr4, addrlen4);
+	}
+      else
+	{
+	  addr6.sin6_family       = AF_INET6;
+	  addr6.sin6_port         = htons(port);
+	  memcpy(&(addr6.sin6_addr.s6_addr), &anyaddr, sizeof(anyaddr));
+	  retval = bind (sock, (struct sockaddr *) &addr6, addrlen6);
+	}
 
       if (retval == 0)
@@ -1282,7 +1364,7 @@
 	       */
 	      if (protocol == IPPROTO_TCP)
-		check_port_tcp(port);
+		check_port_tcp(port, domain);
 	      else
-		check_port_udp(port);
+		check_port_udp(port, domain);
 	    }
 	  else
@@ -1306,10 +1388,20 @@
 static int sh_portchk_scan_ports_tcp (int min_port, int max_port)
 {
-  return sh_portchk_scan_ports_generic (min_port, max_port, SOCK_STREAM, IPPROTO_TCP);
+#if defined(USE_IPVX)
+  sh_portchk_scan_ports_generic (min_port, max_port, AF_INET6, 
+				 SOCK_STREAM, IPPROTO_TCP);
+#endif
+  return sh_portchk_scan_ports_generic (min_port, max_port, AF_INET, 
+					SOCK_STREAM, IPPROTO_TCP);
 }
  
 static int sh_portchk_scan_ports_udp (int min_port, int max_port)
 {
-  return sh_portchk_scan_ports_generic (min_port, max_port, SOCK_DGRAM, IPPROTO_UDP);
+#if defined(USE_IPVX)
+  sh_portchk_scan_ports_generic (min_port, max_port, AF_INET6, 
+				 SOCK_DGRAM, IPPROTO_UDP);
+#endif
+  return sh_portchk_scan_ports_generic (min_port, max_port, AF_INET,
+					SOCK_DGRAM, IPPROTO_UDP);
 }
 
@@ -1320,5 +1412,5 @@
 static int sh_portchk_add_interface (const char * str)
 {
-  struct in_addr   haddr;
+  struct sh_sockaddr saddr;
   char errbuf[256];
   char buf[64];
@@ -1338,6 +1430,8 @@
     if (*str)
       {
+	char ipbuf[SH_IP_BUF];
 	unsigned int i = 0;
-	while (*str && i < (sizeof(buf)-1) && *str != ',' && *str != ' ' && *str != '\t')
+	while (*str && i < (sizeof(buf)-1) && 
+	       *str != ',' && *str != ' ' && *str != '\t')
 	  {
 	    buf[i] = *str; ++str; ++i;
@@ -1345,5 +1439,5 @@
 	buf[i] = '\0';
 
-	if (0 == inet_aton(buf, &haddr))
+	if (0 == sh_ipvx_aton(buf, &saddr))
 	  return -1;
 
@@ -1351,5 +1445,6 @@
 	  return -1;
 
-	sl_snprintf(errbuf, sizeof(errbuf), _("interface: %s"), inet_ntoa(haddr));
+	sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), &saddr);
+	sl_snprintf(errbuf, sizeof(errbuf), _("interface: %s"), ipbuf);
 	SH_MUTEX_LOCK(mutex_thread_nolog);
 	sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGEN, 
@@ -1357,5 +1452,5 @@
 	SH_MUTEX_UNLOCK(mutex_thread_nolog);
 	
-	memcpy (&(iface_list.iface[iface_list.used].s_addr), &(haddr.s_addr), sizeof(in_addr_t));
+	memcpy (&(iface_list.iface[iface_list.used]), &(saddr), sizeof(saddr));
 	++iface_list.used;
       }
@@ -1367,5 +1462,6 @@
 /* verify whether port/interface is blacklisted (do not check)
  */
-static int sh_portchk_is_blacklisted(int port, struct in_addr haddr, int proto)
+static int sh_portchk_is_blacklisted(int port, struct sh_sockaddr * saddr, 
+				     int proto)
 {
   struct sh_port * head;
@@ -1380,5 +1476,6 @@
       if (head->port == port)
 	{
-	  if ((head->haddr.s_addr == 0) || (head->haddr.s_addr == haddr.s_addr))
+	  if (sh_ipvx_isany(head->paddr) || 
+	      0 == sh_ipvx_cmp(head->paddr, saddr))
 	    return 1;
 	  else
@@ -1391,5 +1488,5 @@
 
 
-static int sh_portchk_blacklist(int port, struct in_addr haddr, int proto)
+static int sh_portchk_blacklist(int port, struct sh_sockaddr * saddr, int proto)
 {
   struct sh_port * black;
@@ -1405,11 +1502,14 @@
   while (black)
     {
-      if (black->port == port && head->haddr.s_addr == haddr.s_addr)
+      if (black->port == port && 
+	  0 == sh_ipvx_cmp(head->paddr, saddr))
 	return -1;
       black = black->next;
     }
+
   black = SH_ALLOC (sizeof(struct sh_port));
+  black->paddr = SH_ALLOC (sizeof(struct sh_sockaddr));
   black->port  = port;
-  black->haddr.s_addr = haddr.s_addr;
+  memcpy(black->paddr, saddr, sizeof(struct sh_sockaddr));
   black->next  = head;
 
@@ -1424,5 +1524,6 @@
 /* Subroutine to add a required or optional port/service
  */
-static int sh_portchk_add_required_port_generic (char * service, char * interface, int type)
+static int sh_portchk_add_required_port_generic (char * service, 
+						 char * interface, int type)
 {
   char buf[256];
@@ -1431,8 +1532,8 @@
   char * endptr;
   unsigned long int  port;
-  struct in_addr   haddr;
+  struct sh_sockaddr   saddr;
   struct sh_portentry * portent;
 
-  if (0 == inet_aton(interface, &haddr))
+  if (0 == sh_ipvx_aton(interface, &saddr))
     return -1;
 
@@ -1455,11 +1556,11 @@
    */
   if (*endptr == '\0' && port <= 65535 && type == SH_PORT_BLACKLIST)
-    return (sh_portchk_blacklist(port, haddr, proto));
+    return (sh_portchk_blacklist(port, &saddr, proto));
 
   if (*endptr != '\0')
     {  
-      portent = sh_portchk_get_from_list (proto, -1, haddr, buf);
+      portent = sh_portchk_get_from_list (proto, -1, &saddr, buf);
       if (!portent)
-	sh_portchk_add_to_list (proto,   -1, haddr,  buf, type, SH_PORT_UNKN);
+	sh_portchk_add_to_list (proto,   -1, &saddr,  buf, type, SH_PORT_UNKN);
       else
 	{
@@ -1477,7 +1578,7 @@
   else if (port <= 65535)
     {
-      portent = sh_portchk_get_from_list (proto, port, haddr, NULL);
+      portent = sh_portchk_get_from_list (proto, port, &saddr, NULL);
       if (!portent)
-	sh_portchk_add_to_list (proto, port, haddr, NULL, type, SH_PORT_UNKN);
+	sh_portchk_add_to_list (proto, port, &saddr, NULL, type, SH_PORT_UNKN);
       else
 	{
@@ -1669,5 +1770,5 @@
 {
 #if defined(SH_USE_PORTCHECK) && (defined(SH_WITH_CLIENT) || defined(SH_STANDALONE))
-  struct in_addr   haddr_local;
+  struct sh_sockaddr    haddr_local;
   struct sh_portentry * portent;
   char   buf[256];
@@ -1704,9 +1805,9 @@
   CuAssertTrue(tc, 0 == strcmp(buf, "daytime"));
 
-  CuAssertTrue(tc, 0 != inet_aton("127.0.0.1", &haddr_local));
-
-  sh_portchk_add_to_list (IPPROTO_TCP,  8000, haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
-
-  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, NULL);
+  CuAssertTrue(tc, 0 != sh_ipvx_aton("127.0.0.1", &haddr_local));
+
+  sh_portchk_add_to_list (IPPROTO_TCP,  8000, &haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
+
+  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, NULL);
   CuAssertPtrNotNull(tc, portent);
 
@@ -1720,14 +1821,14 @@
   CuAssertTrue(tc, NULL == portlist_tcp);
 
-  sh_portchk_add_to_list (IPPROTO_TCP,  8000, haddr_local, NULL, SH_PORT_REQ, SH_PORT_UNKN);
-  sh_portchk_add_to_list (IPPROTO_TCP,  8001, haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
-  sh_portchk_add_to_list (IPPROTO_TCP,  8002, haddr_local, NULL, SH_PORT_REQ, SH_PORT_UNKN);
-  sh_portchk_add_to_list (IPPROTO_TCP,  8003, haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
-  sh_portchk_add_to_list (IPPROTO_TCP,  8004, haddr_local, NULL, SH_PORT_IGN, SH_PORT_UNKN);
-  sh_portchk_add_to_list (IPPROTO_TCP,    -1, haddr_local, "foo1", SH_PORT_NOT, SH_PORT_UNKN);
-  sh_portchk_add_to_list (IPPROTO_TCP,    -1, haddr_local, "foo2", SH_PORT_REQ, SH_PORT_UNKN);
-  sh_portchk_add_to_list (IPPROTO_TCP,    -1, haddr_local, "foo3", SH_PORT_NOT, SH_PORT_UNKN);
-  sh_portchk_add_to_list (IPPROTO_TCP,    -1, haddr_local, "foo4", SH_PORT_REQ, SH_PORT_UNKN);
-  sh_portchk_add_to_list (IPPROTO_TCP,    -1, haddr_local, "foo5", SH_PORT_IGN, SH_PORT_UNKN);
+  sh_portchk_add_to_list (IPPROTO_TCP,  8000, &haddr_local, NULL, SH_PORT_REQ, SH_PORT_UNKN);
+  sh_portchk_add_to_list (IPPROTO_TCP,  8001, &haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
+  sh_portchk_add_to_list (IPPROTO_TCP,  8002, &haddr_local, NULL, SH_PORT_REQ, SH_PORT_UNKN);
+  sh_portchk_add_to_list (IPPROTO_TCP,  8003, &haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
+  sh_portchk_add_to_list (IPPROTO_TCP,  8004, &haddr_local, NULL, SH_PORT_IGN, SH_PORT_UNKN);
+  sh_portchk_add_to_list (IPPROTO_TCP,    -1, &haddr_local, "foo1", SH_PORT_NOT, SH_PORT_UNKN);
+  sh_portchk_add_to_list (IPPROTO_TCP,    -1, &haddr_local, "foo2", SH_PORT_REQ, SH_PORT_UNKN);
+  sh_portchk_add_to_list (IPPROTO_TCP,    -1, &haddr_local, "foo3", SH_PORT_NOT, SH_PORT_UNKN);
+  sh_portchk_add_to_list (IPPROTO_TCP,    -1, &haddr_local, "foo4", SH_PORT_REQ, SH_PORT_UNKN);
+  sh_portchk_add_to_list (IPPROTO_TCP,    -1, &haddr_local, "foo5", SH_PORT_IGN, SH_PORT_UNKN);
 
   sh_portchk_check_list (&portlist_tcp, IPPROTO_TCP, SH_PORT_NOREPT);
@@ -1735,55 +1836,55 @@
   CuAssertPtrNotNull(tc, portlist_tcp);
 
-  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, NULL);
+  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, NULL);
   CuAssertPtrNotNull(tc, portent);
 
-  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8001, haddr_local, NULL);
+  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8001, &haddr_local, NULL);
   CuAssertTrue(tc, NULL == portent);
 
-  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8002, haddr_local, NULL);
+  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8002, &haddr_local, NULL);
   CuAssertPtrNotNull(tc, portent);
 
-  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8003, haddr_local, NULL);
+  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8003, &haddr_local, NULL);
   CuAssertTrue(tc, NULL == portent);
 
-  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8004, haddr_local, NULL);
+  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8004, &haddr_local, NULL);
   CuAssertPtrNotNull(tc, portent);
 
-  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, "foo1");
+  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, "foo1");
   CuAssertTrue(tc, NULL == portent);
 
-  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, "foo2");
+  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, "foo2");
   CuAssertPtrNotNull(tc, portent);
   CuAssertTrue(tc, 0 == strcmp(portent->service, "foo2"));
 
-  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, "foo3");
+  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, "foo3");
   CuAssertTrue(tc, NULL == portent);
 
-  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, "foo4");
+  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, "foo4");
   CuAssertPtrNotNull(tc, portent);
   CuAssertTrue(tc, 0 == strcmp(portent->service, "foo4"));
 
-  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, "foo5");
+  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, "foo5");
   CuAssertPtrNotNull(tc, portent);
   CuAssertTrue(tc, 0 == strcmp(portent->service, "foo5"));
 
-  CuAssertTrue(tc, 0 == sh_portchk_blacklist(666, haddr_local, IPPROTO_TCP));
-  CuAssertTrue(tc, 0 != sh_portchk_blacklist(666, haddr_local, IPPROTO_TCP));
-  CuAssertTrue(tc, 0 == sh_portchk_blacklist(667, haddr_local, IPPROTO_TCP));
-  CuAssertTrue(tc, 0 == sh_portchk_blacklist(668, haddr_local, IPPROTO_TCP));
-  CuAssertTrue(tc, 0 == sh_portchk_blacklist(666, haddr_local, IPPROTO_UDP));
-  CuAssertTrue(tc, 0 != sh_portchk_blacklist(666, haddr_local, IPPROTO_UDP));
-  CuAssertTrue(tc, 0 == sh_portchk_blacklist(667, haddr_local, IPPROTO_UDP));
-  CuAssertTrue(tc, 0 == sh_portchk_blacklist(668, haddr_local, IPPROTO_UDP));
-
-  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(668, haddr_local, IPPROTO_UDP));
-  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(667, haddr_local, IPPROTO_UDP));
-  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(666, haddr_local, IPPROTO_UDP));
-  CuAssertTrue(tc, 0 == sh_portchk_is_blacklisted(665, haddr_local, IPPROTO_UDP));
-
-  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(668, haddr_local, IPPROTO_TCP));
-  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(667, haddr_local, IPPROTO_TCP));
-  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(666, haddr_local, IPPROTO_TCP));
-  CuAssertTrue(tc, 0 == sh_portchk_is_blacklisted(665, haddr_local, IPPROTO_TCP));
+  CuAssertTrue(tc, 0 == sh_portchk_blacklist(666, &haddr_local, IPPROTO_TCP));
+  CuAssertTrue(tc, 0 != sh_portchk_blacklist(666, &haddr_local, IPPROTO_TCP));
+  CuAssertTrue(tc, 0 == sh_portchk_blacklist(667, &haddr_local, IPPROTO_TCP));
+  CuAssertTrue(tc, 0 == sh_portchk_blacklist(668, &haddr_local, IPPROTO_TCP));
+  CuAssertTrue(tc, 0 == sh_portchk_blacklist(666, &haddr_local, IPPROTO_UDP));
+  CuAssertTrue(tc, 0 != sh_portchk_blacklist(666, &haddr_local, IPPROTO_UDP));
+  CuAssertTrue(tc, 0 == sh_portchk_blacklist(667, &haddr_local, IPPROTO_UDP));
+  CuAssertTrue(tc, 0 == sh_portchk_blacklist(668, &haddr_local, IPPROTO_UDP));
+
+  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(668, &haddr_local, IPPROTO_UDP));
+  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(667, &haddr_local, IPPROTO_UDP));
+  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(666, &haddr_local, IPPROTO_UDP));
+  CuAssertTrue(tc, 0 == sh_portchk_is_blacklisted(665, &haddr_local, IPPROTO_UDP));
+
+  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(668, &haddr_local, IPPROTO_TCP));
+  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(667, &haddr_local, IPPROTO_TCP));
+  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(666, &haddr_local, IPPROTO_TCP));
+  CuAssertTrue(tc, 0 == sh_portchk_is_blacklisted(665, &haddr_local, IPPROTO_TCP));
 #else
   (void) tc; /* fix compiler warning */
Index: /trunk/src/sh_registry.c
===================================================================
--- /trunk/src/sh_registry.c	(revision 294)
+++ /trunk/src/sh_registry.c	(revision 295)
@@ -447,4 +447,10 @@
 }
 
+#if !defined(KEY_WOW64_64KEY)
+#define KEY_WOW64_64KEY 0x0100;
+#endif
+#if !defined(KEY_WOW64_32KEY)
+#define KEY_WOW64_32KEY 0x0200;
+#endif
 
 
@@ -790,5 +796,6 @@
 
 
-int CheckThisSubkey (HKEY key, char * subkey, char * path, int isSingle)
+int CheckThisSubkey (HKEY key, char * subkey, char * path, int isSingle,
+		     int view)
 {
   HKEY hTestKey;
@@ -826,5 +833,5 @@
 		    subkey,
 		    0,
-		    KEY_READ,
+		    (KEY_READ | view),
 		    &hTestKey) == ERROR_SUCCESS
       )
@@ -867,4 +874,5 @@
   char path[20] = "";
   int pos = 0;
+  int retval = -1;
   
   if      (0 == strncmp(key, _("HKEY_CLASSES_ROOT"), 17))
@@ -924,6 +932,14 @@
       return -1;
     }
-  
-  return CheckThisSubkey (topKey, subkey, path, isSingle);
+
+  /************************  
+  if (ShCheckBothViews)
+    {
+      CheckThisSubkey (topKey, subkey, path, isSingle, KEY_WOW64_32KEY);
+      return CheckThisSubkey (topKey, subkey, path, isSingle, KEY_WOW64_64KEY);
+    }
+  *************************/
+
+  return CheckThisSubkey (topKey, subkey, path, isSingle, 0);
 }
 
Index: /trunk/src/sh_socket.c
===================================================================
--- /trunk/src/sh_socket.c	(revision 294)
+++ /trunk/src/sh_socket.c	(revision 295)
@@ -557,5 +557,6 @@
   char message[SH_MAXMSG];
   struct sockaddr_un name;
-  int size;
+  ACCEPT_TYPE_ARG3 size = sizeof(name);
+
   int nbytes;
   int talkfd;
@@ -636,7 +637,8 @@
    * 'name' is the address of the sender socket
    */
-  size = sizeof (name);
-  talkfd = retry_accept(FIL__, __LINE__, 
-			pf_unix_fd, (struct sockaddr *) & name, &size);
+  do {
+    talkfd = accept(pf_unix_fd, (struct sockaddr *) &name, &size);
+  } while (talkfd < 0 && errno == EINTR);
+
   if ((talkfd < 0) && (errno == EAGAIN))
     {
Index: /trunk/src/sh_tools.c
===================================================================
--- /trunk/src/sh_tools.c	(revision 294)
+++ /trunk/src/sh_tools.c	(revision 295)
@@ -89,4 +89,5 @@
 #include "sh_static.h"
 #include "sh_pthread.h"
+#include "sh_ipvx.h"
 
 #undef  FIL__
@@ -127,4 +128,51 @@
 int sh_tools_iface_is_present(char *str)
 {
+#if defined(USE_IPVX)
+  struct addrinfo *ai;
+  struct addrinfo hints;
+  int             res;
+
+  memset (&hints, '\0', sizeof (hints));
+  hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
+  hints.ai_socktype = SOCK_STREAM;
+  res = getaddrinfo (str, _("2543"), &hints, &ai);
+  
+  if (res == 0)
+    {
+      struct addrinfo *p = ai;
+      while (p != NULL)
+	{
+	  int fd = socket (p->ai_family, p->ai_socktype,
+			   p->ai_protocol);
+
+	  if (fd < 0)
+	    {
+	      freeaddrinfo (ai);
+	      return 0;
+	    }
+
+	  if (bind (fd, p->ai_addr, p->ai_addrlen) != 0)
+	    {
+	      /* bind() fails for access reasons, iface exists
+	       */
+	      if (errno == EACCES || errno == EADDRINUSE)
+		{
+		  sl_close_fd (FIL__, __LINE__, fd);
+		  freeaddrinfo (ai);
+		  return 1;
+		}
+
+	      sl_close_fd (FIL__, __LINE__, fd);
+	      freeaddrinfo (ai);
+	      return 0;
+	    }
+
+	  sl_close_fd (FIL__, __LINE__, fd);
+	  freeaddrinfo (ai);
+	  return 1;
+	  /* p = p->ai_next; */ 
+	}
+    }
+#else
   struct sockaddr_in sin;
   int sd;
@@ -158,4 +206,5 @@
       return 1;
     }
+#endif
   return 0;
 }
@@ -428,15 +477,4 @@
 }
 
-int is_numeric (const char * address)
-{
-  int j;
-  int len = sl_strlen(address);
-  
-  for (j = 0; j < len; ++j)
-    if ( (address[j] < '0' || address[j] > '9') && address[j] != '.')
-      return (1 == 0);
-  return (1 == 1);
-}
-
 #if defined (SH_WITH_SERVER)
 
@@ -468,5 +506,5 @@
 typedef struct _sin_cache {
   char * address;
-  struct sockaddr_in sin;
+  struct sh_sockaddr  saddr;
   struct _sin_cache * next;
 } sin_cache;
@@ -503,4 +541,5 @@
 }
 
+#if !defined(USE_IPVX)
 int connect_port (char * address, int port, 
 		  char * ecall, int * errnum, char * errmsg, int errsiz)
@@ -537,5 +576,5 @@
 			       address, sl_strlen(address)))
 	    {
-	      memcpy (&sinr, &(check_cache->sin), sizeof(struct sockaddr_in));
+	      memcpy (&sinr, &((check_cache->saddr).sin), sizeof(struct sockaddr_in));
 	      sinr.sin_family = AF_INET;
 	      sinr.sin_port   = htons (port);
@@ -657,5 +696,7 @@
 	  check_cache->address = SH_ALLOC(sl_strlen(address) + 1);
 	  sl_strlcpy (check_cache->address, address, sl_strlen(address) + 1);
-	  memcpy(&(check_cache->sin), &sinr, sizeof(struct sockaddr_in));
+
+	  sh_ipvx_save(&(check_cache->saddr), AF_INET, (struct sockaddr *) &sinr);
+
 	  ++cached_addr;
 	  
@@ -710,4 +751,237 @@
   SL_RETURN(retval, _("connect_port"));
 }
+#else
+int connect_port (char * address, int port, 
+		  char * ecall, int * errnum, char * errmsg, int errsiz)
+{
+  struct sockaddr_in *sin;
+  struct sockaddr_in6 *sin6;
+  struct sh_sockaddr ss;
+  sin_cache * check_cache = conn_cache;
+  int    cached = 0;
+  int    fail   = 0;
+  int    fd     = -1;
+  int    status = 0;
+
+  int    retval;
+  char   errbuf[SH_ERRBUF_SIZE];
+
+  SL_ENTER(_("connect_port"));
+
+  /* paranoia -- should not happen
+   */
+  if (cached_addr > 128)
+    delete_cache();
+
+  if (check_cache != NULL)
+    {
+      while (check_cache && check_cache->address)
+	{
+	  if ( 0 == sl_strncmp(check_cache->address, 
+			       address, sl_strlen(address)))
+	    {
+	      memcpy (&ss, &(check_cache->saddr), sizeof(struct sh_sockaddr));
+	      switch (ss.ss_family) 
+		{
+		case AF_INET:
+		  sin = &(ss.sin);
+		  sin->sin_port   = htons (port);
+		case AF_INET6:
+		  sin6 = &(ss.sin6);
+		  sin6->sin6_port  = htons (port);
+		}
+	      cached = 1;
+	      break;
+	    }
+	  if (check_cache->next)
+	    check_cache = check_cache->next;
+	  else
+	    check_cache = NULL;
+	}
+    }
+
+  if (cached != 0)
+    {
+      fd = socket(ss.ss_family, SOCK_STREAM, 0);
+      if (fd < 0) 
+	{
+	  status = errno;
+	  fail   = (-1);
+	  sl_strlcpy(ecall, _("socket"), SH_MINIBUF);
+	  *errnum = status;
+	  sl_strlcpy(errmsg, sh_error_message (status, errbuf, sizeof(errbuf)), errsiz);
+	  sl_strlcat(errmsg, _(", address "), errsiz);
+	  sl_strlcat(errmsg, address, errsiz);
+	}
+    
+  
+      if (fail != (-1)) 
+	{
+	  int addrlen = SH_SS_LEN(ss);
+	
+	  if ( retry_connect(FIL__, __LINE__, fd, 
+			     sh_ipvx_sockaddr_cast(&ss), addrlen) < 0) 
+	    {
+	      status = errno;
+	      sl_strlcpy(ecall, _("connect"), SH_MINIBUF);
+	      *errnum = status;
+	      sl_strlcpy(errmsg, sh_error_message (status, errbuf, sizeof(errbuf)), errsiz);
+	      sl_strlcat(errmsg, _(", address "), errsiz);
+	      sl_strlcat(errmsg, address, errsiz);
+	      sl_close_fd(FIL__, __LINE__, fd);
+	      fail = (-1); 
+	    }
+	}
+
+      if (fail != 0)
+	{
+	  delete_cache();
+	  cached = 0;
+	}
+    }
+
+  if (cached == 0)
+    {
+      int    res;
+      char   sport[32];
+      struct addrinfo *ai;
+      struct addrinfo hints;
+
+      memset (&hints, '\0', sizeof (hints));
+      hints.ai_flags = AI_ADDRCONFIG;
+#if defined(AI_CANONNAME)
+      hints.ai_flags |= AI_CANONNAME;
+#endif 
+      hints.ai_socktype = SOCK_STREAM;
+      sl_snprintf(sport, sizeof(sport), "%d", port);
+
+      res = getaddrinfo (address, sport, &hints, &ai);
+      if (res != 0)
+	{
+	  fail = (-1);
+	  status = errno;
+	  sl_strlcpy(ecall, _("getaddrinfo"), SH_MINIBUF);
+	  *errnum = status;
+	  sl_strlcpy(errmsg, gai_strerror (res), errsiz);
+	  sl_strlcat(errmsg, _(", address "), errsiz);
+	  sl_strlcat(errmsg, address, errsiz);
+	}
+
+      if (fail != (-1) && (DoReverseLookup == S_TRUE) && !sh_ipvx_is_numeric(address))
+	{
+	  struct addrinfo *p = ai;
+	  int    success = 0;
+	  char hostname[SH_BUFSIZE];
+	  const char * canonical;
+
+#if defined(AI_CANONNAME)
+	  if (ai->ai_canonname && strlen(ai->ai_canonname) > 0)
+	    {
+	      canonical = ai->ai_canonname;
+	    }
+	  else
+	    {
+	      canonical = address;
+	    }
+#else
+	  canonical = address;
+#endif
+
+	  while (p != NULL)
+	    {
+	      int e = getnameinfo (p->ai_addr, p->ai_addrlen, 
+				   hostname, sizeof(hostname),
+				   NULL, 0, NI_NAMEREQD);
+	      
+	      if (e == 0)
+		{
+		  if (sl_strcasecmp(hostname, canonical) == 0)
+		    {
+		      success = 1;
+		      break;
+		    }
+		}
+	    
+	      p = p->ai_next;
+	    }
+
+	  if (success == 0)
+	    {
+	      sl_strlcpy(ecall, _("strcmp"), SH_MINIBUF);
+	      sl_strlcpy(errmsg, _("Reverse lookup failed: "), 
+			 errsiz);
+	      sl_strlcat(errmsg, address, errsiz);
+	      fail = -1;
+	      freeaddrinfo (ai);
+	    }
+	}
+
+      if (fail != (-1))
+	{
+	  struct addrinfo *p = ai;
+
+	  while (p != NULL)
+	    {
+	      fd = socket(p->ai_family, p->ai_socktype,
+			  p->ai_protocol);
+
+	      if (fd != (-1))
+		{
+		  if (retry_connect(FIL__, __LINE__, fd, 
+				    p->ai_addr, p->ai_addrlen) >= 0)
+		    {
+		      /* put it into the cache
+		       */
+		      check_cache          = SH_ALLOC(sizeof(sin_cache));
+		      check_cache->address = SH_ALLOC(sl_strlen(address) + 1);
+		      sl_strlcpy (check_cache->address, address, sl_strlen(address) + 1);
+
+		      sh_ipvx_save(&(check_cache->saddr), p->ai_family, p->ai_addr);
+
+		      ++cached_addr;
+	  
+		      if (conn_cache)
+			{
+			  if (conn_cache->next)
+			    check_cache->next    = conn_cache->next;
+			  else
+			    check_cache->next    = NULL;
+			  conn_cache->next     = check_cache;
+			}
+		      else
+			{
+			  check_cache->next    = NULL;
+			  conn_cache           = check_cache;
+			}
+		    
+		      freeaddrinfo (ai);
+		      goto end;
+		    }
+		  status = errno;
+		  sl_close_fd(FIL__, __LINE__, fd);
+		}
+	      else
+		{
+		  status = errno;
+		}
+	      p = p->ai_next;
+	    }
+	  fail = (-1);
+	  freeaddrinfo (ai);
+
+	  sl_strlcpy(ecall, _("connect"), SH_MINIBUF);
+	  *errnum = status;
+	  sl_strlcpy(errmsg, sh_error_message (status, errbuf, sizeof(errbuf)), errsiz);
+	  sl_strlcat(errmsg, _(", address "), errsiz);
+	  sl_strlcat(errmsg, address, errsiz);
+	}
+    }
+
+ end:
+  retval = (fail < 0) ? (-1) : fd;
+  SL_RETURN(retval, _("connect_port"));
+
+}
+#endif
 
 int connect_port_2 (char * address1, char * address2, int port, 
Index: /trunk/src/sh_unix.c
===================================================================
--- /trunk/src/sh_unix.c	(revision 294)
+++ /trunk/src/sh_unix.c	(revision 295)
@@ -98,4 +98,5 @@
 #include "sh_hash.h"
 #include "sh_tools.h"
+#include "sh_ipvx.h"
 #include "sh_tiger.h"
 #include "sh_prelink.h"
@@ -1605,5 +1606,4 @@
 {
   struct utsname   buf;
-  struct hostent * he1;
   int              i;
   int              ddot;
@@ -1611,4 +1611,6 @@
   char           * p;
   char             hostname[256];
+  char             numeric[SH_IP_BUF];
+  char           * canonical;
 
 
@@ -1656,23 +1658,16 @@
     }
 
-  SH_MUTEX_LOCK(mutex_resolv);
-  he1 = sh_gethostbyname(hostname);
-
-  if (he1 != NULL)
-    {
-      sl_strlcpy (sh.host.name, sh_unix_h_name(he1), SH_PATHBUF);
-      sh_tolower (sh.host.name);
-    }
-  SH_MUTEX_UNLOCK(mutex_resolv);
-
-  if (he1 == NULL)
-    {
-      dlog(1, FIL__, __LINE__, 
-	   _("According to uname, your nodename is %s, but your resolver\nlibrary cannot resolve this nodename to a FQDN. For more information, see the entry about self-resolving under 'Most frequently' in the FAQ that you will find in the docs/ subdirectory.\n"),
-	   hostname);
+  canonical = sh_ipvx_canonical(hostname, numeric, sizeof(numeric));
+
+  if (canonical == NULL)
+    {
       sl_strlcpy (sh.host.name, hostname,    SH_PATHBUF);
       sh_tolower (sh.host.name);
     }
-  
+  else
+    {
+      sl_strlcpy (sh.host.name, canonical,   SH_PATHBUF);
+      SH_FREE(canonical);
+    }
 
   /* check whether it looks like a FQDN
@@ -1683,16 +1678,14 @@
     if (sh.host.name[i] == '.') ++ddot; 
 
-  if (ddot == 0 && he1 != NULL)
+  if (ddot == 0)
     { 
       dlog(1, FIL__, __LINE__, 
 	   _("According to uname, your nodename is %s, but your resolver\nlibrary cannot resolve this nodename to a FQDN.\nRather, it resolves this to %s.\nFor more information, see the entry about self-resolving under\n'Most frequently' in the FAQ that you will find in the docs/ subdirectory.\n"),
 	   hostname, sh.host.name);
-      sl_strlcpy (sh.host.name, 
-		  inet_ntoa (*(struct in_addr *) he1->h_addr), 
-		  SH_PATHBUF);
+      sl_strlcpy (sh.host.name, numeric, SH_PATHBUF);
       SL_RET0(_("sh_unix_localhost"));
     } 
 
-  if (is_numeric(sh.host.name)) 
+  if (sh_ipvx_is_numeric(sh.host.name)) 
     {
       dlog(1, FIL__, __LINE__, 
@@ -1717,10 +1710,10 @@
   struct utsname   buf;
 #endif
-  struct hostent * he1;
   int              i;
   int              ddot;
   int              len;
   char             hostname[1024];
-
+  char             numeric[SH_IP_BUF];
+  char           * canonical;
 
   SL_ENTER(_("sh_unix_localhost"));
@@ -1737,21 +1730,15 @@
   hostname[1023] = '\0';
 
-  SH_MUTEX_LOCK(mutex_resolv);
-  he1 = sh_gethostbyname(hostname);
-
-  if (he1 != NULL)
-    {
-      sl_strlcpy (sh.host.name, sh_unix_h_name(he1), SH_PATHBUF);
+  canonical = sh_ipvx_canonical(hostname, numeric, sizeof(numeric));
+
+  if (canonical == NULL)
+    {
+      sl_strlcpy (sh.host.name, hostname, SH_PATHBUF);
       sh_tolower (sh.host.name);
     }
-  SH_MUTEX_UNLOCK(mutex_resolv);
-
-  if (he1 == NULL)
-    {
-      dlog(1, FIL__, __LINE__, 
-	   _("According to gethostname, your nodename is %s, but your resolver\nlibrary cannot resolve this nodename to a FQDN.\nFor more information, see the entry about self-resolving under\n'Most frequently' in the FAQ that you will find in the docs/ subdirectory.\n"),
-	   hostname);
-      sl_strlcpy (sh.host.name, _("localhost"), SH_PATHBUF);
-      SL_RET0(_("sh_unix_localhost"));
+  else
+    {
+      sl_strlcpy (sh.host.name, canonical,   SH_PATHBUF);
+      SH_FREE(canonical);
     }
 
@@ -1767,11 +1754,9 @@
 	   _("According to uname, your nodename is %s, but your resolver\nlibrary cannot resolve this nodename to a FQDN.\nRather, it resolves this to %s.\nFor more information, see the entry about self-resolving under\n'Most frequently' in the FAQ that you will find in the docs/ subdirectory.\n"),
 	   hostname, sh.host.name);
-      sl_strlcpy (sh.host.name, 
-		  inet_ntoa (*(struct in_addr *) he1->h_addr), 
-		  SH_PATHBUF);
+      sl_strlcpy (sh.host.name, numeric, SH_PATHBUF);
       SL_RET0(_("sh_unix_localhost"));
     }
 
-  if (is_numeric(sh.host.name)) 
+  if (sh_ipvx_is_numeric(sh.host.name)) 
     {
       dlog(1, FIL__, __LINE__, 
Index: /trunk/src/sh_utmp.c
===================================================================
--- /trunk/src/sh_utmp.c	(revision 294)
+++ /trunk/src/sh_utmp.c	(revision 295)
@@ -179,5 +179,5 @@
   char                name[UT_NAMESIZE+1];
   char                ut_host[UT_HOSTSIZE+1];
-  char                ut_ship[16]; /* IP address */
+  char                ut_ship[SH_IP_BUF]; /* IP address */
   time_t              time;
   struct log_user   * next;
@@ -454,23 +454,32 @@
 
 #ifdef HAVE_UTADDR
-#ifdef HAVE_INET_ATON
-static char * my_inet_ntoa(struct in_addr in)
-{
-  return /*@-unrecog@*/inet_ntoa(in)/*@+unrecog@*/;
-}
-#else
-static char * my_inet_ntoa(struct in_addr in)
-{
-  unsigned char a, b, c, d;
-  static char   foo[16];
-  char          bar[4];
-  memcpy (bar, &(in.s_addr), 4); /* memory alignment (?) */
-  memcpy (&a, &bar[0], 1);
-  memcpy (&b, &bar[1], 1);
-  memcpy (&c, &bar[2], 1);
-  memcpy (&d, &bar[3], 1);
-  sprintf(foo, _("%d.%d.%d.%d"),                        /* known to fit  */
-	  (int) a, (int) b, (int) c, (int) d);
-  return foo;
+#ifdef HAVE_UTADDR_V6
+static char * my_inet_ntoa(SINT32 * ut_addr_v6, char * buf, size_t buflen)
+{
+  struct in_addr in;
+
+  buf[0] = '\0';
+
+  if (0 == (ut_addr_v6[1] + ut_addr_v6[2] + ut_addr_v6[3]))
+    {
+      memcpy(&in, ut_addr_v6, sizeof(struct in_addr));
+      sl_strlcpy(buf, inet_ntoa(in), buflen);
+    }
+  else
+    {
+      inet_ntop(AF_INET6, ut_addr_v6, buf, buflen);
+    }
+  return buf;
+}
+#else
+static char * my_inet_ntoa(SINT32 ut_addr, char * buf, size_t buflen)
+{
+  struct in_addr in;
+
+  buf[0] = '\0';
+
+  memcpy(&in, ut_addr, sizeof(struct in_addr));
+  sl_strlcpy(buf, inet_ntoa(in), buflen);
+  return buf;
 }
 #endif
@@ -915,12 +924,9 @@
 #endif
 #ifdef HAVE_UTADDR
-      /*@-type@*//* ut_addr does exist !!! */
-      {
-	struct in_addr saddr;
-	memcpy (&saddr, &(ut->ut_addr), sizeof(struct in_addr));
-	(void) sl_strlcpy((char*)(user->ut_ship), 
-			  my_inet_ntoa(saddr), 16);
-      }
-      /*@+type@*/
+#ifdef HAVE_UTADDR_V6
+      my_inet_ntoa(ut->ut_addr_v6, user->ut_ship, SH_IP_BUF);
+#else
+      my_inet_ntoa(ut->ut_addr, user->ut_ship, SH_IP_BUF);
+#endif
 #endif
       user->time = ut->ut_time;
@@ -1059,5 +1065,9 @@
 #endif
 #ifdef HAVE_UTADDR
-      sl_strlcpy(user->ut_ship,my_inet_ntoa((struct in_addr)ut->ut_addr),16);
+#ifdef HAVE_UTADDR_V6
+      my_inet_ntoa(ut->ut_addr_v6, user->ut_ship, SH_IP_BUF);
+#else
+      my_inet_ntoa(ut->ut_addr, user->ut_ship, SH_IP_BUF);
+#endif
 #endif
       user->time       = ut->ut_time;
Index: /trunk/test/testrun_1e.sh
===================================================================
--- /trunk/test/testrun_1e.sh	(revision 294)
+++ /trunk/test/testrun_1e.sh	(revision 295)
@@ -20,5 +20,5 @@
 #
 
-BUILDOPTS="--quiet $TRUST --enable-xml-log --enable-port-check --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$RCFILE --with-log-file=$LOGFILE --with-pid-file=$PW_DIR/.samhain_lock --with-data-file=$PW_DIR/.samhain_file"
+BUILDOPTS="--quiet $TRUST --enable-debug=gdb --enable-xml-log --enable-port-check --prefix=$PW_DIR --localstatedir=$PW_DIR --with-config-file=$RCFILE --with-log-file=$LOGFILE --with-pid-file=$PW_DIR/.samhain_lock --with-data-file=$PW_DIR/.samhain_file"
 export BUILDOPTS
 
