diff -ur aolserver-4.5.1.orig/include/ns.h aolserver-4.5.1/include/ns.h
--- aolserver-4.5.1.orig/include/ns.h	2009-02-01 18:45:34.000000000 +0100
+++ aolserver-4.5.1/include/ns.h	2012-06-10 19:41:18.000000000 +0200
@@ -687,6 +687,7 @@
  * dns.c:
  */
 
+NS_EXTERN int Ns_inet_pton(struct in6_addr *ia6, char *host);
 NS_EXTERN int Ns_GetHostByAddr(Ns_DString *dsPtr, char *addr);
 NS_EXTERN int Ns_GetAddrByHost(Ns_DString *dsPtr, char *host);
 NS_EXTERN int Ns_GetAllAddrByHost(Ns_DString *dsPtr, char *host);
@@ -1129,8 +1130,8 @@
 NS_EXTERN int Ns_SockWait(SOCKET sock, int what, int timeout);
 NS_EXTERN int Ns_SockWaitEx(SOCKET sock, int what, int ms);
 
-NS_EXTERN SOCKET Ns_BindSock(struct sockaddr_in *psa);
-NS_EXTERN SOCKET Ns_SockBind(struct sockaddr_in *psa);
+NS_EXTERN SOCKET Ns_BindSock(struct sockaddr_in6 *psa);
+NS_EXTERN SOCKET Ns_SockBind(struct sockaddr_in6 *psa);
 NS_EXTERN SOCKET Ns_SockListen(char *address, int port);
 NS_EXTERN SOCKET Ns_SockListenEx(char *address, int port, int backlog);
 NS_EXTERN SOCKET Ns_SockAccept(SOCKET sock, struct sockaddr *psa, int *lenPtr);
@@ -1144,7 +1145,7 @@
 
 NS_EXTERN int Ns_SockSetNonBlocking(SOCKET sock);
 NS_EXTERN int Ns_SockSetBlocking(SOCKET sock);
-NS_EXTERN int Ns_GetSockAddr(struct sockaddr_in *psa, char *host, int port);
+NS_EXTERN int Ns_GetSockAddr(struct sockaddr_in6 *psa, char *host, int port);
 NS_EXTERN int Ns_SockCloseLater(SOCKET sock);
 
 NS_EXTERN char *Ns_SockError(void);
diff -ur aolserver-4.5.1.orig/include/nsthread.h aolserver-4.5.1/include/nsthread.h
--- aolserver-4.5.1.orig/include/nsthread.h	2005-08-23 23:41:31.000000000 +0200
+++ aolserver-4.5.1/include/nsthread.h	2012-06-10 19:41:18.000000000 +0200
@@ -260,7 +260,7 @@
 NS_EXTERN char *ns_ctime(const time_t * clock);
 NS_EXTERN char *ns_asctime(const struct tm *tmPtr);
 NS_EXTERN char *ns_strtok(char *s1, const char *s2);
-NS_EXTERN char *ns_inet_ntoa(struct in_addr addr);
+NS_EXTERN char *ns_inet_ntoa(struct in6_addr addr);
 
 /*
  * sema.c:
diff -ur aolserver-4.5.1.orig/nscp/nscp.c aolserver-4.5.1/nscp/nscp.c
--- aolserver-4.5.1.orig/nscp/nscp.c	2008-06-20 10:06:32.000000000 +0200
+++ aolserver-4.5.1/nscp/nscp.c	2012-06-10 19:41:18.000000000 +0200
@@ -64,7 +64,7 @@
     char *user;
     int id;
     SOCKET sock;
-    struct sockaddr_in sa;
+    struct sockaddr_in6 sa;
 } Sess;
 
 static Ns_SockProc AcceptProc;
@@ -312,7 +312,7 @@
     Tcl_DStringInit(&unameDS);
     sprintf(buf, "-nscp:%d-", sessPtr->id);
     Ns_ThreadSetName(buf);
-    Ns_Log(Notice, "nscp: %s connected", ns_inet_ntoa(sessPtr->sa.sin_addr));
+    Ns_Log(Notice, "nscp: %s connected", ns_inet_ntoa(sessPtr->sa.sin6_addr));
     if (!Login(sessPtr, &unameDS)) {
 	goto done;
     }
@@ -381,7 +381,7 @@
     if (interp != NULL) {
     	Ns_TclDeAllocateInterp(interp);
     }
-    Ns_Log(Notice, "nscp: %s disconnected", ns_inet_ntoa(sessPtr->sa.sin_addr));
+    Ns_Log(Notice, "nscp: %s disconnected", ns_inet_ntoa(sessPtr->sa.sin6_addr));
     ns_sockclose(sessPtr->sock);
     ns_free(sessPtr);
 }
diff -ur aolserver-4.5.1.orig/nsd/binder.c aolserver-4.5.1/nsd/binder.c
--- aolserver-4.5.1.orig/nsd/binder.c	2005-08-17 23:18:21.000000000 +0200
+++ aolserver-4.5.1/nsd/binder.c	2012-06-12 18:37:18.000000000 +0200
@@ -64,7 +64,7 @@
  */
 
 SOCKET
-NsSockGetBound(struct sockaddr_in *saPtr)
+NsSockGetBound(struct sockaddr_in6 *saPtr)
 {
     SOCKET sock = INVALID_SOCKET;
     Tcl_HashEntry *hPtr;
@@ -100,7 +100,7 @@
 NsInitBinder(void)
 {
     Ns_MutexSetName(&lock, "ns:binder");
-    Tcl_InitHashTable(&prebound, sizeof(struct sockaddr_in)/sizeof(int));
+    Tcl_InitHashTable(&prebound, sizeof(struct sockaddr_in6)/sizeof(int));
 }
 
 
@@ -161,21 +161,21 @@
     Tcl_HashSearch search;
     char *addr;
     int port, sock;
-    struct sockaddr_in *saPtr;
+    struct sockaddr_in6 *saPtr;
 
     Ns_MutexLock(&lock);
     hPtr = Tcl_FirstHashEntry(&prebound, &search);
     while (hPtr != NULL) {
-	saPtr = (struct sockaddr_in *) Tcl_GetHashKey(&prebound, hPtr);
-	addr = ns_inet_ntoa(saPtr->sin_addr);
-	port = htons(saPtr->sin_port);
-	sock = (int) Tcl_GetHashValue(hPtr);
-	Ns_Log(Warning, "prebind: closed unused: %s:%d = %d", addr, port, sock);
-	close(sock);
-	hPtr = Tcl_NextHashEntry(&search);
+        saPtr = (struct sockaddr_in6 *) Tcl_GetHashKey(&prebound, hPtr);
+        addr = ns_inet_ntoa(saPtr->sin6_addr);
+        port = htons(saPtr->sin6_port);
+        sock = (int) Tcl_GetHashValue(hPtr);
+        Ns_Log(Warning, "prebind: closed unused: %s:%d = %d", addr, port, sock);
+        close(sock);
+        hPtr = Tcl_NextHashEntry(&search);
     }
     Tcl_DeleteHashTable(&prebound);
-    Tcl_InitHashTable(&prebound, sizeof(struct sockaddr_in)/sizeof(int));
+    Tcl_InitHashTable(&prebound, sizeof(struct sockaddr_in6)/sizeof(int));
     Ns_MutexUnlock(&lock);
 }
 
@@ -202,52 +202,48 @@
 {
     Tcl_HashEntry *hPtr;
     int new, sock, port;
-    struct sockaddr_in sa;
-    char *err, *ent, *p, *q, *addr, *baddr;
+    struct sockaddr_in6 sa;
+    char *err, *ent, *p, *q, *addr;
+    char baddr[INET6_ADDRSTRLEN];
 
     ent = line;
     do {
-	p = strchr(ent, ',');
-	if (p != NULL) {
-	    *p = '\0';
-	}
-	baddr = NULL;
-    	addr = "0.0.0.0";
-    	q = strchr(ent, ':');
-	if (q == NULL) {
-	    port = atoi(ent);
-	} else {
-	    *q = '\0';
-	    port = atoi(q+1);
-	    baddr = addr = ent;
-	}
-	if (port == 0) {
-	    err = "invalid port";
-	} else if (Ns_GetSockAddr(&sa, baddr, port) != NS_OK) {
-	    err = "invalid address";
-	} else {
-	    hPtr = Tcl_CreateHashEntry(&prebound, (char *) &sa, &new);
-	    if (!new) {
-		err = "duplicate entry";
-	    } else if ((sock = Ns_SockBind(&sa)) == -1) {
-		Tcl_DeleteHashEntry(hPtr);
-	    	err = strerror(errno);
-	    } else {
-	    	Tcl_SetHashValue(hPtr, sock);
-		err = NULL;
-	    }
-	}
-	if (q != NULL) {
-	    *q = ':';
-	}
-	if (p != NULL) {
-	    *p++ = ',';
-	}
-	if (err != NULL) {
-	    Ns_Log(Error, "prebind: invalid entry: %s: %s", ent, err);
-	} else {
-	    Ns_Log(Notice, "prebind: bound: %s", ent);
-	}
-	ent = p;
+        p = strchr(ent, ',');
+        if (p != NULL) {
+            *p = '\0';
+        }
+        err = NULL;
+        if (sscanf(ent,"[%[^]]]:%d",baddr,&port)!=2)    /* IPV6 notation */
+            if (sscanf(ent,"%[^:]:%d",baddr,&port)!=2)  /* IPV4 notation */
+                if (sscanf(ent,"%d",&port)==1)          /* Just a port */
+                    strcpy(baddr,"::0");
+                else
+                    err = "invalid address and/or port";
+        if (err == NULL) {
+            if (port == 0 || port > 65535) {
+                err = "invalid port";
+            } else if (Ns_GetSockAddr(&sa, baddr, port) != NS_OK) {
+                err = "invalid address";
+            } else {
+                hPtr = Tcl_CreateHashEntry(&prebound, (char *) &sa, &new);
+                if (!new) {
+                    err = "duplicate entry";
+                } else if ((sock = Ns_SockBind(&sa)) == -1) {
+                    Tcl_DeleteHashEntry(hPtr);
+                    err = strerror(errno);
+                } else {
+                    Tcl_SetHashValue(hPtr, sock);
+                }
+            }
+        }
+        if (p != NULL) {
+            *p++ = ',';
+        }
+        if (err != NULL) {
+            Ns_Log(Error, "prebind: invalid entry: %s: %s", ent, err);
+        } else {
+            Ns_Log(Notice, "prebind: bound: %s", ent);
+        }
+        ent = p;
     } while (ent != NULL);
 }
diff -ur aolserver-4.5.1.orig/nsd/dns.c aolserver-4.5.1/nsd/dns.c
--- aolserver-4.5.1.orig/nsd/dns.c	2005-10-13 16:16:59.000000000 +0200
+++ aolserver-4.5.1/nsd/dns.c	2012-06-10 19:41:18.000000000 +0200
@@ -88,6 +88,55 @@
 
 /*
  *----------------------------------------------------------------------
+ *
+ * Ns_inet_pton --
+ *
+ *  Convert an ipv4/ipv6 address in textual form to a binary ipv6
+ *  form. IPV4 addresses are converted to "mapped ipv4 addresses".
+ *
+ * Results:
+ *  >0  = Success.
+ *  <=0 = Error:
+ *          <0 = Invalid address family. As this routine hardcodes the AF,
+ *               this result should not occur.
+ *           0 = Parse error.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Ns_inet_pton(struct in6_addr *ia6, char *host) {
+    struct in_addr  ia4;
+    int               r;
+
+    /*
+     * First try wether the address parses as an ipv4 address
+     */
+    r=inet_pton(AF_INET,host,&ia4.s_addr);
+    if (r <= 0) {
+        /*
+         * No ipv4 address, try to parse as ipv6 address
+         */
+        r=inet_pton(AF_INET6,host,&(ia6->s6_addr));
+    } else {
+        /*
+         * Ipv4 address, convert into an ipv6 address with
+         * type "mapped ipv4 address"
+         */
+        ia6->s6_addr32[0]=0;
+        ia6->s6_addr32[1]=0;
+        ia6->s6_addr32[2]=htonl(65535);
+        ia6->s6_addr32[3]=ia4.s_addr;
+    }
+    return r;
+}
+
+
+/*
+ *----------------------------------------------------------------------
  * Ns_GetHostByAddr, Ns_GetAddrByHost --
  *
  *      Convert an IP address to a hostname or vice versa.
@@ -254,71 +303,33 @@
 static int
 GetHost(Ns_DString *dsPtr, char *addr)
 {
-#if defined(HAVE_GETNAMEINFO)
     char buf[NI_MAXHOST];
-    int err;
-#elif defined(HAVE_GETHOSTBYADDR_R)
-    struct hostent he, *hp;
-    char buf[2048];
-    int err;
-#else
-    struct hostent *hp;
-    static Ns_Cs cs;
-#endif
-    struct sockaddr_in sa;
+    int err,r;
+    struct sockaddr_in6 sa;
     char *host;
 
     host = NULL;
-    sa.sin_family = AF_INET;
-    sa.sin_addr.s_addr = inet_addr(addr);
-    if (sa.sin_addr.s_addr == INADDR_NONE) {
-	return NS_FALSE;
+    sa.sin6_family = AF_INET6;
+    r=Ns_inet_pton(&sa.sin6_addr,addr);
+    if (r <= 0) {
+        return NS_FALSE;
     }
-#if defined(HAVE_GETNAMEINFO)
     err = getnameinfo((const struct sockaddr *) &sa,
-                      sizeof(struct sockaddr_in), buf, sizeof(buf),
+                      sizeof(struct sockaddr_in6), buf, sizeof(buf),
                       NULL, 0, NI_NAMEREQD);
     if (err != 0) {
         Ns_Log(Error, "dns: getnameinfo failed: %s", gai_strerror(err));
     } else {
-	host = buf;
-    }
-#elif defined(HAVE_GETHOSTBYADDR_R)
-    hp = gethostbyaddr_r((char *) &sa.sin_addr, sizeof(struct in_addr),
-            AF_INET, &he, buf, sizeof(buf), &err);
-    if (hp == NULL) {
-        DnsLogError("gethostbyaddr_r", err);
-    } else {
-	host = he.h_name;
+        host = buf;
     }
-#else
-    /*
-     * This version is not thread-safe, but we have no thread-safe
-     * alternative on this platform.  Use critsec to try and serialize
-     * calls, but beware: Tcl core as of 8.4.6 still calls gethostbyaddr()
-     * as well, so it's still possible for two threads to call it at
-     * the same time.
-     */
-
-    Ns_CsEnter(&cs);
-    hp = gethostbyaddr((char *) &sa.sin_addr, sizeof(struct in_addr), AF_INET);
-    if (hp == NULL) {
-	DnsLogError("gethostbyaddr", h_errno);
-    } else {
-	host = hp->h_name;
-    }
-    Ns_CsLeave(&cs);
-#endif
     if (host == NULL) {
-	return NS_FALSE;
+        return NS_FALSE;
     }
     Ns_DStringAppend(dsPtr, host);
     return NS_TRUE;
 }
 
 
-#if defined(HAVE_GETADDRINFO)
-
 static int
 GetAddr(Ns_DString *dsPtr, char *host)
 {
@@ -326,9 +337,12 @@
     struct addrinfo *res, *ptr;
     int result;
     int status = NS_FALSE;
+    struct in6_addr addr;
     
     memset(&hints, 0, sizeof(hints));
-    hints.ai_family = PF_INET;
+    hints.ai_family = AF_UNSPEC;
+//    hints.ai_family = AF_INET6;
+    hints.ai_flags = AI_ADDRCONFIG;
     hints.ai_socktype = SOCK_STREAM;
     if ((result = getaddrinfo(host, NULL, &hints, &res)) != 0) {
         Ns_Log(Error, "dns: getaddrinfo failed for %s: %s", host,
@@ -336,8 +350,28 @@
     } else {
         ptr = res;
         while (ptr != NULL) {
-            Tcl_DStringAppendElement(dsPtr, ns_inet_ntoa(
-                        ((struct sockaddr_in *) ptr->ai_addr)->sin_addr));
+            /*
+             * Getaddrinfo can return both AF_INET and AF_INET6 addresses.
+             *
+             * There exists an AI_V4MAPPED hint flag which should return ipv4
+             * addresses as AF_INET6, but for some reason it doesn't work, so
+             * we have to handle AF_INET results and convert manually.
+             */
+            if (ptr->ai_family == AF_INET6)
+                addr = ((struct sockaddr_in6 *) ptr->ai_addr)->sin6_addr;
+            else {
+                if (ptr->ai_family != AF_INET) {
+                    Ns_Log(Error, "dns: getaddrinfo failed for %s: unknown address family %d",
+                           host,ptr->ai_family);
+                    freeaddrinfo(res);
+                    return NS_FALSE;
+                }
+                addr.s6_addr32[0]=0;
+                addr.s6_addr32[1]=0;
+                addr.s6_addr32[2]=htonl(65535);
+                addr.s6_addr32[3]=((struct sockaddr_in *) ptr->ai_addr)->sin_addr.s_addr;
+            };
+            Tcl_DStringAppendElement(dsPtr, ns_inet_ntoa(addr));
             ptr = ptr->ai_next;
         }
         freeaddrinfo(res);
@@ -346,82 +380,6 @@
     return status;
 }
 
-#elif defined(HAVE_GETHOSTBYNAME_R)
-
-static int
-GetAddr(Ns_DString *dsPtr, char *host)
-{
-    struct hostent he, *res;
-    struct in_addr ia, *ptr;
-#ifdef HAVE_GETHOSTBYNAME_R_3
-    struct hostent_data data;
-#endif
-    char buf[2048];
-    int result;
-    int i = 0;
-    int h_errnop;
-    int status = NS_FALSE;
-    
-#if defined(HAVE_GETHOSTBYNAME_R_6)
-    result = gethostbyname_r(host, &he, buf, sizeof(buf), &res, &h_errnop);
-#elif defined(HAVE_GETHOSTBYNAME_R_5)
-    result = 0;
-    res = gethostbyname_r(host, &he, buf, sizeof(buf), &h_errnop);
-    if (res == NULL) {
-        result = -1;
-    }
-#elif defined(HAVE_GETHOSTBYNAME_R_3)
-    result = gethostbyname_r(host, &he, &data);
-    h_errnop = h_errno;
-#endif
-
-    if (result != 0) { 
-	DnsLogError("gethostbyname_r", h_errnop);
-    } else {
-        while ((ptr = (struct in_addr *) he.h_addr_list[i++]) != NULL) {
-            ia.s_addr = ptr->s_addr;
-            Tcl_DStringAppendElement(dsPtr, ns_inet_ntoa(ia));
-            status = NS_TRUE;
-        }
-    }
-    return status;
-}
-
-#else
-
-/*
- * This version is not thread-safe, but we have no thread-safe
- * alternative on this platform.  Use critsec to try and serialize
- * calls, but beware: Tcl core as of 8.4.6 still calls gethostbyname()
- * as well, so it's still possible for two threads to call it at
- * the same time.
- */
-
-static int
-GetAddr(Ns_DString *dsPtr, char *host)
-{
-    struct hostent *he;
-    struct in_addr ia, *ptr;
-    static Ns_Cs cs;
-    int i = 0;
-    int status = NS_FALSE;
-
-    Ns_CsEnter(&cs);
-    he = gethostbyname(host);
-    if (he == NULL) {
-	DnsLogError("gethostbyname", h_errno);
-    } else {
-        while ((ptr = (struct in_addr *) he.h_addr_list[i++]) != NULL) {
-            ia.s_addr = ptr->s_addr;
-            Tcl_DStringAppendElement(dsPtr, ns_inet_ntoa(ia));
-            status = NS_TRUE;
-        }
-    }
-    Ns_CsLeave(&cs);
-    return status;
-}
-
-#endif
 
 
 /*
diff -ur aolserver-4.5.1.orig/nsd/driver.c aolserver-4.5.1/nsd/driver.c
--- aolserver-4.5.1.orig/nsd/driver.c	2009-01-29 21:54:24.000000000 +0100
+++ aolserver-4.5.1/nsd/driver.c	2012-06-10 19:41:18.000000000 +0200
@@ -221,7 +221,7 @@
     Tcl_HashEntry *hPtr;
     Ns_DString ds;
     Ns_Set *set;
-    struct in_addr  ia;
+    struct in6_addr  ia;
     struct hostent *he;
     Driver *drvPtr;
     Sock *sockPtr;
@@ -288,7 +288,7 @@
             Ns_Log(Error, "%s: no addresses for %s", module, he->h_name);
 	    return NS_ERROR;
 	}
-        memcpy(&ia.s_addr, *(he->h_addr_list), sizeof(ia.s_addr));
+        memcpy(&ia.s6_addr, *(he->h_addr_list), sizeof(ia.s6_addr));
         address = ns_inet_ntoa(ia);
 
 	/*
@@ -1496,7 +1496,7 @@
      * Accept the new connection.
      */
 
-    slen = sizeof(struct sockaddr_in);
+    slen = sizeof(struct sockaddr_in6);
     sockPtr->sock = Ns_SockAccept(lsock,
             (struct sockaddr *) &sockPtr->sa, &slen);
     if (sockPtr->sock == INVALID_SOCKET) {
@@ -2160,8 +2160,8 @@
     connPtr->times.accept = *nowPtr;
     connPtr->id = id;
     sprintf(connPtr->idstr, "cns%u", connPtr->id);
-    connPtr->port = ntohs(sockPtr->sa.sin_port);
-    strcpy(connPtr->peer, ns_inet_ntoa(sockPtr->sa.sin_addr));
+    connPtr->port = ntohs(sockPtr->sa.sin6_port);
+    strcpy(connPtr->peer, ns_inet_ntoa(sockPtr->sa.sin6_addr));
     connPtr->times.accept = sockPtr->acceptTime;
     connPtr->sockPtr = sockPtr;
     return connPtr;
Alleen in aolserver-4.5.1/nsd: driver.c.orig
diff -ur aolserver-4.5.1.orig/nsd/fd.c aolserver-4.5.1/nsd/fd.c
--- aolserver-4.5.1.orig/nsd/fd.c	2008-03-22 18:43:39.000000000 +0100
+++ aolserver-4.5.1/nsd/fd.c	2012-06-10 19:41:18.000000000 +0200
@@ -455,31 +455,31 @@
     return -1;
 #else
     SOCKET          sock;
-    struct sockaddr_in ia[2];
+    struct sockaddr_in6 ia[2];
     int             size;
 
-    size = sizeof(struct sockaddr_in);
-    sock = Ns_SockListen("127.0.0.1", 0);
+    size = sizeof(struct sockaddr_in6);
+    sock = Ns_SockListen("::1", 0);
     if (sock == INVALID_SOCKET ||
     	getsockname(sock, (struct sockaddr *) &ia[0], &size) != 0) {
 	return -1;
     }
-    size = sizeof(struct sockaddr_in);
-    socks[1] = Ns_SockConnect("127.0.0.1", (int) ntohs(ia[0].sin_port));
+    size = sizeof(struct sockaddr_in6);
+    socks[1] = Ns_SockConnect("::1", (int) ntohs(ia[0].sin6_port));
     if (socks[1] == INVALID_SOCKET ||
     	getsockname(socks[1], (struct sockaddr *) &ia[1], &size) != 0) {
 	ns_sockclose(sock);
 	return -1;
     }
-    size = sizeof(struct sockaddr_in);
+    size = sizeof(struct sockaddr_in6);
     socks[0] = accept(sock, (struct sockaddr *) &ia[0], &size);
     ns_sockclose(sock);
     if (socks[0] == INVALID_SOCKET) {
 	ns_sockclose(socks[1]);
 	return -1;
     }
-    if (ia[0].sin_addr.s_addr != ia[1].sin_addr.s_addr ||
-	ia[0].sin_port != ia[1].sin_port) {
+    if (ia[0].sin6_addr.s_addr != ia[1].sin6_addr.s6_addr ||
+	ia[0].sin6_port != ia[1].sin6_port) {
 	ns_sockclose(socks[0]);
 	ns_sockclose(socks[1]);
 	return -1;
diff -ur aolserver-4.5.1.orig/nsd/listen.c aolserver-4.5.1/nsd/listen.c
--- aolserver-4.5.1.orig/nsd/listen.c	2005-07-19 01:32:12.000000000 +0200
+++ aolserver-4.5.1/nsd/listen.c	2012-06-10 19:41:18.000000000 +0200
@@ -112,7 +112,7 @@
     ListenData         *ldPtr;
     SOCKET              new, sock;
     int                 status;
-    struct sockaddr_in  sa;
+    struct sockaddr_in6  sa;
 
     if (Ns_GetSockAddr(&sa, addr, port) != NS_OK) {
         return NS_ERROR;
@@ -122,7 +122,7 @@
 	 * Make sure we can bind to the specified interface.
 	 */
 	
-        sa.sin_port = 0;
+        sa.sin6_port = 0;
         sock = Ns_SockBind(&sa);
         if (sock == INVALID_SOCKET) {
             return NS_ERROR;
@@ -155,7 +155,7 @@
         }
     }
     if (status == NS_OK) {
-        hPtr = Tcl_CreateHashEntry(tablePtr, (char *) sa.sin_addr.s_addr, &new);
+        hPtr = Tcl_CreateHashEntry(tablePtr, (char *) sa.sin6_addr.s6_addr, &new);
         if (!new) {
             status = NS_ERROR;
         } else {
@@ -220,7 +220,7 @@
 static int
 ListenProc(SOCKET sock, void *arg, int why)
 {
-    struct sockaddr_in  sa;
+    struct sockaddr_in6  sa;
     int                 len;
     Tcl_HashTable      *tablePtr;
     Tcl_HashEntry      *hPtr;
@@ -239,7 +239,7 @@
         getsockname(new, (struct sockaddr *) &sa, &len);
         ldPtr = NULL;
         Ns_MutexLock(&lock);
-        hPtr = Tcl_FindHashEntry(tablePtr, (char *) sa.sin_addr.s_addr);
+        hPtr = Tcl_FindHashEntry(tablePtr, (char *) sa.sin6_addr.s6_addr);
         if (hPtr == NULL) {
             hPtr = Tcl_FindHashEntry(tablePtr, (char *) INADDR_ANY);
         }
diff -ur aolserver-4.5.1.orig/nsd/nsd.h aolserver-4.5.1/nsd/nsd.h
--- aolserver-4.5.1.orig/nsd/nsd.h	2008-12-27 01:36:38.000000000 +0100
+++ aolserver-4.5.1/nsd/nsd.h	2012-06-12 18:36:54.000000000 +0200
@@ -151,7 +151,7 @@
     int             pid;
     time_t          boot_t;
     char            hostname[255];
-    char	    address[16];
+    char            address[INET6_ADDRSTRLEN];
     int             shutdowntimeout;
     int             backlog;
     int             debug;
@@ -378,7 +378,7 @@
 
     struct Sock *nextPtr;
     struct Conn *connPtr;
-    struct sockaddr_in sa;
+    struct sockaddr_in6 sa;
     unsigned int id;
     int		 state;
     int		 pidx;		    /* poll() index. */
@@ -484,7 +484,7 @@
      * The following are copied from Sock.
      */
      
-    char	    peer[16];	/* Client peer address. */
+    char	    peer[INET6_ADDRSTRLEN];	/* Client peer address. */
     int		    port;	/* Client peer port. */
 
     /*
@@ -975,7 +975,7 @@
 extern void NsHandleSignals(void);
 extern void NsStopDrivers(void);
 extern void NsPreBind(char *bindargs, char *bindfile);
-extern SOCKET NsSockGetBound(struct sockaddr_in *saPtr);
+extern SOCKET NsSockGetBound(struct sockaddr_in6 *saPtr);
 extern void NsClosePreBound(void);
 extern void NsInitServer(char *server, Ns_ServerInitProc *initProc);
 extern char *NsConfigRead(char *file);
Alleen in aolserver-4.5.1/nsd: nsd.h.orig
diff -ur aolserver-4.5.1.orig/nsd/nsmain.c aolserver-4.5.1/nsd/nsmain.c
--- aolserver-4.5.1.orig/nsd/nsmain.c	2006-04-13 21:06:37.000000000 +0200
+++ aolserver-4.5.1/nsd/nsmain.c	2012-06-11 23:37:03.000000000 +0200
@@ -828,7 +828,7 @@
 	    "  -u  run as <user>\n"
 	    "  -g  run as <group>\n"
 	    "  -r  chroot to <path>\n"
-	    "  -b  bind <address:port>\n"
+	    "  -b  bind <address:port> (Example: 192.168.0.1:80,[::1]:80 )>\n"
 	    "  -B  bind address:port list from <file>\n"
 #endif
 	    "  -s  use server named <server> in config file\n"
diff -ur aolserver-4.5.1.orig/nsd/sock.c aolserver-4.5.1/nsd/sock.c
--- aolserver-4.5.1.orig/nsd/sock.c	2005-10-09 18:16:54.000000000 +0200
+++ aolserver-4.5.1/nsd/sock.c	2012-06-10 19:41:18.000000000 +0200
@@ -194,7 +194,7 @@
 Ns_SockListenEx(char *address, int port, int backlog)
 {
     SOCKET sock;
-    struct sockaddr_in sa;
+    struct sockaddr_in6 sa;
 
     if (Ns_GetSockAddr(&sa, address, port) != NS_OK) {
 	return -1;
@@ -261,28 +261,36 @@
  */
 
 SOCKET
-Ns_BindSock(struct sockaddr_in *saPtr)
+Ns_BindSock(struct sockaddr_in6 *saPtr)
 {
     return Ns_SockBind(saPtr);
 }
 
 SOCKET
-Ns_SockBind(struct sockaddr_in *saPtr)
+Ns_SockBind(struct sockaddr_in6 *saPtr)
 {
     SOCKET sock;
     int n;
 
-    sock = socket(AF_INET, SOCK_STREAM, 0);
+    sock = socket(AF_INET6, SOCK_STREAM, 0);
     if (sock != INVALID_SOCKET) {
 	sock = SockSetup(sock);
     }
     if (sock != INVALID_SOCKET) {
-        n = 1;
-        if (saPtr->sin_port != 0) {
+        if (saPtr->sin6_port != 0) {
+            n = 1;
             setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n));
+            /*
+             * IPv4 connectivity through AF_INET6 can be disabled by default, for
+             * example by /proc/sys/net/ipv6/bindv6only to 1 on Linux. We
+             * explicitely enable IPv4 so we don't need to bind separate sockets
+             * for v4 and v6.
+             */
+            n = 0;
+            setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &n, sizeof(n));
         }
         if (bind(sock, (struct sockaddr *) saPtr,
-		 sizeof(struct sockaddr_in)) != 0) {
+		 sizeof(struct sockaddr_in6)) != 0) {
             ns_sockclose(sock);
             sock = INVALID_SOCKET;
         }
@@ -461,7 +469,7 @@
  *
  * Ns_GetSockAddr --
  *
- *	Take a host/port and fill in a sockaddr_in structure 
+ *	Take a host/port and fill in a sockaddr_in6 structure 
  *	appropriately. Host may be an IP address or a DNS name. 
  *
  * Results:
@@ -474,30 +482,32 @@
  */
 
 int
-Ns_GetSockAddr(struct sockaddr_in *saPtr, char *host, int port)
+Ns_GetSockAddr(struct sockaddr_in6 *saPtr, char *host, int port)
 {
-    struct in_addr  ia;
-    Ns_DString ds;
+    struct in6_addr  ia;
+    Ns_DString       ds;
+    int               r;
+
 
     if (host == NULL) {
-        ia.s_addr = htonl(INADDR_ANY);
+        ia = in6addr_any;
     } else {
-        ia.s_addr = inet_addr(host);
-        if (ia.s_addr == INADDR_NONE) {
+        r = Ns_inet_pton(&ia,host);
+        if (r <= 0) {
     	    Ns_DStringInit(&ds);
-	    if (Ns_GetAddrByHost(&ds, host) == NS_TRUE) {
-		ia.s_addr = inet_addr(ds.string);
-	    }
+            if (Ns_GetAddrByHost(&ds, host) == NS_TRUE) {
+                r = Ns_inet_pton(&ia,ds.string);
+            }
     	    Ns_DStringFree(&ds);
-	    if (ia.s_addr == INADDR_NONE) {
-		return NS_ERROR;
-	    }
-	}
+            if (r <= 0) {
+                return NS_ERROR;
+            }
+        }
     }
-    memset(saPtr, 0, sizeof(struct sockaddr_in));
-    saPtr->sin_family = AF_INET;
-    saPtr->sin_addr = ia;
-    saPtr->sin_port = htons((unsigned short) port);
+    memset(saPtr, 0, sizeof(struct sockaddr_in6));
+    saPtr->sin6_family = AF_INET6;
+    saPtr->sin6_addr = ia;
+    saPtr->sin6_port = htons((unsigned short) port);
 
     return NS_OK;
 }
@@ -548,13 +558,13 @@
 static SOCKET
 SockConnect(char *host, int port, char *lhost, int lport, int async)
 {
-    SOCKET             sock;
-    struct sockaddr_in lsa;
-    struct sockaddr_in sa;
-    int                err;
+    SOCKET              sock;
+    struct sockaddr_in6 lsa;
+    struct sockaddr_in6 sa;
+    int                 err;
 
     if (Ns_GetSockAddr(&sa, host, port) != NS_OK ||
-	Ns_GetSockAddr(&lsa, lhost, lport) != NS_OK) {
+        Ns_GetSockAddr(&lsa, lhost, lport) != NS_OK) {
         return INVALID_SOCKET;
     }
     sock = Ns_SockBind(&lsa);
diff -ur aolserver-4.5.1.orig/nsthread/reentrant.c aolserver-4.5.1/nsthread/reentrant.c
--- aolserver-4.5.1.orig/nsthread/reentrant.c	2006-04-14 17:45:51.000000000 +0200
+++ aolserver-4.5.1/nsthread/reentrant.c	2012-06-12 18:43:12.000000000 +0200
@@ -45,7 +45,7 @@
  */
 
 typedef struct Tls {
-    char	    	nabuf[16];
+    char	    	nabuf[INET6_ADDRSTRLEN];
 #ifndef _WIN32
     char	       *stbuf;
     struct tm   	gtbuf;
@@ -69,16 +69,19 @@
 }
 
 char *
-ns_inet_ntoa(struct in_addr addr)
+ns_inet_ntoa(struct in6_addr addr)
 {
     Tls *tlsPtr = GetTls();
-    union {
-    	unsigned int i;
-    	unsigned char b[4];
-    } u;
-    
-    u.i = (unsigned int) addr.s_addr;
-    sprintf(tlsPtr->nabuf, "%u.%u.%u.%u", u.b[0], u.b[1], u.b[2], u.b[3]);
+    if (IN6_IS_ADDR_V4MAPPED(&addr))
+      sprintf(tlsPtr->nabuf, "%u.%u.%u.%u",
+              addr.s6_addr[12], addr.s6_addr[13],
+              addr.s6_addr[14], addr.s6_addr[15]);
+    else
+      sprintf(tlsPtr->nabuf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
+              ntohs(addr.s6_addr16[0]), ntohs(addr.s6_addr16[1]),
+              ntohs(addr.s6_addr16[2]), ntohs(addr.s6_addr16[3]),
+              ntohs(addr.s6_addr16[4]), ntohs(addr.s6_addr16[5]),
+              ntohs(addr.s6_addr16[6]), ntohs(addr.s6_addr16[7]));
     return tlsPtr->nabuf;
 }
 
