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