xref: /original-bsd/usr.sbin/trsp/trsp.c (revision 3e9e8393)
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.2 (Berkeley) 07/01/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_var.h>
49 #define SANAMES
50 #include <netns/spp_debug.h>
51 
52 #include <stdio.h>
53 #include <errno.h>
54 #include <nlist.h>
55 
56 unsigned long	ntime;
57 int	sflag;
58 int	tflag;
59 int	jflag;
60 int	aflag;
61 int	zflag;
62 int	numeric();
63 struct	nlist nl[] = {
64 	{ "_spp_debug" },
65 	{ "_spp_debx" },
66 	0
67 };
68 struct	spp_debug spp_debug[SPP_NDEBUG];
69 caddr_t	spp_pcbs[SPP_NDEBUG];
70 int	spp_debx;
71 
72 main(argc, argv)
73 	int argc;
74 	char **argv;
75 {
76 	int i, mask = 0, npcbs = 0;
77 	char *system = "/vmunix", *core = "/dev/kmem";
78 
79 	argc--, argv++;
80 again:
81 	if (argc > 0 && !strcmp(*argv, "-a")) {
82 		aflag++, argc--, argv++;
83 		goto again;
84 	}
85 	if (argc > 0 && !strcmp(*argv, "-z")) {
86 		zflag++, argc--, argv++;
87 		goto again;
88 	}
89 	if (argc > 0 && !strcmp(*argv, "-s")) {
90 		sflag++, argc--, argv++;
91 		goto again;
92 	}
93 	if (argc > 0 && !strcmp(*argv, "-t")) {
94 		tflag++, argc--, argv++;
95 		goto again;
96 	}
97 	if (argc > 0 && !strcmp(*argv, "-j")) {
98 		jflag++, argc--, argv++;
99 		goto again;
100 	}
101 	if (argc > 0 && !strcmp(*argv, "-p")) {
102 		argc--, argv++;
103 		if (argc < 1) {
104 			fprintf(stderr, "-p: missing sppcb address\n");
105 			exit(1);
106 		}
107 		if (npcbs >= SPP_NDEBUG) {
108 			fprintf(stderr, "-p: too many pcb's specified\n");
109 			exit(1);
110 		}
111 		sscanf(*argv, "%x", &spp_pcbs[npcbs++]);
112 		argc--, argv++;
113 		goto again;
114 	}
115 	if (argc > 0) {
116 		system = *argv;
117 		argc--, argv++;
118 		mask++;
119 	}
120 	if (argc > 0) {
121 		core = *argv;
122 		argc--, argv++;
123 		mask++;
124 	}
125 	(void) nlist(system, nl);
126 	if (nl[0].n_value == 0) {
127 		fprintf(stderr, "trsp: %s: no namelist\n", system);
128 		exit(1);
129 	}
130 	(void) close(0);
131 	if (open(core, 0) < 0) {
132 		fprintf(stderr, "trsp: "); perror(core);
133 		exit(2);
134 	}
135 	if (mask) {
136 		nl[0].n_value &= 0x7fffffff;
137 		nl[1].n_value &= 0x7fffffff;
138 	}
139 	(void) lseek(0, nl[1].n_value, 0);
140 	if (read(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
141 		fprintf(stderr, "trsp: "); perror("spp_debx");
142 		exit(3);
143 	}
144 	printf("spp_debx=%d\n", spp_debx);
145 	(void) lseek(0, nl[0].n_value, 0);
146 	if (read(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
147 		fprintf(stderr, "trsp: "); perror("spp_debug");
148 		exit(3);
149 	}
150 	/*
151 	 * Here, we just want to clear out the old trace data and start over.
152 	 */
153 	if (zflag) {
154 		char *cp = (char *) spp_debug,
155 		     *cplim = cp + sizeof(spp_debug);
156 		(void) close(0);
157 		if (open(core, 2) < 0) {
158 			fprintf(stderr, "trsp: "); perror(core);
159 			exit(2);
160 		}
161 		while(cp < cplim) *cp++ = 0;
162 		(void) lseek(0, nl[0].n_value, 0);
163 		if (write(0, spp_debug, sizeof (spp_debug)) != sizeof (spp_debug)) {
164 			fprintf(stderr, "trsp: "); perror("spp_debug");
165 			exit(3);
166 		}
167 		(void) lseek(0, nl[1].n_value, 0);
168 		spp_debx = 0;
169 		if (write(0, &spp_debx, sizeof (spp_debx)) != sizeof (spp_debx)) {
170 			fprintf(stderr, "trsp: "); perror("spp_debx");
171 			exit(3);
172 		}
173 		exit(0);
174 	}
175 	/*
176 	 * If no control blocks have been specified, figure
177 	 * out how many distinct one we have and summarize
178 	 * them in spp_pcbs for sorting the trace records
179 	 * below.
180 	 */
181 	if (npcbs == 0) {
182 		for (i = 0; i < SPP_NDEBUG; i++) {
183 			register int j;
184 			register struct spp_debug *sd = &spp_debug[i];
185 
186 			if (sd->sd_cb == 0)
187 				continue;
188 			for (j = 0; j < npcbs; j++)
189 				if (spp_pcbs[j] == sd->sd_cb)
190 					break;
191 			if (j >= npcbs)
192 				spp_pcbs[npcbs++] = sd->sd_cb;
193 		}
194 	}
195 	qsort(spp_pcbs, npcbs, sizeof (caddr_t), numeric);
196 	if (jflag) {
197 		char *cp = "";
198 
199 		for (i = 0; i < npcbs; i++) {
200 			printf("%s%x", cp, spp_pcbs[i]);
201 			cp = ", ";
202 		}
203 		if (*cp)
204 			putchar('\n');
205 		exit(0);
206 	}
207 	for (i = 0; i < npcbs; i++) {
208 		printf("\n%x:\n", spp_pcbs[i]);
209 		dotrace(spp_pcbs[i]);
210 	}
211 	exit(0);
212 }
213 
214 dotrace(sppcb)
215 	register caddr_t sppcb;
216 {
217 	register int i;
218 	register struct spp_debug *sd;
219 
220 	for (i = spp_debx % SPP_NDEBUG; i < SPP_NDEBUG; i++) {
221 		sd = &spp_debug[i];
222 		if (sppcb && sd->sd_cb != sppcb)
223 			continue;
224 		ntime = ntohl(sd->sd_time);
225 		spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
226 		    &sd->sd_si, sd->sd_req);
227 	}
228 	for (i = 0; i < spp_debx % SPP_NDEBUG; i++) {
229 		sd = &spp_debug[i];
230 		if (sppcb && sd->sd_cb != sppcb)
231 			continue;
232 		ntime = ntohl(sd->sd_time);
233 		spp_trace(sd->sd_act, sd->sd_ostate, sd->sd_cb, &sd->sd_sp,
234 		    &sd->sd_si, sd->sd_req);
235 	}
236 }
237 
238 ptime(ms)
239 	int ms;
240 {
241 
242 	printf("%03d ", (ms/10) % 1000);
243 }
244 
245 numeric(c1, c2)
246 	caddr_t *c1, *c2;
247 {
248 
249 	return (*c1 - *c2);
250 }
251 
252 spp_trace(act, ostate, asp, sp, si, req)
253 	short act, ostate;
254 	struct sppcb *asp, *sp;
255 	struct spidp *si;
256 	int req;
257 {
258 	u_short seq, ack, len, alo;
259 	int flags, timer;
260 	char *cp;
261 
262 	if(ostate >= TCP_NSTATES) ostate = 0;
263 	if(act > SA_DROP) act = SA_DROP;
264 	printf("\n");
265 	ptime(ntime);
266 	printf("%s:%s", tcpstates[ostate], sanames[act]);
267 
268 	if (si != 0) {
269 		seq = si->si_seq;
270 		ack = si->si_ack;
271 		alo = si->si_alo;
272 		len = si->si_len;
273 		switch (act) {
274 		case SA_RESPOND:
275 		case SA_OUTPUT:
276 				seq = ntohs(seq);
277 				ack = ntohs(ack);
278 				alo = ntohs(alo);
279 				len = ntohs(len);
280 		case SA_INPUT:
281 		case SA_DROP:
282 			if (aflag) {
283 				printf("\n\tsna=");
284 				ns_printhost(&si->si_sna);
285 				printf("\tdna=");
286 				ns_printhost(&si->si_dna);
287 			}
288 			printf("\n\t");
289 #define p1(f)  { printf("%s = %x, ", "f", f); }
290 			p1(seq); p1(ack); p1(alo); p1(len);
291 			flags = si->si_cc;
292 			printf("flags=%x", flags);
293 			if (flags) {
294 				char *cp = "<";
295 #define pf(f) { if (flags&SP_/**/f) { printf("%s%s", cp, "f"); cp = ","; } }
296 				pf(SP); pf(SA); pf(OB); pf(EM);
297 				printf(">");
298 			}
299 			printf(", ");
300 #define p2(f)  { printf("%s = %x, ", "f", si->si_/**/f); }
301 			p2(sid);p2(did);p2(dt);
302 			printf("\n\tsna=");
303 			ns_printhost(&si->si_sna);
304 			printf("\tdna=");
305 			ns_printhost(&si->si_dna);
306 		}
307 	}
308 	if(act == SA_USER) {
309 		printf("\treq=%s", prurequests[req&0xff]);
310 		if ((req & 0xff) == PRU_SLOWTIMO)
311 			printf("<%s>", tcptimers[req>>8]);
312 	}
313 	printf(" -> %s", tcpstates[sp->s_state]);
314 
315 	/* print out internal state of sp !?! */
316 	printf("\n");
317 	if (sp == 0)
318 		return;
319 #define p3(f)  { printf("%s = %x, ", "f", sp->s_/**/f); }
320 	if(sflag) {
321 		printf("\t"); p3(rack); p3(ralo); p3(snt); p3(flags);
322 #undef pf
323 #define pf(f) { if (flags&SF_/**/f) { printf("%s%s", cp, "f"); cp = ","; } }
324 		flags = sp->s_flags;
325 		if (flags || sp->s_oobflags) {
326 			char *cp = "<";
327 			pf(AK); pf(DELACK); pf(HI); pf(HO);
328 			flags = sp->s_oobflags;
329 			pf(SOOB); pf(IOOB);
330 			printf(">");
331 		}
332 
333 	}
334 	/* print out timers? */
335 	if (tflag) {
336 		char *cp = "\t";
337 		register int i;
338 
339 		printf("\n\tTIMERS: ");
340 		p3(idle); p3(force); p3(rtseq);
341 		for (i = 0; i < TCPT_NTIMERS; i++) {
342 			if (sp->s_timer[i] == 0)
343 				continue;
344 			printf("%s%s=%d", cp, tcptimers[i], sp->s_timer[i]);
345 			if (i == TCPT_REXMT)
346 				printf(" (s_rxtshft=%d)", sp->s_rxtshift);
347 			cp = ", ";
348 		}
349 		if (*cp != '\t')
350 			putchar('\n');
351 	}
352 }
353 
354 ns_printhost(p)
355 register struct ns_addr *p;
356 {
357 
358 	printf("<net:%x%x,host:%4.4x%4.4x%4.4x,port:%x>",
359 			p->x_net.s_net[0],
360 			p->x_net.s_net[1],
361 			p->x_host.s_host[0],
362 			p->x_host.s_host[1],
363 			p->x_host.s_host[2],
364 			p->x_port);
365 
366 }
367 
368