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