1: /* 2: * Copyright (c) 1983 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: #ifndef lint 8: char copyright[] = 9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10: All rights reserved.\n"; 11: #endif not lint 12: 13: #ifndef lint 14: static char sccsid[] = "@(#)main.c 5.7 (Berkeley) 5/22/86"; 15: #endif not lint 16: 17: #include <sys/param.h> 18: #include <sys/vmmac.h> 19: #include <sys/socket.h> 20: #include <machine/pte.h> 21: #include <ctype.h> 22: #include <errno.h> 23: #include <netdb.h> 24: #include <nlist.h> 25: #include <stdio.h> 26: 27: struct nlist nl[] = { 28: #define N_MBSTAT 0 29: { "_mbstat" }, 30: #define N_IPSTAT 1 31: { "_ipstat" }, 32: #define N_TCB 2 33: { "_tcb" }, 34: #define N_TCPSTAT 3 35: { "_tcpstat" }, 36: #define N_UDB 4 37: { "_udb" }, 38: #define N_UDPSTAT 5 39: { "_udpstat" }, 40: #define N_RAWCB 6 41: { "_rawcb" }, 42: #define N_SYSMAP 7 43: { "_Sysmap" }, 44: #define N_SYSSIZE 8 45: { "_Syssize" }, 46: #define N_IFNET 9 47: { "_ifnet" }, 48: #define N_HOSTS 10 49: { "_hosts" }, 50: #define N_RTHOST 11 51: { "_rthost" }, 52: #define N_RTNET 12 53: { "_rtnet" }, 54: #define N_ICMPSTAT 13 55: { "_icmpstat" }, 56: #define N_RTSTAT 14 57: { "_rtstat" }, 58: #define N_NFILE 15 59: { "_nfile" }, 60: #define N_FILE 16 61: { "_file" }, 62: #define N_UNIXSW 17 63: { "_unixsw" }, 64: #define N_RTHASHSIZE 18 65: { "_rthashsize" }, 66: #define N_IDP 19 67: { "_nspcb"}, 68: #define N_IDPSTAT 20 69: { "_idpstat"}, 70: #define N_SPPSTAT 21 71: { "_spp_istat"}, 72: #define N_NSERR 22 73: { "_ns_errstat"}, 74: "", 75: }; 76: 77: /* internet protocols */ 78: extern int protopr(); 79: extern int tcp_stats(), udp_stats(), ip_stats(), icmp_stats(); 80: extern int nsprotopr(); 81: extern int spp_stats(), idp_stats(), nserr_stats(); 82: 83: struct protox { 84: u_char pr_index; /* index into nlist of cb head */ 85: u_char pr_sindex; /* index into nlist of stat block */ 86: u_char pr_wanted; /* 1 if wanted, 0 otherwise */ 87: int (*pr_cblocks)(); /* control blocks printing routine */ 88: int (*pr_stats)(); /* statistics printing routine */ 89: char *pr_name; /* well-known name */ 90: } protox[] = { 91: { N_TCB, N_TCPSTAT, 1, protopr, 92: tcp_stats, "tcp" }, 93: { N_UDB, N_UDPSTAT, 1, protopr, 94: udp_stats, "udp" }, 95: { -1, N_IPSTAT, 1, 0, 96: ip_stats, "ip" }, 97: { -1, N_ICMPSTAT, 1, 0, 98: icmp_stats, "icmp" }, 99: { -1, -1, 0, 0, 100: 0, 0 } 101: }; 102: 103: struct protox nsprotox[] = { 104: { N_IDP, N_IDPSTAT, 1, nsprotopr, 105: idp_stats, "idp" }, 106: { N_IDP, N_SPPSTAT, 1, nsprotopr, 107: spp_stats, "spp" }, 108: { -1, N_NSERR, 1, 0, 109: nserr_stats, "ns_err" }, 110: { -1, -1, 0, 0, 111: 0, 0 } 112: }; 113: 114: struct pte *Sysmap; 115: 116: char *system = "/vmunix"; 117: char *kmemf = "/dev/kmem"; 118: int kmem; 119: int kflag; 120: int Aflag; 121: int aflag; 122: int hflag; 123: int iflag; 124: int mflag; 125: int nflag; 126: int rflag; 127: int sflag; 128: int tflag; 129: int fflag; 130: int interval; 131: char *interface; 132: int unit; 133: char usage[] = "[ -Aaihmnrst ] [-f address_family] [-I interface] [ interval ] [ system ] [ core ]"; 134: 135: int af = AF_UNSPEC; 136: 137: main(argc, argv) 138: int argc; 139: char *argv[]; 140: { 141: int i; 142: char *cp, *name; 143: register struct protoent *p; 144: register struct protox *tp; 145: 146: name = argv[0]; 147: argc--, argv++; 148: while (argc > 0 && **argv == '-') { 149: for (cp = &argv[0][1]; *cp; cp++) 150: switch(*cp) { 151: 152: case 'A': 153: Aflag++; 154: break; 155: 156: case 'a': 157: aflag++; 158: break; 159: 160: case 'h': 161: hflag++; 162: break; 163: 164: case 'i': 165: iflag++; 166: break; 167: 168: case 'm': 169: mflag++; 170: break; 171: 172: case 'n': 173: nflag++; 174: break; 175: 176: case 'r': 177: rflag++; 178: break; 179: 180: case 's': 181: sflag++; 182: break; 183: 184: case 't': 185: tflag++; 186: break; 187: 188: case 'u': 189: af = AF_UNIX; 190: break; 191: 192: case 'f': 193: argv++; 194: argc--; 195: if (strcmp(*argv, "ns") == 0) 196: af = AF_NS; 197: else if (strcmp(*argv, "inet") == 0) 198: af = AF_INET; 199: else if (strcmp(*argv, "unix") == 0) 200: af = AF_UNIX; 201: else { 202: fprintf(stderr, "%s: unknown address family\n", 203: *argv); 204: exit(10); 205: } 206: break; 207: 208: case 'I': 209: iflag++; 210: if (*(interface = cp + 1) == 0) { 211: if ((interface = argv[1]) == 0) 212: break; 213: argv++; 214: argc--; 215: } 216: for (cp = interface; isalpha(*cp); cp++) 217: ; 218: unit = atoi(cp); 219: *cp-- = 0; 220: break; 221: 222: default: 223: use: 224: printf("usage: %s %s\n", name, usage); 225: exit(1); 226: } 227: argv++, argc--; 228: } 229: if (argc > 0 && isdigit(argv[0][0])) { 230: interval = atoi(argv[0]); 231: if (interval <= 0) 232: goto use; 233: argv++, argc--; 234: iflag++; 235: } 236: if (argc > 0) { 237: system = *argv; 238: argv++, argc--; 239: } 240: nlist(system, nl); 241: if (nl[0].n_type == 0) { 242: fprintf(stderr, "%s: no namelist\n", system); 243: exit(1); 244: } 245: if (argc > 0) { 246: kmemf = *argv; 247: kflag++; 248: } 249: kmem = open(kmemf, 0); 250: if (kmem < 0) { 251: fprintf(stderr, "cannot open "); 252: perror(kmemf); 253: exit(1); 254: } 255: if (kflag) { 256: off_t off; 257: 258: off = nl[N_SYSMAP].n_value & 0x7fffffff; 259: lseek(kmem, off, 0); 260: nl[N_SYSSIZE].n_value *= 4; 261: Sysmap = (struct pte *)malloc(nl[N_SYSSIZE].n_value); 262: if (Sysmap == 0) { 263: perror("Sysmap"); 264: exit(1); 265: } 266: read(kmem, Sysmap, nl[N_SYSSIZE].n_value); 267: } 268: if (mflag) { 269: mbpr(nl[N_MBSTAT].n_value); 270: exit(0); 271: } 272: /* 273: * Keep file descriptors open to avoid overhead 274: * of open/close on each call to get* routines. 275: */ 276: sethostent(1); 277: setnetent(1); 278: if (iflag) { 279: intpr(interval, nl[N_IFNET].n_value); 280: exit(0); 281: } 282: if (hflag) { 283: hostpr(nl[N_HOSTS].n_value); 284: exit(0); 285: } 286: if (rflag) { 287: if (sflag) 288: rt_stats(nl[N_RTSTAT].n_value); 289: else 290: routepr(nl[N_RTHOST].n_value, nl[N_RTNET].n_value, 291: nl[N_RTHASHSIZE].n_value); 292: exit(0); 293: } 294: if (af == AF_INET || af == AF_UNSPEC) { 295: setprotoent(1); 296: setservent(1); 297: while (p = getprotoent()) { 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 (sflag) { 305: if (tp->pr_stats) 306: (*tp->pr_stats)(nl[tp->pr_sindex].n_value, 307: p->p_name); 308: } else 309: if (tp->pr_cblocks) 310: (*tp->pr_cblocks)(nl[tp->pr_index].n_value, 311: p->p_name); 312: } 313: endprotoent(); 314: } 315: if (af == AF_NS || af == AF_UNSPEC) { 316: for (tp = nsprotox; tp->pr_name; tp++) { 317: if (sflag) { 318: if (tp->pr_stats) 319: (*tp->pr_stats)(nl[tp->pr_sindex].n_value, 320: tp->pr_name); 321: } else 322: if (tp->pr_cblocks) 323: (*tp->pr_cblocks)(nl[tp->pr_index].n_value, 324: tp->pr_name); 325: } 326: } 327: if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag) 328: unixpr(nl[N_NFILE].n_value, nl[N_FILE].n_value, 329: nl[N_UNIXSW].n_value); 330: exit(0); 331: } 332: 333: /* 334: * Seek into the kernel for a value. 335: */ 336: klseek(fd, base, off) 337: int fd, base, off; 338: { 339: 340: if (kflag) { 341: /* get kernel pte */ 342: #ifdef vax 343: base &= 0x7fffffff; 344: #endif 345: base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET); 346: } 347: lseek(fd, base, off); 348: } 349: 350: char * 351: plural(n) 352: int n; 353: { 354: 355: return (n != 1 ? "s" : ""); 356: }