xref: /csrg-svn/usr.sbin/trsp/trsp.c (revision 61895)
125117Ssklower /*
2*61895Sbostic  * Copyright (c) 1985, 1993
3*61895Sbostic  *	The Regents of the University of California.  All rights reserved.
434940Sbostic  *
542829Sbostic  * %sccs.include.redist.c%
625117Ssklower  */
725117Ssklower 
825117Ssklower #ifndef lint
9*61895Sbostic static char copyright[] =
10*61895Sbostic "@(#) Copyright (c) 1985, 1993\n\
11*61895Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1234940Sbostic #endif /* not lint */
1325117Ssklower 
1425117Ssklower #ifndef lint
15*61895Sbostic static char sccsid[] = "@(#)trsp.c	8.1 (Berkeley) 06/06/93";
1634940Sbostic #endif /* not lint */
1725117Ssklower 
1846933Sbostic #include <sys/cdefs.h>
1925117Ssklower #include <sys/param.h>
2025117Ssklower #include <sys/socket.h>
2125117Ssklower #include <sys/socketvar.h>
2225117Ssklower #define PRUREQUESTS
2325117Ssklower #include <sys/protosw.h>
2425117Ssklower 
2525117Ssklower #include <net/route.h>
2625117Ssklower #include <net/if.h>
2725117Ssklower 
2825117Ssklower #define TCPSTATES
2925117Ssklower #include <netinet/tcp_fsm.h>
3025117Ssklower #define	TCPTIMERS
3125117Ssklower #include <netinet/tcp_timer.h>
3225117Ssklower 
3325117Ssklower #include <netns/ns.h>
3446933Sbostic #include <netns/sp.h>
3525117Ssklower #include <netns/idp.h>
3625117Ssklower #include <netns/spidp.h>
3735616Sbostic #include <netns/spp_timer.h>
3825117Ssklower #include <netns/spp_var.h>
3946933Sbostic #include <netns/ns_pcb.h>
4046933Sbostic #include <netns/idp_var.h>
4125117Ssklower #define SANAMES
4225117Ssklower #include <netns/spp_debug.h>
4325117Ssklower 
4425117Ssklower #include <stdio.h>
4525117Ssklower #include <errno.h>
4625117Ssklower #include <nlist.h>
4737985Sbostic #include <paths.h>
4825117Ssklower 
4925117Ssklower unsigned long	ntime;
5025117Ssklower int	sflag;
5125117Ssklower int	tflag;
5225117Ssklower int	jflag;
5325117Ssklower int	aflag;
5425117Ssklower int	zflag;
5525117Ssklower int	numeric();
5625117Ssklower struct	nlist nl[] = {
5725117Ssklower 	{ "_spp_debug" },
5825117Ssklower 	{ "_spp_debx" },
5925117Ssklower 	0
6025117Ssklower };
6125117Ssklower struct	spp_debug spp_debug[SPP_NDEBUG];
6225117Ssklower caddr_t	spp_pcbs[SPP_NDEBUG];
6325117Ssklower int	spp_debx;
6425117Ssklower 
main(argc,argv)6525117Ssklower main(argc, argv)
6625117Ssklower 	int argc;
6725117Ssklower 	char **argv;
6825117Ssklower {
6925117Ssklower 	int i, mask = 0, npcbs = 0;
7037309Sbostic 	char *system, *core;
7125117Ssklower 
7237309Sbostic 	system = _PATH_UNIX;
7337309Sbostic 	core = _PATH_KMEM;
7437309Sbostic 
7525117Ssklower 	argc--, argv++;
7625117Ssklower again:
7725117Ssklower 	if (argc > 0 && !strcmp(*argv, "-a")) {
7825117Ssklower 		aflag++, argc--, argv++;
7925117Ssklower 		goto again;
8025117Ssklower 	}
8125117Ssklower 	if (argc > 0 && !strcmp(*argv, "-z")) {
8225117Ssklower 		zflag++, argc--, argv++;
8325117Ssklower 		goto again;
8425117Ssklower 	}
8525117Ssklower 	if (argc > 0 && !strcmp(*argv, "-s")) {
8625117Ssklower 		sflag++, argc--, argv++;
8725117Ssklower 		goto again;
8825117Ssklower 	}
8925117Ssklower 	if (argc > 0 && !strcmp(*argv, "-t")) {
9025117Ssklower 		tflag++, argc--, argv++;
9125117Ssklower 		goto again;
9225117Ssklower 	}
9325117Ssklower 	if (argc > 0 && !strcmp(*argv, "-j")) {
9425117Ssklower 		jflag++, argc--, argv++;
9525117Ssklower 		goto again;
9625117Ssklower 	}
9725117Ssklower 	if (argc > 0 && !strcmp(*argv, "-p")) {
9825117Ssklower 		argc--, argv++;
9925117Ssklower 		if (argc < 1) {
10025117Ssklower 			fprintf(stderr, "-p: missing sppcb address\n");
10125117Ssklower 			exit(1);
10225117Ssklower 		}
10325117Ssklower 		if (npcbs >= SPP_NDEBUG) {
10425117Ssklower 			fprintf(stderr, "-p: too many pcb's specified\n");
10525117Ssklower 			exit(1);
10625117Ssklower 		}
10725117Ssklower 		sscanf(*argv, "%x", &spp_pcbs[npcbs++]);
10825117Ssklower 		argc--, argv++;
10925117Ssklower 		goto again;
11025117Ssklower 	}
11125117Ssklower 	if (argc > 0) {
11225117Ssklower 		system = *argv;
11325117Ssklower 		argc--, argv++;
11425117Ssklower 		mask++;
11552256Sbostic 		/*
11652256Sbostic 		 * Discard setgid privileges if not the running kernel so that
11752256Sbostic 		 * bad guys can't print interesting stuff from kernel memory.
11852256Sbostic 		 */
11952256Sbostic 		setgid(getgid());
12025117Ssklower 	}
12125117Ssklower 	if (argc > 0) {
12225117Ssklower 		core = *argv;
12325117Ssklower 		argc--, argv++;
12425117Ssklower 		mask++;
12552256Sbostic 		setgid(getgid());
12625117Ssklower 	}
12725117Ssklower 	(void) nlist(system, nl);
12825117Ssklower 	if (nl[0].n_value == 0) {
12925117Ssklower 		fprintf(stderr, "trsp: %s: no namelist\n", system);
13025117Ssklower 		exit(1);
13125117Ssklower 	}
13225117Ssklower 	(void) close(0);
13325117Ssklower 	if (open(core, 0) < 0) {
13425117Ssklower 		fprintf(stderr, "trsp: "); perror(core);
13525117Ssklower 		exit(2);
13625117Ssklower 	}
13725117Ssklower 	if (mask) {
13825117Ssklower 		nl[0].n_value &= 0x7fffffff;
13925117Ssklower 		nl[1].n_value &= 0x7fffffff;
14025117Ssklower 	}
14125117Ssklower 	(void) lseek(0, nl[1].n_value, 0);
14225117Ssklower 	if (read(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
14325117Ssklower 		fprintf(stderr, "trsp: "); perror("spp_debx");
14425117Ssklower 		exit(3);
14525117Ssklower 	}
14625117Ssklower 	printf("spp_debx=%d\n", spp_debx);
14725117Ssklower 	(void) lseek(0, nl[0].n_value, 0);
14825117Ssklower 	if (read(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
14925117Ssklower 		fprintf(stderr, "trsp: "); perror("spp_debug");
15025117Ssklower 		exit(3);
15125117Ssklower 	}
15225117Ssklower 	/*
15325117Ssklower 	 * Here, we just want to clear out the old trace data and start over.
15425117Ssklower 	 */
15525117Ssklower 	if (zflag) {
15625117Ssklower 		char *cp = (char *) spp_debug,
15725117Ssklower 		     *cplim = cp + sizeof(spp_debug);
15825117Ssklower 		(void) close(0);
15925117Ssklower 		if (open(core, 2) < 0) {
16025117Ssklower 			fprintf(stderr, "trsp: "); perror(core);
16125117Ssklower 			exit(2);
16225117Ssklower 		}
16325117Ssklower 		while(cp < cplim) *cp++ = 0;
16425117Ssklower 		(void) lseek(0, nl[0].n_value, 0);
16525117Ssklower 		if (write(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
16625117Ssklower 			fprintf(stderr, "trsp: "); perror("spp_debug");
16725117Ssklower 			exit(3);
16825117Ssklower 		}
16925117Ssklower 		(void) lseek(0, nl[1].n_value, 0);
17025117Ssklower 		spp_debx = 0;
17125117Ssklower 		if (write(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
17225117Ssklower 			fprintf(stderr, "trsp: "); perror("spp_debx");
17325117Ssklower 			exit(3);
17425117Ssklower 		}
17525117Ssklower 		exit(0);
17625117Ssklower 	}
17725117Ssklower 	/*
17825117Ssklower 	 * If no control blocks have been specified, figure
17925117Ssklower 	 * out how many distinct one we have and summarize
18025117Ssklower 	 * them in spp_pcbs for sorting the trace records
18125117Ssklower 	 * below.
18225117Ssklower 	 */
18325117Ssklower 	if (npcbs == 0) {
18425117Ssklower 		for (i = 0; i < SPP_NDEBUG; i++) {
18525117Ssklower 			register int j;
18625117Ssklower 			register struct spp_debug *sd = &spp_debug[i];
18725117Ssklower 
18825117Ssklower 			if (sd->sd_cb == 0)
18925117Ssklower 				continue;
19025117Ssklower 			for (j = 0; j < npcbs; j++)
19125117Ssklower 				if (spp_pcbs[j] == sd->sd_cb)
19225117Ssklower 					break;
19325117Ssklower 			if (j >= npcbs)
19425117Ssklower 				spp_pcbs[npcbs++] = sd->sd_cb;
19525117Ssklower 		}
19625117Ssklower 	}
19725117Ssklower 	qsort(spp_pcbs, npcbs, sizeof (caddr_t), numeric);
19825117Ssklower 	if (jflag) {
19925117Ssklower 		char *cp = "";
20025117Ssklower 
20125117Ssklower 		for (i = 0; i < npcbs; i++) {
20225117Ssklower 			printf("%s%x", cp, spp_pcbs[i]);
20325117Ssklower 			cp = ", ";
20425117Ssklower 		}
20525117Ssklower 		if (*cp)
20625117Ssklower 			putchar('\n');
20725117Ssklower 		exit(0);
20825117Ssklower 	}
20925117Ssklower 	for (i = 0; i < npcbs; i++) {
21025117Ssklower 		printf("\n%x:\n", spp_pcbs[i]);
21125117Ssklower 		dotrace(spp_pcbs[i]);
21225117Ssklower 	}
21325117Ssklower 	exit(0);
21425117Ssklower }
21525117Ssklower 
dotrace(sppcb)21625117Ssklower dotrace(sppcb)
21725117Ssklower 	register caddr_t sppcb;
21825117Ssklower {
21925117Ssklower 	register int i;
22025117Ssklower 	register struct spp_debug *sd;
22125117Ssklower 
22225117Ssklower 	for (i = spp_debx % SPP_NDEBUG; i < SPP_NDEBUG; i++) {
22325117Ssklower 		sd = &spp_debug[i];
22425117Ssklower 		if (sppcb && sd->sd_cb != sppcb)
22525117Ssklower 			continue;
22625117Ssklower 		ntime = ntohl(sd->sd_time);
22725117Ssklower 		spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
22825117Ssklower 		    &sd->sd_si, sd->sd_req);
22925117Ssklower 	}
23025117Ssklower 	for (i = 0; i < spp_debx % SPP_NDEBUG; i++) {
23125117Ssklower 		sd = &spp_debug[i];
23225117Ssklower 		if (sppcb && sd->sd_cb != sppcb)
23325117Ssklower 			continue;
23425117Ssklower 		ntime = ntohl(sd->sd_time);
23525117Ssklower 		spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
23625117Ssklower 		    &sd->sd_si, sd->sd_req);
23725117Ssklower 	}
23825117Ssklower }
23925117Ssklower 
ptime(ms)24025117Ssklower ptime(ms)
24125117Ssklower 	int ms;
24225117Ssklower {
24325117Ssklower 
24425117Ssklower 	printf("%03d ", (ms/10) % 1000);
24525117Ssklower }
24625117Ssklower 
numeric(c1,c2)24725117Ssklower numeric(c1, c2)
24825117Ssklower 	caddr_t *c1, *c2;
24925117Ssklower {
25025117Ssklower 
25125117Ssklower 	return (*c1 - *c2);
25225117Ssklower }
25325117Ssklower 
spp_trace(act,ostate,asp,sp,si,req)25425117Ssklower spp_trace(act, ostate, asp, sp, si, req)
25525117Ssklower 	short act, ostate;
25625117Ssklower 	struct sppcb *asp, *sp;
25725117Ssklower 	struct spidp *si;
25825117Ssklower 	int req;
25925117Ssklower {
26025117Ssklower 	u_short seq, ack, len, alo;
26125117Ssklower 	int flags, timer;
26225117Ssklower 	char *cp;
26325117Ssklower 
26425117Ssklower 	if(ostate >= TCP_NSTATES) ostate = 0;
26525117Ssklower 	if(act > SA_DROP) act = SA_DROP;
26625117Ssklower 	printf("\n");
26725117Ssklower 	ptime(ntime);
26825117Ssklower 	printf("%s:%s", tcpstates[ostate], sanames[act]);
26925117Ssklower 
27025117Ssklower 	if (si != 0) {
27125117Ssklower 		seq = si->si_seq;
27225117Ssklower 		ack = si->si_ack;
27325117Ssklower 		alo = si->si_alo;
27425117Ssklower 		len = si->si_len;
27525117Ssklower 		switch (act) {
27625117Ssklower 		case SA_RESPOND:
27725117Ssklower 		case SA_OUTPUT:
27825117Ssklower 				seq = ntohs(seq);
27925117Ssklower 				ack = ntohs(ack);
28025117Ssklower 				alo = ntohs(alo);
28125117Ssklower 				len = ntohs(len);
28225117Ssklower 		case SA_INPUT:
28325117Ssklower 		case SA_DROP:
28425117Ssklower 			if (aflag) {
28525117Ssklower 				printf("\n\tsna=");
28625117Ssklower 				ns_printhost(&si->si_sna);
28725117Ssklower 				printf("\tdna=");
28825117Ssklower 				ns_printhost(&si->si_dna);
28925117Ssklower 			}
29025117Ssklower 			printf("\n\t");
29146933Sbostic #define p1(name, f) { \
29246933Sbostic 	printf("%s = %x, ", name, f); \
29346933Sbostic  }
29446933Sbostic 			p1("seq", seq);
29546933Sbostic 			p1("ack", ack);
29646933Sbostic 			p1("alo", alo);
29746933Sbostic 			p1("len", len);
29825117Ssklower 			flags = si->si_cc;
29925117Ssklower 			printf("flags=%x", flags);
30046933Sbostic #define pf(name, f) { \
30146933Sbostic 	if (flags & f) { \
30246933Sbostic 		printf("%s%s", cp, name); \
30346933Sbostic 		cp = ","; \
30446933Sbostic 	} \
30546933Sbostic }
30625117Ssklower 			if (flags) {
30725117Ssklower 				char *cp = "<";
30846933Sbostic 				pf("SP_SP", SP_SP);
30946933Sbostic 				pf("SP_SA", SP_SA);
31046933Sbostic 				pf("SP_OB", SP_OB);
31146933Sbostic 				pf("SP_EM", SP_EM);
31225117Ssklower 				printf(">");
31325117Ssklower 			}
31425117Ssklower 			printf(", ");
31546933Sbostic #define p2(name, f) { \
31646933Sbostic 	printf("%s = %x, ", name, f); \
31746933Sbostic }
31846933Sbostic 			p2("sid", si->si_sid);
31946933Sbostic 			p2("did", si->si_did);
32046933Sbostic 			p2("dt", si->si_dt);
32125117Ssklower 			printf("\n\tsna=");
32225117Ssklower 			ns_printhost(&si->si_sna);
32325117Ssklower 			printf("\tdna=");
32425117Ssklower 			ns_printhost(&si->si_dna);
32525117Ssklower 		}
32625117Ssklower 	}
32725117Ssklower 	if(act == SA_USER) {
32825117Ssklower 		printf("\treq=%s", prurequests[req&0xff]);
32925117Ssklower 		if ((req & 0xff) == PRU_SLOWTIMO)
33025117Ssklower 			printf("<%s>", tcptimers[req>>8]);
33125117Ssklower 	}
33225117Ssklower 	printf(" -> %s", tcpstates[sp->s_state]);
33325117Ssklower 
33425117Ssklower 	/* print out internal state of sp !?! */
33525117Ssklower 	printf("\n");
33625117Ssklower 	if (sp == 0)
33725117Ssklower 		return;
33846933Sbostic #define p3(name, f)  { \
33946933Sbostic 	printf("%s = %x, ", name, f); \
34046933Sbostic }
34146933Sbostic 	if (sflag) {
34246933Sbostic 		printf("\t");
34346933Sbostic 		p3("rack", sp->s_rack);
34446933Sbostic 		p3("ralo", sp->s_ralo);
34546933Sbostic 		p3("smax", sp->s_smax);
34646933Sbostic 		p3("snxt", sp->s_snxt);
34746933Sbostic 		p3("flags", sp->s_flags);
34825117Ssklower #undef pf
34946933Sbostic #define pf(name, f) { \
35046933Sbostic 	if (flags & f) { \
35146933Sbostic 		printf("%s%s", cp, name); \
35246933Sbostic 		cp = ","; \
35346933Sbostic 	} \
35446933Sbostic }
35525117Ssklower 		flags = sp->s_flags;
35625117Ssklower 		if (flags || sp->s_oobflags) {
35725117Ssklower 			char *cp = "<";
35846933Sbostic 			pf("ACKNOW", SF_ACKNOW);
35946933Sbostic 			pf("DELACK", SF_DELACK);
36046933Sbostic 			pf("HI", SF_HI);
36146933Sbostic 			pf("HO", SF_HO);
36246933Sbostic 			pf("PI", SF_PI);
36346933Sbostic 			pf("WIN", SF_WIN);
36446933Sbostic 			pf("RXT", SF_RXT);
36546933Sbostic 			pf("RVD", SF_RVD);
36625117Ssklower 			flags = sp->s_oobflags;
36746933Sbostic 			pf("SOOB", SF_SOOB);
36846933Sbostic 			pf("IOOB", SF_IOOB);
36925117Ssklower 			printf(">");
37025117Ssklower 		}
37125117Ssklower 	}
37225117Ssklower 	/* print out timers? */
37325117Ssklower 	if (tflag) {
37425117Ssklower 		char *cp = "\t";
37525117Ssklower 		register int i;
37625117Ssklower 
37725117Ssklower 		printf("\n\tTIMERS: ");
37846933Sbostic 		p3("idle", sp->s_idle);
37946933Sbostic 		p3("force", sp->s_force);
38046933Sbostic 		p3("rtseq", sp->s_rtseq);
38125117Ssklower 		for (i = 0; i < TCPT_NTIMERS; i++) {
38225117Ssklower 			if (sp->s_timer[i] == 0)
38325117Ssklower 				continue;
38425117Ssklower 			printf("%s%s=%d", cp, tcptimers[i], sp->s_timer[i]);
38525117Ssklower 			if (i == TCPT_REXMT)
38625117Ssklower 				printf(" (s_rxtshft=%d)", sp->s_rxtshift);
38725117Ssklower 			cp = ", ";
38825117Ssklower 		}
38925117Ssklower 		if (*cp != '\t')
39025117Ssklower 			putchar('\n');
39125117Ssklower 	}
39225117Ssklower }
39325117Ssklower 
ns_printhost(p)39425117Ssklower ns_printhost(p)
39525117Ssklower register struct ns_addr *p;
39625117Ssklower {
39725117Ssklower 
39825117Ssklower 	printf("<net:%x%x,host:%4.4x%4.4x%4.4x,port:%x>",
39925117Ssklower 			p->x_net.s_net[0],
40025117Ssklower 			p->x_net.s_net[1],
40125117Ssklower 			p->x_host.s_host[0],
40225117Ssklower 			p->x_host.s_host[1],
40325117Ssklower 			p->x_host.s_host[2],
40425117Ssklower 			p->x_port);
40525117Ssklower 
40625117Ssklower }
40725117Ssklower 
408