Blob


1 #include <u.h>
2 #define NOPLAN9DEFINES
3 #include <libc.h>
5 #include <sys/types.h>
6 #include <netdb.h>
7 #include <sys/un.h>
8 #include <netinet/in.h>
10 static char *nets[] = { "tcp", "udp", nil };
11 #define CLASS(p) ((*(uchar*)(p))>>6)
13 static int
14 parseip(char *host, u32int *pip)
15 {
16 uchar addr[4];
17 int x, i;
18 char *p;
20 p = host;
21 for(i=0; i<4 && *p; i++){
22 x = strtoul(p, &p, 0);
23 if(x < 0 || x >= 256)
24 return -1;
25 if(*p != '.' && *p != 0)
26 return -1;
27 if(*p == '.')
28 p++;
29 addr[i] = x;
30 }
32 switch(CLASS(addr)){
33 case 0:
34 case 1:
35 if(i == 3){
36 addr[3] = addr[2];
37 addr[2] = addr[1];
38 addr[1] = 0;
39 }else if(i == 2){
40 addr[3] = addr[1];
41 addr[2] = 0;
42 addr[1] = 0;
43 }else if(i != 4)
44 return -1;
45 break;
46 case 2:
47 if(i == 3){
48 addr[3] = addr[2];
49 addr[2] = 0;
50 }else if(i != 4)
51 return -1;
52 break;
53 }
54 *pip = *(u32int*)addr;
55 return 0;
56 }
58 int
59 p9dialparse(char *addr, char **pnet, char **punix, u32int *phost, int *pport)
60 {
61 char *net, *host, *port, *e;
62 int i;
63 struct servent *se;
64 struct hostent *he;
65 struct sockaddr_un *sockun;
67 if(strncmp(addr, "/net/", 5) == 0)
68 addr += 5;
70 net = addr;
71 if((host = strchr(net, '!')) == nil){
72 werrstr("malformed address");
73 return -1;
74 }
75 *host++ = 0;
76 if((port = strchr(host, '!')) == nil){
77 if(strcmp(net, "unix")==0 || strcmp(net, "net")==0){
78 Unix:
79 if(strlen(host)+1 > sizeof sockun->sun_path){
80 werrstr("unix socket name too long");
81 return -1;
82 }
83 *punix = host;
84 *pnet = "unix";
85 *phost = 0;
86 *pport = 0;
87 return 0;
88 }
89 werrstr("malformed address");
90 return -1;
91 }
92 *port++ = 0;
94 if(*host == 0){
95 werrstr("malformed address (empty host)");
96 return -1;
97 }
98 if(*port == 0){
99 werrstr("malformed address (empty port)");
100 return -1;
103 if(strcmp(net, "unix") == 0)
104 goto Unix;
106 if(strcmp(net, "tcp")!=0 && strcmp(net, "udp")!=0){
107 werrstr("bad network %s!%s!%s", net, host, port);
108 return -1;
111 /* translate host */
112 if(strcmp(host, "*") == 0)
113 *phost = 0;
114 else if(parseip(host, phost) == 0)
115 {}
116 else if((he = gethostbyname(host)) != nil)
117 *phost = *(u32int*)(he->h_addr);
118 else{
119 werrstr("unknown host %s", host);
120 return -1;
123 /* translate network and port; should return list rather than first */
124 if(strcmp(net, "net") == 0){
125 for(i=0; nets[i]; i++){
126 if((se = getservbyname(port, nets[i])) != nil){
127 *pnet = nets[i];
128 *pport = ntohs(se->s_port);
129 return 0;
132 werrstr("unknown service %s", port);
133 return -1;
136 if(strcmp(net, "tcp") != 0 && strcmp(net, "udp") != 0){
137 werrstr("unknown network %s", net);
138 return -1;
141 *pnet = net;
142 i = strtol(port, &e, 0);
143 if(*e == 0){
144 *pport = i;
145 return 0;
148 if((se = getservbyname(port, net)) != nil){
149 *pport = ntohs(se->s_port);
150 return 0;
152 werrstr("unknown service %s", port);
153 return -1;