ref: c9ff32c97711bc0a0150d3cc03e79aad3c80e381
parent: d14cd19f715966e736d7439aac7909f83f7a9159
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Aug 20 23:12:39 EDT 2016
devip: return multiple addresses in /net/cs for dial(), handle ipv6 for windows
--- a/Make.win32
+++ b/Make.win32
@@ -17,7 +17,7 @@
IP=win32
OS=win32
GUI=win32
-LDADD=-lkernel32 -ladvapi32 -lgdi32 -lmpr -lwsock32 -lmsvcrt -lmingw32 -lwinmm
+LDADD=-lkernel32 -ladvapi32 -lgdi32 -lmpr -lwsock32 -lws2_32 -lmsvcrt -lmingw32 -lwinmm
TARG=drawterm.exe
XOFILES=glenda-t.$O
--- a/kern/devip-posix.c
+++ b/kern/devip-posix.c
@@ -207,54 +207,30 @@
}
int
-so_gethostbyname(char *host, char**hostv, int n)
+so_gethostbyname(char *host, char **hostv, int n)
{
+ char buf[INET6_ADDRSTRLEN];
+ PADDRINFOA r, p;
int i;
- char buf[32];
- unsigned char *p;
- struct hostent *hp;
- hp = gethostbyname(host);
- if(hp == 0)
+ r = NULL;
+ if(getaddrinfo(host, NULL, NULL, &r))
return 0;
-
- for(i = 0; hp->h_addr_list[i] && i < n; i++) {
- p = (unsigned char*)hp->h_addr_list[i];
- sprint(buf, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
- hostv[i] = strdup(buf);
- if(hostv[i] == 0)
- break;
- }
- return i;
-}
-
-char*
-hostlookup(char *host)
-{
- 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) {
+ for(i = 0, p = r; i < n && p != NULL; p = p->ai_next){
+ switch (p->ai_family) {
+ default:
+ continue;
case AF_INET:
- inet_ntop(AF_INET, &((struct sockaddr_in*)result->ai_addr)->sin_addr, buf, sizeof(buf));
+ inet_ntop(AF_INET, &((struct sockaddr_in*)p->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));
+ inet_ntop(AF_INET6, &((struct sockaddr_in6*)p->ai_addr)->sin6_addr, buf, sizeof(buf));
break;
- default:
- return nil;
}
- } else
- return nil;
-
- return strdup(buf);
+ hostv[i++] = strdup(buf);
+ }
+ freeaddrinfo(r);
+ return i;
}
int
--- a/kern/devip-win32.c
+++ b/kern/devip-win32.c
@@ -212,42 +212,30 @@
}
int
-so_gethostbyname(char *host, char**hostv, int n)
+so_gethostbyname(char *host, char **hostv, int n)
{
+ char buf[INET6_ADDRSTRLEN];
+ PADDRINFOA r, p;
+ DWORD l;
int i;
- char buf[32];
- unsigned char *p;
- struct hostent *hp;
- hp = gethostbyname(host);
- if(hp == 0)
+ r = NULL;
+ if(getaddrinfo(host, NULL, NULL, &r))
return 0;
-
- for(i = 0; hp->h_addr_list[i] && i < n; i++) {
- p = (unsigned char*)hp->h_addr_list[i];
- sprint(buf, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
- hostv[i] = strdup(buf);
- if(hostv[i] == 0)
+ for(i = 0, p = r; i < n && p != NULL; p = p->ai_next){
+ switch (p->ai_family) {
+ default:
+ continue;
+ case AF_INET:
+ case AF_INET6:
+ l = sizeof(buf);
+ WSAAddressToStringA(p->ai_addr, p->ai_addrlen, NULL, buf, &l);
break;
+ }
+ hostv[i++] = strdup(buf);
}
+ freeaddrinfo(r);
return i;
-}
-
-char*
-hostlookup(char *host)
-{
- char buf[100];
- uchar *p;
- struct hostent *he;
-
- 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
- strcpy(buf, host);
-
- return strdup(buf);
}
int
--- a/kern/devip.c
+++ b/kern/devip.c
@@ -642,14 +642,30 @@
csclose(Chan *c)
{
free(c->aux);
+ c->aux = nil;
}
long
csread(Chan *c, void *a, long n, vlong offset)
{
- if(c->aux == nil)
+ char *s, *e, *p;
+
+ s = c->aux;
+ if(s == nil)
return 0;
- return readstr(offset, a, n, c->aux);
+ e = strchr(s, 0);
+ s += offset;
+ if(s >= e)
+ return 0;
+ p = strchr(s, '\n');
+ if(p != nil)
+ p++;
+ else
+ p = e;
+ if(p - s < n)
+ n = p - s;
+ memmove(a, s, n);
+ return n;
}
static struct
@@ -777,26 +793,13 @@
return 0;
}
-static int
-lookuphost(char *s, uchar *to)
-{
- ipzero(to);
- if(parseip(to, s) != -1)
- return 0;
- if((s = hostlookup(s)) == nil)
- return -1;
- parseip(to, s);
- free(s);
- return 0;
-}
-
long
cswrite(Chan *c, void *a, long n, vlong offset)
{
- char *f[4];
+ char *f[4], *ips[8];
char *s, *ns;
uchar ip[IPaddrlen];
- int nf, port;
+ int i, nf, port, nips;
s = malloc(n+1);
if(s == nil)
@@ -814,13 +817,22 @@
port = lookupport(f[2]);
if(port <= 0)
error("no translation for port found");
-
- if(lookuphost(f[1], ip) < 0)
- error("no translation for host found");
-
- ns = smprint("/net/%s/clone %I!%d", f[0], ip, port);
- if(ns == nil)
- error(Enomem);
+ if(parseip(ip, f[1]) != -1){
+ ips[0] = smprint("%I", ip);
+ nips = 1;
+ } else {
+ nips = so_gethostbyname(f[1], ips, nelem(ips));
+ if(nips <= 0)
+ error("no translation for host found");
+ }
+ ns = smprint("/net/%s/clone %s!%d", f[0], ips[0], port);
+ free(ips[0]);
+ for(i=1; i<nips; i++){
+ ips[0] = smprint("%s\n/net/%s/clone %s!%d", ns, f[0], ips[i], port);
+ free(ips[i]);
+ free(ns);
+ ns = ips[0];
+ }
free(c->aux);
c->aux = ns;
poperror();
--- a/kern/devip.h
+++ b/kern/devip.h
@@ -14,6 +14,3 @@
int so_accept(int, unsigned char*, unsigned short*);
int so_getservbyname(char*, char*, char*);
int so_gethostbyname(char*, char**, int);
-
-char* hostlookup(char*);
-