Annotation of cci/usr/src/etc/nstat/main.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)main.c     4.9 83/05/30";
                      3: #endif
                      4: 
                      5: #include <sys/param.h>
                      6: #include <sys/vmmac.h>
                      7: #include <machine/pte.h>
                      8: #include <sys/socket.h>
                      9: #include <ctype.h>
                     10: #include <errno.h>
                     11: #include <netdb.h>
                     12: #include <nlist.h>
                     13: #include <stdio.h>
                     14: #include "nstat.h"
                     15: 
                     16: extern int protopr(), arptab(), enperrors(), enpbuf();
                     17: extern int tcp_stats(), udp_stats(), ip_stats(), icmp_stats();
                     18: extern int acestat(), enpstat();
                     19: 
                     20: struct protox {
                     21:        u_char  pr_wanted;              /* 1 if wanted, 0 otherwise */
                     22:        int     (*pr_cblocks)();        /* control blocks printing routine */
                     23:        int     (*pr_stats)();          /* statistics printing routine */
                     24:        char    *pr_name;               /* well-known name */
                     25: };
                     26: struct protox protox[] = {
                     27:        {       1,      protopr, tcp_stats,     "tcp" },
                     28: 
                     29:        {       1,      protopr, udp_stats,     "udp" },
                     30: 
                     31:        {       1,      0,      ip_stats,       "ip" },
                     32: 
                     33:        {       1,      0,      icmp_stats,     "icmp" },
                     34: 
                     35:        {       0,      0,      0,              0 }
                     36: };
                     37: 
                     38: 
                     39: struct devx {
                     40:        int     (*d_stats)();           /* device statistics printing func */
                     41:        char    *d_name;                /* well-known name */
                     42: };
                     43: struct devx devstat[] = {
                     44:        { acestat, "ace"},              
                     45:        { enpstat, "enp"},
                     46:        { 0 }
                     47: };
                     48: 
                     49: struct pte *Sysmap;
                     50: 
                     51: char   *system = "/vmunix";
                     52: char   *kmemf = "/dev/kmem";
                     53: int    kmem;                   /* file descriptor of kmemf */
                     54: 
                     55: 
                     56: int    interval;               /* looping interval */
                     57: char   *printproto;            /* protocol flag */
                     58: char   *devname;               /* device name */
                     59: 
                     60: #define        DELIM()         {printf("--------------------------------\n");}
                     61: 
                     62: long   flaggiven = 0x00000000;
                     63: int    s;              /* socket id */
                     64: 
                     65: main(argc, argv)
                     66:        int argc;
                     67:        char *argv[];
                     68: {
                     69:        int i;
                     70:        char *cp, *name;
                     71:        register struct protoent *p;
                     72:        register struct protox *tp;
                     73: 
                     74: 
                     75:        name = argv[0];
                     76:        argc--, argv++;
                     77:        while (argc > 0 && **argv == '-') {
                     78:           for (cp = &argv[0][1]; *cp; cp++)
                     79:                switch(*cp) {
                     80: 
                     81:                case 'A':
                     82:                        flaggiven |= AFLAG;
                     83:                        break;
                     84:                case 'E':
                     85:                        s = socket(AF_INET, SOCK_DGRAM, 0);
                     86:                        if (s < 0) {
                     87:                                perror("main: socket");
                     88:                                exit(1);
                     89:                        }
                     90:                        flaggiven |= EFLAG;
                     91:                        break;
                     92:                case 'e':
                     93:                        flaggiven |= eFLAG;
                     94:                        break;
                     95:                case 'b':
                     96:                        argv++, argc--;
                     97:                        if (argc <= 0)
                     98:                                goto use;
                     99:                        devname = *argv;
                    100:                        flaggiven |= bFLAG;
                    101:                        break;
                    102:                case 'a':
                    103:                        argv++, argc--;
                    104:                        if (argc <= 0)
                    105:                                goto use;
                    106:                        interval = atoi(argv[0]);
                    107:                        if (interval <= 0)
                    108:                                goto use;
                    109:                        break;
                    110: 
                    111:                case 'h':
                    112:                        flaggiven |= hFLAG;
                    113:                        break;
                    114: 
                    115:                case 'i':
                    116:                        flaggiven |= iFLAG;
                    117:                        break;
                    118: 
                    119:                case 'm':
                    120:                        flaggiven |= mFLAG;
                    121:                        break;
                    122: 
                    123:                case 'n':
                    124:                        flaggiven |= nFLAG;
                    125:                        break;
                    126: 
                    127:                case 'r':
                    128:                        flaggiven |= rFLAG;
                    129:                        break;
                    130: 
                    131:                case 's':
                    132:                        flaggiven |= sFLAG;
                    133:                        break;
                    134: 
                    135:                case 'c':
                    136:                        flaggiven |= cFLAG;
                    137:                        break;
                    138: 
                    139:                case 'p':
                    140:                        argv++, argc--; 
                    141:                        if (argc <= 0)
                    142:                                goto use;
                    143:                        printproto = *argv;
                    144:                        flaggiven |= pFLAG;
                    145:                        break;
                    146: 
                    147:                case 'd':
                    148:                        argv++, argc--;
                    149:                        if (argc <= 0)
                    150:                                goto use;
                    151:                        devname = *argv;
                    152:                        flaggiven |= dFLAG;
                    153:                        break;
                    154:                case 't':
                    155:                        flaggiven |= tFLAG;
                    156:                        break;
                    157: 
                    158:                case 'H':
                    159:                default:
                    160: use:
                    161:                        help();
                    162:                        exit(1);
                    163:                }       /* end of switch */
                    164:                argv++, argc--;
                    165:        }               /* end of while loop */
                    166:        /* will print pcb when: */
                    167:        if (!flaggiven ||               /* no option given at all */
                    168:              Aflag ||                  /* debug option */
                    169:             (flaggiven == nFLAG) ||    /* only numeric flag given */
                    170:             (flaggiven == pFLAG) ||    /* only protocol flag given */
                    171:             (flaggiven == (nFLAG | pFLAG)) ) {
                    172:                flaggiven |= cFLAG;
                    173:        }
                    174: 
                    175:        if (argc > 0) {
                    176:                system = *argv;
                    177:                argv++, argc--;
                    178:        }
                    179:        if (argc > 0) {
                    180:                kmemf = *argv;
                    181:                flaggiven |= kFLAG;
                    182:        }
                    183:        kmem = open(kmemf, 0);
                    184:        if (kmem < 0) {
                    185:                fprintf(stderr, "nstat: cannot open ");
                    186:                perror(kmemf);
                    187:                exit(1);
                    188:        }
                    189: 
                    190:        /*
                    191:         * Keep file descriptors open to avoid overhead
                    192:         * of open/close on each call to get* routines.
                    193:         */
                    194:        sethostent(1);
                    195:        setnetent(1);
                    196: 
                    197:        for (;;) {
                    198:          if (Eflag) {
                    199:                DELIM();
                    200:                arptab();
                    201:          }
                    202:          if (eflag) {
                    203:                enperrors();
                    204:          }
                    205:          if (iflag || tflag) {
                    206:                if (tflag && interval <= 0)
                    207:                        interval = 1;
                    208:                DELIM();
                    209:                intpr(interval);
                    210:          }
                    211:          if (kflag) {
                    212:                rkmem();
                    213:          }
                    214:          if (mflag) {
                    215:                DELIM();
                    216:                mbpr();
                    217:          }
                    218: 
                    219:          if (hflag) {
                    220:                DELIM();
                    221:                hostpr();
                    222:          }
                    223:          if (sflag) {
                    224:                DELIM();
                    225:                rt_stats();
                    226:          }
                    227:          if (rflag) {
                    228:                DELIM();
                    229:                routepr();
                    230:          }
                    231:          if (dflag || bflag) {
                    232:                struct  devx    *p;
                    233:                int     i, unit;
                    234:                char    *c;
                    235: 
                    236:                c = devname;
                    237:                while (*c && !isdigit(*c)) {
                    238:                        c++, i++;
                    239:                }
                    240:                if (*c)
                    241:                        unit = *c - '0';
                    242:                else
                    243:                        unit = WILDCARD;
                    244: 
                    245:                for (p = devstat; p->d_name; p++) {
                    246:                        if (strncmp(p->d_name, devname, i) == 0)
                    247:                                break;
                    248:                }
                    249:                if (p->d_name == 0)
                    250:                        fprintf(stderr, "nstat: illegal device %s\n",devname);
                    251:                else {
                    252:                        if (bflag) {
                    253:                                if (strncmp(p->d_name, "enp", 3) == 0)
                    254:                                        enpbuf(unit);
                    255:                                else  
                    256:                                        fprintf(stderr,
                    257:                                           "nstat: -b works for enp device only\n");
                    258:                         } else         
                    259:                                if (dflag && p->d_stats)  
                    260:                                        (*p->d_stats)(unit, 0);
                    261:                }
                    262:          }
                    263:          if (sflag) {
                    264:                  /* go through list of available protocols in system */
                    265:                  setprotoent(1);
                    266:                  setservent(1);
                    267:                  while (p = getprotoent()) {
                    268: 
                    269:                        /* user gave any specific protocol? */
                    270:                        if (pflag &&
                    271:                            strcmp(p->p_name, printproto) != 0)
                    272:                                continue;
                    273: 
                    274:                        /* go through list of protocols 'nstat' supports */
                    275:                        for (tp = protox; tp->pr_name; tp++)
                    276:                                if (strcmp(tp->pr_name, p->p_name) == 0)
                    277:                                        break;
                    278:                        if (tp->pr_name == 0 || tp->pr_wanted == 0)
                    279:                                continue;
                    280: 
                    281:                        /* found one protocol */
                    282:                        if (tp->pr_stats) {
                    283:                                DELIM();
                    284:                                (*tp->pr_stats)();
                    285:                                continue;
                    286:                        }
                    287:                  }
                    288:          }
                    289: 
                    290:          if (cflag) {
                    291:                  setprotoent(1);
                    292:                  setservent(1);
                    293:                  while (p = getprotoent()) {
                    294: 
                    295:                        if (pflag &&
                    296:                            strcmp(p->p_name, printproto) != 0)
                    297:                                continue;
                    298: 
                    299:                        for (tp = protox; tp->pr_name; tp++)
                    300:                                if (strcmp(tp->pr_name, p->p_name) == 0)
                    301:                                        break;
                    302:                        if (tp->pr_name == 0 || tp->pr_wanted == 0)
                    303:                                continue;
                    304:                        if (tp->pr_cblocks) {
                    305:                                DELIM();
                    306:                                (*tp->pr_cblocks)(tp->pr_name);
                    307:                        }
                    308:                  }
                    309:          }
                    310:          if (interval)
                    311:                sleep(interval);
                    312:          else {
                    313:                DELIM();
                    314:                close(kmem);
                    315:                exit(0);
                    316:          }
                    317:        }
                    318: }
                    319: 
                    320: /*
                    321:  * Seek into the kernel for a value.
                    322:  */
                    323: klseek(fd, base, off)
                    324:        int fd, base, off;
                    325: {
                    326: 
                    327:        if (kflag) {
                    328:                /* get kernel pte */
                    329: #if defined(vax) || defined(tahoe)
                    330:                base &= 0x3FFFFFFF;
                    331: #endif
                    332:                base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
                    333:        }
                    334:        lseek(fd, base, off);
                    335: }
                    336: 
                    337: char *
                    338: plural(n)
                    339:        int n;
                    340: {
                    341: 
                    342:        return (n != 1 ? "s" : "");
                    343: }
                    344: 
                    345: 
                    346: 
                    347: help()
                    348: {
                    349: 
                    350:      printf("nstat [-HdchimnprstEAeb] [-p proto] [interval] [system] [core]\n");
                    351:      printf("where:\n");
                    352:      printf("-H          HELP. print all available options.\n");
                    353:      printf("-a interval\n");
                    354:      printf("     specify nstat to continuously list the status, pausing");
                    355:      printf("     for each interval between displays.\n");
                    356:      printf("-d devicename\n");
                    357:      printf("     show statistics associated with device.\n");
                    358:      printf("-c   show all connections.\n");
                    359:      printf("-h   show the state of the IMP host table.\n");
                    360:      printf("-i   show the state of auto-configured interfaces.\n");
                    361:      printf("-m   show mbuf statistics.\n");
                    362:      printf("-n   show network addresses as numbers.\n");
                    363:      printf("-p protocol\n");
                    364:      printf("     only print connections of 'protocol'.\n");
                    365:      printf("-r   show the routing tables\n");
                    366:      printf("-s   show protocol statistics\n");
                    367:      printf("-t   show data transmission through interfaces periodically.\n");
                    368:      printf("-E          show Ethernet/Internet addresses of currently-up hosts.\n");
                    369:      printf("-A   show addresses of PCBs; for debugging\n");
                    370: /* don't expose these 2 options to users */
                    371: #ifdef notdef
                    372:      printf("-e   show Driver-Level input-packet error types; for debugging\n");
                    373:      printf("-b   devicename (for enpX only); for debugging\n");
                    374:      printf("     show ENP buffer rings' pointers.\n");
                    375: #endif
                    376:      printf("The arguments 'system' and 'core' allow substitutes for the\n");
                    377:      printf("defaults '/vmunix' and '/dev/kmem'.\n");
                    378: }
                    379: 
                    380: struct nlist   sysmapnl[] = {
                    381: #define        N_SYSMAP        0
                    382:        { "_Sysmap" },
                    383: #define        N_SYSSIZE       1
                    384:        { "_Syssize" },
                    385:        {""},
                    386: };
                    387: rkmem()
                    388: {
                    389:        static  int     getvm = 0;
                    390:        off_t off;
                    391: 
                    392:        if (!getvm) {
                    393:                nlist(system, sysmapnl);
                    394:                getvm++;
                    395:        }
                    396:        sysmapnl[N_SYSSIZE].n_value *= 4;
                    397:        Sysmap = (struct pte *)malloc(sysmapnl[N_SYSSIZE].n_value);
                    398:        if (Sysmap == 0) {
                    399:                perror("rsysmap");
                    400:                exit(1);
                    401:        }
                    402: #ifdef tahoe
                    403:        off = sysmapnl[N_SYSMAP].n_value & 0x3FFFFFFF;
                    404: #endif
                    405:        lseek(kmem, off, 0);
                    406:        read(kmem, Sysmap, sysmapnl[N_SYSSIZE].n_value);
                    407: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.