--- /dev/null
+diff -urN boa-0.94.13.orig/src/boa.c boa-0.94.13/src/boa.c
+--- boa-0.94.13.orig/src/boa.c 2008-10-28 16:15:45.000000000 +0100
++++ boa-0.94.13/src/boa.c 2008-10-28 15:56:27.000000000 +0100
+@@ -27,6 +27,12 @@
+ #include <sys/resource.h>
+
+ /* globals */
++
++#ifdef INET6
++int server_addr_family;
++socklen_t server_addr_len;
++#endif
++
+ int backlog = SO_MAXCONN;
+ time_t start_time;
+
+@@ -164,14 +170,36 @@
+ return 0;
+ }
+
++#ifdef INET6
++sa_family_t *get_addr_family(struct sockaddr *address)
++{
++ if(server_addr_family == AF_INET6) {
++ return &(((struct sockaddr_in6 *) address)->sin6_family);
++ }
++
++ return &(((struct sockaddr_in *) address)->sin_family);
++}
++#endif
++
+ static int create_server_socket(void)
+ {
+ int server_s;
+
+- server_s = socket(SERVER_AF, SOCK_STREAM, IPPROTO_TCP);
++#ifdef INET6
++ server_addr_family = AF_INET6;
++ server_addr_len = sizeof(struct sockaddr_in6);
++ server_s = socket(server_addr_family, SOCK_STREAM, IPPROTO_TCP);
+ if (server_s == -1) {
+- DIE("unable to create socket");
++ server_addr_family = AF_INET;
++ server_addr_len = sizeof(struct sockaddr_in);
++#endif
++ server_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
++ if (server_s == -1) {
++ DIE("unable to create socket");
++ }
++#ifdef INET6
+ }
++#endif
+
+ /* server socket is nonblocking */
+ if (set_nonblock_fd(server_s) == -1) {
+diff -urN boa-0.94.13.orig/src/boa.h boa-0.94.13/src/boa.h
+--- boa-0.94.13.orig/src/boa.h 2008-10-28 16:15:58.000000000 +0100
++++ boa-0.94.13/src/boa.h 2008-10-28 14:45:52.000000000 +0100
+@@ -199,4 +199,12 @@
+ int plugin_handle(request * req);
+ struct httpd_plugin *plugin_lookup(request *req);
+
++/* IPv6 */
++
++#ifdef INET6
++extern int server_addr_family;
++extern socklen_t server_addr_len;
++sa_family_t *get_addr_family(struct sockaddr *address);
++#endif
++
+ #endif
+diff -urN boa-0.94.13.orig/src/compat.h boa-0.94.13/src/compat.h
+--- boa-0.94.13.orig/src/compat.h 2002-06-06 07:02:28.000000000 +0200
++++ boa-0.94.13/src/compat.h 2008-10-28 15:31:16.000000000 +0100
+@@ -71,11 +71,13 @@
+
+ #ifdef INET6
+ #define SOCKADDR sockaddr_storage
+-#define S_FAMILY __s_family
+-#define SERVER_AF AF_INET6
++#define SOCKADDR_LEN server_addr_len
++#define S_FAMILY(address) (*get_addr_family((struct sockaddr *) (address)))
++#define SERVER_AF server_addr_family
+ #else
+ #define SOCKADDR sockaddr_in
+-#define S_FAMILY sin_family
++#define SOCKADDR_LEN sizeof(struct sockaddr_in)
++#define S_FAMILY(address) ((*address).sin_family)
+ #define SERVER_AF AF_INET
+ #endif
+
+diff -urN boa-0.94.13.orig/src/ip.c boa-0.94.13/src/ip.c
+--- boa-0.94.13.orig/src/ip.c 2002-01-21 03:19:16.000000000 +0100
++++ boa-0.94.13/src/ip.c 2008-10-28 15:52:05.000000000 +0100
+@@ -44,52 +44,64 @@
+
+ #include "boa.h"
+ #include <arpa/inet.h> /* inet_ntoa */
++#include <netinet/in.h>
+
+ /* Binds to the existing server_s, based on the configuration string
+ in server_ip. IPv6 version doesn't pay attention to server_ip yet. */
+ int bind_server(int server_s, char *server_ip)
+ {
++ struct sockaddr *server_sockaddr;
++ struct sockaddr_in server_sockaddr4;
++
+ #ifdef INET6
+- struct sockaddr_in6 server_sockaddr;
+- server_sockaddr.sin6_family = AF_INET6;
+- memcpy(&server_sockaddr.sin6_addr, &in6addr_any, sizeof (in6addr_any));
+- server_sockaddr.sin6_port = htons(server_port);
+-#else
+- struct sockaddr_in server_sockaddr;
+- memset(&server_sockaddr, 0, sizeof server_sockaddr);
++ struct sockaddr_in6 server_sockaddr6;
++ if(SERVER_AF == AF_INET6) {
++ server_sockaddr6.sin6_family = AF_INET6;
++ memcpy(&server_sockaddr6.sin6_addr, &in6addr_any, sizeof (in6addr_any));
++ server_sockaddr6.sin6_port = htons(server_port);
++ server_sockaddr = (struct sockaddr *) &server_sockaddr6;
++ } else {
++#endif
++ memset(&server_sockaddr4, 0, SOCKADDR_LEN);
+ #ifdef HAVE_SIN_LEN /* uncomment for BSDs */
+- server_sockaddr.sin_len = sizeof server_sockaddr;
++ server_sockaddr4.sin_len = SOCKADDR_LEN;
+ #endif
+- server_sockaddr.sin_family = AF_INET;
+- if (server_ip != NULL) {
+- inet_aton(server_ip, &server_sockaddr.sin_addr);
+- } else {
+- server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
++ server_sockaddr4.sin_family = AF_INET;
++ if (server_ip != NULL) {
++ inet_aton(server_ip, &server_sockaddr4.sin_addr);
++ } else {
++ server_sockaddr4.sin_addr.s_addr = htonl(INADDR_ANY);
++ }
++ server_sockaddr4.sin_port = htons(server_port);
++ server_sockaddr = (struct sockaddr *) &server_sockaddr4;
++#ifdef INET6
+ }
+- server_sockaddr.sin_port = htons(server_port);
+ #endif
+
+- return bind(server_s, (struct sockaddr *) &server_sockaddr,
+- sizeof (server_sockaddr));
++ return bind(server_s, server_sockaddr, SOCKADDR_LEN);
+ }
+
+ char *ascii_sockaddr(struct SOCKADDR *s, char *dest, int len)
+ {
+ #ifdef INET6
+- if (getnameinfo((struct sockaddr *) s,
+- sizeof(struct SOCKADDR),
+- dest, len, NULL, 0, NI_NUMERICHOST)) {
+- fprintf(stderr, "[IPv6] getnameinfo failed\n");
+- *dest = '\0';
+- }
++ if(SERVER_AF == AF_INET6) {
++ if (getnameinfo((struct sockaddr *) s,
++ SOCKADDR_LEN,
++ dest, len, NULL, 0, NI_NUMERICHOST)) {
++ fprintf(stderr, "[IPv6] getnameinfo failed\n");
++ *dest = '\0';
++ }
+ #ifdef WHEN_DOES_THIS_APPLY
+- if ((s->__ss_family == AF_INET6) &&
+- IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *) s)->sin6_addr))) {
+- memmove(dest, dest+7, NI_MAXHOST);
+- }
++ if (((((struct sockaddr_in6 *) s)->sin6_family) == AF_INET6) &&
++ IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *) s)->sin6_addr))) {
++ memmove(dest, dest+7, NI_MAXHOST);
++ }
+ #endif
+-#else
+- memmove(dest, inet_ntoa(s->sin_addr), len);
++ } else {
++#endif
++ memmove(dest, inet_ntoa(((struct sockaddr_in *) s)->sin_addr), len);
++#ifdef INET6
++ }
+ #endif
+ return dest;
+ }
+@@ -98,17 +110,21 @@
+ {
+ int p = -1;
+ #ifdef INET6
+- char serv[NI_MAXSERV];
++ if(SERVER_AF == AF_INET6) {
++ char serv[NI_MAXSERV];
+
+- if (getnameinfo((struct sockaddr *) s,
+- sizeof(struct SOCKADDR),
+- NULL, 0, serv, sizeof(serv), NI_NUMERICSERV)) {
+- fprintf(stderr, "[IPv6] getnameinfo failed\n");
++ if (getnameinfo((struct sockaddr *) s,
++ SOCKADDR_LEN,
++ NULL, 0, serv, sizeof(serv), NI_NUMERICSERV)) {
++ fprintf(stderr, "[IPv6] getnameinfo failed\n");
++ } else {
++ p = atoi(serv);
++ }
+ } else {
+- p = atoi(serv);
++#endif
++ p = ntohs(((struct sockaddr_in *) s)->sin_port);
++#ifdef INET6
+ }
+-#else
+- p = ntohs(s->sin_port);
+ #endif
+ return p;
+ }
+diff -urN boa-0.94.13.orig/src/mmap_cache.c boa-0.94.13/src/mmap_cache.c
+--- boa-0.94.13.orig/src/mmap_cache.c 2002-03-24 23:35:34.000000000 +0100
++++ boa-0.94.13/src/mmap_cache.c 2008-10-28 14:55:16.000000000 +0100
+@@ -67,7 +67,7 @@
+
+ m = mmap(0, s->st_size, PROT_READ, MAP_OPTIONS, data_fd, 0);
+
+- if ((int) m == -1) {
++ if ((ssize_t) m == -1) {
+ /* boa_perror(req,"mmap"); */
+ return NULL;
+ }
+diff -urN boa-0.94.13.orig/src/request.c boa-0.94.13/src/request.c
+--- boa-0.94.13.orig/src/request.c 2008-10-28 16:16:03.000000000 +0100
++++ boa-0.94.13/src/request.c 2008-10-28 15:17:20.000000000 +0100
+@@ -75,12 +75,12 @@
+ int fd; /* socket */
+ struct SOCKADDR remote_addr; /* address */
+ struct SOCKADDR salocal;
+- int remote_addrlen = sizeof (struct SOCKADDR);
++ int remote_addrlen = SOCKADDR_LEN;
+ request *conn; /* connection */
+- size_t len;
++ socklen_t len;
+ static int system_bufsize = 0; /* Default size of SNDBUF given by system */
+
+- remote_addr.S_FAMILY = 0xdead;
++ S_FAMILY(&remote_addr) = 0xdead;
+ fd = accept(server_s, (struct sockaddr *) &remote_addr,
+ &remote_addrlen);
+
+@@ -133,7 +133,7 @@
+ }
+ #endif
+
+- len = sizeof(salocal);
++ len = SOCKADDR_LEN;
+
+ if (getsockname(fd, (struct sockaddr *) &salocal, &len) != 0) {
+ WARN("getsockname");