vmm: refactor userspace's emsr_fakewrite()
[akaros.git] / tests / netstat.c
1 /* 
2  * This file is part of the UCB release of Plan 9. It is subject to the license
3  * terms in the LICENSE file found in the top-level directory of this
4  * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
5  * part of the UCB release of Plan 9, including this file, may be copied,
6  * modified, propagated, or distributed except according to the terms contained
7  * in the LICENSE file.
8  */
9 #include <sys/types.h>
10
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <parlib/parlib.h>
16 #include <unistd.h>
17 #include <signal.h>
18 #include <iplib/iplib.h>
19 #include <dirent.h>
20
21 enum {
22         maxproto = 20,
23 };
24 void pip(char *, struct dirent *);
25 void nstat(char *, void (*)(char *, struct dirent *));
26 void pipifc(void);
27
28 FILE *out;
29 char *netroot;
30 char *proto[maxproto];
31 int nproto;
32 int notrans;
33
34 void usage(char *argv0)
35 {
36         fprintf(stderr, "usage: %s [-in] [-p proto] [network-dir]\n", argv0);
37         fprintf(stderr, "usage");
38         exit(1);
39 }
40
41 void main(int argc, char *argv[])
42 {
43         int justinterfaces = 0;
44         int i, tot, fd;
45         DIR *dir;
46         struct dirent *d;
47         char buf[128];
48         out = stdout;
49         argc--, argv++;
50         while (argc > 0 && *argv[0] == '-') {
51                 switch (argv[0][1]) {
52                 case 'i':
53                         justinterfaces = 1;
54                         break;
55                 case 'n':
56                         notrans = 1;
57                         break;
58                 case 'p':
59                         if (nproto >= maxproto){
60                                 fprintf(stderr, "too many protos");
61                                 exit(1);
62                         }
63                         if (argc < 2)
64                                 usage("netstat");
65                         argc--, argv++;
66                         proto[nproto++] = argv[0];
67                         break;
68                 default:
69                         usage("netstat");
70                 }
71                 argc--, argv++;
72         }
73
74         netroot = "/net";
75         switch (argc) {
76         case 0:
77                 break;
78         case 1:
79                 netroot = argv[0];
80                 break;
81         default:
82                 usage("netstat");
83         }
84
85         if (justinterfaces) {
86                 pipifc();
87                 exit(0);
88         }
89
90         if (nproto) {
91                 for (i = 0; i < nproto; i++)
92                         nstat(proto[i], pip);
93         } else {
94                 dir = opendir(netroot);
95                 if (!dir) {
96                         fprintf(stderr, "open %s: %r", netroot);
97                         exit(1);
98                 }
99
100                 while ((d = readdir(dir))) {
101                         if (strcmp(d->d_name, "ipifc") == 0)
102                                 continue;
103                         snprintf(buf, sizeof buf, "%s/%s/0/local", netroot,
104                                  d->d_name);
105                         /* access is bogus for now. */
106                         if (1 || access(buf, 0) >= 0)
107                                 nstat(d->d_name, pip);
108                         else
109                                 fprintf(stderr, "Can't access %s\n", d->d_name);
110                 }
111         }
112
113         exit(0);
114 }
115
116 void nstat(char *net, void (*f) (char *, struct dirent *))
117 {
118         int fdir, i, tot;
119         struct dirent *d;
120         DIR *dir;
121         char buf[128];
122
123         snprintf(buf, sizeof buf, "%s/%s", netroot, net);
124         dir = opendir(buf);
125         if (!dir)
126                 return;
127
128         while ((d = readdir(dir))) {
129                 (*f) (net, d);
130         }
131         /* leak dir */
132 }
133
134 char *getport(char *net, char *p)
135 {
136         static char port[10];
137
138         strncpy(port, p, sizeof(port) - 1);
139         port[sizeof(port) - 1] = 0;
140         //if(notrans || (p = csgetvalue(netroot, "port", p, net, nil)) == nil)
141         if (1)
142                 return port;
143         strncpy(port, p, sizeof(port) - 1);
144         port[sizeof(port) - 1] = 0;
145         free(p);
146         return port;
147 }
148
149 void pip(char *net, struct dirent *db)
150 {
151         int n, fd;
152         char buf[128], *p;
153         char *dname;
154
155         if (strcmp(db->d_name, "clone") == 0)
156                 return;
157         if (strcmp(db->d_name, "stats") == 0)
158                 return;
159
160         snprintf(buf, sizeof buf, "%s/%s/%s/status", netroot, net, db->d_name);
161         fd = open(buf, O_RDONLY);
162         if (fd < 0)
163                 return;
164         n = read(fd, buf, sizeof(buf));
165         close(fd);
166         if (n < 0)
167                 return;
168         buf[n] = 0;
169
170         p = strchr(buf, ' ');
171         if (p != 0)
172                 *p = 0;
173         p = strrchr(buf, '\n');
174         if (p != 0)
175                 *p = 0;
176         fprintf(out, "%-4s %-4s %-12s ", net, db->d_name, /*db->uid, */ buf);
177
178         snprintf(buf, sizeof buf, "%s/%s/%s/local", netroot, net, db->d_name);
179         fd = open(buf, O_RDONLY);
180         if (fd < 0) {
181                 fprintf(out, "\n");
182                 return;
183         }
184         n = read(fd, buf, sizeof(buf));
185         close(fd);
186         if (n < 0) {
187                 fprintf(out, "\n");
188                 return;
189         }
190         buf[n - 1] = 0;
191         p = strchr(buf, '!');
192         if (p == 0) {
193                 fprintf(out, "\n");
194                 return;
195         }
196         *p = '\0';
197         fprintf(out, "%-10s ", getport(net, p + 1));
198
199         snprintf(buf, sizeof buf, "%s/%s/%s/remote", netroot, net, db->d_name);
200         fd = open(buf, O_RDONLY);
201         if (fd < 0) {
202                 printf("\n");
203                 return;
204         }
205         n = read(fd, buf, sizeof(buf));
206         close(fd);
207         if (n < 0) {
208                 printf("\n");
209                 return;
210         }
211         buf[n - 1] = 0;
212         p = strchr(buf, '!');
213         if (p != NULL)
214                 *p++ = '\0';
215
216         if (notrans) {
217                 fprintf(out, "%-10s %s\n", getport(net, p), buf);
218                 return;
219         }
220         dname = NULL;   //csgetvalue(netroot, "ip", buf, "dom", nil);
221         if (dname == NULL) {
222                 fprintf(out, "%-10s %s\n", getport(net, p), buf);
223                 return;
224         }
225         fprintf(out, "%-10s %s\n", getport(net, p), dname);
226         free(dname);
227 }
228
229 void pipifc(void)
230 {
231         struct ipifc *ip, *nip;
232         struct iplifc *lifc;
233         char buf[100];
234         int l, i;
235
236 //  fmtinstall('I', eipfmt);
237 //  fmtinstall('M', eipfmt);
238
239         ip = readipifc(netroot, NULL, -1);
240
241         l = 7;
242         for (nip = ip; nip; nip = nip->next) {
243                 for (lifc = nip->lifc; lifc; lifc = lifc->next) {
244                         i = snprintf(buf, sizeof buf, "%I", lifc->ip);
245                         if (i > l)
246                                 l = i;
247                         i = snprintf(buf, sizeof buf, "%I", lifc->net);
248                         if (i > l)
249                                 l = i;
250                 }
251         }
252
253         for (nip = ip; nip; nip = nip->next) {
254                 for (lifc = nip->lifc; lifc; lifc = lifc->next)
255                         fprintf(out, "%-12s %5d %-*I %5M %-*I %8lud %8lud %8lud %8lud\n",
256                                 nip->dev, nip->mtu,
257                                 l, lifc->ip, lifc->mask, l, lifc->net,
258                                 nip->pktin, nip->pktout, nip->errin,
259                                 nip->errout);
260         }
261 }