tgetnetconn.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tgetnetconn.c (3240B) | |
--- | |
1 #include <u.h> | |
2 #define NOPLAN9DEFINES | |
3 #include <libc.h> | |
4 | |
5 #include <sys/socket.h> | |
6 #include <netinet/in.h> | |
7 #include <netinet/tcp.h> | |
8 #include <arpa/inet.h> | |
9 #include <sys/un.h> | |
10 #include <errno.h> | |
11 | |
12 #undef sun | |
13 #define sun sockun | |
14 | |
15 extern int _p9netfd(char*); | |
16 | |
17 static char *unknown = "unknown"; | |
18 | |
19 static int | |
20 convert(int s, struct sockaddr *sa, char **lsys, char **lserv, char **la… | |
21 { | |
22 struct sockaddr_un *sun; | |
23 struct sockaddr_in *sin; | |
24 struct sockaddr_in6 *sin6; | |
25 uchar *ip; | |
26 u32int ipl; | |
27 socklen_t sn; | |
28 int n; | |
29 char *net; | |
30 | |
31 switch(sa->sa_family){ | |
32 case AF_INET: | |
33 sin = (void*)sa; | |
34 ip = (uchar*)&sin->sin_addr; | |
35 ipl = *(u32int*)ip; | |
36 if(ipl == 0) | |
37 *lsys = strdup("*"); | |
38 else | |
39 *lsys = smprint("%d.%d.%d.%d", ip[0], ip[1], ip[… | |
40 *lserv = smprint("%d", ntohs(sin->sin_port)); | |
41 sn = sizeof n; | |
42 if(getsockopt(s, SOL_SOCKET, SO_TYPE, (void*)&n, &sn) < … | |
43 return -1; | |
44 if(n == SOCK_STREAM) | |
45 net = "tcp"; | |
46 else if(n == SOCK_DGRAM) | |
47 net = "udp"; | |
48 else{ | |
49 werrstr("unknown network type"); | |
50 return -1; | |
51 } | |
52 *laddr = smprint("%s!%s!%s", net, *lsys, *lserv); | |
53 if(*lsys == nil || *lserv == nil || *laddr == nil) | |
54 return -1; | |
55 return 0; | |
56 case AF_INET6: | |
57 sin6 = (void*)sa; | |
58 if (memcmp(&sin6->sin6_addr, &in6addr_any, sizeof(in6add… | |
59 *lsys = strdup("*"); | |
60 else{ | |
61 *lsys = malloc(INET6_ADDRSTRLEN); | |
62 inet_ntop(AF_INET6, &sin6->sin6_addr, *lsys, INE… | |
63 } | |
64 *lserv = smprint("%d", ntohs(sin6->sin6_port)); | |
65 sn = sizeof n; | |
66 if(getsockopt(s, SOL_SOCKET, SO_TYPE, (void*)&n, &sn) < … | |
67 return -1; | |
68 if(n == SOCK_STREAM) | |
69 net = "tcp"; | |
70 else if(n == SOCK_DGRAM) | |
71 net = "udp"; | |
72 else{ | |
73 werrstr("unknown network type"); | |
74 return -1; | |
75 } | |
76 *laddr = smprint("%s!%s!%s", net, *lsys, *lserv); | |
77 if(*lsys == nil || *lserv == nil || *laddr == nil) | |
78 return -1; | |
79 return 0; | |
80 case AF_UNIX: | |
81 sun = (void*)sa; | |
82 *lsys = unknown; | |
83 *lserv = unknown; | |
84 *laddr = smprint("unix!%s", sun->sun_path); | |
85 if(*laddr == nil) | |
86 return -1; | |
87 return 0; | |
88 default: | |
89 werrstr("unknown socket family"); | |
90 return -1; | |
91 } | |
92 } | |
93 | |
94 NetConnInfo* | |
95 getnetconninfo(char *dir, int fd) | |
96 { | |
97 socklen_t sn; | |
98 union { | |
99 struct sockaddr sa; | |
100 struct sockaddr_in sin; | |
101 struct sockaddr_in6 sin6; | |
102 struct sockaddr_un sun; | |
103 } u; | |
104 NetConnInfo *nci; | |
105 | |
106 if(dir){ | |
107 if((fd = _p9netfd(dir)) < 0){ | |
108 werrstr("no such network connection %s", dir); | |
109 return nil; | |
110 } | |
111 } | |
112 | |
113 nci = mallocz(sizeof *nci, 1); | |
114 if(nci == nil) | |
115 goto err; | |
116 nci->dir = smprint("/dev/fd/%d", fd); | |
117 nci->root = strdup("/net"); | |
118 nci->spec = unknown; | |
119 if(nci->dir == nil || nci->root == nil) | |
120 goto err; | |
121 sn = sizeof u; | |
122 if(getsockname(fd, &u.sa, &sn) < 0) | |
123 goto err; | |
124 if(convert(fd, &u.sa, &nci->lsys, &nci->lserv, &nci->laddr) < 0) | |
125 goto err; | |
126 sn = sizeof u; | |
127 if(getpeername(fd, &u.sa, &sn) < 0) | |
128 goto err; | |
129 if(convert(fd, &u.sa, &nci->rsys, &nci->rserv, &nci->raddr) < 0) | |
130 goto err; | |
131 return nci; | |
132 | |
133 err: | |
134 freenetconninfo(nci); | |
135 return nil; | |
136 } | |
137 | |
138 static void | |
139 xfree(void *v) | |
140 { | |
141 if(v != nil && v != unknown) | |
142 free(v); | |
143 } | |
144 | |
145 void | |
146 freenetconninfo(NetConnInfo *nci) | |
147 { | |
148 if(nci == nil) | |
149 return; | |
150 xfree(nci->dir); | |
151 xfree(nci->root); | |
152 xfree(nci->spec); | |
153 xfree(nci->lsys); | |
154 xfree(nci->lserv); | |
155 xfree(nci->rsys); | |
156 xfree(nci->rserv); | |
157 xfree(nci->laddr); | |
158 xfree(nci->raddr); | |
159 free(nci); | |
160 } |