1 /*
2 * Copyright (c) 1985, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char copyright[] =
10 "@(#) Copyright (c) 1985, 1993\n\
11 The Regents of the University of California. All rights reserved.\n";
12 #endif /* not lint */
13
14 #ifndef lint
15 static char sccsid[] = "@(#)trsp.c 8.1 (Berkeley) 06/06/93";
16 #endif /* not lint */
17
18 #include <sys/cdefs.h>
19 #include <sys/param.h>
20 #include <sys/socket.h>
21 #include <sys/socketvar.h>
22 #define PRUREQUESTS
23 #include <sys/protosw.h>
24
25 #include <net/route.h>
26 #include <net/if.h>
27
28 #define TCPSTATES
29 #include <netinet/tcp_fsm.h>
30 #define TCPTIMERS
31 #include <netinet/tcp_timer.h>
32
33 #include <netns/ns.h>
34 #include <netns/sp.h>
35 #include <netns/idp.h>
36 #include <netns/spidp.h>
37 #include <netns/spp_timer.h>
38 #include <netns/spp_var.h>
39 #include <netns/ns_pcb.h>
40 #include <netns/idp_var.h>
41 #define SANAMES
42 #include <netns/spp_debug.h>
43
44 #include <stdio.h>
45 #include <errno.h>
46 #include <nlist.h>
47 #include <paths.h>
48
49 unsigned long ntime;
50 int sflag;
51 int tflag;
52 int jflag;
53 int aflag;
54 int zflag;
55 int numeric();
56 struct nlist nl[] = {
57 { "_spp_debug" },
58 { "_spp_debx" },
59 0
60 };
61 struct spp_debug spp_debug[SPP_NDEBUG];
62 caddr_t spp_pcbs[SPP_NDEBUG];
63 int spp_debx;
64
main(argc,argv)65 main(argc, argv)
66 int argc;
67 char **argv;
68 {
69 int i, mask = 0, npcbs = 0;
70 char *system, *core;
71
72 system = _PATH_UNIX;
73 core = _PATH_KMEM;
74
75 argc--, argv++;
76 again:
77 if (argc > 0 && !strcmp(*argv, "-a")) {
78 aflag++, argc--, argv++;
79 goto again;
80 }
81 if (argc > 0 && !strcmp(*argv, "-z")) {
82 zflag++, argc--, argv++;
83 goto again;
84 }
85 if (argc > 0 && !strcmp(*argv, "-s")) {
86 sflag++, argc--, argv++;
87 goto again;
88 }
89 if (argc > 0 && !strcmp(*argv, "-t")) {
90 tflag++, argc--, argv++;
91 goto again;
92 }
93 if (argc > 0 && !strcmp(*argv, "-j")) {
94 jflag++, argc--, argv++;
95 goto again;
96 }
97 if (argc > 0 && !strcmp(*argv, "-p")) {
98 argc--, argv++;
99 if (argc < 1) {
100 fprintf(stderr, "-p: missing sppcb address\n");
101 exit(1);
102 }
103 if (npcbs >= SPP_NDEBUG) {
104 fprintf(stderr, "-p: too many pcb's specified\n");
105 exit(1);
106 }
107 sscanf(*argv, "%x", &spp_pcbs[npcbs++]);
108 argc--, argv++;
109 goto again;
110 }
111 if (argc > 0) {
112 system = *argv;
113 argc--, argv++;
114 mask++;
115 /*
116 * Discard setgid privileges if not the running kernel so that
117 * bad guys can't print interesting stuff from kernel memory.
118 */
119 setgid(getgid());
120 }
121 if (argc > 0) {
122 core = *argv;
123 argc--, argv++;
124 mask++;
125 setgid(getgid());
126 }
127 (void) nlist(system, nl);
128 if (nl[0].n_value == 0) {
129 fprintf(stderr, "trsp: %s: no namelist\n", system);
130 exit(1);
131 }
132 (void) close(0);
133 if (open(core, 0) < 0) {
134 fprintf(stderr, "trsp: "); perror(core);
135 exit(2);
136 }
137 if (mask) {
138 nl[0].n_value &= 0x7fffffff;
139 nl[1].n_value &= 0x7fffffff;
140 }
141 (void) lseek(0, nl[1].n_value, 0);
142 if (read(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
143 fprintf(stderr, "trsp: "); perror("spp_debx");
144 exit(3);
145 }
146 printf("spp_debx=%d\n", spp_debx);
147 (void) lseek(0, nl[0].n_value, 0);
148 if (read(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
149 fprintf(stderr, "trsp: "); perror("spp_debug");
150 exit(3);
151 }
152 /*
153 * Here, we just want to clear out the old trace data and start over.
154 */
155 if (zflag) {
156 char *cp = (char *) spp_debug,
157 *cplim = cp + sizeof(spp_debug);
158 (void) close(0);
159 if (open(core, 2) < 0) {
160 fprintf(stderr, "trsp: "); perror(core);
161 exit(2);
162 }
163 while(cp < cplim) *cp++ = 0;
164 (void) lseek(0, nl[0].n_value, 0);
165 if (write(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
166 fprintf(stderr, "trsp: "); perror("spp_debug");
167 exit(3);
168 }
169 (void) lseek(0, nl[1].n_value, 0);
170 spp_debx = 0;
171 if (write(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
172 fprintf(stderr, "trsp: "); perror("spp_debx");
173 exit(3);
174 }
175 exit(0);
176 }
177 /*
178 * If no control blocks have been specified, figure
179 * out how many distinct one we have and summarize
180 * them in spp_pcbs for sorting the trace records
181 * below.
182 */
183 if (npcbs == 0) {
184 for (i = 0; i < SPP_NDEBUG; i++) {
185 register int j;
186 register struct spp_debug *sd = &spp_debug[i];
187
188 if (sd->sd_cb == 0)
189 continue;
190 for (j = 0; j < npcbs; j++)
191 if (spp_pcbs[j] == sd->sd_cb)
192 break;
193 if (j >= npcbs)
194 spp_pcbs[npcbs++] = sd->sd_cb;
195 }
196 }
197 qsort(spp_pcbs, npcbs, sizeof (caddr_t), numeric);
198 if (jflag) {
199 char *cp = "";
200
201 for (i = 0; i < npcbs; i++) {
202 printf("%s%x", cp, spp_pcbs[i]);
203 cp = ", ";
204 }
205 if (*cp)
206 putchar('\n');
207 exit(0);
208 }
209 for (i = 0; i < npcbs; i++) {
210 printf("\n%x:\n", spp_pcbs[i]);
211 dotrace(spp_pcbs[i]);
212 }
213 exit(0);
214 }
215
dotrace(sppcb)216 dotrace(sppcb)
217 register caddr_t sppcb;
218 {
219 register int i;
220 register struct spp_debug *sd;
221
222 for (i = spp_debx % SPP_NDEBUG; i < SPP_NDEBUG; i++) {
223 sd = &spp_debug[i];
224 if (sppcb && sd->sd_cb != sppcb)
225 continue;
226 ntime = ntohl(sd->sd_time);
227 spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
228 &sd->sd_si, sd->sd_req);
229 }
230 for (i = 0; i < spp_debx % SPP_NDEBUG; i++) {
231 sd = &spp_debug[i];
232 if (sppcb && sd->sd_cb != sppcb)
233 continue;
234 ntime = ntohl(sd->sd_time);
235 spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
236 &sd->sd_si, sd->sd_req);
237 }
238 }
239
ptime(ms)240 ptime(ms)
241 int ms;
242 {
243
244 printf("%03d ", (ms/10) % 1000);
245 }
246
numeric(c1,c2)247 numeric(c1, c2)
248 caddr_t *c1, *c2;
249 {
250
251 return (*c1 - *c2);
252 }
253
spp_trace(act,ostate,asp,sp,si,req)254 spp_trace(act, ostate, asp, sp, si, req)
255 short act, ostate;
256 struct sppcb *asp, *sp;
257 struct spidp *si;
258 int req;
259 {
260 u_short seq, ack, len, alo;
261 int flags, timer;
262 char *cp;
263
264 if(ostate >= TCP_NSTATES) ostate = 0;
265 if(act > SA_DROP) act = SA_DROP;
266 printf("\n");
267 ptime(ntime);
268 printf("%s:%s", tcpstates[ostate], sanames[act]);
269
270 if (si != 0) {
271 seq = si->si_seq;
272 ack = si->si_ack;
273 alo = si->si_alo;
274 len = si->si_len;
275 switch (act) {
276 case SA_RESPOND:
277 case SA_OUTPUT:
278 seq = ntohs(seq);
279 ack = ntohs(ack);
280 alo = ntohs(alo);
281 len = ntohs(len);
282 case SA_INPUT:
283 case SA_DROP:
284 if (aflag) {
285 printf("\n\tsna=");
286 ns_printhost(&si->si_sna);
287 printf("\tdna=");
288 ns_printhost(&si->si_dna);
289 }
290 printf("\n\t");
291 #define p1(name, f) { \
292 printf("%s = %x, ", name, f); \
293 }
294 p1("seq", seq);
295 p1("ack", ack);
296 p1("alo", alo);
297 p1("len", len);
298 flags = si->si_cc;
299 printf("flags=%x", flags);
300 #define pf(name, f) { \
301 if (flags & f) { \
302 printf("%s%s", cp, name); \
303 cp = ","; \
304 } \
305 }
306 if (flags) {
307 char *cp = "<";
308 pf("SP_SP", SP_SP);
309 pf("SP_SA", SP_SA);
310 pf("SP_OB", SP_OB);
311 pf("SP_EM", SP_EM);
312 printf(">");
313 }
314 printf(", ");
315 #define p2(name, f) { \
316 printf("%s = %x, ", name, f); \
317 }
318 p2("sid", si->si_sid);
319 p2("did", si->si_did);
320 p2("dt", si->si_dt);
321 printf("\n\tsna=");
322 ns_printhost(&si->si_sna);
323 printf("\tdna=");
324 ns_printhost(&si->si_dna);
325 }
326 }
327 if(act == SA_USER) {
328 printf("\treq=%s", prurequests[req&0xff]);
329 if ((req & 0xff) == PRU_SLOWTIMO)
330 printf("<%s>", tcptimers[req>>8]);
331 }
332 printf(" -> %s", tcpstates[sp->s_state]);
333
334 /* print out internal state of sp !?! */
335 printf("\n");
336 if (sp == 0)
337 return;
338 #define p3(name, f) { \
339 printf("%s = %x, ", name, f); \
340 }
341 if (sflag) {
342 printf("\t");
343 p3("rack", sp->s_rack);
344 p3("ralo", sp->s_ralo);
345 p3("smax", sp->s_smax);
346 p3("snxt", sp->s_snxt);
347 p3("flags", sp->s_flags);
348 #undef pf
349 #define pf(name, f) { \
350 if (flags & f) { \
351 printf("%s%s", cp, name); \
352 cp = ","; \
353 } \
354 }
355 flags = sp->s_flags;
356 if (flags || sp->s_oobflags) {
357 char *cp = "<";
358 pf("ACKNOW", SF_ACKNOW);
359 pf("DELACK", SF_DELACK);
360 pf("HI", SF_HI);
361 pf("HO", SF_HO);
362 pf("PI", SF_PI);
363 pf("WIN", SF_WIN);
364 pf("RXT", SF_RXT);
365 pf("RVD", SF_RVD);
366 flags = sp->s_oobflags;
367 pf("SOOB", SF_SOOB);
368 pf("IOOB", SF_IOOB);
369 printf(">");
370 }
371 }
372 /* print out timers? */
373 if (tflag) {
374 char *cp = "\t";
375 register int i;
376
377 printf("\n\tTIMERS: ");
378 p3("idle", sp->s_idle);
379 p3("force", sp->s_force);
380 p3("rtseq", sp->s_rtseq);
381 for (i = 0; i < TCPT_NTIMERS; i++) {
382 if (sp->s_timer[i] == 0)
383 continue;
384 printf("%s%s=%d", cp, tcptimers[i], sp->s_timer[i]);
385 if (i == TCPT_REXMT)
386 printf(" (s_rxtshft=%d)", sp->s_rxtshift);
387 cp = ", ";
388 }
389 if (*cp != '\t')
390 putchar('\n');
391 }
392 }
393
ns_printhost(p)394 ns_printhost(p)
395 register struct ns_addr *p;
396 {
397
398 printf("<net:%x%x,host:%4.4x%4.4x%4.4x,port:%x>",
399 p->x_net.s_net[0],
400 p->x_net.s_net[1],
401 p->x_host.s_host[0],
402 p->x_host.s_host[1],
403 p->x_host.s_host[2],
404 p->x_port);
405
406 }
407
408