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