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