xref: /csrg-svn/usr.sbin/trpt/trpt.c (revision 10425)
16463Swnj #ifndef lint
2*10425Ssam static char sccsid[] = "@(#)trpt.c	4.6 01/19/83";
36463Swnj #endif
46463Swnj 
56463Swnj #include <sys/param.h>
66463Swnj #include <sys/socket.h>
76463Swnj #include <sys/socketvar.h>
86463Swnj #define PRUREQUESTS
96463Swnj #include <sys/protosw.h>
109202Ssam 
116463Swnj #include <net/route.h>
126463Swnj #include <net/if.h>
139202Ssam 
149202Ssam #include <netinet/in.h>
159202Ssam #include <netinet/in_pcb.h>
169202Ssam #include <netinet/in_systm.h>
179202Ssam #include <netinet/ip.h>
189202Ssam #include <netinet/ip_var.h>
199202Ssam #include <netinet/tcp.h>
206463Swnj #define TCPSTATES
219202Ssam #include <netinet/tcp_fsm.h>
229202Ssam #include <netinet/tcp_seq.h>
236463Swnj #define	TCPTIMERS
249202Ssam #include <netinet/tcp_timer.h>
259202Ssam #include <netinet/tcp_var.h>
269202Ssam #include <netinet/tcpip.h>
276463Swnj #define	TANAMES
289202Ssam #include <netinet/tcp_debug.h>
299202Ssam 
3010272Ssam #include <stdio.h>
316463Swnj #include <errno.h>
326463Swnj #include <nlist.h>
336463Swnj 
346463Swnj n_time	ntime;
356463Swnj int	sflag;
36*10425Ssam int	tflag;
37*10425Ssam int	jflag;
38*10425Ssam int	numeric();
396463Swnj struct	nlist nl[] = {
406463Swnj 	{ "_tcp_debug" },
416463Swnj 	{ "_tcp_debx" },
426463Swnj 	0
436463Swnj };
446463Swnj struct	tcp_debug tcp_debug[TCP_NDEBUG];
45*10425Ssam caddr_t	tcp_pcbs[TCP_NDEBUG];
466463Swnj int	tcp_debx;
476463Swnj 
486463Swnj main(argc, argv)
496463Swnj 	int argc;
506463Swnj 	char **argv;
516463Swnj {
52*10425Ssam 	int i, mask = 0, npcbs = 0;
5310272Ssam 	char *system = "/vmunix", *core = "/dev/kmem";
546463Swnj 
556463Swnj 	argc--, argv++;
566463Swnj again:
576463Swnj 	if (argc > 0 && !strcmp(*argv, "-s")) {
586463Swnj 		sflag++, argc--, argv++;
596463Swnj 		goto again;
606463Swnj 	}
61*10425Ssam 	if (argc > 0 && !strcmp(*argv, "-t")) {
62*10425Ssam 		tflag++, argc--, argv++;
63*10425Ssam 		goto again;
64*10425Ssam 	}
65*10425Ssam 	if (argc > 0 && !strcmp(*argv, "-j")) {
66*10425Ssam 		jflag++, argc--, argv++;
67*10425Ssam 		goto again;
68*10425Ssam 	}
6910272Ssam 	if (argc > 0 && !strcmp(*argv, "-p")) {
70*10425Ssam 		argc--, argv++;
7110272Ssam 		if (argc < 1) {
7210272Ssam 			fprintf(stderr, "-p: missing tcpcb address\n");
7310272Ssam 			exit(1);
7410272Ssam 		}
75*10425Ssam 		if (npcbs >= TCP_NDEBUG) {
76*10425Ssam 			fprintf(stderr, "-p: too many pcb's specified\n");
77*10425Ssam 			exit(1);
78*10425Ssam 		}
79*10425Ssam 		sscanf(*argv, "%x", &tcp_pcbs[npcbs++]);
8010272Ssam 		argc--, argv++;
8110272Ssam 		goto again;
8210272Ssam 	}
8310272Ssam 	if (argc > 0) {
8410272Ssam 		system = *argv;
8510272Ssam 		argc--, argv++;
8610272Ssam 		mask++;
8710272Ssam 	}
8810272Ssam 	if (argc > 0) {
8910272Ssam 		core = *argv;
9010272Ssam 		argc--, argv++;
9110272Ssam 		mask++;
9210272Ssam 	}
9310272Ssam 	(void) nlist(system, nl);
946463Swnj 	if (nl[0].n_value == 0) {
9510272Ssam 		fprintf(stderr, "trpt: %s: no namelist\n", system);
966463Swnj 		exit(1);
976463Swnj 	}
9810272Ssam 	(void) close(0);
9910272Ssam 	if (open(core, 0) < 0) {
10010272Ssam 		fprintf(stderr, "trpt: "); perror(core);
10110272Ssam 		exit(2);
10210272Ssam 	}
10310272Ssam 	if (mask) {
1046463Swnj 		nl[0].n_value &= 0x7fffffff;
1056463Swnj 		nl[1].n_value &= 0x7fffffff;
1066463Swnj 	}
10710272Ssam 	(void) lseek(0, nl[1].n_value, 0);
10810272Ssam 	if (read(0, &tcp_debx, sizeof (tcp_debx)) != sizeof (tcp_debx)) {
10910272Ssam 		fprintf(stderr, "trpt: "); perror("tcp_debx");
11010272Ssam 		exit(3);
11110272Ssam 	}
1126463Swnj 	printf("tcp_debx=%d\n", tcp_debx);
11310272Ssam 	(void) lseek(0, nl[0].n_value, 0);
11410272Ssam 	if (read(0, tcp_debug, sizeof (tcp_debug)) != sizeof (tcp_debug)) {
11510272Ssam 		fprintf(stderr, "trpt: "); perror("tcp_debug");
11610272Ssam 		exit(3);
11710272Ssam 	}
118*10425Ssam 	/*
119*10425Ssam 	 * If no control blocks have been specified, figure
120*10425Ssam 	 * out how many distinct one we have and summarize
121*10425Ssam 	 * them in tcp_pcbs for sorting the trace records
122*10425Ssam 	 * below.
123*10425Ssam 	 */
124*10425Ssam 	if (npcbs == 0) {
125*10425Ssam 		for (i = 0; i < TCP_NDEBUG; i++) {
126*10425Ssam 			register int j;
127*10425Ssam 			register struct tcp_debug *td = &tcp_debug[i];
1288382Ssam 
129*10425Ssam 			if (td->td_tcb == 0)
130*10425Ssam 				continue;
131*10425Ssam 			for (j = 0; j < npcbs; j++)
132*10425Ssam 				if (tcp_pcbs[j] == td->td_tcb)
133*10425Ssam 					break;
134*10425Ssam 			if (j >= npcbs)
135*10425Ssam 				tcp_pcbs[npcbs++] = td->td_tcb;
136*10425Ssam 		}
137*10425Ssam 	}
138*10425Ssam 	qsort(tcp_pcbs, npcbs, sizeof (caddr_t), numeric);
139*10425Ssam 	if (jflag) {
140*10425Ssam 		char *cp = "";
141*10425Ssam 
142*10425Ssam 		for (i = 0; i < npcbs; i++) {
143*10425Ssam 			printf("%s%x", cp, tcp_pcbs[i]);
144*10425Ssam 			cp = ", ";
145*10425Ssam 		}
146*10425Ssam 		if (*cp)
147*10425Ssam 			putchar('\n');
148*10425Ssam 		exit(0);
149*10425Ssam 	}
150*10425Ssam 	for (i = 0; i < npcbs; i++) {
151*10425Ssam 		printf("\n%x:\n", tcp_pcbs[i]);
152*10425Ssam 		dotrace(tcp_pcbs[i]);
153*10425Ssam 	}
154*10425Ssam 	exit(0);
155*10425Ssam }
156*10425Ssam 
157*10425Ssam dotrace(tcpcb)
158*10425Ssam 	register caddr_t tcpcb;
159*10425Ssam {
160*10425Ssam 	register int i;
161*10425Ssam 	register struct tcp_debug *td;
162*10425Ssam 
163*10425Ssam 	for (i = 0; i < tcp_debx % TCP_NDEBUG; i++) {
164*10425Ssam 		td = &tcp_debug[i];
16510272Ssam 		if (tcpcb && td->td_tcb != tcpcb)
16610272Ssam 			continue;
1678382Ssam 		ntime = ntohl(td->td_time);
1686463Swnj 		tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb,
1696463Swnj 		    &td->td_ti, td->td_req);
1706463Swnj 	}
171*10425Ssam 	for (i = tcp_debx % TCP_NDEBUG; i < TCP_NDEBUG; i++) {
172*10425Ssam 		td = &tcp_debug[i];
17310272Ssam 		if (tcpcb && td->td_tcb != tcpcb)
17410272Ssam 			continue;
1758382Ssam 		ntime = ntohl(td->td_time);
1766463Swnj 		tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb,
1776463Swnj 		    &td->td_ti, td->td_req);
1786463Swnj 	}
1796463Swnj }
1806463Swnj 
1816463Swnj /*
1826463Swnj  * Tcp debug routines
1836463Swnj  */
1846463Swnj tcp_trace(act, ostate, atp, tp, ti, req)
1856463Swnj 	short act, ostate;
1866463Swnj 	struct tcpcb *atp, *tp;
1876463Swnj 	struct tcpiphdr *ti;
1886463Swnj 	int req;
1896463Swnj {
1906463Swnj 	tcp_seq seq, ack;
1918382Ssam 	int len, flags, win, timer;
1926463Swnj 	char *cp;
1936463Swnj 
1946463Swnj 	ptime(ntime);
195*10425Ssam 	printf("%s:%s ", tcpstates[ostate], tanames[act]);
1966463Swnj 	switch (act) {
1976463Swnj 
1986463Swnj 	case TA_INPUT:
1996463Swnj 	case TA_OUTPUT:
2006463Swnj 		seq = ti->ti_seq;
2016463Swnj 		ack = ti->ti_ack;
2026463Swnj 		len = ti->ti_len;
2036463Swnj 		win = ti->ti_win;
2046463Swnj 		if (act == TA_OUTPUT) {
2056463Swnj 			seq = ntohl(seq);
2066463Swnj 			ack = ntohl(ack);
2076463Swnj 			len = ntohs(len);
2086463Swnj 			win = ntohs(win);
2096463Swnj 		}
2106463Swnj 		if (act == TA_OUTPUT)
2116463Swnj 			len -= sizeof (struct tcphdr);
2126463Swnj 		if (len)
2136463Swnj 			printf("[%x..%x)", seq, seq+len);
2146463Swnj 		else
2156463Swnj 			printf("%x", seq);
2166463Swnj 		printf("@%x", ack);
2176463Swnj 		if (win)
2186463Swnj 			printf("(win=%d)", win);
2196463Swnj 		flags = ti->ti_flags;
2206463Swnj 		if (flags) {
2216463Swnj 			char *cp = "<";
2226463Swnj #define pf(f) { if (ti->ti_flags&TH_/**/f) { printf("%s%s", cp, "f"); cp = ","; } }
22310411Ssam 			pf(SYN); pf(ACK); pf(FIN); pf(RST); pf(PUSH); pf(URG);
2246463Swnj 			printf(">");
2256463Swnj 		}
2266463Swnj 		break;
2276463Swnj 
2286463Swnj 	case TA_USER:
2298382Ssam 		timer = req >> 8;
2308382Ssam 		req &= 0xff;
2318382Ssam 		printf("%s", prurequests[req]);
2328382Ssam 		if (req == PRU_SLOWTIMO || req == PRU_FASTTIMO)
2338382Ssam 			printf("<%s>", tcptimers[timer]);
2346463Swnj 		break;
2356463Swnj 	}
2366463Swnj 	printf(" -> %s", tcpstates[tp->t_state]);
2376463Swnj 	/* print out internal state of tp !?! */
2386463Swnj 	printf("\n");
2396463Swnj 	if (sflag) {
2406463Swnj 		printf("\trcv_nxt %x rcv_wnd %d snd_una %x snd_nxt %x snd_max %x\n",
24110272Ssam 		    tp->rcv_nxt, tp->rcv_wnd, tp->snd_una, tp->snd_nxt,
24210272Ssam 		    tp->snd_max);
24310272Ssam 		printf("\tsnd_wl1 %x snd_wl2 %x snd_wnd %x\n", tp->snd_wl1,
24410272Ssam 		    tp->snd_wl2, tp->snd_wnd);
2456463Swnj 	}
246*10425Ssam 	/* print out timers? */
247*10425Ssam 	if (tflag) {
248*10425Ssam 		char *cp = "\t";
249*10425Ssam 		register int i;
250*10425Ssam 
251*10425Ssam 		for (i = 0; i < TCPT_NTIMERS; i++) {
252*10425Ssam 			if (tp->t_timer[i] == 0)
253*10425Ssam 				continue;
254*10425Ssam 			printf("%s%s=%d", cp, tcptimers[i], tp->t_timer[i]);
255*10425Ssam 			if (i == TCPT_REXMT)
256*10425Ssam 				printf(" (t_rxtshft=%d)", tp->t_rxtshift);
257*10425Ssam 			cp = ", ";
258*10425Ssam 		}
259*10425Ssam 		if (*cp != '\t')
260*10425Ssam 			putchar('\n');
261*10425Ssam 	}
2626463Swnj }
2636463Swnj 
2646463Swnj ptime(ms)
2656463Swnj 	int ms;
2666463Swnj {
2676463Swnj 
2686463Swnj 	printf("%03d ", (ms/10) % 1000);
2696463Swnj }
270*10425Ssam 
271*10425Ssam numeric(c1, c2)
272*10425Ssam 	caddr_t *c1, *c2;
273*10425Ssam {
274*10425Ssam 
275*10425Ssam 	return (*c1 - *c2);
276*10425Ssam }
277