xref: /csrg-svn/usr.sbin/trsp/trsp.c (revision 35616)
125117Ssklower /*
225117Ssklower  * Copyright (c) 1985 Regents of the University of California.
334940Sbostic  * All rights reserved.
434940Sbostic  *
534940Sbostic  * Redistribution and use in source and binary forms are permitted
634940Sbostic  * provided that the above copyright notice and this paragraph are
734940Sbostic  * duplicated in all such forms and that any documentation,
834940Sbostic  * advertising materials, and other materials related to such
934940Sbostic  * distribution and use acknowledge that the software was developed
1034940Sbostic  * by the University of California, Berkeley.  The name of the
1134940Sbostic  * University may not be used to endorse or promote products derived
1234940Sbostic  * from this software without specific prior written permission.
1334940Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1434940Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1534940Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1625117Ssklower  */
1725117Ssklower 
1825117Ssklower #ifndef lint
1925117Ssklower char copyright[] =
2034940Sbostic "@(#) Copyright (c) 1985 Regents of the University of California.\n\
2125117Ssklower  All rights reserved.\n";
2234940Sbostic #endif /* not lint */
2325117Ssklower 
2425117Ssklower #ifndef lint
25*35616Sbostic static char sccsid[] = "@(#)trsp.c	6.3 (Berkeley) 09/20/88";
2634940Sbostic #endif /* not lint */
2725117Ssklower 
2825117Ssklower #include <sys/param.h>
2925117Ssklower #include <sys/socket.h>
3025117Ssklower #include <sys/socketvar.h>
3125117Ssklower #define PRUREQUESTS
3225117Ssklower #include <sys/protosw.h>
3325117Ssklower 
3425117Ssklower #include <net/route.h>
3525117Ssklower #include <net/if.h>
3625117Ssklower 
3725117Ssklower #define TCPSTATES
3825117Ssklower #include <netinet/tcp_fsm.h>
3925117Ssklower #define	TCPTIMERS
4025117Ssklower #include <netinet/tcp_timer.h>
4125117Ssklower 
4225117Ssklower #include <netns/ns.h>
4325117Ssklower #include <netns/ns_pcb.h>
4425117Ssklower #include <netns/idp.h>
4525117Ssklower #include <netns/idp_var.h>
4625117Ssklower #include <netns/sp.h>
4725117Ssklower #include <netns/spidp.h>
48*35616Sbostic #include <netns/spp_timer.h>
4925117Ssklower #include <netns/spp_var.h>
5025117Ssklower #define SANAMES
5125117Ssklower #include <netns/spp_debug.h>
5225117Ssklower 
5325117Ssklower #include <stdio.h>
5425117Ssklower #include <errno.h>
5525117Ssklower #include <nlist.h>
5625117Ssklower 
5725117Ssklower unsigned long	ntime;
5825117Ssklower int	sflag;
5925117Ssklower int	tflag;
6025117Ssklower int	jflag;
6125117Ssklower int	aflag;
6225117Ssklower int	zflag;
6325117Ssklower int	numeric();
6425117Ssklower struct	nlist nl[] = {
6525117Ssklower 	{ "_spp_debug" },
6625117Ssklower 	{ "_spp_debx" },
6725117Ssklower 	0
6825117Ssklower };
6925117Ssklower struct	spp_debug spp_debug[SPP_NDEBUG];
7025117Ssklower caddr_t	spp_pcbs[SPP_NDEBUG];
7125117Ssklower int	spp_debx;
7225117Ssklower 
7325117Ssklower main(argc, argv)
7425117Ssklower 	int argc;
7525117Ssklower 	char **argv;
7625117Ssklower {
7725117Ssklower 	int i, mask = 0, npcbs = 0;
7825117Ssklower 	char *system = "/vmunix", *core = "/dev/kmem";
7925117Ssklower 
8025117Ssklower 	argc--, argv++;
8125117Ssklower again:
8225117Ssklower 	if (argc > 0 && !strcmp(*argv, "-a")) {
8325117Ssklower 		aflag++, argc--, argv++;
8425117Ssklower 		goto again;
8525117Ssklower 	}
8625117Ssklower 	if (argc > 0 && !strcmp(*argv, "-z")) {
8725117Ssklower 		zflag++, argc--, argv++;
8825117Ssklower 		goto again;
8925117Ssklower 	}
9025117Ssklower 	if (argc > 0 && !strcmp(*argv, "-s")) {
9125117Ssklower 		sflag++, argc--, argv++;
9225117Ssklower 		goto again;
9325117Ssklower 	}
9425117Ssklower 	if (argc > 0 && !strcmp(*argv, "-t")) {
9525117Ssklower 		tflag++, argc--, argv++;
9625117Ssklower 		goto again;
9725117Ssklower 	}
9825117Ssklower 	if (argc > 0 && !strcmp(*argv, "-j")) {
9925117Ssklower 		jflag++, argc--, argv++;
10025117Ssklower 		goto again;
10125117Ssklower 	}
10225117Ssklower 	if (argc > 0 && !strcmp(*argv, "-p")) {
10325117Ssklower 		argc--, argv++;
10425117Ssklower 		if (argc < 1) {
10525117Ssklower 			fprintf(stderr, "-p: missing sppcb address\n");
10625117Ssklower 			exit(1);
10725117Ssklower 		}
10825117Ssklower 		if (npcbs >= SPP_NDEBUG) {
10925117Ssklower 			fprintf(stderr, "-p: too many pcb's specified\n");
11025117Ssklower 			exit(1);
11125117Ssklower 		}
11225117Ssklower 		sscanf(*argv, "%x", &spp_pcbs[npcbs++]);
11325117Ssklower 		argc--, argv++;
11425117Ssklower 		goto again;
11525117Ssklower 	}
11625117Ssklower 	if (argc > 0) {
11725117Ssklower 		system = *argv;
11825117Ssklower 		argc--, argv++;
11925117Ssklower 		mask++;
12025117Ssklower 	}
12125117Ssklower 	if (argc > 0) {
12225117Ssklower 		core = *argv;
12325117Ssklower 		argc--, argv++;
12425117Ssklower 		mask++;
12525117Ssklower 	}
12625117Ssklower 	(void) nlist(system, nl);
12725117Ssklower 	if (nl[0].n_value == 0) {
12825117Ssklower 		fprintf(stderr, "trsp: %s: no namelist\n", system);
12925117Ssklower 		exit(1);
13025117Ssklower 	}
13125117Ssklower 	(void) close(0);
13225117Ssklower 	if (open(core, 0) < 0) {
13325117Ssklower 		fprintf(stderr, "trsp: "); perror(core);
13425117Ssklower 		exit(2);
13525117Ssklower 	}
13625117Ssklower 	if (mask) {
13725117Ssklower 		nl[0].n_value &= 0x7fffffff;
13825117Ssklower 		nl[1].n_value &= 0x7fffffff;
13925117Ssklower 	}
14025117Ssklower 	(void) lseek(0, nl[1].n_value, 0);
14125117Ssklower 	if (read(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
14225117Ssklower 		fprintf(stderr, "trsp: "); perror("spp_debx");
14325117Ssklower 		exit(3);
14425117Ssklower 	}
14525117Ssklower 	printf("spp_debx=%d\n", spp_debx);
14625117Ssklower 	(void) lseek(0, nl[0].n_value, 0);
14725117Ssklower 	if (read(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
14825117Ssklower 		fprintf(stderr, "trsp: "); perror("spp_debug");
14925117Ssklower 		exit(3);
15025117Ssklower 	}
15125117Ssklower 	/*
15225117Ssklower 	 * Here, we just want to clear out the old trace data and start over.
15325117Ssklower 	 */
15425117Ssklower 	if (zflag) {
15525117Ssklower 		char *cp = (char *) spp_debug,
15625117Ssklower 		     *cplim = cp + sizeof(spp_debug);
15725117Ssklower 		(void) close(0);
15825117Ssklower 		if (open(core, 2) < 0) {
15925117Ssklower 			fprintf(stderr, "trsp: "); perror(core);
16025117Ssklower 			exit(2);
16125117Ssklower 		}
16225117Ssklower 		while(cp < cplim) *cp++ = 0;
16325117Ssklower 		(void) lseek(0, nl[0].n_value, 0);
16425117Ssklower 		if (write(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
16525117Ssklower 			fprintf(stderr, "trsp: "); perror("spp_debug");
16625117Ssklower 			exit(3);
16725117Ssklower 		}
16825117Ssklower 		(void) lseek(0, nl[1].n_value, 0);
16925117Ssklower 		spp_debx = 0;
17025117Ssklower 		if (write(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
17125117Ssklower 			fprintf(stderr, "trsp: "); perror("spp_debx");
17225117Ssklower 			exit(3);
17325117Ssklower 		}
17425117Ssklower 		exit(0);
17525117Ssklower 	}
17625117Ssklower 	/*
17725117Ssklower 	 * If no control blocks have been specified, figure
17825117Ssklower 	 * out how many distinct one we have and summarize
17925117Ssklower 	 * them in spp_pcbs for sorting the trace records
18025117Ssklower 	 * below.
18125117Ssklower 	 */
18225117Ssklower 	if (npcbs == 0) {
18325117Ssklower 		for (i = 0; i < SPP_NDEBUG; i++) {
18425117Ssklower 			register int j;
18525117Ssklower 			register struct spp_debug *sd = &spp_debug[i];
18625117Ssklower 
18725117Ssklower 			if (sd->sd_cb == 0)
18825117Ssklower 				continue;
18925117Ssklower 			for (j = 0; j < npcbs; j++)
19025117Ssklower 				if (spp_pcbs[j] == sd->sd_cb)
19125117Ssklower 					break;
19225117Ssklower 			if (j >= npcbs)
19325117Ssklower 				spp_pcbs[npcbs++] = sd->sd_cb;
19425117Ssklower 		}
19525117Ssklower 	}
19625117Ssklower 	qsort(spp_pcbs, npcbs, sizeof (caddr_t), numeric);
19725117Ssklower 	if (jflag) {
19825117Ssklower 		char *cp = "";
19925117Ssklower 
20025117Ssklower 		for (i = 0; i < npcbs; i++) {
20125117Ssklower 			printf("%s%x", cp, spp_pcbs[i]);
20225117Ssklower 			cp = ", ";
20325117Ssklower 		}
20425117Ssklower 		if (*cp)
20525117Ssklower 			putchar('\n');
20625117Ssklower 		exit(0);
20725117Ssklower 	}
20825117Ssklower 	for (i = 0; i < npcbs; i++) {
20925117Ssklower 		printf("\n%x:\n", spp_pcbs[i]);
21025117Ssklower 		dotrace(spp_pcbs[i]);
21125117Ssklower 	}
21225117Ssklower 	exit(0);
21325117Ssklower }
21425117Ssklower 
21525117Ssklower dotrace(sppcb)
21625117Ssklower 	register caddr_t sppcb;
21725117Ssklower {
21825117Ssklower 	register int i;
21925117Ssklower 	register struct spp_debug *sd;
22025117Ssklower 
22125117Ssklower 	for (i = spp_debx % SPP_NDEBUG; i < SPP_NDEBUG; i++) {
22225117Ssklower 		sd = &spp_debug[i];
22325117Ssklower 		if (sppcb && sd->sd_cb != sppcb)
22425117Ssklower 			continue;
22525117Ssklower 		ntime = ntohl(sd->sd_time);
22625117Ssklower 		spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
22725117Ssklower 		    &sd->sd_si, sd->sd_req);
22825117Ssklower 	}
22925117Ssklower 	for (i = 0; i < spp_debx % SPP_NDEBUG; i++) {
23025117Ssklower 		sd = &spp_debug[i];
23125117Ssklower 		if (sppcb && sd->sd_cb != sppcb)
23225117Ssklower 			continue;
23325117Ssklower 		ntime = ntohl(sd->sd_time);
23425117Ssklower 		spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
23525117Ssklower 		    &sd->sd_si, sd->sd_req);
23625117Ssklower 	}
23725117Ssklower }
23825117Ssklower 
23925117Ssklower ptime(ms)
24025117Ssklower 	int ms;
24125117Ssklower {
24225117Ssklower 
24325117Ssklower 	printf("%03d ", (ms/10) % 1000);
24425117Ssklower }
24525117Ssklower 
24625117Ssklower numeric(c1, c2)
24725117Ssklower 	caddr_t *c1, *c2;
24825117Ssklower {
24925117Ssklower 
25025117Ssklower 	return (*c1 - *c2);
25125117Ssklower }
25225117Ssklower 
25325117Ssklower spp_trace(act, ostate, asp, sp, si, req)
25425117Ssklower 	short act, ostate;
25525117Ssklower 	struct sppcb *asp, *sp;
25625117Ssklower 	struct spidp *si;
25725117Ssklower 	int req;
25825117Ssklower {
25925117Ssklower 	u_short seq, ack, len, alo;
26025117Ssklower 	int flags, timer;
26125117Ssklower 	char *cp;
26225117Ssklower 
26325117Ssklower 	if(ostate >= TCP_NSTATES) ostate = 0;
26425117Ssklower 	if(act > SA_DROP) act = SA_DROP;
26525117Ssklower 	printf("\n");
26625117Ssklower 	ptime(ntime);
26725117Ssklower 	printf("%s:%s", tcpstates[ostate], sanames[act]);
26825117Ssklower 
26925117Ssklower 	if (si != 0) {
27025117Ssklower 		seq = si->si_seq;
27125117Ssklower 		ack = si->si_ack;
27225117Ssklower 		alo = si->si_alo;
27325117Ssklower 		len = si->si_len;
27425117Ssklower 		switch (act) {
27525117Ssklower 		case SA_RESPOND:
27625117Ssklower 		case SA_OUTPUT:
27725117Ssklower 				seq = ntohs(seq);
27825117Ssklower 				ack = ntohs(ack);
27925117Ssklower 				alo = ntohs(alo);
28025117Ssklower 				len = ntohs(len);
28125117Ssklower 		case SA_INPUT:
28225117Ssklower 		case SA_DROP:
28325117Ssklower 			if (aflag) {
28425117Ssklower 				printf("\n\tsna=");
28525117Ssklower 				ns_printhost(&si->si_sna);
28625117Ssklower 				printf("\tdna=");
28725117Ssklower 				ns_printhost(&si->si_dna);
28825117Ssklower 			}
28925117Ssklower 			printf("\n\t");
29025117Ssklower #define p1(f)  { printf("%s = %x, ", "f", f); }
29125117Ssklower 			p1(seq); p1(ack); p1(alo); p1(len);
29225117Ssklower 			flags = si->si_cc;
29325117Ssklower 			printf("flags=%x", flags);
29425117Ssklower 			if (flags) {
29525117Ssklower 				char *cp = "<";
29625117Ssklower #define pf(f) { if (flags&SP_/**/f) { printf("%s%s", cp, "f"); cp = ","; } }
29725117Ssklower 				pf(SP); pf(SA); pf(OB); pf(EM);
29825117Ssklower 				printf(">");
29925117Ssklower 			}
30025117Ssklower 			printf(", ");
30125117Ssklower #define p2(f)  { printf("%s = %x, ", "f", si->si_/**/f); }
30225117Ssklower 			p2(sid);p2(did);p2(dt);
30325117Ssklower 			printf("\n\tsna=");
30425117Ssklower 			ns_printhost(&si->si_sna);
30525117Ssklower 			printf("\tdna=");
30625117Ssklower 			ns_printhost(&si->si_dna);
30725117Ssklower 		}
30825117Ssklower 	}
30925117Ssklower 	if(act == SA_USER) {
31025117Ssklower 		printf("\treq=%s", prurequests[req&0xff]);
31125117Ssklower 		if ((req & 0xff) == PRU_SLOWTIMO)
31225117Ssklower 			printf("<%s>", tcptimers[req>>8]);
31325117Ssklower 	}
31425117Ssklower 	printf(" -> %s", tcpstates[sp->s_state]);
31525117Ssklower 
31625117Ssklower 	/* print out internal state of sp !?! */
31725117Ssklower 	printf("\n");
31825117Ssklower 	if (sp == 0)
31925117Ssklower 		return;
32025117Ssklower #define p3(f)  { printf("%s = %x, ", "f", sp->s_/**/f); }
32125117Ssklower 	if(sflag) {
322*35616Sbostic 		printf("\t"); p3(rack); p3(ralo); p3(smax); p3(snxt); p3(flags);
32325117Ssklower #undef pf
32425117Ssklower #define pf(f) { if (flags&SF_/**/f) { printf("%s%s", cp, "f"); cp = ","; } }
32525117Ssklower 		flags = sp->s_flags;
32625117Ssklower 		if (flags || sp->s_oobflags) {
32725117Ssklower 			char *cp = "<";
328*35616Sbostic 			pf(ACKNOW); pf(DELACK); pf(HI); pf(HO);
329*35616Sbostic 			pf(PI); pf(WIN); pf(RXT); pf(RVD);
33025117Ssklower 			flags = sp->s_oobflags;
33125117Ssklower 			pf(SOOB); pf(IOOB);
33225117Ssklower 			printf(">");
33325117Ssklower 		}
33425117Ssklower 
33525117Ssklower 	}
33625117Ssklower 	/* print out timers? */
33725117Ssklower 	if (tflag) {
33825117Ssklower 		char *cp = "\t";
33925117Ssklower 		register int i;
34025117Ssklower 
34125117Ssklower 		printf("\n\tTIMERS: ");
34225117Ssklower 		p3(idle); p3(force); p3(rtseq);
34325117Ssklower 		for (i = 0; i < TCPT_NTIMERS; i++) {
34425117Ssklower 			if (sp->s_timer[i] == 0)
34525117Ssklower 				continue;
34625117Ssklower 			printf("%s%s=%d", cp, tcptimers[i], sp->s_timer[i]);
34725117Ssklower 			if (i == TCPT_REXMT)
34825117Ssklower 				printf(" (s_rxtshft=%d)", sp->s_rxtshift);
34925117Ssklower 			cp = ", ";
35025117Ssklower 		}
35125117Ssklower 		if (*cp != '\t')
35225117Ssklower 			putchar('\n');
35325117Ssklower 	}
35425117Ssklower }
35525117Ssklower 
35625117Ssklower ns_printhost(p)
35725117Ssklower register struct ns_addr *p;
35825117Ssklower {
35925117Ssklower 
36025117Ssklower 	printf("<net:%x%x,host:%4.4x%4.4x%4.4x,port:%x>",
36125117Ssklower 			p->x_net.s_net[0],
36225117Ssklower 			p->x_net.s_net[1],
36325117Ssklower 			p->x_host.s_host[0],
36425117Ssklower 			p->x_host.s_host[1],
36525117Ssklower 			p->x_host.s_host[2],
36625117Ssklower 			p->x_port);
36725117Ssklower 
36825117Ssklower }
36925117Ssklower 
370