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 struct {
14 char *net;
15 char *service;
16 int port;
17 } porttbl[] = {
18 "tcp", "9fs", 564,
19 "tcp", "whoami", 565,
20 "tcp", "guard", 566,
21 "tcp", "ticket", 567,
22 "tcp", "exportfs", 17007,
23 "tcp", "rexexec", 17009,
24 "tcp", "ncpu", 17010,
25 "tcp", "cpu", 17013,
26 "tcp", "venti", 17034,
27 "tcp", "wiki", 17035,
28 "tcp", "secstore", 5356,
29 "udp", "dns", 53,
30 "tcp", "dns", 53,
31 };
33 static int
34 parseip(char *host, u32int *pip)
35 {
36 uchar addr[4];
37 int x, i;
38 char *p;
40 p = host;
41 for(i=0; i<4 && *p; i++){
42 x = strtoul(p, &p, 0);
43 if(x < 0 || x >= 256)
44 return -1;
45 if(*p != '.' && *p != 0)
46 return -1;
47 if(*p == '.')
48 p++;
49 addr[i] = x;
50 }
52 switch(CLASS(addr)){
53 case 0:
54 case 1:
55 if(i == 3){
56 addr[3] = addr[2];
57 addr[2] = addr[1];
58 addr[1] = 0;
59 }else if(i == 2){
60 addr[3] = addr[1];
61 addr[2] = 0;
62 addr[1] = 0;
63 }else if(i != 4)
64 return -1;
65 break;
66 case 2:
67 if(i == 3){
68 addr[3] = addr[2];
69 addr[2] = 0;
70 }else if(i != 4)
71 return -1;
72 break;
73 }
74 *pip = *(u32int*)addr;
75 return 0;
76 }
78 int
79 p9dialparse(char *addr, char **pnet, char **punix, u32int *phost, int *pport)
80 {
81 char *net, *host, *port, *e;
82 int i;
83 struct servent *se;
84 struct hostent *he;
85 struct sockaddr_un *sockun;
87 if(strncmp(addr, "/net/", 5) == 0)
88 addr += 5;
90 *punix = nil;
91 net = addr;
92 if((host = strchr(net, '!')) == nil){
93 werrstr("malformed address");
94 return -1;
95 }
96 *host++ = 0;
97 if((port = strchr(host, '!')) == nil){
98 if(strcmp(net, "unix")==0 || strcmp(net, "net")==0){
99 Unix:
100 if(strlen(host)+1 > sizeof sockun->sun_path){
101 werrstr("unix socket name too long");
102 return -1;
104 *punix = host;
105 *pnet = "unix";
106 *phost = 0;
107 *pport = 0;
108 return 0;
110 werrstr("malformed address");
111 return -1;
113 *port++ = 0;
115 if(*host == 0){
116 werrstr("malformed address (empty host)");
117 return -1;
119 if(*port == 0){
120 werrstr("malformed address (empty port)");
121 return -1;
124 if(strcmp(net, "unix") == 0)
125 goto Unix;
127 if(strcmp(net, "tcp")!=0 && strcmp(net, "udp")!=0 && strcmp(net, "net") != 0){
128 werrstr("bad network %s!%s!%s", net, host, port);
129 return -1;
132 /* translate host */
133 if(strcmp(host, "*") == 0)
134 *phost = 0;
135 else if(parseip(host, phost) == 0)
136 {}
137 else if((he = gethostbyname(host)) != nil)
138 *phost = *(u32int*)(he->h_addr);
139 else{
140 werrstr("unknown host %s", host);
141 return -1;
144 /* translate network and port; should return list rather than first */
145 if(strcmp(net, "net") == 0){
146 for(i=0; nets[i]; i++){
147 if((se = getservbyname(port, nets[i])) != nil){
148 *pnet = nets[i];
149 *pport = ntohs(se->s_port);
150 return 0;
155 for(i=0; i<nelem(porttbl); i++){
156 if(strcmp(net, "net") == 0 || strcmp(porttbl[i].net, net) == 0)
157 if(strcmp(porttbl[i].service, port) == 0){
158 *pnet = porttbl[i].net;
159 *pport = porttbl[i].port;
160 return 0;
164 if(strcmp(net, "net") == 0){
165 werrstr("unknown service net!*!%s", port);
166 return -1;
169 if(strcmp(net, "tcp") != 0 && strcmp(net, "udp") != 0){
170 werrstr("unknown network %s", net);
171 return -1;
174 *pnet = net;
175 i = strtol(port, &e, 0);
176 if(*e == 0){
177 *pport = i;
178 return 0;
181 if((se = getservbyname(port, net)) != nil){
182 *pport = ntohs(se->s_port);
183 return 0;
185 werrstr("unknown service %s!*!%s", net, port);
186 return -1;