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