|
|
1.1 root 1: /*
2: * Copyright (c) 1983, 1988 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)trpt.c 5.13 (Berkeley) 6/1/90";
28: #endif /* not lint */
29:
30: #include <machine/pte.h>
31:
32: #include <sys/param.h>
33: #include <sys/vmmac.h>
34: #include <sys/socket.h>
35: #include <sys/socketvar.h>
36: #define PRUREQUESTS
37: #include <sys/protosw.h>
38: #include <sys/file.h>
39:
40: #include <net/route.h>
41: #include <net/if.h>
42:
43: #include <netinet/in.h>
44: #include <netinet/in_systm.h>
45: #include <netinet/ip.h>
46: #include <netinet/in_pcb.h>
47: #include <netinet/ip_var.h>
48: #include <netinet/tcp.h>
49: #define TCPSTATES
50: #include <netinet/tcp_fsm.h>
51: #include <netinet/tcp_seq.h>
52: #define TCPTIMERS
53: #include <netinet/tcp_timer.h>
54: #include <netinet/tcp_var.h>
55: #include <netinet/tcpip.h>
56: #define TANAMES
57: #include <netinet/tcp_debug.h>
58:
59: #include <arpa/inet.h>
60:
61: #include <stdio.h>
62: #include <errno.h>
63: #include <nlist.h>
64: #include <paths.h>
65:
66: struct nlist nl[] = {
67: #define N_TCP_DEBUG 0
68: { "_tcp_debug" },
69: #define N_TCP_DEBX 1
70: { "_tcp_debx" },
71: #define N_SYSMAP 2
72: { "_Sysmap" },
73: #define N_SYSSIZE 3
74: { "_Syssize" },
75: { "" },
76: };
77:
78: static struct pte *Sysmap;
79: static caddr_t tcp_pcbs[TCP_NDEBUG];
80: static n_time ntime;
81: static int aflag, kflag, memf, follow, sflag, tflag;
82:
83: main(argc, argv)
84: int argc;
85: char **argv;
86: {
87: extern char *optarg;
88: extern int optind;
89: int ch, i, jflag, npcbs, numeric();
90: char *system, *core, *malloc();
91: off_t lseek();
92:
93: jflag = npcbs = 0;
94: while ((ch = getopt(argc, argv, "afjp:st")) != EOF)
95: switch((char)ch) {
96: case 'a':
97: ++aflag;
98: break;
99: case 'f':
100: ++follow;
101: setlinebuf(stdout);
102: break;
103: case 'j':
104: ++jflag;
105: break;
106: case 'p':
107: if (npcbs >= TCP_NDEBUG) {
108: fputs("trpt: too many pcb's specified\n",
109: stderr);
110: exit(1);
111: }
112: (void)sscanf(optarg, "%x", (int *)&tcp_pcbs[npcbs++]);
113: break;
114: case 's':
115: ++sflag;
116: break;
117: case 't':
118: ++tflag;
119: break;
120: case '?':
121: default:
122: (void)fprintf(stderr,
123: "usage: trpt [-afjst] [-p hex-address] [system [core]]\n");
124: exit(1);
125: }
126: argc -= optind;
127: argv += optind;
128:
129: core = _PATH_KMEM;
130: if (argc > 0) {
131: system = *argv;
132: argc--, argv++;
133: if (argc > 0) {
134: core = *argv;
135: argc--, argv++;
136: ++kflag;
137: }
138: }
139: else
140: system = _PATH_UNIX;
141:
142: if (nlist(system, nl) < 0 || !nl[0].n_value) {
143: fprintf(stderr, "trpt: %s: no namelist\n", system);
144: exit(1);
145: }
146: if ((memf = open(core, O_RDONLY)) < 0) {
147: perror(core);
148: exit(2);
149: }
150: if (kflag) {
151: off_t off;
152:
153: Sysmap = (struct pte *)
154: malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
155: if (!Sysmap) {
156: fputs("arp: can't get memory for Sysmap.\n", stderr);
157: exit(1);
158: }
159: off = nl[N_SYSMAP].n_value & ~KERNBASE;
160: (void)lseek(memf, off, L_SET);
161: (void)read(memf, (char *)Sysmap,
162: (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
163: }
164: (void)klseek(memf, (off_t)nl[N_TCP_DEBX].n_value, L_SET);
165: if (read(memf, (char *)&tcp_debx, sizeof(tcp_debx)) !=
166: sizeof(tcp_debx)) {
167: perror("trpt: tcp_debx");
168: exit(3);
169: }
170: (void)klseek(memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
171: if (read(memf, (char *)tcp_debug, sizeof(tcp_debug)) !=
172: sizeof(tcp_debug)) {
173: perror("trpt: tcp_debug");
174: exit(3);
175: }
176: /*
177: * If no control blocks have been specified, figure
178: * out how many distinct one we have and summarize
179: * them in tcp_pcbs for sorting the trace records
180: * below.
181: */
182: if (!npcbs) {
183: for (i = 0; i < TCP_NDEBUG; i++) {
184: register struct tcp_debug *td = &tcp_debug[i];
185: register int j;
186:
187: if (td->td_tcb == 0)
188: continue;
189: for (j = 0; j < npcbs; j++)
190: if (tcp_pcbs[j] == td->td_tcb)
191: break;
192: if (j >= npcbs)
193: tcp_pcbs[npcbs++] = td->td_tcb;
194: }
195: if (!npcbs)
196: exit(0);
197: }
198: qsort(tcp_pcbs, npcbs, sizeof(caddr_t), numeric);
199: if (jflag) {
200: for (i = 0;;) {
201: printf("%x", (int)tcp_pcbs[i]);
202: if (++i == npcbs)
203: break;
204: fputs(", ", stdout);
205: }
206: putchar('\n');
207: }
208: else for (i = 0; i < npcbs; i++) {
209: printf("\n%x:\n", (int)tcp_pcbs[i]);
210: dotrace(tcp_pcbs[i]);
211: }
212: exit(0);
213: }
214:
215: dotrace(tcpcb)
216: register caddr_t tcpcb;
217: {
218: register struct tcp_debug *td;
219: register int i;
220: int prev_debx = tcp_debx;
221:
222: again: if (--tcp_debx < 0)
223: tcp_debx = TCP_NDEBUG - 1;
224: for (i = prev_debx % TCP_NDEBUG; i < TCP_NDEBUG; i++) {
225: td = &tcp_debug[i];
226: if (tcpcb && td->td_tcb != tcpcb)
227: continue;
228: ntime = ntohl(td->td_time);
229: tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb,
230: &td->td_ti, td->td_req);
231: if (i == tcp_debx)
232: goto done;
233: }
234: for (i = 0; i <= tcp_debx % TCP_NDEBUG; i++) {
235: td = &tcp_debug[i];
236: if (tcpcb && td->td_tcb != tcpcb)
237: continue;
238: ntime = ntohl(td->td_time);
239: tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb,
240: &td->td_ti, td->td_req);
241: }
242: done: if (follow) {
243: prev_debx = tcp_debx + 1;
244: if (prev_debx >= TCP_NDEBUG)
245: prev_debx = 0;
246: do {
247: sleep(1);
248: (void)klseek(memf, (off_t)nl[N_TCP_DEBX].n_value, L_SET);
249: if (read(memf, (char *)&tcp_debx, sizeof(tcp_debx)) !=
250: sizeof(tcp_debx)) {
251: perror("trpt: tcp_debx");
252: exit(3);
253: }
254: } while (tcp_debx == prev_debx);
255: (void)klseek(memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
256: if (read(memf, (char *)tcp_debug, sizeof(tcp_debug)) !=
257: sizeof(tcp_debug)) {
258: perror("trpt: tcp_debug");
259: exit(3);
260: }
261: goto again;
262: }
263: }
264:
265: /*
266: * Tcp debug routines
267: */
268: /*ARGSUSED*/
269: tcp_trace(act, ostate, atp, tp, ti, req)
270: short act, ostate;
271: struct tcpcb *atp, *tp;
272: struct tcpiphdr *ti;
273: int req;
274: {
275: tcp_seq seq, ack;
276: int flags, len, win, timer;
277:
278: printf("%03ld %s:%s ",(ntime/10) % 1000, tcpstates[ostate],
279: tanames[act]);
280: switch (act) {
281: case TA_INPUT:
282: case TA_OUTPUT:
283: case TA_DROP:
284: if (aflag) {
285: printf("(src=%s,%u, ",
286: inet_ntoa(ti->ti_src), ntohs(ti->ti_sport));
287: printf("dst=%s,%u)",
288: inet_ntoa(ti->ti_dst), ntohs(ti->ti_dport));
289: }
290: seq = ti->ti_seq;
291: ack = ti->ti_ack;
292: len = ti->ti_len;
293: win = ti->ti_win;
294: if (act == TA_OUTPUT) {
295: seq = ntohl(seq);
296: ack = ntohl(ack);
297: len = ntohs(len);
298: win = ntohs(win);
299: }
300: if (act == TA_OUTPUT)
301: len -= sizeof(struct tcphdr);
302: if (len)
303: printf("[%lx..%lx)", seq, seq + len);
304: else
305: printf("%lx", seq);
306: printf("@%lx", ack);
307: if (win)
308: printf("(win=%x)", win);
309: flags = ti->ti_flags;
310: if (flags) {
311: register char *cp = "<";
312: #define pf(flag, string) { \
313: if (ti->ti_flags&flag) { \
314: (void)printf("%s%s", cp, string); \
315: cp = ","; \
316: } \
317: }
318: pf(TH_SYN, "SYN");
319: pf(TH_ACK, "ACK");
320: pf(TH_FIN, "FIN");
321: pf(TH_RST, "RST");
322: pf(TH_PUSH, "PUSH");
323: pf(TH_URG, "URG");
324: printf(">");
325: }
326: break;
327: case TA_USER:
328: timer = req >> 8;
329: req &= 0xff;
330: printf("%s", prurequests[req]);
331: if (req == PRU_SLOWTIMO || req == PRU_FASTTIMO)
332: printf("<%s>", tcptimers[timer]);
333: break;
334: }
335: printf(" -> %s", tcpstates[tp->t_state]);
336: /* print out internal state of tp !?! */
337: printf("\n");
338: if (sflag) {
339: printf("\trcv_nxt %lx rcv_wnd %x snd_una %lx snd_nxt %lx snd_max %lx\n",
340: tp->rcv_nxt, tp->rcv_wnd, tp->snd_una, tp->snd_nxt,
341: tp->snd_max);
342: printf("\tsnd_wl1 %lx snd_wl2 %lx snd_wnd %x\n", tp->snd_wl1,
343: tp->snd_wl2, tp->snd_wnd);
344: }
345: /* print out timers? */
346: if (tflag) {
347: register char *cp = "\t";
348: register int i;
349:
350: for (i = 0; i < TCPT_NTIMERS; i++) {
351: if (tp->t_timer[i] == 0)
352: continue;
353: printf("%s%s=%d", cp, tcptimers[i], tp->t_timer[i]);
354: if (i == TCPT_REXMT)
355: printf(" (t_rxtshft=%d)", tp->t_rxtshift);
356: cp = ", ";
357: }
358: if (*cp != '\t')
359: putchar('\n');
360: }
361: }
362:
363: numeric(c1, c2)
364: caddr_t *c1, *c2;
365: {
366: return(*c1 - *c2);
367: }
368:
369: klseek(fd, base, off)
370: int fd, off;
371: off_t base;
372: {
373: off_t lseek();
374:
375: if (kflag) { /* get kernel pte */
376: base &= ~KERNBASE;
377: base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
378: }
379: (void)lseek(fd, base, off);
380: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.