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