akaros/tests/netstat.c
<<
>>
Prefs
   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
  21enum {
  22        maxproto = 20,
  23};
  24void pip(char *, struct dirent *);
  25void nstat(char *, void (*)(char *, struct dirent *));
  26void pipifc(void);
  27
  28FILE *out;
  29char *netroot;
  30char *proto[maxproto];
  31int nproto;
  32int notrans;
  33
  34void 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
  41void 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
 116void 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
 134char *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
 149void 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
 229void 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}
 262