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