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