|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: char copyright[] =
9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif not lint
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)trpt.c 5.2 (Berkeley) 9/18/85";
15: #endif not lint
16:
17: #include <sys/param.h>
18: #include <sys/socket.h>
19: #include <sys/socketvar.h>
20: #define PRUREQUESTS
21: #include <sys/protosw.h>
22:
23: #include <net/route.h>
24: #include <net/if.h>
25:
26: #include <netinet/in.h>
27: #include <netinet/in_pcb.h>
28: #include <netinet/in_systm.h>
29: #include <netinet/ip.h>
30: #include <netinet/ip_var.h>
31: #include <netinet/tcp.h>
32: #define TCPSTATES
33: #include <netinet/tcp_fsm.h>
34: #include <netinet/tcp_seq.h>
35: #define TCPTIMERS
36: #include <netinet/tcp_timer.h>
37: #include <netinet/tcp_var.h>
38: #include <netinet/tcpip.h>
39: #define TANAMES
40: #include <netinet/tcp_debug.h>
41:
42: #include <arpa/inet.h>
43:
44: #include <stdio.h>
45: #include <errno.h>
46: #include <nlist.h>
47:
48: n_time ntime;
49: int sflag;
50: int tflag;
51: int jflag;
52: int aflag;
53: int follow;
54: int numeric();
55: struct nlist nl[] = {
56: { "_tcp_debug" },
57: { "_tcp_debx" },
58: 0
59: };
60: struct tcp_debug tcp_debug[TCP_NDEBUG];
61: caddr_t tcp_pcbs[TCP_NDEBUG];
62: int tcp_debx;
63:
64: main(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++;
72: again:
73: if (argc > 0 && !strcmp(*argv, "-a")) {
74: aflag++, argc--, argv++;
75: goto again;
76: }
77: if (argc > 0 && !strcmp(*argv, "-f")) {
78: follow++, 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 tcpcb address\n");
97: exit(1);
98: }
99: if (npcbs >= TCP_NDEBUG) {
100: fprintf(stderr, "-p: too many pcb's specified\n");
101: exit(1);
102: }
103: sscanf(*argv, "%x", &tcp_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, "trpt: %s: no namelist\n", system);
120: exit(1);
121: }
122: (void) close(0);
123: if (open(core, 0) < 0) {
124: fprintf(stderr, "trpt: "); 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, &tcp_debx, sizeof (tcp_debx)) != sizeof (tcp_debx)) {
133: fprintf(stderr, "trpt: "); perror("tcp_debx");
134: exit(3);
135: }
136: (void) lseek(0, nl[0].n_value, 0);
137: if (read(0, tcp_debug, sizeof (tcp_debug)) != sizeof (tcp_debug)) {
138: fprintf(stderr, "trpt: "); perror("tcp_debug");
139: exit(3);
140: }
141: /*
142: * If no control blocks have been specified, figure
143: * out how many distinct one we have and summarize
144: * them in tcp_pcbs for sorting the trace records
145: * below.
146: */
147: if (npcbs == 0) {
148: for (i = 0; i < TCP_NDEBUG; i++) {
149: register int j;
150: register struct tcp_debug *td = &tcp_debug[i];
151:
152: if (td->td_tcb == 0)
153: continue;
154: for (j = 0; j < npcbs; j++)
155: if (tcp_pcbs[j] == td->td_tcb)
156: break;
157: if (j >= npcbs)
158: tcp_pcbs[npcbs++] = td->td_tcb;
159: }
160: }
161: qsort(tcp_pcbs, npcbs, sizeof (caddr_t), numeric);
162: if (jflag) {
163: char *cp = "";
164:
165: for (i = 0; i < npcbs; i++) {
166: printf("%s%x", cp, tcp_pcbs[i]);
167: cp = ", ";
168: }
169: if (*cp)
170: putchar('\n');
171: exit(0);
172: }
173: for (i = 0; i < npcbs; i++) {
174: printf("\n%x:\n", tcp_pcbs[i]);
175: dotrace(tcp_pcbs[i]);
176: }
177: exit(0);
178: }
179:
180: dotrace(tcpcb)
181: register caddr_t tcpcb;
182: {
183: register int i;
184: register struct tcp_debug *td;
185: int prev_debx = tcp_debx;
186:
187: again:
188: if (--tcp_debx < 0)
189: tcp_debx = TCP_NDEBUG - 1;
190: for (i = prev_debx % TCP_NDEBUG; i < TCP_NDEBUG; i++) {
191: td = &tcp_debug[i];
192: if (tcpcb && td->td_tcb != tcpcb)
193: continue;
194: ntime = ntohl(td->td_time);
195: tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb,
196: &td->td_ti, td->td_req);
197: if (i == tcp_debx)
198: goto done;
199: }
200: for (i = 0; i <= tcp_debx % TCP_NDEBUG; i++) {
201: td = &tcp_debug[i];
202: if (tcpcb && td->td_tcb != tcpcb)
203: continue;
204: ntime = ntohl(td->td_time);
205: tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb,
206: &td->td_ti, td->td_req);
207: }
208: done:
209: if (follow) {
210: prev_debx = tcp_debx + 1;
211: if (prev_debx >= TCP_NDEBUG)
212: prev_debx = 0;
213: do {
214: sleep(1);
215: (void) lseek(0, nl[1].n_value, 0);
216: if (read(0, &tcp_debx, sizeof(tcp_debx)) != sizeof(tcp_debx)) {
217: fprintf(stderr, "trpt: "); perror("tcp_debx");
218: exit(3);
219: }
220: } while (tcp_debx == prev_debx);
221: (void) lseek(0, nl[0].n_value, 0);
222: if (read(0, tcp_debug, sizeof(tcp_debug)) != sizeof(tcp_debug)) {
223: fprintf(stderr, "trpt: "); perror("tcp_debug");
224: exit(3);
225: }
226: goto again;
227: }
228: }
229:
230: /*
231: * Tcp debug routines
232: */
233: tcp_trace(act, ostate, atp, tp, ti, req)
234: short act, ostate;
235: struct tcpcb *atp, *tp;
236: struct tcpiphdr *ti;
237: int req;
238: {
239: tcp_seq seq, ack;
240: int len, flags, win, timer;
241: char *cp;
242:
243: ptime(ntime);
244: printf("%s:%s ", tcpstates[ostate], tanames[act]);
245: switch (act) {
246:
247: case TA_INPUT:
248: case TA_OUTPUT:
249: case TA_DROP:
250: if (aflag) {
251: printf("(src=%s,%d, ", inet_ntoa(ti->ti_src),
252: ntohs(ti->ti_sport));
253: printf("dst=%s,%d)", inet_ntoa(ti->ti_dst),
254: ntohs(ti->ti_dport));
255: }
256: seq = ti->ti_seq;
257: ack = ti->ti_ack;
258: len = ti->ti_len;
259: win = ti->ti_win;
260: if (act == TA_OUTPUT) {
261: seq = ntohl(seq);
262: ack = ntohl(ack);
263: len = ntohs(len);
264: win = ntohs(win);
265: }
266: if (act == TA_OUTPUT)
267: len -= sizeof (struct tcphdr);
268: if (len)
269: printf("[%x..%x)", seq, seq+len);
270: else
271: printf("%x", seq);
272: printf("@%x", ack);
273: if (win)
274: printf("(win=%x)", win);
275: flags = ti->ti_flags;
276: if (flags) {
277: char *cp = "<";
278: #define pf(f) { if (ti->ti_flags&TH_/**/f) { printf("%s%s", cp, "f"); cp = ","; } }
279: pf(SYN); pf(ACK); pf(FIN); pf(RST); pf(PUSH); pf(URG);
280: printf(">");
281: }
282: break;
283:
284: case TA_USER:
285: timer = req >> 8;
286: req &= 0xff;
287: printf("%s", prurequests[req]);
288: if (req == PRU_SLOWTIMO || req == PRU_FASTTIMO)
289: printf("<%s>", tcptimers[timer]);
290: break;
291: }
292: printf(" -> %s", tcpstates[tp->t_state]);
293: /* print out internal state of tp !?! */
294: printf("\n");
295: if (sflag) {
296: printf("\trcv_nxt %x rcv_wnd %x snd_una %x snd_nxt %x snd_max %x\n",
297: tp->rcv_nxt, tp->rcv_wnd, tp->snd_una, tp->snd_nxt,
298: tp->snd_max);
299: printf("\tsnd_wl1 %x snd_wl2 %x snd_wnd %x\n", tp->snd_wl1,
300: tp->snd_wl2, tp->snd_wnd);
301: }
302: /* print out timers? */
303: if (tflag) {
304: char *cp = "\t";
305: register int i;
306:
307: for (i = 0; i < TCPT_NTIMERS; i++) {
308: if (tp->t_timer[i] == 0)
309: continue;
310: printf("%s%s=%d", cp, tcptimers[i], tp->t_timer[i]);
311: if (i == TCPT_REXMT)
312: printf(" (t_rxtshft=%d)", tp->t_rxtshift);
313: cp = ", ";
314: }
315: if (*cp != '\t')
316: putchar('\n');
317: }
318: }
319:
320: ptime(ms)
321: int ms;
322: {
323:
324: printf("%03d ", (ms/10) % 1000);
325: }
326:
327: numeric(c1, c2)
328: caddr_t *c1, *c2;
329: {
330:
331: return (*c1 - *c2);
332: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.