aboutsummaryrefslogtreecommitdiff
path: root/src/lib9/_p9dialparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib9/_p9dialparse.c')
-rw-r--r--src/lib9/_p9dialparse.c105
1 files changed, 53 insertions, 52 deletions
diff --git a/src/lib9/_p9dialparse.c b/src/lib9/_p9dialparse.c
index 0c84ecdb..d8e91003 100644
--- a/src/lib9/_p9dialparse.c
+++ b/src/lib9/_p9dialparse.c
@@ -31,58 +31,35 @@ static struct {
};
static int
-parseip(char *host, u32int *pip)
+setport(struct sockaddr_storage *ss, int port)
{
- uchar addr[4];
- int x, i;
- char *p;
-
- p = host;
- for(i=0; i<4 && *p; i++){
- x = strtoul(p, &p, 0);
- if(x < 0 || x >= 256)
- return -1;
- if(*p != '.' && *p != 0)
- return -1;
- if(*p == '.')
- p++;
- addr[i] = x;
- }
-
- switch(CLASS(addr)){
- case 0:
- case 1:
- if(i == 3){
- addr[3] = addr[2];
- addr[2] = addr[1];
- addr[1] = 0;
- }else if(i == 2){
- addr[3] = addr[1];
- addr[2] = 0;
- addr[1] = 0;
- }else if(i != 4)
- return -1;
+ switch(ss->ss_family){
+ case AF_INET:
+ ((struct sockaddr_in*)ss)->sin_port = htons(port);
break;
- case 2:
- if(i == 3){
- addr[3] = addr[2];
- addr[2] = 0;
- }else if(i != 4)
- return -1;
+ case AF_INET6:
+ ((struct sockaddr_in6*)ss)->sin6_port = htons(port);
break;
+ default:
+ errstr("unknown protocol family %d", ss->ss_family);
+ return -1;
}
- memmove(pip, addr, 4);
return 0;
}
int
-p9dialparse(char *addr, char **pnet, char **punix, u32int *phost, int *pport)
+p9dialparse(char *addr, char **pnet, char **punix, void *phost, int *pport)
{
char *net, *host, *port, *e;
int i;
struct servent *se;
struct hostent *he;
- struct sockaddr_un *sockun;
+ struct sockaddr_storage *ss;
+ struct addrinfo *result;
+
+ ss = phost;
+
+ memset(ss, 0, sizeof(ss));
*punix = nil;
net = addr;
@@ -94,13 +71,14 @@ p9dialparse(char *addr, char **pnet, char **punix, u32int *phost, int *pport)
if((port = strchr(host, '!')) == nil){
if(strcmp(net, "unix")==0 || strcmp(net, "net")==0){
Unix:
- if(strlen(host)+1 > sizeof sockun->sun_path){
+ if(strlen(host)+1 > sizeof ((struct sockaddr_un*)&ss)->sun_path){
werrstr("unix socket name too long");
return -1;
}
*punix = host;
*pnet = "unix";
- *phost = 0;
+ ss->ss_family = AF_UNIX;
+ strcpy(((struct sockaddr_un*)ss)->sun_path, host);
*pport = 0;
return 0;
}
@@ -127,13 +105,36 @@ p9dialparse(char *addr, char **pnet, char **punix, u32int *phost, int *pport)
}
/* translate host */
- if(strcmp(host, "*") == 0)
- *phost = 0;
- else if(parseip(host, phost) == 0)
- {}
- else if((he = gethostbyname(host)) != nil)
- *phost = *(u32int*)(he->h_addr);
- else{
+ if(strcmp(host, "*") == 0){
+ ss->ss_family = AF_INET6;
+ ((struct sockaddr_in6*)ss)->sin6_addr = in6addr_any;
+ }else if((he = gethostbyname(host)) != nil){
+ ss->ss_family = he->h_addrtype;
+ switch(ss->ss_family){
+ case AF_INET:
+ ((struct sockaddr_in*)ss)->sin_addr = *(struct in_addr*) *(he->h_addr_list);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6*)ss)->sin6_addr = *(struct in6_addr*) *(he->h_addr_list);
+ break;
+ default:
+ errstr("unknown protocol family %d", ss->ss_family);
+ return -1;
+ }
+ }else if(getaddrinfo(host, NULL, NULL, &result) == 0) {
+ ss->ss_family = result->ai_family;
+ switch (ss->ss_family) {
+ case AF_INET:
+ memcpy((struct sockaddr_in*)ss, result->ai_addr, result->ai_addrlen);
+ break;
+ case AF_INET6:
+ memcpy((struct sockaddr_in6*)ss, result->ai_addr, result->ai_addrlen);
+ break;
+ default:
+ errstr("unknown protocol family %d", ss->ss_family);
+ return -1;
+ }
+ }else{
werrstr("unknown host %s", host);
return -1;
}
@@ -144,7 +145,7 @@ p9dialparse(char *addr, char **pnet, char **punix, u32int *phost, int *pport)
if((se = getservbyname(port, nets[i])) != nil){
*pnet = nets[i];
*pport = ntohs(se->s_port);
- return 0;
+ return setport(ss, *pport);
}
}
}
@@ -154,7 +155,7 @@ p9dialparse(char *addr, char **pnet, char **punix, u32int *phost, int *pport)
if(strcmp(porttbl[i].service, port) == 0){
*pnet = porttbl[i].net;
*pport = porttbl[i].port;
- return 0;
+ return setport(ss, *pport);
}
}
@@ -172,12 +173,12 @@ p9dialparse(char *addr, char **pnet, char **punix, u32int *phost, int *pport)
i = strtol(port, &e, 0);
if(*e == 0){
*pport = i;
- return 0;
+ return setport(ss, *pport);
}
if((se = getservbyname(port, net)) != nil){
*pport = ntohs(se->s_port);
- return 0;
+ return setport(ss, *pport);
}
werrstr("unknown service %s!*!%s", net, port);
return -1;