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