1287759Sgnn#!/usr/sbin/dtrace -s
2287759Sgnn/*
3287759Sgnn * Copyright (c) 2015 George V. Neville-Neil
4287759Sgnn * All rights reserved.
5287759Sgnn *
6287759Sgnn * Redistribution and use in source and binary forms, with or without
7287759Sgnn * modification, are permitted provided that the following conditions
8287759Sgnn * are met:
9287759Sgnn * 1. Redistributions of source code must retain the above copyright
10287759Sgnn *    notice, this list of conditions and the following disclaimer.
11287759Sgnn * 2. Redistributions in binary form must reproduce the above copyright
12287759Sgnn *    notice, this list of conditions and the following disclaimer in the
13287759Sgnn *    documentation and/or other materials provided with the distribution.
14287759Sgnn *
15287759Sgnn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16287759Sgnn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17287759Sgnn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18287759Sgnn * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19287759Sgnn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20287759Sgnn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21287759Sgnn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22287759Sgnn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23287759Sgnn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24287759Sgnn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25287759Sgnn * SUCH DAMAGE.
26287759Sgnn *
27287759Sgnn * $FreeBSD: releng/11.0/share/dtrace/tcpdebug 296335 2016-03-03 02:46:12Z gnn $
28287759Sgnn *
29287759Sgnn * The tcpdebug D script uses the tcp:kernel::debug tracepoints
30287759Sgnn * to replicate the action of turning on TCPDEBUG in a kernel configuration.
31287759Sgnn *
32287759Sgnn * A TCP debug statement shows a connection's
33287759Sgnn *
34287759Sgnn * direction:	input, output, user, drop
35287759Sgnn * state:	CLOSED,	LISTEN,	SYN_SENT, SYN_RCVD, ESTABLISHED,
36287759Sgnn * 		CLOSE_WAIT, FIN_WAIT_1, CLOSING, LAST_ACK, FIN_WAIT_2,TIME_WAIT
37287759Sgnn * sequence:	sequence space
38287759Sgnn *
39287759Sgnn * congestion:	rcv_nxt, rcv_wnd, rcv_up, snd_una, snd_nxt, snx_max,
40287759Sgnn *		snd_wl1, snd_wl2, snd_wnd
41287759Sgnn *
42287759Sgnn * NOTE: Only sockets with SO_DEBUG set will be shown.
43287759Sgnn * 
44287759Sgnn * Usage: tcpdebug
45287759Sgnn */
46287759Sgnn
47287759Sgnn#pragma D option quiet
48287759Sgnntcp:kernel::debug-input
49287759Sgnn/args[0]->tcps_debug/
50287759Sgnn{
51287759Sgnn	seq = args[1]->tcp_seq;
52287759Sgnn	ack = args[1]->tcp_ack;
53287759Sgnn	len = args[2]->ip_plength - sizeof(struct tcphdr);
54287759Sgnn	flags = args[1]->tcp_flags;
55287759Sgnn	
56287759Sgnn	printf("%p %s: input [%xu..%xu]", arg0,
57287759Sgnn	       tcp_state_string[args[0]->tcps_state], seq, seq + len);
58287759Sgnn
59287759Sgnn	printf("@%x, urp=%x", ack, args[1]->tcp_urgent);
60287759Sgnn
61287759Sgnn	printf("%s", flags != 0 ? "<" : "");
62287759Sgnn	printf("%s", flags & TH_SYN ? "SYN," :"");
63287759Sgnn	printf("%s", flags & TH_ACK ? "ACK," :"");
64287759Sgnn	printf("%s", flags & TH_FIN ? "FIN," :"");
65287759Sgnn	printf("%s", flags & TH_RST ? "RST," :"");
66287759Sgnn	printf("%s", flags & TH_PUSH ? "PUSH," :"");
67287759Sgnn	printf("%s", flags & TH_URG ? "URG," :"");
68287759Sgnn	printf("%s", flags & TH_ECE ? "ECE," :"");
69287759Sgnn	printf("%s", flags & TH_CWR ? "CWR" :"");
70287759Sgnn	printf("%s", flags != 0 ? ">" : "");
71287759Sgnn
72287759Sgnn	printf("\n");
73287759Sgnn	printf("\trcv_(nxt,wnd,up) (%x,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n",
74287759Sgnn	       args[0]->tcps_rnxt, args[0]->tcps_rwnd, args[0]->tcps_rup,
75287759Sgnn	       args[0]->tcps_suna, args[0]->tcps_snxt, args[0]->tcps_smax);
76287759Sgnn	printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n",
77287759Sgnn	       args[0]->tcps_swl1, args[0]->tcps_swl2, args[0]->tcps_swnd);
78287759Sgnn
79287759Sgnn}
80287759Sgnn
81287759Sgnntcp:kernel::debug-output
82287759Sgnn/args[0]->tcps_debug/
83287759Sgnn{
84287759Sgnn	seq = args[1]->tcp_seq;
85287759Sgnn	ack = args[1]->tcp_ack;
86296335Sgnn	len = args[2]->ip_plength - sizeof(struct tcphdr);
87296335Sgnn	flags = args[1]->tcp_flags;
88287759Sgnn
89287759Sgnn	printf("%p %s: output [%x..%x]", arg0,
90287759Sgnn	       tcp_state_string[args[0]->tcps_state], seq, seq + len);
91287759Sgnn
92287759Sgnn	printf("@%x, urp=%x", ack, args[1]->tcp_urgent);
93287759Sgnn
94287759Sgnn	printf("%s", flags != 0 ? "<" : "");
95287759Sgnn	printf("%s", flags & TH_SYN ? "SYN," :"");
96287759Sgnn	printf("%s", flags & TH_ACK ? "ACK," :"");
97287759Sgnn	printf("%s", flags & TH_FIN ? "FIN," :"");
98287759Sgnn	printf("%s", flags & TH_RST ? "RST," :"");
99287759Sgnn	printf("%s", flags & TH_PUSH ? "PUSH," :"");
100287759Sgnn	printf("%s", flags & TH_URG ? "URG," :"");
101287759Sgnn	printf("%s", flags & TH_ECE ? "ECE," :"");
102287759Sgnn	printf("%s", flags & TH_CWR ? "CWR" :"");
103287759Sgnn	printf("%s", flags != 0 ? ">" : "");
104287759Sgnn
105287759Sgnn	printf("\n");
106287759Sgnn	printf("\trcv_(nxt,wnd,up) (%u,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n",
107287759Sgnn	       args[0]->tcps_rnxt, args[0]->tcps_rwnd, args[0]->tcps_rup,
108287759Sgnn	       args[0]->tcps_suna, args[0]->tcps_snxt, args[0]->tcps_smax);
109287759Sgnn	printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n",
110287759Sgnn	       args[0]->tcps_swl1, args[0]->tcps_swl2, args[0]->tcps_swnd);
111287759Sgnn
112287759Sgnn}
113287759Sgnn
114287759Sgnntcp:kernel::debug-drop
115287759Sgnn/args[0]->tcps_debug/
116287759Sgnn{
117287759Sgnn	printf("%p %s: output [x..x] @%x, urp=%x\n", arg0,
118287759Sgnn	       tcp_state_string[args[0]->tcps_state],
119287759Sgnn	       args[1]->tcp_ack,
120287759Sgnn	       args[1]->tcp_urgent);
121287759Sgnn
122287759Sgnn	seq = args[1]->tcp_seq;
123287759Sgnn	ack = args[1]->tcp_ack;
124296335Sgnn	len = args[2]->ip_plength - sizeof(struct tcphdr);
125296335Sgnn	flags = args[1]->tcp_flags;
126287759Sgnn
127287759Sgnn	printf("%p %s: drop [%x..%x]", arg0,
128287759Sgnn	       tcp_state_string[args[0]->tcps_state], seq, seq + len);
129287759Sgnn
130287759Sgnn	printf("@%x, urp=%x", ack, args[1]->tcp_urgent);
131287759Sgnn
132287759Sgnn	printf("%s", flags != 0 ? "<" : "");
133287759Sgnn	printf("%s", flags & TH_SYN ? "SYN," :"");
134287759Sgnn	printf("%s", flags & TH_ACK ? "ACK," :"");
135287759Sgnn	printf("%s", flags & TH_FIN ? "FIN," :"");
136287759Sgnn	printf("%s", flags & TH_RST ? "RST," :"");
137287759Sgnn	printf("%s", flags & TH_PUSH ? "PUSH," :"");
138287759Sgnn	printf("%s", flags & TH_URG ? "URG," :"");
139287759Sgnn	printf("%s", flags & TH_ECE ? "ECE," :"");
140287759Sgnn	printf("%s", flags & TH_CWR ? "CWR" :"");
141287759Sgnn	printf("%s", flags != 0 ? ">" : "");
142287759Sgnn
143287759Sgnn	printf("\n");
144287759Sgnn	printf("\trcv_(nxt,wnd,up) (%x,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n",
145287759Sgnn	       args[0]->tcps_rnxt, args[0]->tcps_rwnd, args[0]->tcps_rup,
146287759Sgnn	       args[0]->tcps_suna, args[0]->tcps_snxt, args[0]->tcps_smax);
147287759Sgnn	printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n",
148287759Sgnn	       args[0]->tcps_swl1, args[0]->tcps_swl2, args[0]->tcps_swnd);
149287759Sgnn
150287759Sgnn}
151287759Sgnn
152287759Sgnntcp:kernel::debug-user
153287759Sgnn/args[0]->tcps_debug/
154287759Sgnn{
155287759Sgnn	printf("%p %s: user ", arg0,
156287759Sgnn	       tcp_state_string[args[0]->tcps_state]);
157287759Sgnn
158287759Sgnn	printf("%s", prureq_string[arg1]);
159287759Sgnn	printf("\n");
160287759Sgnn	printf("\trcv_(nxt,wnd,up) (%x,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n",
161287759Sgnn	       args[0]->tcps_rnxt, args[0]->tcps_rwnd, args[0]->tcps_rup,
162287759Sgnn	       args[0]->tcps_suna, args[0]->tcps_snxt, args[0]->tcps_smax);
163287759Sgnn	printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n",
164287759Sgnn	       args[0]->tcps_swl1, args[0]->tcps_swl2, args[0]->tcps_swnd);
165287759Sgnn
166287759Sgnn}
167287759Sgnn
168