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