|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.