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.2 (Berkeley) 08/16/85"; 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 uflag; 130 int fflag; 131 int interval; 132 char *interface; 133 int unit; 134 char usage[] = "[ -Aaihmnrstu ] [-f address_family] [-I interface] [ interval ] [ system ] [ core ]"; 135 136 int af = AF_UNSPEC; 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 uflag++; 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 } 200 break; 201 202 case 'I': 203 iflag++; 204 if (*(interface = cp + 1) == 0) { 205 if ((interface = argv[1]) == 0) 206 break; 207 argv++; 208 argc--; 209 } 210 for (cp = interface; isalpha(*cp); cp++) 211 ; 212 unit = atoi(cp); 213 *cp-- = 0; 214 break; 215 216 default: 217 use: 218 printf("usage: %s %s\n", name, usage); 219 exit(1); 220 } 221 argv++, argc--; 222 } 223 if (argc > 0 && isdigit(argv[0][0])) { 224 interval = atoi(argv[0]); 225 if (interval <= 0) 226 goto use; 227 argv++, argc--; 228 iflag++; 229 } 230 if (argc > 0) { 231 system = *argv; 232 argv++, argc--; 233 } 234 nlist(system, nl); 235 if (nl[0].n_type == 0) { 236 fprintf(stderr, "%s: no namelist\n", system); 237 exit(1); 238 } 239 if (argc > 0) { 240 kmemf = *argv; 241 kflag++; 242 } 243 kmem = open(kmemf, 0); 244 if (kmem < 0) { 245 fprintf(stderr, "cannot open "); 246 perror(kmemf); 247 exit(1); 248 } 249 if (kflag) { 250 off_t off; 251 252 off = nl[N_SYSMAP].n_value & 0x7fffffff; 253 lseek(kmem, off, 0); 254 nl[N_SYSSIZE].n_value *= 4; 255 Sysmap = (struct pte *)malloc(nl[N_SYSSIZE].n_value); 256 if (Sysmap == 0) { 257 perror("Sysmap"); 258 exit(1); 259 } 260 read(kmem, Sysmap, nl[N_SYSSIZE].n_value); 261 } 262 if (mflag) { 263 mbpr(nl[N_MBSTAT].n_value); 264 exit(0); 265 } 266 if (uflag) { 267 unixpr(nl[N_NFILE].n_value, nl[N_FILE].n_value, 268 nl[N_UNIXSW].n_value); 269 exit(0); 270 } 271 /* 272 * Keep file descriptors open to avoid overhead 273 * of open/close on each call to get* routines. 274 */ 275 sethostent(1); 276 setnetent(1); 277 if (iflag) { 278 intpr(interval, nl[N_IFNET].n_value); 279 exit(0); 280 } 281 if (hflag) { 282 hostpr(nl[N_HOSTS].n_value); 283 exit(0); 284 } 285 if (rflag) { 286 if (sflag) 287 rt_stats(nl[N_RTSTAT].n_value); 288 else 289 routepr(nl[N_RTHOST].n_value, nl[N_RTNET].n_value, 290 nl[N_RTHASHSIZE].n_value); 291 exit(0); 292 } 293 if (af == AF_INET || af == AF_UNSPEC) { 294 setprotoent(1); 295 setservent(1); 296 while (p = getprotoent()) { 297 298 for (tp = protox; tp->pr_name; tp++) 299 if (strcmp(tp->pr_name, p->p_name) == 0) 300 break; 301 if (tp->pr_name == 0 || tp->pr_wanted == 0) 302 continue; 303 if (sflag && tp->pr_stats) { 304 (*tp->pr_stats)(nl[tp->pr_sindex].n_value, p->p_name); 305 continue; 306 } 307 if (tp->pr_cblocks) 308 (*tp->pr_cblocks)(nl[tp->pr_index].n_value, p->p_name); 309 } 310 endprotoent(); 311 } 312 if (af == AF_NS || af == AF_UNSPEC) { 313 for (tp = nsprotox; tp->pr_name; tp++) { 314 if (sflag && tp->pr_stats) { 315 (*tp->pr_stats)(nl[tp->pr_sindex].n_value, tp->pr_name); 316 continue; 317 } 318 if (tp->pr_cblocks) 319 (*tp->pr_cblocks)(nl[tp->pr_index].n_value, tp->pr_name); 320 } 321 } 322 } 323 324 /* 325 * Seek into the kernel for a value. 326 */ 327 klseek(fd, base, off) 328 int fd, base, off; 329 { 330 331 if (kflag) { 332 /* get kernel pte */ 333 #ifdef vax 334 base &= 0x7fffffff; 335 #endif 336 base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET); 337 } 338 lseek(fd, base, off); 339 } 340 341 char * 342 plural(n) 343 int n; 344 { 345 346 return (n != 1 ? "s" : ""); 347 } 348