xref: /original-bsd/usr.sbin/trsp/trsp.c (revision ea3a8ee8)
1 /*
2  * Copyright (c) 1985 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 char copyright[] =
10 "@(#) Copyright (c) 1985 Regents of the University of California.\n\
11  All rights reserved.\n";
12 #endif /* not lint */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)trsp.c	6.9 (Berkeley) 01/28/92";
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 
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 
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 
240 ptime(ms)
241 	int ms;
242 {
243 
244 	printf("%03d ", (ms/10) % 1000);
245 }
246 
247 numeric(c1, c2)
248 	caddr_t *c1, *c2;
249 {
250 
251 	return (*c1 - *c2);
252 }
253 
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 
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