file reorg, pathnames.h, paths.h
[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
7abf8d65 25static char sccsid[] = "@(#)trpt.c 5.8 (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 61#include <nlist.h>
7abf8d65 62#include <paths.h>
9a3a7863 63
7c5704a5
KB
64struct nlist nl[] = {
65#define N_TCP_DEBUG 0
9a3a7863 66 { "_tcp_debug" },
7c5704a5 67#define N_TCP_DEBX 1
9a3a7863 68 { "_tcp_debx" },
7c5704a5
KB
69#define N_SYSMAP 2
70 { "_Sysmap" },
71#define N_SYSSIZE 3
72 { "_Syssize" },
73 { "" },
9a3a7863 74};
7c5704a5 75
bb1dac50
KB
76static struct pte *Sysmap;
77static caddr_t tcp_pcbs[TCP_NDEBUG];
78static n_time ntime;
79static int aflag, kflag, memf, follow, sflag, tflag;
9a3a7863
BJ
80
81main(argc, argv)
82 int argc;
83 char **argv;
84{
7c5704a5
KB
85 extern char *optarg;
86 extern int optind;
87 int ch, i, jflag, npcbs, numeric();
88 char *system, *core, *malloc();
89 off_t lseek();
9a3a7863 90
7c5704a5
KB
91 jflag = npcbs = 0;
92 while ((ch = getopt(argc, argv, "afjp:st")) != EOF)
93 switch((char)ch) {
94 case 'a':
95 ++aflag;
96 break;
97 case 'f':
98 ++follow;
99 setlinebuf(stdout);
100 break;
101 case 'j':
102 ++jflag;
103 break;
104 case 'p':
105 if (npcbs >= TCP_NDEBUG) {
106 fputs("trpt: too many pcb's specified\n",
107 stderr);
108 exit(1);
109 }
110 (void)sscanf(optarg, "%x", (int *)&tcp_pcbs[npcbs++]);
111 break;
112 case 's':
113 ++sflag;
114 break;
115 case 't':
116 ++tflag;
117 break;
118 case '?':
119 default:
383be14d
KB
120 (void)fprintf(stderr,
121"usage: trpt [-afjst] [-p hex-address] [system [core]]\n");
175d35a6
SL
122 exit(1);
123 }
7c5704a5
KB
124 argc -= optind;
125 argv += optind;
126
383be14d 127 core = _PATH_KMEM;
eb0fbeab
SL
128 if (argc > 0) {
129 system = *argv;
130 argc--, argv++;
7c5704a5
KB
131 if (argc > 0) {
132 core = *argv;
133 argc--, argv++;
134 ++kflag;
135 }
eb0fbeab 136 }
7c5704a5 137 else
383be14d 138 system = _PATH_UNIX;
7c5704a5
KB
139
140 if (nlist(system, nl) < 0 || !nl[0].n_value) {
eb0fbeab 141 fprintf(stderr, "trpt: %s: no namelist\n", system);
9a3a7863
BJ
142 exit(1);
143 }
7c5704a5
KB
144 if ((memf = open(core, O_RDONLY)) < 0) {
145 perror(core);
eb0fbeab
SL
146 exit(2);
147 }
7c5704a5
KB
148 if (kflag) {
149 off_t off;
150
151 Sysmap = (struct pte *)
152 malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
153 if (!Sysmap) {
154 fputs("arp: can't get memory for Sysmap.\n", stderr);
155 exit(1);
156 }
157 off = nl[N_SYSMAP].n_value & ~KERNBASE;
158 (void)lseek(memf, off, L_SET);
159 (void)read(memf, (char *)Sysmap,
160 (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
9a3a7863 161 }
7c5704a5
KB
162 (void)klseek(memf, (off_t)nl[N_TCP_DEBX].n_value, L_SET);
163 if (read(memf, (char *)&tcp_debx, sizeof(tcp_debx)) !=
164 sizeof(tcp_debx)) {
165 perror("trpt: tcp_debx");
eb0fbeab
SL
166 exit(3);
167 }
7c5704a5
KB
168 (void)klseek(memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
169 if (read(memf, (char *)tcp_debug, sizeof(tcp_debug)) !=
170 sizeof(tcp_debug)) {
171 perror("trpt: tcp_debug");
eb0fbeab
SL
172 exit(3);
173 }
175d35a6
SL
174 /*
175 * If no control blocks have been specified, figure
176 * out how many distinct one we have and summarize
177 * them in tcp_pcbs for sorting the trace records
178 * below.
179 */
7c5704a5 180 if (!npcbs) {
175d35a6 181 for (i = 0; i < TCP_NDEBUG; i++) {
175d35a6 182 register struct tcp_debug *td = &tcp_debug[i];
7c5704a5 183 register int j;
175d35a6
SL
184
185 if (td->td_tcb == 0)
186 continue;
187 for (j = 0; j < npcbs; j++)
188 if (tcp_pcbs[j] == td->td_tcb)
189 break;
190 if (j >= npcbs)
191 tcp_pcbs[npcbs++] = td->td_tcb;
192 }
7c5704a5
KB
193 if (!npcbs)
194 exit(0);
175d35a6 195 }
7c5704a5 196 qsort(tcp_pcbs, npcbs, sizeof(caddr_t), numeric);
175d35a6 197 if (jflag) {
7c5704a5
KB
198 for (i = 0;;) {
199 printf("%x", (int)tcp_pcbs[i]);
200 if (++i == npcbs)
201 break;
202 fputs(", ", stdout);
175d35a6 203 }
7c5704a5 204 putchar('\n');
175d35a6 205 }
7c5704a5
KB
206 else for (i = 0; i < npcbs; i++) {
207 printf("\n%x:\n", (int)tcp_pcbs[i]);
175d35a6
SL
208 dotrace(tcp_pcbs[i]);
209 }
210 exit(0);
211}
212
213dotrace(tcpcb)
214 register caddr_t tcpcb;
215{
175d35a6 216 register struct tcp_debug *td;
7c5704a5 217 register int i;
89586647 218 int prev_debx = tcp_debx;
175d35a6 219
7c5704a5 220again: if (--tcp_debx < 0)
89586647
MK
221 tcp_debx = TCP_NDEBUG - 1;
222 for (i = prev_debx % TCP_NDEBUG; i < TCP_NDEBUG; i++) {
175d35a6 223 td = &tcp_debug[i];
eb0fbeab
SL
224 if (tcpcb && td->td_tcb != tcpcb)
225 continue;
10ce0f6a 226 ntime = ntohl(td->td_time);
9a3a7863
BJ
227 tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb,
228 &td->td_ti, td->td_req);
89586647
MK
229 if (i == tcp_debx)
230 goto done;
9a3a7863 231 }
89586647 232 for (i = 0; i <= tcp_debx % TCP_NDEBUG; i++) {
175d35a6 233 td = &tcp_debug[i];
eb0fbeab
SL
234 if (tcpcb && td->td_tcb != tcpcb)
235 continue;
10ce0f6a 236 ntime = ntohl(td->td_time);
9a3a7863
BJ
237 tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb,
238 &td->td_ti, td->td_req);
239 }
7c5704a5
KB
240done: if (follow) {
241 prev_debx = tcp_debx + 1;
242 if (prev_debx >= TCP_NDEBUG)
243 prev_debx = 0;
244 do {
245 sleep(1);
246 (void)klseek(memf, (off_t)nl[N_TCP_DEBX].n_value, L_SET);
247 if (read(memf, (char *)&tcp_debx, sizeof(tcp_debx)) !=
248 sizeof(tcp_debx)) {
249 perror("trpt: tcp_debx");
250 exit(3);
251 }
252 } while (tcp_debx == prev_debx);
253 (void)klseek(memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET);
254 if (read(memf, (char *)tcp_debug, sizeof(tcp_debug)) !=
255 sizeof(tcp_debug)) {
256 perror("trpt: tcp_debug");
89586647
MK
257 exit(3);
258 }
7c5704a5 259 goto again;
89586647 260 }
9a3a7863
BJ
261}
262
263/*
264 * Tcp debug routines
265 */
7c5704a5 266/*ARGSUSED*/
9a3a7863
BJ
267tcp_trace(act, ostate, atp, tp, ti, req)
268 short act, ostate;
269 struct tcpcb *atp, *tp;
270 struct tcpiphdr *ti;
271 int req;
272{
273 tcp_seq seq, ack;
7c5704a5 274 int flags, len, win, timer;
9a3a7863 275
7c5704a5
KB
276 printf("%03ld %s:%s ",(ntime/10) % 1000, tcpstates[ostate],
277 tanames[act]);
9a3a7863 278 switch (act) {
9a3a7863
BJ
279 case TA_INPUT:
280 case TA_OUTPUT:
3cd6f35b 281 case TA_DROP:
7c5704a5
KB
282 if (aflag)
283 printf("(src=%s,%u, dst=%s,%u)", inet_ntoa(ti->ti_src),
284 ntohs(ti->ti_sport), inet_ntoa(ti->ti_dst),
285 ntohs(ti->ti_dport));
9a3a7863
BJ
286 seq = ti->ti_seq;
287 ack = ti->ti_ack;
288 len = ti->ti_len;
289 win = ti->ti_win;
9a3a7863
BJ
290 if (act == TA_OUTPUT) {
291 seq = ntohl(seq);
292 ack = ntohl(ack);
293 len = ntohs(len);
294 win = ntohs(win);
295 }
9a3a7863 296 if (act == TA_OUTPUT)
7c5704a5 297 len -= sizeof(struct tcphdr);
9a3a7863 298 if (len)
7c5704a5 299 printf("[%lx..%lx)", seq, seq + len);
9a3a7863 300 else
7c5704a5
KB
301 printf("%lx", seq);
302 printf("@%lx", ack);
9a3a7863 303 if (win)
23c416d7 304 printf("(win=%x)", win);
9a3a7863
BJ
305 flags = ti->ti_flags;
306 if (flags) {
7c5704a5
KB
307 register char *cp = "<";
308#define pf(flag) { \
309 if (ti->ti_flags&flag) \
310 printf("%s%s", cp, "f"); \
311 cp = ","; \
312 }
313 pf(TH_SYN);
314 pf(TH_ACK);
315 pf(TH_FIN);
316 pf(TH_RST);
317 pf(TH_PUSH);
318 pf(TH_URG);
9a3a7863
BJ
319 printf(">");
320 }
321 break;
9a3a7863 322 case TA_USER:
10ce0f6a
SL
323 timer = req >> 8;
324 req &= 0xff;
325 printf("%s", prurequests[req]);
326 if (req == PRU_SLOWTIMO || req == PRU_FASTTIMO)
327 printf("<%s>", tcptimers[timer]);
9a3a7863
BJ
328 break;
329 }
330 printf(" -> %s", tcpstates[tp->t_state]);
331 /* print out internal state of tp !?! */
332 printf("\n");
333 if (sflag) {
7c5704a5 334 printf("\trcv_nxt %lx rcv_wnd %x snd_una %lx snd_nxt %lx snd_max %lx\n",
eb0fbeab
SL
335 tp->rcv_nxt, tp->rcv_wnd, tp->snd_una, tp->snd_nxt,
336 tp->snd_max);
7c5704a5 337 printf("\tsnd_wl1 %lx snd_wl2 %lx snd_wnd %x\n", tp->snd_wl1,
eb0fbeab 338 tp->snd_wl2, tp->snd_wnd);
9a3a7863 339 }
175d35a6
SL
340 /* print out timers? */
341 if (tflag) {
7c5704a5 342 register char *cp = "\t";
175d35a6
SL
343 register int i;
344
345 for (i = 0; i < TCPT_NTIMERS; i++) {
346 if (tp->t_timer[i] == 0)
347 continue;
348 printf("%s%s=%d", cp, tcptimers[i], tp->t_timer[i]);
349 if (i == TCPT_REXMT)
350 printf(" (t_rxtshft=%d)", tp->t_rxtshift);
351 cp = ", ";
352 }
353 if (*cp != '\t')
354 putchar('\n');
355 }
9a3a7863
BJ
356}
357
7c5704a5
KB
358numeric(c1, c2)
359 caddr_t *c1, *c2;
9a3a7863 360{
7c5704a5 361 return(*c1 - *c2);
9a3a7863 362}
175d35a6 363
7c5704a5
KB
364klseek(fd, base, off)
365 int fd, off;
366 off_t base;
175d35a6 367{
7c5704a5
KB
368 off_t lseek();
369
370 if (kflag) { /* get kernel pte */
371 base &= ~KERNBASE;
372 base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
373 }
374 (void)lseek(fd, base, off);
175d35a6 375}