xref: /illumos-gate/usr/src/cmd/dtrace/demo/ip/tcprst.d (revision 3d393ee6c37fa10ac512ed6d36109ad616dc7c1a)
1 #!/usr/sbin/dtrace -Cqs
2 /*
3  * CDDL HEADER START
4  *
5  * The contents of this file are subject to the terms of the
6  * Common Development and Distribution License (the "License").
7  * You may not use this file except in compliance with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma D option dynvarsize=64m
28 
29 #define TH_RST		0x04
30 #define MAX_RECORDS	10
31 #define M_CTL		0x0d
32 
33 #define PRINT_MAIN_HEADER()						\
34 	(printf("\n%-25s %-6s %-25s %-6s %-10s %-10s %8s %8s\n",	\
35 	    "LADDR", "LPORT", "RADDR", "RPORT", "ISS", "IRS",		\
36 	    "SND_CNT", "RCV_CNT"))
37 
38 #define PRINT_RECORD_HEADER()						\
39 	(printf("%-20s %-20s %-3s %15s %15s %8s %8s %5s\n",		\
40 	    "PROBENAME", "TIME", "S/R", "SEQ", "ACK", "DATALEN",	\
41 	    "WND", "FLAGS"))
42 
43 #define PRINT_MAIN_HEADER_VALUES()					\
44 	(printf("%-25s %-6d %-25s %-6d %-10d %-10d %8d %8d\n",		\
45 	    laddr[self->conn_id], lport[self->conn_id],			\
46 	    faddr[self->conn_id], fport[self->conn_id],			\
47 	    iss[self->conn_id], irs[self->conn_id],			\
48 	    send_count[self->conn_id], recv_count[self->conn_id]))
49 
50 #define PRINT_HEADER()							\
51 	PRINT_MAIN_HEADER(); PRINT_MAIN_HEADER_VALUES();		\
52 	    PRINT_RECORD_HEADER()
53 
54 #define PRINT_RECORD(i)							\
55 	(printf("%-20s %-20Y %-3s %15d %15d %8d %8d %2x\n",		\
56 	    probe_name[self->conn_id, i],				\
57 	    conn_time[self->conn_id, i],				\
58 	    send_recv[self->conn_id, i],				\
59 	    seqno[self->conn_id, i],					\
60 	    ack[self->conn_id, i],					\
61 	    datalen[self->conn_id, i],					\
62 	    wnd[self->conn_id, i],					\
63 	    flags[self->conn_id, i]))
64 
65 tcp-trace-*
66 {
67 	/* extract connection details */
68 
69 	this->mp = (mblk_t *)arg0;
70 	this->mp = (this->mp->b_datap->db_type == M_CTL?
71 	    this->mp->b_cont : this->mp);
72 	self->tcpp = (tcp_t *)arg1;
73 	this->connp = (conn_t *)self->tcpp->tcp_connp;
74 
75 	self->iph = (ipha_t *)this->mp->b_rptr;
76 	this->iph_length =
77 	    (int)(((ipha_t *)self->iph)->ipha_version_and_hdr_length
78 	    & 0xF) << 2;
79 	self->tcph = (tcpha_t *)((char *)self->iph + this->iph_length);
80 	this->tcph_length =
81 	    (((tcph_t *)self->tcph)->th_offset_and_rsrvd[0] >>2) &(0xF << 2);
82 
83 	/* ports */
84 	self->i_lport = ntohs(this->connp->u_port.tcpu_ports.tcpu_lport);
85 	self->i_fport = ntohs(this->connp->u_port.tcpu_ports.tcpu_fport);
86 
87 	/* IP addresses */
88 	this->i_fad = (in6_addr_t *)&this->connp->connua_v6addr.connua_faddr;
89 	this->i_lad = (in6_addr_t *)&this->connp->connua_v6addr.connua_laddr;
90 
91 	/* the address would either be IPv6 or IPv4-mapped-IPv6  */
92 	self->i_faddr = inet_ntop(AF_INET6, (void *)this->i_fad);
93 	self->i_laddr = inet_ntop(AF_INET6, (void *)this->i_lad);
94 
95 	/* create connection identifier, so we can track packets by conn */
96 	self->conn_id = (uint64_t)self->tcpp->tcp_connp;
97 }
98 
99 tcp-trace-*
100 /first[self->conn_id] == 0/
101 {
102 	/* initialize counters - this is the first packet for this connection */
103 	pcount[self->conn_id] = -1;
104 	rollover[self->conn_id] = 0;
105 	end_ptr[self->conn_id] = 0;
106 	num[self->conn_id] = 0;
107 
108 	first[self->conn_id] = 1;
109 
110 	/* connection info */
111 	laddr[self->conn_id] = self->i_laddr;
112 	faddr[self->conn_id] = self->i_faddr;
113 	lport[self->conn_id] = self->i_lport;
114 	fport[self->conn_id] = self->i_fport;
115 	iss[self->conn_id] = self->tcpp->tcp_iss;
116 	irs[self->conn_id] = self->tcpp->tcp_irs;
117 
118 }
119 
120 tcp-trace-*
121 {
122 	/* counters, to keep track of how much info to dump */
123 	pcount[self->conn_id]++;
124 	rollover[self->conn_id] |= pcount[self->conn_id]/MAX_RECORDS;
125 	pcount[self->conn_id] = pcount[self->conn_id]%MAX_RECORDS;
126 	self->pcount = pcount[self->conn_id];
127 	end_ptr[self->conn_id] = self->pcount;
128 	num[self->conn_id] = (rollover[self->conn_id]?
129 	    MAX_RECORDS : pcount[self->conn_id] + 1);
130 	conn_time[self->conn_id, self->pcount] = walltimestamp;
131 
132 	/* tcp state info */
133 	seqno[self->conn_id, self->pcount] = ntohl(self->tcph->tha_seq);
134 	ack[self->conn_id, self->pcount] = ntohl(self->tcph->tha_ack);
135 	datalen[self->conn_id, self->pcount] =  ntohs(self->iph->ipha_length);
136 	wnd[self->conn_id, self->pcount] =  ntohs(self->tcph->tha_win);
137 	probe_name[self->conn_id, self->pcount] = probename;
138 
139 	/* flag 0x04 indicates a RST packet */
140 	flags[self->conn_id, self->pcount] = self->tcph->tha_flags;
141 	self->flags = self->tcph->tha_flags;
142 }
143 
144 tcp-trace-send
145 {
146 	send_count[self->conn_id]++;
147 	send_recv[self->conn_id, self->pcount] = "S";
148 }
149 
150 tcp-trace-recv
151 {
152 	recv_count[self->conn_id]++;
153 	send_recv[self->conn_id, self->pcount] = "R";
154 }
155 
156 tcp-trace-*
157 /(self->flags & TH_RST)/
158 {
159 	PRINT_HEADER();
160 
161 	self->i = (end_ptr[self->conn_id] + MAX_RECORDS - num[self->conn_id]
162 	    + 1)%MAX_RECORDS;
163 }
164 
165 tcp-trace-*
166 /(self->flags & TH_RST) && (num[self->conn_id] >= 10)/
167 {
168 	PRINT_RECORD(self->i);
169 	self->i = (self->i + 1)%MAX_RECORDS;
170 
171 	num[self->conn_id]--;
172 }
173 
174 tcp-trace-*
175 /(self->flags & TH_RST) && (num[self->conn_id] >= 9)/
176 {
177 	PRINT_RECORD(self->i);
178 	self->i = (self->i + 1)%MAX_RECORDS;
179 
180 	num[self->conn_id]--;
181 }
182 
183 tcp-trace-*
184 /(self->flags & TH_RST) && (num[self->conn_id] >= 8)/
185 {
186 	PRINT_RECORD(self->i);
187 	self->i = (self->i + 1)%MAX_RECORDS;
188 
189 	num[self->conn_id]--;
190 }
191 
192 tcp-trace-*
193 /(self->flags & TH_RST) && (num[self->conn_id] >= 7)/
194 {
195 	PRINT_RECORD(self->i);
196 	self->i = (self->i + 1)%MAX_RECORDS;
197 
198 	num[self->conn_id]--;
199 }
200 
201 tcp-trace-*
202 /(self->flags & TH_RST) && (num[self->conn_id] >= 6)/
203 {
204 	PRINT_RECORD(self->i);
205 	self->i = (self->i + 1)%MAX_RECORDS;
206 
207 	num[self->conn_id]--;
208 }
209 
210 tcp-trace-*
211 /(self->flags & TH_RST) && (num[self->conn_id] >= 5)/
212 {
213 	PRINT_RECORD(self->i);
214 	self->i = (self->i + 1)%MAX_RECORDS;
215 
216 	num[self->conn_id]--;
217 }
218 
219 tcp-trace-*
220 /(self->flags & TH_RST) && (num[self->conn_id] >= 4)/
221 {
222 	PRINT_RECORD(self->i);
223 	self->i = (self->i + 1)%MAX_RECORDS;
224 
225 	num[self->conn_id]--;
226 }
227 
228 tcp-trace-*
229 /(self->flags & TH_RST) && (num[self->conn_id] >= 3)/
230 {
231 	PRINT_RECORD(self->i);
232 	self->i = (self->i + 1)%MAX_RECORDS;
233 
234 	num[self->conn_id]--;
235 }
236 
237 tcp-trace-*
238 /(self->flags & TH_RST) && (num[self->conn_id] >= 2)/
239 {
240 	PRINT_RECORD(self->i);
241 	self->i = (self->i + 1)%MAX_RECORDS;
242 
243 	num[self->conn_id]--;
244 }
245 
246 tcp-trace-*
247 /(self->flags & TH_RST) && (num[self->conn_id] >= 1)/
248 {
249 	PRINT_RECORD(self->i);
250 	self->i = (self->i + 1)%MAX_RECORDS;
251 
252 	num[self->conn_id]--;
253 	self->reset = self->conn_id;
254 }
255 
256 tcp-trace-*
257 /self->reset/
258 {
259 	pcount[self->reset] = -1;
260 	rollover[self->reset] = 0;
261 	end_ptr[self->reset] = 0;
262 	num[self->reset] = 0;
263 
264 	self->reset = 0;
265 }
266 
267 conn-destroy
268 {
269 	/* clear old connection state */
270 	this->conn_id = (uint64_t)arg0;
271 
272 	pcount[this->conn_id] = -1;
273 	rollover[this->conn_id] = 0;
274 	end_ptr[this->conn_id] = 0;
275 	num[this->conn_id] = 0;
276 	first[this->conn_id] = 0;
277 
278 	laddr[this->conn_id] = 0;
279 	faddr[this->conn_id] = 0;
280 	lport[this->conn_id] = 0;
281 	fport[this->conn_id] = 0;
282 	iss[this->conn_id] = 0;
283 	irs[this->conn_id] = 0;
284 }
285