Index: kern/devip-win32.c |
=================================================================== |
--- a/kern/devip-win32.c |
+++ b/kern/devip-win32.c |
@@ -1,9 +1,11 @@ |
#include <windows.h> |
+#include <ws2tcpip.h> |
#include "u.h" |
#include "lib.h" |
#include "dat.h" |
#include "fns.h" |
#include "error.h" |
+#include "ip.h" |
#include "devip.h" |
@@ -15,6 +17,14 @@ |
#undef accept |
#undef bind |
+static int |
+family(unsigned char *addr) |
+{ |
+ if(isv4(addr)) |
+ return AF_INET; |
+ return AF_INET6; |
+} |
+ |
void |
osipinit(void) |
{ |
@@ -29,7 +39,7 @@ |
} |
int |
-so_socket(int type) |
+so_socket(int type, unsigned char *addr) |
{ |
int fd, one; |
@@ -44,7 +54,7 @@ |
break; |
} |
- fd = socket(AF_INET, type, 0); |
+ fd = socket(family(addr), type, 0); |
if(fd < 0) |
oserror(); |
@@ -59,34 +69,51 @@ |
void |
-so_connect(int fd, unsigned long raddr, unsigned short rport) |
+so_connect(int fd, unsigned char *raddr, unsigned short rport) |
{ |
- struct sockaddr_in sin; |
+ struct sockaddr_storage ss; |
- memset(&sin, 0, sizeof(sin)); |
- sin.sin_family = AF_INET; |
- hnputs(&sin.sin_port, rport); |
- hnputl(&sin.sin_addr.s_addr, raddr); |
+ memset(&ss, 0, sizeof(ss)); |
- if(connect(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0) |
+ ss.ss_family = family(raddr); |
+ |
+ switch(ss.ss_family){ |
+ case AF_INET: |
+ hnputs(&((struct sockaddr_in*)&ss)->sin_port, rport); |
+ v6tov4((unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr, raddr); |
+ break; |
+ case AF_INET6: |
+ hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, rport); |
+ memcpy(&((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, raddr, sizeof(struct in6_addr)); |
+ break; |
+ } |
+ |
+ if(connect(fd, (struct sockaddr*)&ss, sizeof(ss)) < 0) |
oserror(); |
} |
void |
-so_getsockname(int fd, unsigned long *laddr, unsigned short *lport) |
+so_getsockname(int fd, unsigned char *laddr, unsigned short *lport) |
{ |
int len; |
- struct sockaddr_in sin; |
+ struct sockaddr_storage ss; |
- len = sizeof(sin); |
- if(getsockname(fd, (struct sockaddr*)&sin, &len) < 0) |
+ len = sizeof(ss); |
+ if(getsockname(fd, (struct sockaddr*)&ss, &len) < 0) |
oserror(); |
- if(sin.sin_family != AF_INET || len != sizeof(sin)) |
- error("not AF_INET"); |
- |
- *laddr = nhgetl(&sin.sin_addr.s_addr); |
- *lport = nhgets(&sin.sin_port); |
+ switch(ss.ss_family){ |
+ case AF_INET: |
+ v4tov6(laddr, (unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr); |
+ *lport = nhgets(&((struct sockaddr_in*)&ss)->sin_port); |
+ break; |
+ case AF_INET6: |
+ memcpy(laddr, &((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, sizeof(struct in6_addr)); |
+ *lport = nhgets(&((struct sockaddr_in6*)&ss)->sin6_port); |
+ break; |
+ default: |
+ error("not AF_INET or AF_INET6"); |
+ } |
} |
void |
@@ -97,53 +124,77 @@ |
} |
int |
-so_accept(int fd, unsigned long *raddr, unsigned short *rport) |
+so_accept(int fd, unsigned char *raddr, unsigned short *rport) |
{ |
- int nfd, len; |
- struct sockaddr_in sin; |
+ int nfd; |
+ int len; |
+ struct sockaddr_storage ss; |
- len = sizeof(sin); |
- nfd = accept(fd, (struct sockaddr*)&sin, &len); |
+ len = sizeof(ss); |
+ nfd = accept(fd, (struct sockaddr*)&ss, &len); |
if(nfd < 0) |
oserror(); |
- if(sin.sin_family != AF_INET || len != sizeof(sin)) |
- error("not AF_INET"); |
- |
- *raddr = nhgetl(&sin.sin_addr.s_addr); |
- *rport = nhgets(&sin.sin_port); |
+ switch(ss.ss_family){ |
+ case AF_INET: |
+ v4tov6(raddr, (unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr); |
+ *rport = nhgets(&((struct sockaddr_in*)&ss)->sin_port); |
+ break; |
+ case AF_INET6: |
+ memcpy(raddr, &((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, sizeof(struct in6_addr)); |
+ *rport = nhgets(&((struct sockaddr_in6*)&ss)->sin6_port); |
+ break; |
+ default: |
+ error("not AF_INET or AF_INET6"); |
+ } |
return nfd; |
} |
void |
-so_bind(int fd, int su, unsigned short port) |
+so_bind(int fd, int su, unsigned short port, unsigned char *addr) |
{ |
int i, one; |
- struct sockaddr_in sin; |
+ struct sockaddr_storage ss; |
one = 1; |
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0){ |
oserrstr(); |
- print("setsockopt: %s", up->errstr); |
+ print("setsockopt: %r"); |
} |
if(su) { |
for(i = 600; i < 1024; i++) { |
- memset(&sin, 0, sizeof(sin)); |
- sin.sin_family = AF_INET; |
- sin.sin_port = i; |
+ memset(&ss, 0, sizeof(ss)); |
+ ss.ss_family = family(addr); |
- if(bind(fd, (struct sockaddr*)&sin, sizeof(sin)) >= 0) |
+ switch(ss.ss_family){ |
+ case AF_INET: |
+ ((struct sockaddr_in*)&ss)->sin_port = i; |
+ break; |
+ case AF_INET6: |
+ ((struct sockaddr_in6*)&ss)->sin6_port = i; |
+ break; |
+ } |
+ |
+ if(bind(fd, (struct sockaddr*)&ss, sizeof(ss)) >= 0) |
return; |
} |
oserror(); |
} |
- memset(&sin, 0, sizeof(sin)); |
- sin.sin_family = AF_INET; |
- hnputs(&sin.sin_port, port); |
+ memset(&ss, 0, sizeof(ss)); |
+ ss.ss_family = family(addr); |
- if(bind(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0) |
+ switch(ss.ss_family){ |
+ case AF_INET: |
+ hnputs(&((struct sockaddr_in*)&ss)->sin_port, port); |
+ break; |
+ case AF_INET6: |
+ hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, port); |
+ break; |
+ } |
+ |
+ if(bind(fd, (struct sockaddr*)&ss, sizeof(ss)) < 0) |
oserror(); |
} |
@@ -174,7 +225,7 @@ |
{ |
char buf[100]; |
uchar *p; |
- HOSTENT *he; |
+ struct hostent *he; |
he = gethostbyname(host); |
if(he != 0 && he->h_addr_list[0]) { |