1#!/usr/sbin/dtrace -s
2/*
3 * Copyright (c) 2015 George V. Neville-Neil
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * The tcpdebug D script uses the tcp:kernel::debug tracepoints
28 * to replicate the action of turning on TCPDEBUG in a kernel configuration.
29 *
30 * A TCP debug statement shows a connection's
31 *
32 * direction:	input, output, user, drop
33 * state:	CLOSED,	LISTEN,	SYN_SENT, SYN_RCVD, ESTABLISHED,
34 * 		CLOSE_WAIT, FIN_WAIT_1, CLOSING, LAST_ACK, FIN_WAIT_2,TIME_WAIT
35 * sequence:	sequence space
36 *
37 * congestion:	rcv_nxt, rcv_wnd, rcv_up, snd_una, snd_nxt, snx_max,
38 *		snd_wl1, snd_wl2, snd_wnd
39 *
40 * NOTE: Only sockets with SO_DEBUG set will be shown.
41 * 
42 * Usage: tcpdebug
43 */
44
45#pragma D option quiet
46tcp:kernel::debug-input
47/args[0]->tcps_debug/
48{
49	seq = args[1]->tcp_seq;
50	ack = args[1]->tcp_ack;
51	len = args[2]->ip_plength - sizeof(struct tcphdr);
52	flags = args[1]->tcp_flags;
53	
54	printf("%p %s: input [%xu..%xu]", arg0,
55	       tcp_state_string[args[0]->tcps_state], seq, seq + len);
56
57	printf("@%x, urp=%x", ack, args[1]->tcp_urgent);
58
59	printf("%s", flags != 0 ? "<" : "");
60	printf("%s", flags & TH_SYN ? "SYN," :"");
61	printf("%s", flags & TH_ACK ? "ACK," :"");
62	printf("%s", flags & TH_FIN ? "FIN," :"");
63	printf("%s", flags & TH_RST ? "RST," :"");
64	printf("%s", flags & TH_PUSH ? "PUSH," :"");
65	printf("%s", flags & TH_URG ? "URG," :"");
66	printf("%s", flags & TH_ECE ? "ECE," :"");
67	printf("%s", flags & TH_CWR ? "CWR," :"");
68	printf("%s", flags & TH_AE ? "AE" :"");
69	printf("%s", flags != 0 ? ">" : "");
70
71	printf("\n");
72	printf("\trcv_(nxt,wnd,up) (%x,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n",
73	       args[0]->tcps_rnxt, args[0]->tcps_rwnd, args[0]->tcps_rup,
74	       args[0]->tcps_suna, args[0]->tcps_snxt, args[0]->tcps_smax);
75	printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n",
76	       args[0]->tcps_swl1, args[0]->tcps_swl2, args[0]->tcps_swnd);
77
78}
79
80tcp:kernel::debug-output
81/args[0]->tcps_debug/
82{
83	seq = args[1]->tcp_seq;
84	ack = args[1]->tcp_ack;
85	len = args[2]->ip_plength - sizeof(struct tcphdr);
86	flags = args[1]->tcp_flags;
87
88	printf("%p %s: output [%x..%x]", arg0,
89	       tcp_state_string[args[0]->tcps_state], seq, seq + len);
90
91	printf("@%x, urp=%x", ack, args[1]->tcp_urgent);
92
93	printf("%s", flags != 0 ? "<" : "");
94	printf("%s", flags & TH_SYN ? "SYN," :"");
95	printf("%s", flags & TH_ACK ? "ACK," :"");
96	printf("%s", flags & TH_FIN ? "FIN," :"");
97	printf("%s", flags & TH_RST ? "RST," :"");
98	printf("%s", flags & TH_PUSH ? "PUSH," :"");
99	printf("%s", flags & TH_URG ? "URG," :"");
100	printf("%s", flags & TH_ECE ? "ECE," :"");
101	printf("%s", flags & TH_CWR ? "CWR," :"");
102	printf("%s", flags & TH_AE ? "AE" :"");
103	printf("%s", flags != 0 ? ">" : "");
104
105	printf("\n");
106	printf("\trcv_(nxt,wnd,up) (%u,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n",
107	       args[0]->tcps_rnxt, args[0]->tcps_rwnd, args[0]->tcps_rup,
108	       args[0]->tcps_suna, args[0]->tcps_snxt, args[0]->tcps_smax);
109	printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n",
110	       args[0]->tcps_swl1, args[0]->tcps_swl2, args[0]->tcps_swnd);
111
112}
113
114tcp:kernel::debug-drop
115/args[0]->tcps_debug/
116{
117	printf("%p %s: output [x..x] @%x, urp=%x\n", arg0,
118	       tcp_state_string[args[0]->tcps_state],
119	       args[1]->tcp_ack,
120	       args[1]->tcp_urgent);
121
122	seq = args[1]->tcp_seq;
123	ack = args[1]->tcp_ack;
124	len = args[2]->ip_plength - sizeof(struct tcphdr);
125	flags = args[1]->tcp_flags;
126
127	printf("%p %s: drop [%x..%x]", arg0,
128	       tcp_state_string[args[0]->tcps_state], seq, seq + len);
129
130	printf("@%x, urp=%x", ack, args[1]->tcp_urgent);
131
132	printf("%s", flags != 0 ? "<" : "");
133	printf("%s", flags & TH_SYN ? "SYN," :"");
134	printf("%s", flags & TH_ACK ? "ACK," :"");
135	printf("%s", flags & TH_FIN ? "FIN," :"");
136	printf("%s", flags & TH_RST ? "RST," :"");
137	printf("%s", flags & TH_PUSH ? "PUSH," :"");
138	printf("%s", flags & TH_URG ? "URG," :"");
139	printf("%s", flags & TH_ECE ? "ECE," :"");
140	printf("%s", flags & TH_CWR ? "CWR," :"");
141	printf("%s", flags & TH_AE ? "AE" :"");
142	printf("%s", flags != 0 ? ">" : "");
143
144	printf("\n");
145	printf("\trcv_(nxt,wnd,up) (%x,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n",
146	       args[0]->tcps_rnxt, args[0]->tcps_rwnd, args[0]->tcps_rup,
147	       args[0]->tcps_suna, args[0]->tcps_snxt, args[0]->tcps_smax);
148	printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n",
149	       args[0]->tcps_swl1, args[0]->tcps_swl2, args[0]->tcps_swnd);
150
151}
152
153tcp:kernel::debug-user
154/args[0]->tcps_debug/
155{
156	printf("%p %s: user ", arg0,
157	       tcp_state_string[args[0]->tcps_state]);
158
159	printf("%s", prureq_string[arg1]);
160	printf("\n");
161	printf("\trcv_(nxt,wnd,up) (%x,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n",
162	       args[0]->tcps_rnxt, args[0]->tcps_rwnd, args[0]->tcps_rup,
163	       args[0]->tcps_suna, args[0]->tcps_snxt, args[0]->tcps_smax);
164	printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n",
165	       args[0]->tcps_swl1, args[0]->tcps_swl2, args[0]->tcps_swnd);
166
167}
168
169