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