#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ip.h>
#include <ndb.h>
void pip(char*, Dir*);
void nstat(char*, void (*)(char*, Dir*));
void pipifc(void);
Biobuf out;
char *netroot;
int notrans;
void
usage(void){
fprint(2, "usage: %s [-in] [network-dir]\n", argv0);
exits("usage");
}
void
main(int argc, char *argv[])
{
int justinterfaces = 0;
ARGBEGIN{
case 'n':
notrans = 1;
break;
case 'i':
justinterfaces = 1;
break;
default:
usage();
}ARGEND;
netroot = "/net";
switch(argc){
case 0:
break;
case 1:
netroot = argv[0];
break;
default:
usage();
}
Binit(&out, 1, OWRITE);
if(justinterfaces){
pipifc();
exits(0);
}
nstat("tcp", pip);
nstat("udp", pip);
nstat("rudp", pip);
nstat("il", pip);
exits(0);
}
void
nstat(char *net, void (*f)(char*, Dir*))
{
int fdir, i, tot;
Dir *dir;
char buf[128];
snprint(buf, sizeof buf, "%s/%s", netroot, net);
fdir = open(buf, OREAD);
if(fdir < 0)
return;
tot = dirreadall(fdir, &dir);
for(i = 0; i < tot; i++) {
(*f)(net, &dir[i]);
Bflush(&out);
}
free(dir);
close(fdir);
}
char*
getport(char *net, char *p)
{
static char buf[Ndbvlen];
Ndbtuple *t;
if(notrans)
return p;
t = csgetval(netroot, "port", p, net, buf);
if(t)
ndbfree(t);
if(buf[0] == 0)
return p;
return buf;
}
void
pip(char *net, Dir *db)
{
int n, fd;
char buf[128], *p;
Ndbtuple *tp;
char dname[Ndbvlen];
if(strcmp(db->name, "clone") == 0)
return;
if(strcmp(db->name, "stats") == 0)
return;
snprint(buf, sizeof buf, "%s/%s/%s/ctl", netroot, net, db->name);
sprint(buf, "%s/%s/%s/status", netroot, net, db->name);
fd = open(buf, OREAD);
if(fd < 0)
return;
n = read(fd, buf, sizeof(buf));
if(n < 0)
return;
buf[n] = 0;
close(fd);
p = strchr(buf, ' ');
if(p != 0)
*p = 0;
Bprint(&out, "%-4s %-4s %-10s %-12s ", net, db->name, db->uid, buf);
sprint(buf, "%s/%s/%s/local", netroot, net, db->name);
fd = open(buf, OREAD);
if(fd < 0) {
Bprint(&out, "\n");
return;
}
n = read(fd, buf, sizeof(buf));
if(n < 0) {
Bprint(&out, "\n");
return;
}
buf[n-1] = 0;
close(fd);
p = strchr(buf, '!');
if(p == 0) {
Bprint(&out, "\n");
return;
}
*p = '\0';
Bprint(&out, "%-10s ", getport(net, p+1));
sprint(buf, "%s/%s/%s/remote", netroot, net, db->name);
fd = open(buf, OREAD);
if(fd < 0) {
print("\n");
return;
}
n = read(fd, buf, sizeof(buf));
if(n < 0) {
print("\n");
return;
}
buf[n-1] = 0;
close(fd);
p = strchr(buf, '!');
*p++ = '\0';
if(notrans){
Bprint(&out, "%-10s %s\n", getport(net, p), buf);
return;
}
tp = csgetval(netroot, "ip", buf, "dom", dname);
if(tp)
ndbfree(tp);
if(dname[0] == 0) {
Bprint(&out, "%-10s %s\n", getport(net, p), buf);
return;
}
Bprint(&out, "%-10s %s\n", getport(net, p), dname);
Bflush(&out);
}
void
pipifc(void)
{
Ipifc *ip, *nip;
Iplifc *lifc;
char buf[100];
int l, i;
fmtinstall('I', eipfmt);
fmtinstall('M', eipfmt);
ip = readipifc(netroot, nil, -1);
l = 7;
for(nip = ip; nip; nip = nip->next){
for(lifc = nip->lifc; lifc; lifc = lifc->next){
i = snprint(buf, sizeof buf, "%I", lifc->ip);
if(i > l)
l = i;
i = snprint(buf, sizeof buf, "%I", lifc->net);
if(i > l)
l = i;
}
}
for(nip = ip; nip; nip = nip->next){
for(lifc = nip->lifc; lifc; lifc = lifc->next)
Bprint(&out, "%-12s %5d %-*I %5.5M %-*I %8lud %8lud %8lud %8lud\n",
nip->dev, nip->mtu,
l, lifc->ip, lifc->mask, l, lifc->net,
nip->pktin, nip->pktout,
nip->errin, nip->errout);
}
Bflush(&out);
}