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