xref: /plan9/sys/src/cmd/netstat.c (revision d9306527b4a7229dcf0cf3c58aed36bb9da82854)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
43e12c5d1SDavid du Colombier #include <ip.h>
53e12c5d1SDavid du Colombier #include <ndb.h>
63e12c5d1SDavid du Colombier 
79a747e4fSDavid du Colombier void	pip(char*, Dir*);
89a747e4fSDavid du Colombier void	nstat(char*, void (*)(char*, Dir*));
99a747e4fSDavid du Colombier void	pipifc(void);
103e12c5d1SDavid du Colombier 
113e12c5d1SDavid du Colombier Biobuf	out;
127dd7cddfSDavid du Colombier char	*netroot;
137dd7cddfSDavid du Colombier int	notrans;
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier void
167dd7cddfSDavid du Colombier usage(void){
177dd7cddfSDavid du Colombier 	fprint(2, "usage: %s [-in] [network-dir]\n", argv0);
187dd7cddfSDavid du Colombier 	exits("usage");
197dd7cddfSDavid du Colombier }
207dd7cddfSDavid du Colombier 
217dd7cddfSDavid du Colombier void
227dd7cddfSDavid du Colombier main(int argc, char *argv[])
233e12c5d1SDavid du Colombier {
247dd7cddfSDavid du Colombier 	int justinterfaces = 0;
25*d9306527SDavid du Colombier 	int i, tot, fd;
26*d9306527SDavid du Colombier 	Dir *d;
27*d9306527SDavid du Colombier 	char buf[128];
287dd7cddfSDavid du Colombier 
297dd7cddfSDavid du Colombier 	ARGBEGIN{
307dd7cddfSDavid du Colombier 	case 'n':
317dd7cddfSDavid du Colombier 		notrans = 1;
327dd7cddfSDavid du Colombier 		break;
337dd7cddfSDavid du Colombier 	case 'i':
347dd7cddfSDavid du Colombier 		justinterfaces = 1;
357dd7cddfSDavid du Colombier 		break;
367dd7cddfSDavid du Colombier 	default:
377dd7cddfSDavid du Colombier 		usage();
387dd7cddfSDavid du Colombier 	}ARGEND;
397dd7cddfSDavid du Colombier 
407dd7cddfSDavid du Colombier 	netroot = "/net";
417dd7cddfSDavid du Colombier 	switch(argc){
427dd7cddfSDavid du Colombier 	case 0:
437dd7cddfSDavid du Colombier 		break;
447dd7cddfSDavid du Colombier 	case 1:
457dd7cddfSDavid du Colombier 		netroot = argv[0];
467dd7cddfSDavid du Colombier 		break;
477dd7cddfSDavid du Colombier 	default:
487dd7cddfSDavid du Colombier 		usage();
497dd7cddfSDavid du Colombier 	}
503e12c5d1SDavid du Colombier 
513e12c5d1SDavid du Colombier 	Binit(&out, 1, OWRITE);
523e12c5d1SDavid du Colombier 
537dd7cddfSDavid du Colombier 	if(justinterfaces){
549a747e4fSDavid du Colombier 		pipifc();
557dd7cddfSDavid du Colombier 		exits(0);
567dd7cddfSDavid du Colombier 	}
577dd7cddfSDavid du Colombier 
58*d9306527SDavid du Colombier 	fd = open(netroot, OREAD);
59*d9306527SDavid du Colombier 	if(fd < 0)
60*d9306527SDavid du Colombier 		sysfatal("open %s: %r", netroot);
61*d9306527SDavid du Colombier 
62*d9306527SDavid du Colombier 	tot = dirreadall(fd, &d);
63*d9306527SDavid du Colombier 	for(i=0; i<tot; i++){
64*d9306527SDavid du Colombier 		if(strcmp(d[i].name, "ipifc") == 0)
65*d9306527SDavid du Colombier 			continue;
66*d9306527SDavid du Colombier 		snprint(buf, sizeof buf, "%s/%s/0/local", netroot, d[i].name);
67*d9306527SDavid du Colombier 		if(access(buf, 0) >= 0)
68*d9306527SDavid du Colombier 			nstat(d[i].name, pip);
69*d9306527SDavid du Colombier 	}
707dd7cddfSDavid du Colombier 
713e12c5d1SDavid du Colombier 	exits(0);
723e12c5d1SDavid du Colombier }
733e12c5d1SDavid du Colombier 
743e12c5d1SDavid du Colombier void
759a747e4fSDavid du Colombier nstat(char *net, void (*f)(char*, Dir*))
763e12c5d1SDavid du Colombier {
779a747e4fSDavid du Colombier 	int fdir, i, tot;
789a747e4fSDavid du Colombier 	Dir *dir;
799a747e4fSDavid du Colombier 	char buf[128];
803e12c5d1SDavid du Colombier 
819a747e4fSDavid du Colombier 	snprint(buf, sizeof buf, "%s/%s", netroot, net);
829a747e4fSDavid du Colombier 	fdir = open(buf, OREAD);
833e12c5d1SDavid du Colombier 	if(fdir < 0)
843e12c5d1SDavid du Colombier 		return;
853e12c5d1SDavid du Colombier 
869a747e4fSDavid du Colombier 	tot = dirreadall(fdir, &dir);
879a747e4fSDavid du Colombier 	for(i = 0; i < tot; i++) {
889a747e4fSDavid du Colombier 		(*f)(net, &dir[i]);
893e12c5d1SDavid du Colombier 		Bflush(&out);
903e12c5d1SDavid du Colombier 	}
919a747e4fSDavid du Colombier 	free(dir);
923e12c5d1SDavid du Colombier 	close(fdir);
933e12c5d1SDavid du Colombier }
943e12c5d1SDavid du Colombier 
953e12c5d1SDavid du Colombier char*
963e12c5d1SDavid du Colombier getport(char *net, char *p)
973e12c5d1SDavid du Colombier {
987dd7cddfSDavid du Colombier 	static char buf[Ndbvlen];
997dd7cddfSDavid du Colombier 	Ndbtuple *t;
1003e12c5d1SDavid du Colombier 
1017dd7cddfSDavid du Colombier 	if(notrans)
1023e12c5d1SDavid du Colombier 		return p;
1037dd7cddfSDavid du Colombier 	t = csgetval(netroot, "port", p, net, buf);
1047dd7cddfSDavid du Colombier 	if(t)
1057dd7cddfSDavid du Colombier 		ndbfree(t);
1067dd7cddfSDavid du Colombier 	if(buf[0] == 0)
1077dd7cddfSDavid du Colombier 		return p;
1087dd7cddfSDavid du Colombier 	return buf;
1093e12c5d1SDavid du Colombier }
1103e12c5d1SDavid du Colombier 
1113e12c5d1SDavid du Colombier void
1129a747e4fSDavid du Colombier pip(char *net, Dir *db)
1133e12c5d1SDavid du Colombier {
1143e12c5d1SDavid du Colombier 	int n, fd;
1157dd7cddfSDavid du Colombier 	char buf[128], *p;
1167dd7cddfSDavid du Colombier 	Ndbtuple *tp;
1177dd7cddfSDavid du Colombier 	char dname[Ndbvlen];
1183e12c5d1SDavid du Colombier 
1199a747e4fSDavid du Colombier 	if(strcmp(db->name, "clone") == 0)
1203e12c5d1SDavid du Colombier 		return;
1219a747e4fSDavid du Colombier 	if(strcmp(db->name, "stats") == 0)
1227dd7cddfSDavid du Colombier 		return;
1233e12c5d1SDavid du Colombier 
1249a747e4fSDavid du Colombier 	snprint(buf, sizeof buf, "%s/%s/%s/ctl", netroot, net, db->name);
1253e12c5d1SDavid du Colombier 
1269a747e4fSDavid du Colombier 	sprint(buf, "%s/%s/%s/status", netroot, net, db->name);
1273e12c5d1SDavid du Colombier 	fd = open(buf, OREAD);
1283e12c5d1SDavid du Colombier 	if(fd < 0)
1293e12c5d1SDavid du Colombier 		return;
1307dd7cddfSDavid du Colombier 
1313e12c5d1SDavid du Colombier 	n = read(fd, buf, sizeof(buf));
1323e12c5d1SDavid du Colombier 	if(n < 0)
1333e12c5d1SDavid du Colombier 		return;
1343e12c5d1SDavid du Colombier 	buf[n] = 0;
1353e12c5d1SDavid du Colombier 	close(fd);
1363e12c5d1SDavid du Colombier 
1373e12c5d1SDavid du Colombier 	p = strchr(buf, ' ');
1387dd7cddfSDavid du Colombier 	if(p != 0)
1397dd7cddfSDavid du Colombier 		*p = 0;
1403e12c5d1SDavid du Colombier 
1419a747e4fSDavid du Colombier 	Bprint(&out, "%-4s %-4s %-10s %-12s ", net, db->name, db->uid, buf);
1427dd7cddfSDavid du Colombier 
1439a747e4fSDavid du Colombier 	sprint(buf, "%s/%s/%s/local", netroot, net, db->name);
1443e12c5d1SDavid du Colombier 	fd = open(buf, OREAD);
1453e12c5d1SDavid du Colombier 	if(fd < 0) {
1463e12c5d1SDavid du Colombier 		Bprint(&out, "\n");
1473e12c5d1SDavid du Colombier 		return;
1483e12c5d1SDavid du Colombier 	}
1493e12c5d1SDavid du Colombier 	n = read(fd, buf, sizeof(buf));
1503e12c5d1SDavid du Colombier 	if(n < 0) {
1513e12c5d1SDavid du Colombier 		Bprint(&out, "\n");
1523e12c5d1SDavid du Colombier 		return;
1533e12c5d1SDavid du Colombier 	}
1543e12c5d1SDavid du Colombier 	buf[n-1] = 0;
1553e12c5d1SDavid du Colombier 	close(fd);
1563e12c5d1SDavid du Colombier 	p = strchr(buf, '!');
1573e12c5d1SDavid du Colombier 	if(p == 0) {
1583e12c5d1SDavid du Colombier 		Bprint(&out, "\n");
1593e12c5d1SDavid du Colombier 		return;
1603e12c5d1SDavid du Colombier 	}
1613e12c5d1SDavid du Colombier 	*p = '\0';
1623e12c5d1SDavid du Colombier 	Bprint(&out, "%-10s ", getport(net, p+1));
1633e12c5d1SDavid du Colombier 
1649a747e4fSDavid du Colombier 	sprint(buf, "%s/%s/%s/remote", netroot, net, db->name);
1653e12c5d1SDavid du Colombier 	fd = open(buf, OREAD);
1663e12c5d1SDavid du Colombier 	if(fd < 0) {
1673e12c5d1SDavid du Colombier 		print("\n");
1683e12c5d1SDavid du Colombier 		return;
1693e12c5d1SDavid du Colombier 	}
1703e12c5d1SDavid du Colombier 	n = read(fd, buf, sizeof(buf));
1713e12c5d1SDavid du Colombier 	if(n < 0) {
1723e12c5d1SDavid du Colombier 		print("\n");
1733e12c5d1SDavid du Colombier 		return;
1743e12c5d1SDavid du Colombier 	}
1753e12c5d1SDavid du Colombier 	buf[n-1] = 0;
1763e12c5d1SDavid du Colombier 	close(fd);
1773e12c5d1SDavid du Colombier 	p = strchr(buf, '!');
1783e12c5d1SDavid du Colombier 	*p++ = '\0';
1793e12c5d1SDavid du Colombier 
1807dd7cddfSDavid du Colombier 	if(notrans){
1813e12c5d1SDavid du Colombier 		Bprint(&out, "%-10s %s\n", getport(net, p), buf);
1823e12c5d1SDavid du Colombier 		return;
1833e12c5d1SDavid du Colombier 	}
1847dd7cddfSDavid du Colombier 	tp = csgetval(netroot, "ip", buf, "dom", dname);
1857dd7cddfSDavid du Colombier 	if(tp)
1867dd7cddfSDavid du Colombier 		ndbfree(tp);
1877dd7cddfSDavid du Colombier 	if(dname[0] == 0) {
1887dd7cddfSDavid du Colombier 		Bprint(&out, "%-10s %s\n", getport(net, p), buf);
1897dd7cddfSDavid du Colombier 		return;
1907dd7cddfSDavid du Colombier 	}
1917dd7cddfSDavid du Colombier 	Bprint(&out, "%-10s %s\n", getport(net, p), dname);
1927dd7cddfSDavid du Colombier 	Bflush(&out);
1937dd7cddfSDavid du Colombier }
1947dd7cddfSDavid du Colombier 
1957dd7cddfSDavid du Colombier void
1969a747e4fSDavid du Colombier pipifc(void)
1977dd7cddfSDavid du Colombier {
1989a747e4fSDavid du Colombier 	Ipifc *ip, *nip;
1999a747e4fSDavid du Colombier 	Iplifc *lifc;
2009a747e4fSDavid du Colombier 	char buf[100];
2019a747e4fSDavid du Colombier 	int l, i;
2027dd7cddfSDavid du Colombier 
2039a747e4fSDavid du Colombier 	fmtinstall('I', eipfmt);
2049a747e4fSDavid du Colombier 	fmtinstall('M', eipfmt);
2057dd7cddfSDavid du Colombier 
2069a747e4fSDavid du Colombier 	ip = readipifc(netroot, nil, -1);
2077dd7cddfSDavid du Colombier 
2089a747e4fSDavid du Colombier 	l = 7;
2099a747e4fSDavid du Colombier 	for(nip = ip; nip; nip = nip->next){
2109a747e4fSDavid du Colombier 		for(lifc = nip->lifc; lifc; lifc = lifc->next){
2119a747e4fSDavid du Colombier 			i = snprint(buf, sizeof buf, "%I", lifc->ip);
2129a747e4fSDavid du Colombier 			if(i > l)
2139a747e4fSDavid du Colombier 				l = i;
2149a747e4fSDavid du Colombier 			i = snprint(buf, sizeof buf, "%I", lifc->net);
2159a747e4fSDavid du Colombier 			if(i > l)
2169a747e4fSDavid du Colombier 				l = i;
2179a747e4fSDavid du Colombier 		}
2189a747e4fSDavid du Colombier 	}
2197dd7cddfSDavid du Colombier 
2209a747e4fSDavid du Colombier 	for(nip = ip; nip; nip = nip->next){
2219a747e4fSDavid du Colombier 		for(lifc = nip->lifc; lifc; lifc = lifc->next)
2229a747e4fSDavid du Colombier 			Bprint(&out, "%-12s %5d %-*I %5.5M %-*I %8lud %8lud %8lud %8lud\n",
2239a747e4fSDavid du Colombier 				nip->dev, nip->mtu,
2249a747e4fSDavid du Colombier 				l, lifc->ip, lifc->mask, l, lifc->net,
2259a747e4fSDavid du Colombier 				nip->pktin, nip->pktout,
2269a747e4fSDavid du Colombier 				nip->errin, nip->errout);
2279a747e4fSDavid du Colombier 	}
2289a747e4fSDavid du Colombier 	Bflush(&out);
2293e12c5d1SDavid du Colombier }
230