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