Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#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;
char *proto[20];
int nproto;
int     notrans;

void
usage(void)
{
        fprint(2, "usage: %s [-in] [-p proto] [network-dir]\n", argv0);
        exits("usage");
}

void
main(int argc, char *argv[])
{
        int justinterfaces = 0;
        int i, tot, fd;
        Dir *d;
        char buf[128];

        ARGBEGIN{
        case 'i':
                justinterfaces = 1;
                break;
        case 'n':
                notrans = 1;
                break;
        case 'p':
                if(nproto >= nelem(proto))
                        sysfatal("too many protos");
                proto[nproto++] = EARGF(usage());
                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);
        }

        if(nproto){
                for(i=0; i<nproto; i++)
                        nstat(proto[i], pip);
        }else{
                fd = open(netroot, OREAD);
                if(fd < 0)
                        sysfatal("open %s: %r", netroot);

                tot = dirreadall(fd, &d);
                for(i=0; i<tot; i++){
                        if(strcmp(d[i].name, "ipifc") == 0)
                                continue;
                        snprint(buf, sizeof buf, "%s/%s/0/local", netroot, d[i].name);
                        if(access(buf, 0) >= 0)
                                nstat(d[i].name, 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 port[10];

        strncpy(port, p, sizeof(port)-1);
        port[sizeof(port)-1] = 0;
        if(notrans || (p = csgetvalue(netroot, "port", p, net, nil)) == nil)
                return port;
        strncpy(port, p, sizeof(port)-1);
        port[sizeof(port)-1] = 0;
        free(p);
        return port;
}

void
pip(char *net, Dir *db)
{
        int n, fd;
        char buf[128], *p;
        char *dname;

        if(strcmp(db->name, "clone") == 0)
                return;
        if(strcmp(db->name, "stats") == 0)
                return;

        snprint(buf, sizeof buf, "%s/%s/%s/status", netroot, net, db->name);
        fd = open(buf, OREAD);
        if(fd < 0)
                return;
        n = read(fd, buf, sizeof(buf));
        close(fd);
        if(n < 0)
                return;
        buf[n] = 0;

        p = strchr(buf, ' ');
        if(p != 0)
                *p = 0;
        p = strrchr(buf, '\n');
        if(p != 0)
                *p = 0;
        Bprint(&out, "%-4s %-4s %-10s %-12s ", net, db->name, db->uid, buf);

        snprint(buf, sizeof 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));
        close(fd);
        if(n < 0) {
                Bprint(&out, "\n");
                return;
        }
        buf[n-1] = 0;
        p = strchr(buf, '!');
        if(p == 0) {
                Bprint(&out, "\n");
                return;
        }
        *p = '\0';
        Bprint(&out, "%-10s ", getport(net, p+1));

        snprint(buf, sizeof 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));
        close(fd);
        if(n < 0) {
                print("\n");
                return;
        }
        buf[n-1] = 0;
        p = strchr(buf, '!');
        if(p != nil)
                *p++ = '\0';

        if(notrans){
                Bprint(&out, "%-10s %s\n", getport(net, p), buf);
                return;
        }
        dname = csgetvalue(netroot, "ip", buf, "dom", nil);
        if(dname == nil) {
                Bprint(&out, "%-10s %s\n", getport(net, p), buf);
                return;
        }
        Bprint(&out, "%-10s %s\n", getport(net, p), dname);
        Bflush(&out);
        free(dname);
}

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 %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);
}