display rcv_wnd in hex, not decimal
[unix-history] / usr / src / usr.sbin / trpt / trpt.c
CommitLineData
9a3a7863 1#ifndef lint
49282770 2static char sccsid[] = "@(#)trpt.c 4.8 %G%";
9a3a7863
BJ
3#endif
4
5#include <sys/param.h>
6#include <sys/socket.h>
7#include <sys/socketvar.h>
8#define PRUREQUESTS
9#include <sys/protosw.h>
94a2d2a7 10
9a3a7863 11#include <net/route.h>
9a3a7863 12#include <net/if.h>
94a2d2a7
SL
13
14#include <netinet/in.h>
15#include <netinet/in_pcb.h>
16#include <netinet/in_systm.h>
17#include <netinet/ip.h>
18#include <netinet/ip_var.h>
19#include <netinet/tcp.h>
9a3a7863 20#define TCPSTATES
94a2d2a7
SL
21#include <netinet/tcp_fsm.h>
22#include <netinet/tcp_seq.h>
9a3a7863 23#define TCPTIMERS
94a2d2a7
SL
24#include <netinet/tcp_timer.h>
25#include <netinet/tcp_var.h>
26#include <netinet/tcpip.h>
9a3a7863 27#define TANAMES
94a2d2a7 28#include <netinet/tcp_debug.h>
9a3a7863 29
eb0fbeab 30#include <stdio.h>
94a2d2a7 31#include <errno.h>
9a3a7863
BJ
32#include <nlist.h>
33
34n_time ntime;
35int sflag;
175d35a6
SL
36int tflag;
37int jflag;
49173cdd 38int aflag;
175d35a6 39int numeric();
9a3a7863
BJ
40struct nlist nl[] = {
41 { "_tcp_debug" },
42 { "_tcp_debx" },
43 0
44};
45struct tcp_debug tcp_debug[TCP_NDEBUG];
175d35a6 46caddr_t tcp_pcbs[TCP_NDEBUG];
9a3a7863 47int tcp_debx;
49173cdd 48char *ntoa();
9a3a7863
BJ
49
50main(argc, argv)
51 int argc;
52 char **argv;
53{
175d35a6 54 int i, mask = 0, npcbs = 0;
eb0fbeab 55 char *system = "/vmunix", *core = "/dev/kmem";
9a3a7863
BJ
56
57 argc--, argv++;
58again:
49173cdd
SL
59 if (argc > 0 && !strcmp(*argv, "-a")) {
60 aflag++, argc--, argv++;
61 goto again;
62 }
9a3a7863
BJ
63 if (argc > 0 && !strcmp(*argv, "-s")) {
64 sflag++, argc--, argv++;
65 goto again;
66 }
175d35a6
SL
67 if (argc > 0 && !strcmp(*argv, "-t")) {
68 tflag++, argc--, argv++;
69 goto again;
70 }
71 if (argc > 0 && !strcmp(*argv, "-j")) {
72 jflag++, argc--, argv++;
73 goto again;
74 }
eb0fbeab 75 if (argc > 0 && !strcmp(*argv, "-p")) {
175d35a6 76 argc--, argv++;
eb0fbeab
SL
77 if (argc < 1) {
78 fprintf(stderr, "-p: missing tcpcb address\n");
79 exit(1);
80 }
175d35a6
SL
81 if (npcbs >= TCP_NDEBUG) {
82 fprintf(stderr, "-p: too many pcb's specified\n");
83 exit(1);
84 }
85 sscanf(*argv, "%x", &tcp_pcbs[npcbs++]);
eb0fbeab
SL
86 argc--, argv++;
87 goto again;
88 }
89 if (argc > 0) {
90 system = *argv;
91 argc--, argv++;
92 mask++;
93 }
94 if (argc > 0) {
95 core = *argv;
96 argc--, argv++;
97 mask++;
98 }
99 (void) nlist(system, nl);
9a3a7863 100 if (nl[0].n_value == 0) {
eb0fbeab 101 fprintf(stderr, "trpt: %s: no namelist\n", system);
9a3a7863
BJ
102 exit(1);
103 }
eb0fbeab
SL
104 (void) close(0);
105 if (open(core, 0) < 0) {
106 fprintf(stderr, "trpt: "); perror(core);
107 exit(2);
108 }
109 if (mask) {
9a3a7863
BJ
110 nl[0].n_value &= 0x7fffffff;
111 nl[1].n_value &= 0x7fffffff;
112 }
eb0fbeab
SL
113 (void) lseek(0, nl[1].n_value, 0);
114 if (read(0, &tcp_debx, sizeof (tcp_debx)) != sizeof (tcp_debx)) {
115 fprintf(stderr, "trpt: "); perror("tcp_debx");
116 exit(3);
117 }
9a3a7863 118 printf("tcp_debx=%d\n", tcp_debx);
eb0fbeab
SL
119 (void) lseek(0, nl[0].n_value, 0);
120 if (read(0, tcp_debug, sizeof (tcp_debug)) != sizeof (tcp_debug)) {
121 fprintf(stderr, "trpt: "); perror("tcp_debug");
122 exit(3);
123 }
175d35a6
SL
124 /*
125 * If no control blocks have been specified, figure
126 * out how many distinct one we have and summarize
127 * them in tcp_pcbs for sorting the trace records
128 * below.
129 */
130 if (npcbs == 0) {
131 for (i = 0; i < TCP_NDEBUG; i++) {
132 register int j;
133 register struct tcp_debug *td = &tcp_debug[i];
134
135 if (td->td_tcb == 0)
136 continue;
137 for (j = 0; j < npcbs; j++)
138 if (tcp_pcbs[j] == td->td_tcb)
139 break;
140 if (j >= npcbs)
141 tcp_pcbs[npcbs++] = td->td_tcb;
142 }
143 }
144 qsort(tcp_pcbs, npcbs, sizeof (caddr_t), numeric);
145 if (jflag) {
146 char *cp = "";
10ce0f6a 147
175d35a6
SL
148 for (i = 0; i < npcbs; i++) {
149 printf("%s%x", cp, tcp_pcbs[i]);
150 cp = ", ";
151 }
152 if (*cp)
153 putchar('\n');
154 exit(0);
155 }
156 for (i = 0; i < npcbs; i++) {
157 printf("\n%x:\n", tcp_pcbs[i]);
158 dotrace(tcp_pcbs[i]);
159 }
160 exit(0);
161}
162
163dotrace(tcpcb)
164 register caddr_t tcpcb;
165{
166 register int i;
167 register struct tcp_debug *td;
168
169 for (i = 0; i < tcp_debx % TCP_NDEBUG; i++) {
170 td = &tcp_debug[i];
eb0fbeab
SL
171 if (tcpcb && td->td_tcb != tcpcb)
172 continue;
10ce0f6a 173 ntime = ntohl(td->td_time);
9a3a7863
BJ
174 tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb,
175 &td->td_ti, td->td_req);
176 }
175d35a6
SL
177 for (i = tcp_debx % TCP_NDEBUG; i < TCP_NDEBUG; i++) {
178 td = &tcp_debug[i];
eb0fbeab
SL
179 if (tcpcb && td->td_tcb != tcpcb)
180 continue;
10ce0f6a 181 ntime = ntohl(td->td_time);
9a3a7863
BJ
182 tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb,
183 &td->td_ti, td->td_req);
184 }
9a3a7863
BJ
185}
186
187/*
188 * Tcp debug routines
189 */
190tcp_trace(act, ostate, atp, tp, ti, req)
191 short act, ostate;
192 struct tcpcb *atp, *tp;
193 struct tcpiphdr *ti;
194 int req;
195{
196 tcp_seq seq, ack;
10ce0f6a 197 int len, flags, win, timer;
9a3a7863
BJ
198 char *cp;
199
200 ptime(ntime);
175d35a6 201 printf("%s:%s ", tcpstates[ostate], tanames[act]);
9a3a7863
BJ
202 switch (act) {
203
204 case TA_INPUT:
205 case TA_OUTPUT:
49173cdd
SL
206 if (aflag) {
207 printf("(src=%s,%d, ", ntoa(ti->ti_src),
208 ntohs(ti->ti_sport));
209 printf("dst=%s,%d)", ntoa(ti->ti_dst),
210 ntohs(ti->ti_dport));
211 }
9a3a7863
BJ
212 seq = ti->ti_seq;
213 ack = ti->ti_ack;
214 len = ti->ti_len;
215 win = ti->ti_win;
9a3a7863
BJ
216 if (act == TA_OUTPUT) {
217 seq = ntohl(seq);
218 ack = ntohl(ack);
219 len = ntohs(len);
220 win = ntohs(win);
221 }
9a3a7863
BJ
222 if (act == TA_OUTPUT)
223 len -= sizeof (struct tcphdr);
224 if (len)
225 printf("[%x..%x)", seq, seq+len);
226 else
227 printf("%x", seq);
228 printf("@%x", ack);
229 if (win)
230 printf("(win=%d)", win);
231 flags = ti->ti_flags;
232 if (flags) {
233 char *cp = "<";
234#define pf(f) { if (ti->ti_flags&TH_/**/f) { printf("%s%s", cp, "f"); cp = ","; } }
ed06dc42 235 pf(SYN); pf(ACK); pf(FIN); pf(RST); pf(PUSH); pf(URG);
9a3a7863
BJ
236 printf(">");
237 }
238 break;
239
240 case TA_USER:
10ce0f6a
SL
241 timer = req >> 8;
242 req &= 0xff;
243 printf("%s", prurequests[req]);
244 if (req == PRU_SLOWTIMO || req == PRU_FASTTIMO)
245 printf("<%s>", tcptimers[timer]);
9a3a7863
BJ
246 break;
247 }
248 printf(" -> %s", tcpstates[tp->t_state]);
249 /* print out internal state of tp !?! */
250 printf("\n");
251 if (sflag) {
49282770 252 printf("\trcv_nxt %x rcv_wnd %x snd_una %x snd_nxt %x snd_max %x\n",
eb0fbeab
SL
253 tp->rcv_nxt, tp->rcv_wnd, tp->snd_una, tp->snd_nxt,
254 tp->snd_max);
255 printf("\tsnd_wl1 %x snd_wl2 %x snd_wnd %x\n", tp->snd_wl1,
256 tp->snd_wl2, tp->snd_wnd);
9a3a7863 257 }
175d35a6
SL
258 /* print out timers? */
259 if (tflag) {
260 char *cp = "\t";
261 register int i;
262
263 for (i = 0; i < TCPT_NTIMERS; i++) {
264 if (tp->t_timer[i] == 0)
265 continue;
266 printf("%s%s=%d", cp, tcptimers[i], tp->t_timer[i]);
267 if (i == TCPT_REXMT)
268 printf(" (t_rxtshft=%d)", tp->t_rxtshift);
269 cp = ", ";
270 }
271 if (*cp != '\t')
272 putchar('\n');
273 }
9a3a7863
BJ
274}
275
276ptime(ms)
277 int ms;
278{
279
280 printf("%03d ", (ms/10) % 1000);
281}
175d35a6
SL
282
283numeric(c1, c2)
284 caddr_t *c1, *c2;
285{
286
287 return (*c1 - *c2);
288}
49173cdd
SL
289
290/*
291 * Convert network-format internet address
292 * to base 256 d.d.d.d representation.
293 */
294char *
295ntoa(in)
296 struct in_addr in;
297{
298 static char b[18];
299 register char *p;
300
301 in.s_addr = ntohl(in.s_addr);
302 p = (char *)&in;
303#define UC(b) (((int)b)&0xff)
304 sprintf(b, "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
305 return (b);
306}