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