Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(62)

Unified Diff: kern/devip-win32.c

Issue 6408044: code review 6408044: devip: add support for IPv6 (Closed)
Patch Set: diff -r 9822f642bd61 https://code.google.com/p/drawterm/ Created 12 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « kern/devip-posix.c ('k') | kern/fns.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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]) {
« no previous file with comments | « kern/devip-posix.c ('k') | kern/fns.h » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b