Index: trunk/src/sh_portcheck.c
===================================================================
--- trunk/src/sh_portcheck.c	(revision 290)
+++ 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 */
