diff --git a/api/transport/posix-ip.c b/api/transport/posix-ip.c
index 89a3e18047f65025ca591730c834a555b49f7922..1593a15d24b8f38b33814e99ef8f0fc14b3372b5 100644
--- a/api/transport/posix-ip.c
+++ b/api/transport/posix-ip.c
@@ -36,6 +36,7 @@
 #define EB_DEFAULT_PORT_STR "60368" /* 0xEBD0 */
 
 void eb_posix_ip_close(eb_posix_sock_t sock) {
+  if (sock == -1) return;
 #ifdef __WIN32
   closesocket(sock);
 #else
@@ -47,6 +48,7 @@ eb_posix_sock_t eb_posix_ip_open(int family, int type, const char* port) {
   struct addrinfo hints, *match, *i;
   eb_posix_sock_t sock;
   int protocol;
+  int optval;
   
   switch (type) {
   case SOCK_DGRAM:  protocol = IPPROTO_UDP; break;
@@ -68,6 +70,15 @@ eb_posix_sock_t eb_posix_ip_open(int family, int type, const char* port) {
   for (i = match; i; i = i->ai_next) {
     sock = socket(i->ai_family, i->ai_socktype, i->ai_protocol);
     if (sock == -1) continue;
+
+#ifndef EB_DISABLE_IPV6    
+    /* We bind IPv6 sockets to only IPv6... for compatability with Windows */
+    if (i->ai_family == PF_INET6) {
+      optval = 1;
+      setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&optval, sizeof(optval));
+    }
+#endif
+    
     if (bind(sock, i->ai_addr, i->ai_addrlen) == 0) break;
     eb_posix_ip_close(sock);
   }
@@ -75,6 +86,12 @@ eb_posix_sock_t eb_posix_ip_open(int family, int type, const char* port) {
   freeaddrinfo(match);
   if (!i) return -1;
   
+  /* Etherbone can broadcast over UDP */
+  if (sock != -1 && protocol == IPPROTO_UDP) {
+    optval = 1;
+    setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&optval, sizeof(optval));
+  }
+  
   return sock;
 }
 
@@ -129,6 +146,7 @@ socklen_t eb_posix_ip_resolve(const char* prefix, const char* address, int famil
 }
 
 void eb_posix_ip_force_non_blocking(eb_posix_sock_t sock, unsigned long on) {
+  if (sock == -1) return;
 #if defined(__WIN32)
   ioctlsocket(sock, FIONBIO, &on);
 #else
diff --git a/api/transport/posix-tcp.c b/api/transport/posix-tcp.c
index 4043c94ae92e47be97437bf492a9f7d48bf888e6..075e22f07d5aefb9b72893c1e6b634f6a5fb1b6f 100644
--- a/api/transport/posix-tcp.c
+++ b/api/transport/posix-tcp.c
@@ -36,20 +36,29 @@
 
 eb_status_t eb_posix_tcp_open(struct eb_transport* transportp, const char* port) {
   struct eb_posix_tcp_transport* transport;
-  eb_posix_sock_t sock;
-  
-  sock = eb_posix_ip_open(PF_INET6, SOCK_STREAM, port);
-  if (sock == -1) return EB_BUSY;
-  
-  if (listen(sock, 5) != 0) {
-    eb_posix_ip_close(sock);
+  eb_posix_sock_t sock4, sock6;
+  
+  sock4 = eb_posix_ip_open(PF_INET, SOCK_STREAM, port);
+#ifdef EB_DISABLE_IPV6    
+  sock6 = -1;
+#else
+  sock6 = eb_posix_ip_open(PF_INET6, SOCK_STREAM, port);
+#endif
+  if (sock4 == -1 && sock6 == -1) return EB_BUSY;
+  
+  if ((sock4 != -1 && listen(sock4, 5) != 0) ||
+      (sock6 != -1 && listen(sock6, 5) != 0)) {
+    eb_posix_ip_close(sock4);
+    eb_posix_ip_close(sock6);
     return EB_ADDRESS; 
   }
 
-  eb_posix_ip_force_non_blocking(sock, 1);
+  eb_posix_ip_force_non_blocking(sock4, 1);
+  eb_posix_ip_force_non_blocking(sock6, 1);
   
   transport = (struct eb_posix_tcp_transport*)transportp;
-  transport->port = sock;
+  transport->port4 = sock4;
+  transport->port6 = sock6;
 
   return EB_OK;
 }
@@ -58,7 +67,8 @@ void eb_posix_tcp_close(struct eb_transport* transportp) {
   struct eb_posix_tcp_transport* transport;
   
   transport = (struct eb_posix_tcp_transport*)transportp;
-  eb_posix_ip_close(transport->port);
+  eb_posix_ip_close(transport->port4);
+  eb_posix_ip_close(transport->port6);
 }
 
 eb_status_t eb_posix_tcp_connect(struct eb_transport* transportp, struct eb_link* linkp, const char* address) {
@@ -104,7 +114,8 @@ void eb_posix_tcp_fdes(struct eb_transport* transportp, struct eb_link* linkp, e
     (*cb)(data, link->socket);
   } else {
     transport = (struct eb_posix_tcp_transport*)transportp;
-    (*cb)(data, transport->port);
+    if (transport->port4 != -1) (*cb)(data, transport->port4);
+    if (transport->port6 != -1) (*cb)(data, transport->port6);
   }
 }
 
@@ -162,14 +173,22 @@ int eb_posix_tcp_accept(struct eb_transport* transportp, struct eb_link* result_
   struct eb_posix_tcp_link* result_link;
   eb_posix_sock_t sock;
   
+  sock = -1;
   transport = (struct eb_posix_tcp_transport*)transportp;
   
-  sock = accept(transport->port, 0, 0);
-  if (sock == -1) {
-    if (errno != EAGAIN) return -1;
-    return 0;
+  if (sock == -1 && transport->port4 != -1) {
+    sock = accept(transport->port4, 0, 0);
+    if (sock == -1 && errno != EAGAIN) return -1;
   }
   
+  if (sock == -1 && transport->port6 != -1) {
+    sock = accept(transport->port6, 0, 0);
+    if (sock == -1 && errno != EAGAIN) return -1;
+  }
+  
+  if (sock == -1) 
+    return 0;
+  
   if (result_linkp != 0) {
     result_link = (struct eb_posix_tcp_link*)result_linkp;
     result_link->socket = sock;
diff --git a/api/transport/posix-tcp.h b/api/transport/posix-tcp.h
index 30e84dbe4689a4205e5ce976478a0f45127600e4..a0b6e395c3357007bb337539f3273a4f79d7074f 100644
--- a/api/transport/posix-tcp.h
+++ b/api/transport/posix-tcp.h
@@ -46,7 +46,10 @@ EB_PRIVATE int eb_posix_tcp_accept(struct eb_transport*, struct eb_link* result_
 
 struct eb_posix_tcp_transport {
   /* Contents must fit in 9 bytes */
-  eb_posix_sock_t port;
+  eb_posix_sock_t port4; /* IPv4 */
+#ifndef EB_DISABLE_IPV6
+  eb_posix_sock_t port6; /* IPv6 */
+#endif
 };
 
 struct eb_posix_tcp_link {
diff --git a/api/transport/posix-udp.c b/api/transport/posix-udp.c
index 5fa7a3740c8b5d5c5b0ed59fd8a7d7075534e333..e0de1621863f8316d0f3ab7a8f13720c03d5e226 100644
--- a/api/transport/posix-udp.c
+++ b/api/transport/posix-udp.c
@@ -45,21 +45,22 @@
 
 eb_status_t eb_posix_udp_open(struct eb_transport* transportp, const char* port) {
   struct eb_posix_udp_transport* transport;
-  eb_posix_sock_t sock;
-  int optval;
+  eb_posix_sock_t sock4, sock6;
   
-  sock = eb_posix_ip_open(PF_INET6, SOCK_DGRAM, port);
-  if (sock == -1) return EB_BUSY;
-  
-  /* Etherbone can broadcast */
-  optval = 1;
-  if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&optval, sizeof(optval)) != 0) {
-    eb_posix_ip_close(sock);
-    return EB_FAIL;
-  }
+  sock4 = eb_posix_ip_open(PF_INET, SOCK_DGRAM, port);
+#ifdef EB_DISABLE_IPV6    
+  sock6 = -1;
+#else
+  sock6 = eb_posix_ip_open(PF_INET6, SOCK_DGRAM, port);
+#endif
+
+  /* Failure if we can't get either protocol */
+  if (sock4 == -1 && sock6 == -1) 
+    return EB_BUSY;
   
   transport = (struct eb_posix_udp_transport*)transportp;
-  transport->socket = sock;
+  transport->socket4 = sock4;
+  transport->socket6 = sock6;
   
   return EB_OK;
 }
@@ -68,22 +69,34 @@ void eb_posix_udp_close(struct eb_transport* transportp) {
   struct eb_posix_udp_transport* transport;
   
   transport = (struct eb_posix_udp_transport*)transportp;
-  eb_posix_ip_close(transport->socket);
+  eb_posix_ip_close(transport->socket4);
+  eb_posix_ip_close(transport->socket6);
 }
 
 eb_status_t eb_posix_udp_connect(struct eb_transport* transportp, struct eb_link* linkp, const char* address) {
+  struct eb_posix_udp_transport* transport;
   struct eb_posix_udp_link* link;
   struct sockaddr_storage sa;
   socklen_t len;
   
   len = -1;
-  if (len == -1) len = eb_posix_ip_resolve("udp6/", address, PF_INET6, SOCK_DGRAM, &sa);
   if (len == -1) len = eb_posix_ip_resolve("udp4/", address, PF_INET,  SOCK_DGRAM, &sa);
+#ifndef EB_DISABLE_IPV6
+  if (len == -1) len = eb_posix_ip_resolve("udp6/", address, PF_INET6, SOCK_DGRAM, &sa);
   if (len == -1) len = eb_posix_ip_resolve("udp/",  address, PF_INET6, SOCK_DGRAM, &sa);
+#endif
   if (len == -1) len = eb_posix_ip_resolve("udp/",  address, PF_INET,  SOCK_DGRAM, &sa);
   if (len == -1) return EB_ADDRESS;
   
+  transport = (struct eb_posix_udp_transport*)transportp;
   link = (struct eb_posix_udp_link*)linkp;
+
+  /* Do we have support for the socket? */
+  if (sa.ss_family == PF_INET  && transport->socket4 == -1) return EB_FAIL;
+#ifndef EB_DISABLE_IPV6
+  if (sa.ss_family == PF_INET6 && transport->socket6 == -1) return EB_FAIL;
+#endif
+
   link->sa = (struct sockaddr_storage*)malloc(sizeof(struct sockaddr_storage));
   link->sa_len = len;
   
@@ -104,7 +117,10 @@ void eb_posix_udp_fdes(struct eb_transport* transportp, struct eb_link* linkp, e
   
   transport = (struct eb_posix_udp_transport*)transportp;
   if (linkp == 0) {
-    (*cb)(data, transport->socket);
+    if (transport->socket4 != -1) (*cb)(data, transport->socket4);
+#ifndef EB_DISABLE_IPV6
+    if (transport->socket6 != -1) (*cb)(data, transport->socket6);
+#endif
   } else {
     /* no per-link socket */
   }
@@ -123,14 +139,24 @@ int eb_posix_udp_poll(struct eb_transport* transportp, struct eb_link* linkp, ui
   transport = (struct eb_posix_udp_transport*)transportp;
   
   /* Set non-blocking */
-  eb_posix_ip_non_blocking(transport->socket, 1);
+  eb_posix_ip_non_blocking(transport->socket4, 1);
+  eb_posix_ip_non_blocking(transport->socket6, 1);
+  
+  if (transport->socket4 != -1) {
+    eb_posix_udp_sa_len = sizeof(eb_posix_udp_sa);
+    result = recvfrom(transport->socket4, (char*)buf, len, MSG_DONTWAIT, (struct sockaddr*)&eb_posix_udp_sa, &eb_posix_udp_sa_len);
+    if (result == -1 && errno != EAGAIN) return -1;
+    if (result != -1) return result;
+  }
   
-  eb_posix_udp_sa_len = sizeof(eb_posix_udp_sa);
-  result = recvfrom(transport->socket, (char*)buf, len, MSG_DONTWAIT, (struct sockaddr*)&eb_posix_udp_sa, &eb_posix_udp_sa_len);
+  if (transport->socket6 != -1) {
+    eb_posix_udp_sa_len = sizeof(eb_posix_udp_sa);
+    result = recvfrom(transport->socket6, (char*)buf, len, MSG_DONTWAIT, (struct sockaddr*)&eb_posix_udp_sa, &eb_posix_udp_sa_len);
+    if (result == -1 && errno != EAGAIN) return -1;
+    if (result != -1) return result;
+  }
   
-  if (result == -1 && errno == EAGAIN) return 0;
-  if (result == 0) return -1;
-  return result;
+  return 0;
 }
 
 int eb_posix_udp_recv(struct eb_transport* transportp, struct eb_link* linkp, uint8_t* buf, int len) {
@@ -152,13 +178,24 @@ void eb_posix_udp_send(struct eb_transport* transportp, struct eb_link* linkp, c
   transport = (struct eb_posix_udp_transport*)transportp;
   link = (struct eb_posix_udp_link*)linkp;
   
-  /* Set blocking */
-  eb_posix_ip_non_blocking(transport->socket, 0);
   
-  if (link == 0)
-    sendto(transport->socket, (const char*)buf, len, 0, (struct sockaddr*)&eb_posix_udp_sa, eb_posix_udp_sa_len);
-  else
-    sendto(transport->socket, (const char*)buf, len, 0, (struct sockaddr*)link->sa, link->sa_len);
+  if (link == 0) {
+    if (eb_posix_udp_sa.ss_family == PF_INET6) {
+      eb_posix_ip_non_blocking(transport->socket6, 0);
+      sendto(transport->socket6, (const char*)buf, len, 0, (struct sockaddr*)&eb_posix_udp_sa, eb_posix_udp_sa_len);
+    } else {
+      eb_posix_ip_non_blocking(transport->socket4, 0);
+      sendto(transport->socket4, (const char*)buf, len, 0, (struct sockaddr*)&eb_posix_udp_sa, eb_posix_udp_sa_len);
+    }
+  } else {
+    if (link->sa->ss_family == PF_INET6) {
+      eb_posix_ip_non_blocking(transport->socket6, 0);
+      sendto(transport->socket6, (const char*)buf, len, 0, (struct sockaddr*)link->sa, link->sa_len);
+    } else {
+      eb_posix_ip_non_blocking(transport->socket4, 0);
+      sendto(transport->socket4, (const char*)buf, len, 0, (struct sockaddr*)link->sa, link->sa_len);
+    }
+  }
 }
 
 int eb_posix_udp_accept(struct eb_transport* transportp, struct eb_link* result_linkp) {
diff --git a/api/transport/posix-udp.h b/api/transport/posix-udp.h
index 13587e673c94f8eb79155fefcf46d5bf294d8fed..98184c1f2934a496417cf3443c633cc9be6a03c6 100644
--- a/api/transport/posix-udp.h
+++ b/api/transport/posix-udp.h
@@ -46,7 +46,8 @@ EB_PRIVATE int eb_posix_udp_accept(struct eb_transport*, struct eb_link* result_
 
 struct eb_posix_udp_transport {
   /* Contents must fit in 9 bytes */
-  eb_posix_sock_t socket;
+  eb_posix_sock_t socket4; /* IPv4 */
+  eb_posix_sock_t socket6; /* IPv6 */
 };
 
 struct eb_posix_udp_link {