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