diff -r 17a064eed9c2 src/9vx/devip-posix.c --- a/src/9vx/devip-posix.c Mon May 30 10:09:22 2011 +0200 +++ b/src/9vx/devip-posix.c Wed Jul 18 00:00:00 2012 +0200 @@ -4,18 +4,28 @@ #include #include #include +#include #include #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "error.h" +#include "ip.h" #include "devip.h" #undef listen #undef accept #undef bind +static int +family(unsigned char *addr) +{ + if(isv4(addr)) + return AF_INET; + return AF_INET6; +} + void osipinit(void) { @@ -27,7 +37,7 @@ } int -so_socket(int type) +so_socket(int type, unsigned char *addr) { int fd, one; @@ -42,7 +52,7 @@ break; } - fd = socket(AF_INET, type, 0); + fd = socket(family(addr), type, 0); if(fd < 0) oserror(); @@ -57,34 +67,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) { socklen_t 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 @@ -95,30 +122,37 @@ } int -so_accept(int fd, unsigned long *raddr, unsigned short *rport) +so_accept(int fd, unsigned char *raddr, unsigned short *rport) { int nfd; socklen_t len; - struct sockaddr_in sin; + 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){ @@ -128,21 +162,37 @@ 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(); } @@ -171,16 +221,28 @@ char* hostlookup(char *host) { - char buf[100]; + char buf[INET6_ADDRSTRLEN]; uchar *p; struct hostent *he; + struct addrinfo *result; he = gethostbyname(host); if(he != 0 && he->h_addr_list[0]) { p = (uchar*)he->h_addr_list[0]; sprint(buf, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3]); + } else if(getaddrinfo(host, NULL, NULL, &result) == 0) { + switch (result->ai_family) { + case AF_INET: + inet_ntop(AF_INET, &((struct sockaddr_in*)result->ai_addr)->sin_addr, buf, sizeof(buf)); + break; + case AF_INET6: + inet_ntop(AF_INET6, &((struct sockaddr_in6*)result->ai_addr)->sin6_addr, buf, sizeof(buf)); + break; + default: + return nil; + } } else - strcpy(buf, host); + return nil; return strdup(buf); } diff -r 17a064eed9c2 src/9vx/devip.c --- a/src/9vx/devip.c Mon May 30 10:09:22 2011 +0200 +++ b/src/9vx/devip.c Wed Jul 18 00:00:00 2012 +0200 @@ -1,5 +1,5 @@ /* - * /net interface to host IPv4 stack. + * /net interface to host IP stack. */ #include "u.h" @@ -40,6 +40,7 @@ #define CONV(x) ((int)(((x).path >> 4)&0xfff)) #define PROTO(x) ((int)(((x).path >> 16)&0xff)) #define QID(p, c, y) (((p)<<16) | ((c)<<4) | (y)) +#define ipzero(x) memset(x, 0, IPaddrlen) typedef struct Proto Proto; typedef struct Conv Conv; @@ -52,9 +53,9 @@ int perm; char owner[KNAMELEN]; char* state; - ulong laddr; + uchar laddr[IPaddrlen]; ushort lport; - ulong raddr; + uchar raddr[IPaddrlen]; ushort rport; int restricted; char cerr[KNAMELEN]; @@ -206,7 +207,7 @@ newproto("tcp", S_TCP, 30); fmtinstall('E', eipfmt); - fmtinstall('V', eipfmt); + fmtinstall('I', eipfmt); } Chan * @@ -237,7 +238,7 @@ ipopen(Chan *c, int omode) { Proto *p; - ulong raddr; + uchar raddr[IPaddrlen]; ushort rport; int perm, sfd; Conv *cv, *lcv; @@ -301,13 +302,13 @@ case Qlisten: p = &proto[PROTO(c->qid)]; lcv = p->conv[CONV(c->qid)]; - sfd = so_accept(lcv->sfd, &raddr, &rport); + sfd = so_accept(lcv->sfd, raddr, &rport); cv = protoclone(p, up->user, sfd); if(cv == 0) { close(sfd); error(Enodev); } - cv->raddr = raddr; + ipmove(cv->raddr, raddr); cv->rport = rport; setladdr(cv); cv->state = "Established"; @@ -340,8 +341,8 @@ strcpy(cc->owner, "network"); cc->perm = 0666; cc->state = "Closed"; - cc->laddr = 0; - cc->raddr = 0; + ipzero(cc->laddr); + ipzero(cc->raddr); cc->lport = 0; cc->rport = 0; close(cc->sfd); @@ -366,7 +367,7 @@ int r; Conv *c; Proto *x; - uchar ip[4]; + uchar ip[IPaddrlen]; char buf[128], *p; /*print("ipread %s %lux\n", c2name(ch), (long)ch->qid.path);*/ @@ -386,13 +387,13 @@ return readstr(offset, p, n, buf); case Qremote: c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)]; - hnputl(ip, c->raddr); - sprint(buf, "%V!%d\n", ip, c->rport); + ipmove(ip, c->raddr); + sprint(buf, "%I!%d\n", ip, c->rport); return readstr(offset, p, n, buf); case Qlocal: c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)]; - hnputl(ip, c->laddr); - sprint(buf, "%V!%d\n", ip, c->lport); + ipmove(ip, c->laddr); + sprint(buf, "%I!%d\n", ip, c->lport); return readstr(offset, p, n, buf); case Qstatus: x = &proto[PROTO(ch->qid)]; @@ -416,7 +417,7 @@ static void setladdr(Conv *c) { - so_getsockname(c->sfd, &c->laddr, &c->lport); + so_getsockname(c->sfd, c->laddr, &c->lport); } static void @@ -425,24 +426,27 @@ if(c->restricted == 0 && c->lport == 0) return; - so_bind(c->sfd, c->restricted, c->lport); + if(c->sfd == -1) + c->sfd = so_socket(c->p->stype, c->laddr); + + so_bind(c->sfd, c->restricted, c->lport, c->laddr); } static void setladdrport(Conv *c, char *str) { char *p; - uchar addr[4]; + uchar addr[IPaddrlen]; p = strchr(str, '!'); if(p == 0) { p = str; - c->laddr = 0; + ipzero(c->laddr); } else { *p++ = 0; - v4parseip(addr, str); - c->laddr = nhgetl(addr); + parseip(addr, str); + ipmove(c->laddr, addr); } if(*p == '*') c->lport = 0; @@ -456,14 +460,14 @@ setraddrport(Conv *c, char *str) { char *p; - uchar addr[4]; + uchar addr[IPaddrlen]; p = strchr(str, '!'); if(p == 0) return "malformed address"; *p++ = 0; - v4parseip(addr, str); - c->raddr = nhgetl(addr); + parseip(addr, str); + ipmove(c->raddr, addr); c->rport = atoi(p); p = strchr(p, '!'); if(p) { @@ -513,6 +517,8 @@ setlport(c); break; } + if(c->sfd == -1) + c->sfd = so_socket(c->p->stype, c->raddr); so_connect(c->sfd, c->raddr, c->rport); setladdr(c); c->state = "Established"; @@ -598,13 +604,11 @@ c->perm = 0660; c->state = "Closed"; c->restricted = 0; - c->laddr = 0; - c->raddr = 0; + ipzero(c->laddr); + ipzero(c->raddr); c->lport = 0; c->rport = 0; c->sfd = nfd; - if(nfd == -1) - c->sfd = so_socket(p->stype); c->eof = 0; unlock(&c->r.lk); @@ -809,16 +813,12 @@ static int lookuphost(char *s, uchar *to) { - ulong ip; - char *p; - - memset(to, 0, 4); - p = v4parseip(to, s); - if(p && *p == 0 && (ip = nhgetl(to)) != 0) + ipzero(to); + if(parseip(to, s) != -1) return 0; if((s = hostlookup(s)) == nil) return -1; - v4parseip(to, s); + parseip(to, s); free(s); return 0; } @@ -829,7 +829,7 @@ char *f[4]; char *s, *ns; int nf, port, bang; - uchar ip[4]; + uchar ip[IPaddrlen]; s = malloc(n+1); if(s == nil) @@ -858,7 +858,7 @@ if(lookuphost(f[1], ip) < 0) error("no translation for host found"); - snprint(ns, 128, "/net/%s/clone %V!%d", f[0], ip, port); + snprint(ns, 128, "/net/%s/clone %I!%d", f[0], ip, port); }else{ /* dns */ bang = 0; @@ -872,9 +872,9 @@ if(lookuphost(f[0], ip) < 0) error("no translation for host found"); if(bang) - snprint(ns, 128, "dom=%s ip=%V", f[0], ip); + snprint(ns, 128, "dom=%s ip=%I", f[0], ip); else - snprint(ns, 128, "%s ip\t%V", f[0], ip); + snprint(ns, 128, "%s ip\t%I", f[0], ip); } free(c->aux); c->aux = ns; diff -r 17a064eed9c2 src/9vx/devip.h --- a/src/9vx/devip.h Mon May 30 10:09:22 2011 +0200 +++ b/src/9vx/devip.h Wed Jul 18 00:00:00 2012 +0200 @@ -4,14 +4,14 @@ S_UDP }; -int so_socket(int type); -void so_connect(int, unsigned long, unsigned short); -void so_getsockname(int, unsigned long*, unsigned short*); -void so_bind(int, int, unsigned short); +int so_socket(int, unsigned char*); +void so_connect(int, unsigned char*, unsigned short); +void so_getsockname(int, unsigned char*, unsigned short*); +void so_bind(int, int, unsigned short, unsigned char*); void so_listen(int); int so_send(int, void*, int, int); int so_recv(int, void*, int, int); -int so_accept(int, unsigned long*, unsigned short*); +int so_accept(int, unsigned char*, unsigned short*); int so_getservbyname(char*, char*, char*); int so_gethostbyname(char*, char**, int);