1 #ifndef lint 2 static char sccsid[] = "@(#)main.c 4.8 83/05/01"; 3 #endif 4 5 #include <sys/param.h> 6 #include <sys/vmmac.h> 7 #include <machine/pte.h> 8 #include <ctype.h> 9 #include <errno.h> 10 #include <netdb.h> 11 #include <nlist.h> 12 #include <stdio.h> 13 14 struct nlist nl[] = { 15 #define N_MBSTAT 0 16 { "_mbstat" }, 17 #define N_IPSTAT 1 18 { "_ipstat" }, 19 #define N_TCB 2 20 { "_tcb" }, 21 #define N_TCPSTAT 3 22 { "_tcpstat" }, 23 #define N_UDB 4 24 { "_udb" }, 25 #define N_UDPSTAT 5 26 { "_udpstat" }, 27 #define N_RAWCB 6 28 { "_rawcb" }, 29 #define N_SYSMAP 7 30 { "_Sysmap" }, 31 #define N_SYSSIZE 8 32 { "_Syssize" }, 33 #define N_IFNET 9 34 { "_ifnet" }, 35 #define N_HOSTS 10 36 { "_hosts" }, 37 #define N_RTHOST 11 38 { "_rthost" }, 39 #define N_RTNET 12 40 { "_rtnet" }, 41 #define N_ICMPSTAT 13 42 { "_icmpstat" }, 43 "", 44 }; 45 46 extern int protopr(); 47 extern int tcp_stats(), udp_stats(), ip_stats(), icmp_stats(); 48 49 struct protox { 50 u_char pr_index; /* index into nlist of cb head */ 51 u_char pr_sindex; /* index into nlist of stat block */ 52 u_char pr_wanted; /* 1 if wanted, 0 otherwise */ 53 int (*pr_cblocks)(); /* control blocks printing routine */ 54 int (*pr_stats)(); /* statistics printing routine */ 55 char *pr_name; /* well-known name */ 56 } protox[] = { 57 { N_TCB, N_TCPSTAT, 1, protopr, 58 tcp_stats, "tcp" }, 59 { N_UDB, N_UDPSTAT, 1, protopr, 60 udp_stats, "udp" }, 61 { -1, N_IPSTAT, 1, 0, 62 ip_stats, "ip" }, 63 { -1, N_ICMPSTAT, 1, 0, 64 icmp_stats, "icmp" }, 65 { -1, -1, 0, 0, 66 0, 0 } 67 }; 68 69 struct pte *Sysmap; 70 71 char *system = "/vmunix"; 72 char *kmemf = "/dev/kmem"; 73 int kmem; 74 int kflag; 75 int Aflag; 76 int aflag; 77 int hflag; 78 int iflag; 79 int mflag; 80 int nflag; 81 int rflag; 82 int sflag; 83 int tflag; 84 int interval; 85 char usage[] = "[ -Aaihmnrst ] [ interval ] [ system ] [ core ]"; 86 87 main(argc, argv) 88 int argc; 89 char *argv[]; 90 { 91 int i; 92 char *cp, *name; 93 register struct protoent *p; 94 95 name = argv[0]; 96 argc--, argv++; 97 while (argc > 0 && **argv == '-') { 98 for (cp = &argv[0][1]; *cp; cp++) 99 switch(argv[0][1]) { 100 101 case 'A': 102 Aflag++; 103 break; 104 105 case 'a': 106 aflag++; 107 break; 108 109 case 'h': 110 hflag++; 111 break; 112 113 case 'i': 114 iflag++; 115 break; 116 117 case 'm': 118 mflag++; 119 break; 120 121 case 'n': 122 nflag++; 123 break; 124 125 case 'r': 126 rflag++; 127 break; 128 129 case 's': 130 sflag++; 131 break; 132 133 case 't': 134 tflag++; 135 break; 136 137 default: 138 use: 139 printf("usage: %s %s\n", name, usage); 140 exit(1); 141 } 142 argv++, argc--; 143 } 144 if (argc > 0 && isdigit(argv[0][0])) { 145 interval = atoi(argv[0]); 146 if (interval <= 0) 147 goto use; 148 argv++, argc--; 149 iflag++; 150 } 151 if (argc > 0) { 152 system = *argv; 153 argv++, argc--; 154 } 155 nlist(system, nl); 156 if (nl[0].n_type == 0) { 157 fprintf(stderr, "%s: no namelist\n", system); 158 exit(1); 159 } 160 if (argc > 0) { 161 kmemf = *argv; 162 kflag++; 163 } 164 kmem = open(kmemf, 0); 165 if (kmem < 0) { 166 fprintf(stderr, "cannot open "); 167 perror(kmemf); 168 exit(1); 169 } 170 if (kflag) { 171 off_t off; 172 173 off = nl[N_SYSMAP].n_value & 0x7fffffff; 174 lseek(kmem, off, 0); 175 nl[N_SYSSIZE].n_value *= 4; 176 Sysmap = (struct pte *)malloc(nl[N_SYSSIZE].n_value); 177 if (Sysmap == 0) { 178 perror("Sysmap"); 179 exit(1); 180 } 181 read(kmem, Sysmap, nl[N_SYSSIZE].n_value); 182 } 183 if (mflag) { 184 mbpr(nl[N_MBSTAT].n_value); 185 exit(0); 186 } 187 /* 188 * Keep file descriptors open to avoid overhead 189 * of open/close on each call to get* routines. 190 */ 191 sethostent(1); 192 setnetent(1); 193 if (iflag) { 194 intpr(interval, nl[N_IFNET].n_value); 195 exit(0); 196 } 197 if (hflag) { 198 hostpr(nl[N_HOSTS].n_value); 199 exit(0); 200 } 201 if (rflag) { 202 routepr(nl[N_RTHOST].n_value, nl[N_RTNET].n_value); 203 exit(0); 204 } 205 setprotoent(1); 206 setservent(1); 207 while (p = getprotoent()) { 208 register struct protox *tp; 209 210 for (tp = protox; tp->pr_name; tp++) 211 if (strcmp(tp->pr_name, p->p_name) == 0) 212 break; 213 if (tp->pr_name == 0 || tp->pr_wanted == 0) 214 continue; 215 if (sflag && tp->pr_stats) { 216 (*tp->pr_stats)(nl[tp->pr_sindex].n_value, p->p_name); 217 continue; 218 } 219 if (tp->pr_cblocks) 220 (*tp->pr_cblocks)(nl[tp->pr_index].n_value, p->p_name); 221 } 222 endprotoent(); 223 } 224 225 /* 226 * Seek into the kernel for a value. 227 */ 228 klseek(fd, base, off) 229 int fd, base, off; 230 { 231 232 if (kflag) { 233 /* get kernel pte */ 234 #ifdef vax 235 base &= 0x7fffffff; 236 #endif 237 base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET); 238 } 239 lseek(fd, base, off); 240 } 241