Annotation of 43BSDTahoe/ucb/netstat/main.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983, 1988 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that the above copyright notice and this paragraph are
                      7:  * duplicated in all such forms and that any documentation,
                      8:  * advertising materials, and other materials related to such
                      9:  * distribution and use acknowledge that the software was developed
                     10:  * by the University of California, Berkeley.  The name of the
                     11:  * University may not be used to endorse or promote products derived
                     12:  * from this software without specific prior written permission.
                     13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     16:  */
                     17: 
                     18: #ifndef lint
                     19: char copyright[] =
                     20: "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
                     21:  All rights reserved.\n";
                     22: #endif /* not lint */
                     23: 
                     24: #ifndef lint
                     25: static char sccsid[] = "@(#)main.c     5.14 (Berkeley) 6/29/88";
                     26: #endif /* not lint */
                     27: 
                     28: #include <sys/param.h>
                     29: #include <sys/vmmac.h>
                     30: #include <sys/socket.h>
                     31: #include <sys/file.h>
                     32: #include <machine/pte.h>
                     33: #include <ctype.h>
                     34: #include <errno.h>
                     35: #include <netdb.h>
                     36: #include <nlist.h>
                     37: #include <stdio.h>
                     38: 
                     39: struct nlist nl[] = {
                     40: #define        N_MBSTAT        0
                     41:        { "_mbstat" },
                     42: #define        N_IPSTAT        1
                     43:        { "_ipstat" },
                     44: #define        N_TCB           2
                     45:        { "_tcb" },
                     46: #define        N_TCPSTAT       3
                     47:        { "_tcpstat" },
                     48: #define        N_UDB           4
                     49:        { "_udb" },
                     50: #define        N_UDPSTAT       5
                     51:        { "_udpstat" },
                     52: #define        N_RAWCB         6
                     53:        { "_rawcb" },
                     54: #define        N_SYSMAP        7
                     55:        { "_Sysmap" },
                     56: #define        N_SYSSIZE       8
                     57:        { "_Syssize" },
                     58: #define        N_IFNET         9
                     59:        { "_ifnet" },
                     60: #define        N_IMP           10
                     61:        { "_imp_softc" },
                     62: #define        N_RTHOST        11
                     63:        { "_rthost" },
                     64: #define        N_RTNET         12
                     65:        { "_rtnet" },
                     66: #define        N_ICMPSTAT      13
                     67:        { "_icmpstat" },
                     68: #define        N_RTSTAT        14
                     69:        { "_rtstat" },
                     70: #define        N_NFILE         15
                     71:        { "_nfile" },
                     72: #define        N_FILE          16
                     73:        { "_file" },
                     74: #define        N_UNIXSW        17
                     75:        { "_unixsw" },
                     76: #define N_RTHASHSIZE   18
                     77:        { "_rthashsize" },
                     78: #define N_IDP          19
                     79:        { "_nspcb"},
                     80: #define N_IDPSTAT      20
                     81:        { "_idpstat"},
                     82: #define N_SPPSTAT      21
                     83:        { "_spp_istat"},
                     84: #define N_NSERR                22
                     85:        { "_ns_errstat"},
                     86: #define N_NIMP         23
                     87:        { "_nimp"},
                     88:        "",
                     89: };
                     90: 
                     91: /* internet protocols */
                     92: extern int protopr();
                     93: extern int tcp_stats(), udp_stats(), ip_stats(), icmp_stats();
                     94: /* ns protocols */
                     95: extern int nsprotopr();
                     96: extern int spp_stats(), idp_stats(), nserr_stats();
                     97: 
                     98: #define NULLPROTOX     ((struct protox *) 0)
                     99: struct protox {
                    100:        u_char  pr_index;               /* index into nlist of cb head */
                    101:        u_char  pr_sindex;              /* index into nlist of stat block */
                    102:        u_char  pr_wanted;              /* 1 if wanted, 0 otherwise */
                    103:        int     (*pr_cblocks)();        /* control blocks printing routine */
                    104:        int     (*pr_stats)();          /* statistics printing routine */
                    105:        char    *pr_name;               /* well-known name */
                    106: } protox[] = {
                    107:        { N_TCB,        N_TCPSTAT,      1,      protopr,
                    108:          tcp_stats,    "tcp" },
                    109:        { N_UDB,        N_UDPSTAT,      1,      protopr,
                    110:          udp_stats,    "udp" },
                    111:        { -1,           N_IPSTAT,       1,      0,
                    112:          ip_stats,     "ip" },
                    113:        { -1,           N_ICMPSTAT,     1,      0,
                    114:          icmp_stats,   "icmp" },
                    115:        { -1,           -1,             0,      0,
                    116:          0,            0 }
                    117: };
                    118: 
                    119: struct protox nsprotox[] = {
                    120:        { N_IDP,        N_IDPSTAT,      1,      nsprotopr,
                    121:          idp_stats,    "idp" },
                    122:        { N_IDP,        N_SPPSTAT,      1,      nsprotopr,
                    123:          spp_stats,    "spp" },
                    124:        { -1,           N_NSERR,        1,      0,
                    125:          nserr_stats,  "ns_err" },
                    126:        { -1,           -1,             0,      0,
                    127:          0,            0 }
                    128: };
                    129: 
                    130: struct pte *Sysmap;
                    131: 
                    132: char   *system = "/vmunix";
                    133: char   *kmemf = "/dev/kmem";
                    134: int    kmem;
                    135: int    kflag;
                    136: int    Aflag;
                    137: int    aflag;
                    138: int    hflag;
                    139: int    iflag;
                    140: int    mflag;
                    141: int    nflag;
                    142: int    pflag;
                    143: int    rflag;
                    144: int    sflag;
                    145: int    tflag;
                    146: int    dflag;
                    147: int    interval;
                    148: char   *interface;
                    149: int    unit;
                    150: 
                    151: int    af = AF_UNSPEC;
                    152: 
                    153: extern char *malloc();
                    154: extern off_t lseek();
                    155: 
                    156: main(argc, argv)
                    157:        int argc;
                    158:        char *argv[];
                    159: {
                    160:        extern char *optarg;
                    161:        extern int optind;
                    162:        register struct protoent *p;
                    163:        register struct protox *tp;     /* for printing cblocks & stats */
                    164:        struct protox *name2protox();   /* for -p */
                    165:        int ch;
                    166: 
                    167:        while ((ch = getopt(argc, argv, "AI:af:himnp:drstu")) != EOF)
                    168:                switch((char)ch) {
                    169:                case 'A':
                    170:                        Aflag++;
                    171:                        break;
                    172:                case 'I': {
                    173:                        char *cp;
                    174: 
                    175:                        iflag++;
                    176:                        for (cp = interface = optarg; isalpha(*cp); cp++);
                    177:                        unit = atoi(cp);
                    178:                        *cp = '\0';
                    179:                        break;
                    180:                }
                    181:                case 'a':
                    182:                        aflag++;
                    183:                        break;
                    184:                case 'd':
                    185:                        dflag++;
                    186:                        break;
                    187:                case 'f':
                    188:                        if (strcmp(optarg, "ns") == 0)
                    189:                                af = AF_NS;
                    190:                        else if (strcmp(optarg, "inet") == 0)
                    191:                                af = AF_INET;
                    192:                        else if (strcmp(optarg, "unix") == 0)
                    193:                                af = AF_UNIX;
                    194:                        else {
                    195:                                fprintf(stderr, "%s: unknown address family\n", optarg);
                    196:                                exit(10);
                    197:                        }
                    198:                        break;
                    199:                case 'h':
                    200:                        hflag++;
                    201:                        break;
                    202:                case 'i':
                    203:                        iflag++;
                    204:                        break;
                    205:                case 'm':
                    206:                        mflag++;
                    207:                        break;
                    208:                case 'n':
                    209:                        nflag++;
                    210:                        break;
                    211:                case 'p':
                    212:                        if ((tp = name2protox(optarg)) == NULLPROTOX) {
                    213:                                fprintf(stderr, "%s: unknown or uninstrumented protocol\n", optarg);
                    214:                                exit(10);
                    215:                        }
                    216:                        pflag++;
                    217:                        break;
                    218:                case 'r':
                    219:                        rflag++;
                    220:                        break;
                    221:                case 's':
                    222:                        sflag++;
                    223:                        break;
                    224:                case 't':
                    225:                        tflag++;
                    226:                        break;
                    227:                case 'u':
                    228:                        af = AF_UNIX;
                    229:                        break;
                    230:                case '?':
                    231:                default:
                    232:                        usage();
                    233:                }
                    234:        argv += optind;
                    235:        argc -= optind;
                    236: 
                    237:        if (argc > 0) {
                    238:                if (isdigit(argv[0][0])) {
                    239:                        interval = atoi(argv[0]);
                    240:                        if (interval <= 0)
                    241:                                usage();
                    242:                        argv++, argc--;
                    243:                        iflag++;
                    244:                }
                    245:                if (argc > 0) {
                    246:                        system = *argv;
                    247:                        argv++, argc--;
                    248:                        if (argc > 0) {
                    249:                                kmemf = *argv;
                    250:                                kflag++;
                    251:                        }
                    252:                }
                    253:        }
                    254:        if (nlist(system, nl) < 0 || nl[0].n_type == 0) {
                    255:                fprintf(stderr, "%s: no namelist\n", system);
                    256:                exit(1);
                    257:        }
                    258:        kmem = open(kmemf, O_RDONLY);
                    259:        if (kmem < 0) {
                    260:                perror(kmemf);
                    261:                exit(1);
                    262:        }
                    263:        if (kflag) {
                    264:                off_t off;
                    265: 
                    266:                Sysmap = (struct pte *)
                    267:                   malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
                    268:                if (!Sysmap) {
                    269:                        fputs("netstat: can't get memory for Sysmap.\n", stderr);
                    270:                        exit(1);
                    271:                }
                    272:                off = nl[N_SYSMAP].n_value & ~KERNBASE;
                    273:                (void)lseek(kmem, off, L_SET);
                    274:                (void)read(kmem, (char *)Sysmap,
                    275:                    (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
                    276:        }
                    277:        if (mflag) {
                    278:                mbpr((off_t)nl[N_MBSTAT].n_value);
                    279:                exit(0);
                    280:        }
                    281:        if (pflag) {
                    282:                if (tp->pr_stats)
                    283:                        (*tp->pr_stats)(nl[tp->pr_sindex].n_value,
                    284:                                tp->pr_name);
                    285:                else
                    286:                        printf("%s: no stats routine\n", tp->pr_name);
                    287:                exit(0);
                    288:        }
                    289:        if (hflag) {
                    290:                hostpr(nl[N_IMP].n_value, nl[N_NIMP].n_value);
                    291:                exit(0);
                    292:        }
                    293:        /*
                    294:         * Keep file descriptors open to avoid overhead
                    295:         * of open/close on each call to get* routines.
                    296:         */
                    297:        sethostent(1);
                    298:        setnetent(1);
                    299:        if (iflag) {
                    300:                intpr(interval, nl[N_IFNET].n_value);
                    301:                exit(0);
                    302:        }
                    303:        if (rflag) {
                    304:                if (sflag)
                    305:                        rt_stats((off_t)nl[N_RTSTAT].n_value);
                    306:                else
                    307:                        routepr((off_t)nl[N_RTHOST].n_value, 
                    308:                                (off_t)nl[N_RTNET].n_value,
                    309:                                (off_t)nl[N_RTHASHSIZE].n_value);
                    310:                exit(0);
                    311:        }
                    312:     if (af == AF_INET || af == AF_UNSPEC) {
                    313:        setprotoent(1);
                    314:        setservent(1);
                    315:        while (p = getprotoent()) {
                    316: 
                    317:                for (tp = protox; tp->pr_name; tp++)
                    318:                        if (strcmp(tp->pr_name, p->p_name) == 0)
                    319:                                break;
                    320:                if (tp->pr_name == 0 || tp->pr_wanted == 0)
                    321:                        continue;
                    322:                if (sflag) {
                    323:                        if (tp->pr_stats)
                    324:                                (*tp->pr_stats)(nl[tp->pr_sindex].n_value,
                    325:                                        p->p_name);
                    326:                } else
                    327:                        if (tp->pr_cblocks)
                    328:                                (*tp->pr_cblocks)(nl[tp->pr_index].n_value,
                    329:                                        p->p_name);
                    330:        }
                    331:        endprotoent();
                    332:     }
                    333:     if (af == AF_NS || af == AF_UNSPEC) {
                    334:        for (tp = nsprotox; tp->pr_name; tp++) {
                    335:                if (sflag) {
                    336:                        if (tp->pr_stats)
                    337:                                (*tp->pr_stats)(nl[tp->pr_sindex].n_value,
                    338:                                        tp->pr_name);
                    339:                } else
                    340:                        if (tp->pr_cblocks)
                    341:                                (*tp->pr_cblocks)(nl[tp->pr_index].n_value,
                    342:                                        tp->pr_name);
                    343:        }
                    344:     }
                    345:     if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
                    346:            unixpr((off_t)nl[N_NFILE].n_value, (off_t)nl[N_FILE].n_value,
                    347:                (struct protosw *)nl[N_UNIXSW].n_value);
                    348:     if (af == AF_UNSPEC && sflag)
                    349:        impstats(nl[N_IMP].n_value, nl[N_NIMP].n_value);
                    350:     exit(0);
                    351: }
                    352: 
                    353: /*
                    354:  * Seek into the kernel for a value.
                    355:  */
                    356: off_t
                    357: klseek(fd, base, off)
                    358:        int fd, off;
                    359:        off_t base;
                    360: {
                    361:        if (kflag) {
                    362:                /* get kernel pte */
                    363:                base &= ~KERNBASE;
                    364:                base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
                    365:        }
                    366:        return (lseek(fd, base, off));
                    367: }
                    368: 
                    369: char *
                    370: plural(n)
                    371:        int n;
                    372: {
                    373: 
                    374:        return (n != 1 ? "s" : "");
                    375: }
                    376: 
                    377: /*
                    378:  * Find the protox for the given "well-known" name.
                    379:  */
                    380: struct protox *
                    381: knownname(name)
                    382:        char *name;
                    383: {
                    384:        struct protox *tp;
                    385: 
                    386:        for (tp = protox; tp->pr_name; tp++)
                    387:                if (strcmp(tp->pr_name, name) == 0)
                    388:                        return(tp);
                    389:        for (tp = nsprotox; tp->pr_name; tp++)
                    390:                if (strcmp(tp->pr_name, name) == 0)
                    391:                        return(tp);
                    392:        return(NULLPROTOX);
                    393: }
                    394: 
                    395: /*
                    396:  * Find the protox corresponding to name.
                    397:  */
                    398: struct protox *
                    399: name2protox(name)
                    400:        char *name;
                    401: {
                    402:        struct protox *tp;
                    403:        char **alias;                   /* alias from p->aliases */
                    404:        struct protoent *p;
                    405: 
                    406:        /*
                    407:         * Try to find the name in the list of "well-known" names. If that
                    408:         * fails, check if name is an alias for an Internet protocol.
                    409:         */
                    410:        if (tp = knownname(name))
                    411:                return(tp);
                    412: 
                    413:        setprotoent(1);                 /* make protocol lookup cheaper */
                    414:        while (p = getprotoent()) {
                    415:                /* assert: name not same as p->name */
                    416:                for (alias = p->p_aliases; *alias; alias++)
                    417:                        if (strcmp(name, *alias) == 0) {
                    418:                                endprotoent();
                    419:                                return(knownname(p->p_name));
                    420:                        }
                    421:        }
                    422:        endprotoent();
                    423:        return(NULLPROTOX);
                    424: }
                    425: 
                    426: usage()
                    427: {
                    428:        fputs("usage: netstat [-Aan] [-f address_family] [system] [core]\n               [-himnrs] [-f address_family] [system] [core]\n               [-n] [-I interface] interval [system] [core]\n", stderr);
                    429:        exit(1);
                    430: }

unix.superglobalmegacorp.com

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