2003-11-23 18:12:54 +00:00
|
|
|
#include <netdb.h>
|
|
|
|
#include <sys/un.h>
|
|
|
|
|
2003-11-23 19:49:17 +00:00
|
|
|
#include <u.h>
|
|
|
|
#include <libc.h>
|
|
|
|
|
2003-11-23 18:12:54 +00:00
|
|
|
static char *nets[] = { "tcp", "udp", nil };
|
|
|
|
#define CLASS(p) ((*(uchar*)(p))>>6)
|
|
|
|
|
|
|
|
static int
|
|
|
|
parseip(char *host, u32int *pip)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if(i == 3){
|
|
|
|
addr[3] = addr[2];
|
|
|
|
addr[2] = 0;
|
|
|
|
}else if(i != 4)
|
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
*pip = *(u32int*)addr;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
_p9dialparse(char *addr, char **pnet, char **punix, u32int *phost, int *pport)
|
|
|
|
{
|
|
|
|
char *net, *host, *port, *e;
|
|
|
|
int i;
|
|
|
|
struct servent *se;
|
|
|
|
struct hostent *he;
|
2003-11-23 19:49:17 +00:00
|
|
|
struct sockaddr_un *sockun;
|
2003-11-23 18:12:54 +00:00
|
|
|
|
|
|
|
if(strncmp(addr, "/net/", 5) == 0)
|
|
|
|
addr += 5;
|
|
|
|
|
|
|
|
net = addr;
|
|
|
|
if((host = strchr(net, '!')) == nil){
|
|
|
|
werrstr("malformed address");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*host++ = 0;
|
|
|
|
if((port = strchr(host, '!')) == nil){
|
|
|
|
if(strcmp(net, "unix")==0 || strcmp(net, "net")==0){
|
|
|
|
Unix:
|
2003-11-23 19:49:17 +00:00
|
|
|
if(strlen(host)+1 > sizeof sockun->sun_path){
|
2003-11-23 18:12:54 +00:00
|
|
|
werrstr("unix socket name too long");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*punix = host;
|
|
|
|
*pnet = "unix";
|
|
|
|
*phost = 0;
|
|
|
|
*pport = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
werrstr("malformed address");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*port++ = 0;
|
|
|
|
|
|
|
|
if(*host == 0){
|
|
|
|
werrstr("malformed address (empty host)");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if(*port == 0){
|
|
|
|
werrstr("malformed address (empty port)");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(strcmp(net, "unix") == 0)
|
|
|
|
goto Unix;
|
|
|
|
|
|
|
|
if(strcmp(net, "tcp")!=0 && strcmp(net, "udp")!=0){
|
|
|
|
werrstr("bad network %s!%s!%s", net, host, port);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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{
|
|
|
|
werrstr("unknown host %s", host);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* translate network and port; should return list rather than first */
|
|
|
|
if(strcmp(net, "net") == 0){
|
|
|
|
for(i=0; nets[i]; i++){
|
|
|
|
if((se = getservbyname(port, nets[i])) != nil){
|
|
|
|
*pnet = nets[i];
|
|
|
|
*pport = ntohs(se->s_port);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
werrstr("unknown service %s", port);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(strcmp(net, "tcp") != 0 && strcmp(net, "udp") != 0){
|
|
|
|
werrstr("unknown network %s", net);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pnet = net;
|
|
|
|
i = strtol(port, &e, 0);
|
|
|
|
if(*e == 0){
|
|
|
|
*pport = i;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((se = getservbyname(port, net)) != nil){
|
|
|
|
*pport = ntohs(se->s_port);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
werrstr("unknown service %s", port);
|
|
|
|
return -1;
|
|
|
|
}
|