4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
25 #
pragma D depends_on
module unix
26 #
pragma D depends_on provider tcp
28 inline
int TH_FIN
= @TH_FIN@
;
29 #
pragma D binding
"1.6.3" TH_FIN
30 inline
int TH_SYN
= @TH_SYN@
;
31 #
pragma D binding
"1.6.3" TH_SYN
32 inline
int TH_RST
= @TH_RST@
;
33 #
pragma D binding
"1.6.3" TH_RST
34 inline
int TH_PUSH
= @TH_PUSH@
;
35 #
pragma D binding
"1.6.3" TH_PUSH
36 inline
int TH_ACK
= @TH_ACK@
;
37 #
pragma D binding
"1.6.3" TH_ACK
38 inline
int TH_URG
= @TH_URG@
;
39 #
pragma D binding
"1.6.3" TH_URG
40 inline
int TH_ECE
= @TH_ECE@
;
41 #
pragma D binding
"1.6.3" TH_ECE
42 inline
int TH_CWR
= @TH_CWR@
;
43 #
pragma D binding
"1.6.3" TH_CWR
45 inline int32_t TCP_STATE_CLOSED
= @TCPS_CLOSED@
;
46 #
pragma D binding
"1.6.3" TCP_STATE_CLOSED
47 inline int32_t TCP_STATE_IDLE
= @TCPS_IDLE@
;
48 #
pragma D binding
"1.6.3" TCP_STATE_IDLE
49 inline int32_t TCP_STATE_BOUND
= @TCPS_BOUND@
;
50 #
pragma D binding
"1.6.3" TCP_STATE_BOUND
51 inline int32_t TCP_STATE_LISTEN
= @TCPS_LISTEN@
;
52 #
pragma D binding
"1.6.3" TCP_STATE_LISTEN
53 inline int32_t TCP_STATE_SYN_SENT
= @TCPS_SYN_SENT@
;
54 #
pragma D binding
"1.6.3" TCP_STATE_SYN_SENT
55 inline int32_t TCP_STATE_SYN_RECEIVED
= @TCPS_SYN_RCVD@
;
56 #
pragma D binding
"1.6.3" TCP_STATE_SYN_RECEIVED
57 inline int32_t TCP_STATE_ESTABLISHED
= @TCPS_ESTABLISHED@
;
58 #
pragma D binding
"1.6.3" TCP_STATE_ESTABLISHED
59 inline int32_t TCP_STATE_CLOSE_WAIT
= @TCPS_CLOSE_WAIT@
;
60 #
pragma D binding
"1.6.3" TCP_STATE_CLOSE_WAIT
61 inline int32_t TCP_STATE_FIN_WAIT_1
= @TCPS_FIN_WAIT_1@
;
62 #
pragma D binding
"1.6.3" TCP_STATE_FIN_WAIT_1
63 inline int32_t TCP_STATE_CLOSING
= @TCPS_CLOSING@
;
64 #
pragma D binding
"1.6.3" TCP_STATE_CLOSING
65 inline int32_t TCP_STATE_LAST_ACK
= @TCPS_LAST_ACK@
;
66 #
pragma D binding
"1.6.3" TCP_STATE_LAST_ACK
67 inline int32_t TCP_STATE_FIN_WAIT_2
= @TCPS_FIN_WAIT_2@
;
68 #
pragma D binding
"1.6.3" TCP_STATE_FIN_WAIT_2
69 inline int32_t TCP_STATE_TIME_WAIT
= @TCPS_TIME_WAIT@
;
70 #
pragma D binding
"1.6.3" TCP_STATE_TIME_WAIT
73 * Convert a TCP state value to a string.
75 inline string tcp_state_string
[int32_t state
] =
76 state
== TCP_STATE_CLOSED ?
"state-closed" :
77 state
== TCP_STATE_IDLE ?
"state-idle" :
78 state
== TCP_STATE_BOUND ?
"state-bound" :
79 state
== TCP_STATE_LISTEN ?
"state-listen" :
80 state
== TCP_STATE_SYN_SENT ?
"state-syn-sent" :
81 state
== TCP_STATE_SYN_RECEIVED ?
"state-syn-received" :
82 state
== TCP_STATE_ESTABLISHED ?
"state-established" :
83 state
== TCP_STATE_CLOSE_WAIT ?
"state-close-wait" :
84 state
== TCP_STATE_FIN_WAIT_1 ?
"state-fin-wait-1" :
85 state
== TCP_STATE_CLOSING ?
"state-closing" :
86 state
== TCP_STATE_LAST_ACK ?
"state-last-ack" :
87 state
== TCP_STATE_FIN_WAIT_2 ?
"state-fin-wait-2" :
88 state
== TCP_STATE_TIME_WAIT ?
"state-time-wait" :
90 #
pragma D binding
"1.6.3" tcp_state_string
92 typedef struct tcphdr_s tcph_t
;
94 * tcpinfo is the TCP header fields.
96 typedef struct tcpinfo
{
97 uint16_t tcp_sport
; /* source port */
98 uint16_t tcp_dport
; /* destination port */
99 uint32_t tcp_seq
; /* sequence number */
100 uint32_t tcp_ack
; /* acknowledgment number */
101 uint8_t tcp_offset
; /* data offset, in bytes */
102 uint8_t tcp_flags
; /* flags */
103 uint16_t tcp_window
; /* window size */
104 uint16_t tcp_checksum
; /* checksum */
105 uint16_t tcp_urgent
; /* urgent data pointer */
106 tcph_t
*tcp_hdr
; /* raw TCP header */
110 * tcpsinfo contains stable TCP details from tcp_t.
112 typedef struct tcpsinfo
{
114 int tcps_local
; /* is delivered locally, boolean */
115 int tcps_active
; /* active open (from here), boolean */
116 uint16_t tcps_lport
; /* local port */
117 uint16_t tcps_rport
; /* remote port */
118 string tcps_laddr
; /* local address, as a string */
119 string tcps_raddr
; /* remote address, as a string */
120 int32_t tcps_state
; /* TCP state */
121 uint32_t tcps_iss
; /* Initial sequence # sent */
122 uint32_t tcps_suna
; /* sequence # sent but unacked */
123 uint32_t tcps_snxt
; /* next sequence # to send */
124 uint32_t tcps_rack
; /* sequence # we have acked */
125 uint32_t tcps_rnxt
; /* next sequence # expected */
126 uint32_t tcps_swnd
; /* send window size */
127 int32_t tcps_snd_ws
; /* send window scaling */
128 uint32_t tcps_rwnd
; /* receive window size */
129 int32_t tcps_rcv_ws
; /* receive window scaling */
130 uint32_t tcps_cwnd
; /* congestion window */
131 uint32_t tcps_cwnd_ssthresh
; /* threshold for congestion avoidance */
132 uint32_t tcps_sack_fack
; /* SACK sequence # we have acked */
133 uint32_t tcps_sack_snxt
; /* next SACK seq # for retransmission */
134 uint32_t tcps_rto
; /* round-trip timeout, msec */
135 uint32_t tcps_mss
; /* max segment size */
136 int tcps_retransmit
; /* retransmit send event, boolean */
140 * tcplsinfo provides the old tcp state for state changes.
142 typedef struct tcplsinfo
{
143 int32_t tcps_state
; /* previous TCP state */
147 * __dtrace_tcp_tcph_t is used by the tcpinfo_t * translator to take either
148 * the non-NULL tcph_t * passed in or, if it is NULL, uses arg3 (tcp_t *)
149 * from the tcp:::send and tcp:::recieve probes and translates the tcp_t *
150 * into the tcpinfo_t. When no headers are available - as is the case for
151 * TCP fusion tcp:::send and tcp:::receive - this allows us to present the
152 * consumer with header data based on tcp_t * content and hide TCP fusion
153 * implementation details.
155 typedef tcph_t
* __dtrace_tcp_tcph_t
;
157 #
pragma D binding
"1.6.3" translator
158 translator tcpinfo_t
< tcph_t
*T
> {
159 tcp_sport
= ntohs(*(uint16_t
*)T
->th_lport
);
160 tcp_dport
= ntohs(*(uint16_t
*)T
->th_fport
);
161 tcp_seq
= ntohl(*(uint32_t
*)T
->th_seq
);
162 tcp_ack
= ntohl(*(uint32_t
*)T
->th_ack
);
163 tcp_offset
= (*(uint8_t
*)T
->th_offset_and_rsrvd
& 0xf0) >> 2;
164 tcp_flags
= *(uint8_t
*)T
->th_flags
;
165 tcp_window
= ntohs(*(uint16_t
*)T
->th_win
);
166 tcp_checksum
= ntohs(*(uint16_t
*)T
->th_sum
);
167 tcp_urgent
= ntohs(*(uint16_t
*)T
->th_urp
);
171 #
pragma D binding
"1.6.3" translator
172 translator tcpinfo_t
< __dtrace_tcp_tcph_t
*T
> {
174 T
!= NULL ?
ntohs(*(uint16_t
*)((tcph_t
*)T
)->th_lport
) :
175 arg3
!= NULL
&& probename
== "send" ?
176 ntohs(((tcp_t
*)arg3
)->tcp_connp
->u_port
.connu_ports
.connu_lport
) :
177 arg3
!= NULL
&& probename
== "receive" ?
178 ntohs(((tcp_t
*)arg3
)->tcp_connp
->u_port
.connu_ports
.connu_fport
) :
181 T
!= NULL ?
ntohs(*(uint16_t
*)((tcph_t
*)T
)->th_fport
) :
182 arg3
!= NULL
&& probename
== "send" ?
183 ntohs(((tcp_t
*)arg3
)->tcp_connp
->u_port
.connu_ports
.connu_fport
) :
184 arg3
!= NULL
&& probename
== "receive" ?
185 ntohs(((tcp_t
*)arg3
)->tcp_connp
->u_port
.connu_ports
.connu_lport
) :
188 T
!= NULL ?
ntohl(*(uint32_t
*)((tcph_t
*)T
)->th_seq
) :
189 arg3
!= NULL
&& probename
== "send" ?
190 ((tcp_t
*)arg3
)->tcp_snxt
- ((tcp_t
*)arg3
)->tcp_last_sent_len
:
191 arg3
!= NULL
&& probename
== "receive" ?
192 ((tcp_t
*)arg3
)->tcp_rnxt
- ((tcp_t
*)arg3
)->tcp_last_recv_len
:
195 T
!= NULL ?
ntohl(*(uint32_t
*)((tcph_t
*)T
)->th_ack
) :
196 arg3
!= NULL
&& probename
== "send" ?
197 ((tcp_t
*)arg3
)->tcp_rnxt
:
198 arg3
!= NULL
&& probename
== "receive" ?
199 ((tcp_t
*)arg3
)->tcp_snxt
:
201 tcp_offset
= T
!= NULL ?
202 (*(uint8_t
*)((tcph_t
*)T
)->th_offset_and_rsrvd
& 0xf0) >> 2 :
203 @TCP_MIN_HEADER_LENGTH@
;
204 tcp_flags
= T
!= NULL ?
*(uint8_t
*)((tcph_t
*)T
)->th_flags
: TH_ACK
;
205 tcp_window
= T
!= NULL ?
ntohs(*(uint16_t
*)((tcph_t
*)T
)->th_win
) :
206 arg3
!= NULL ?
((tcp_t
*)arg3
)->tcp_swnd
: 0;
207 tcp_checksum
= T
!= NULL ?
ntohs(*(uint16_t
*)((tcph_t
*)T
)->th_sum
) :
209 tcp_urgent
= T
!= NULL ?
ntohs(*(uint16_t
*)((tcph_t
*)T
)->th_urp
) : 0;
213 #
pragma D binding
"1.6.3" translator
214 translator tcpsinfo_t
< tcp_t
*T
> {
215 tcps_addr
= (uintptr_t
)T
;
217 * The following two members should just use tcp_t->tcp_loopback
218 * and tcp_t->tcp_active_open, however these are bit fields and
219 * can't be used until CR 6876830 is fixed. Meanwhile we source
220 * them a different way.
222 tcps_local
= T ? T
->tcp_ipha ?
223 T
->tcp_ipha
->ipha_src
== T
->tcp_ipha
->ipha_dst
: 1 : 0;
224 tcps_active
= T ?
!T
->tcp_saved_listener
: 0;
226 ntohs(T
->tcp_connp
->u_port
.connu_ports
.connu_lport
) : 0;
228 ntohs(T
->tcp_connp
->u_port
.connu_ports
.connu_fport
) : 0;
230 inet_ntoa6(&T
->tcp_connp
->connua_v6addr
.connua_laddr
) : "<unknown>";
232 inet_ntoa6(&T
->tcp_connp
->connua_v6addr
.connua_faddr
) : "<unknown>";
233 tcps_state
= T ? T
->tcp_state
: TCP_STATE_CLOSED
;
234 tcps_iss
= T ? T
->tcp_iss
: 0;
235 tcps_suna
= T ? T
->tcp_suna
: 0;
236 tcps_snxt
= T ? T
->tcp_snxt
: 0;
237 tcps_rack
= T ? T
->tcp_rack
: 0;
238 tcps_rnxt
= T ? T
->tcp_rnxt
: 0;
239 tcps_swnd
= T ? T
->tcp_swnd
: 0;
240 tcps_snd_ws
= T ? T
->tcp_snd_ws
: 0;
241 tcps_rwnd
= T ? T
->tcp_rwnd
: 0;
242 tcps_rcv_ws
= T ? T
->tcp_rcv_ws
: 0;
243 tcps_cwnd
= T ? T
->tcp_cwnd
: 0;
244 tcps_cwnd_ssthresh
= T ? T
->tcp_cwnd_ssthresh
: 0;
245 tcps_sack_fack
= T ? T
->tcp_sack_info
.tcp_fack
: 0;
246 tcps_sack_snxt
= T ? T
->tcp_sack_info
.tcp_sack_snxt
: 0;
247 tcps_rto
= T ? T
->tcp_rto
: 0;
248 tcps_mss
= T ? T
->tcp_mss
: 0;
250 * Determine if send is a retransmission by comparing the seq # to
251 * tcp_rexmit_nxt/tcp_rexmit_max - if the value is >= rexmit_nxt and
252 * < rexmit_max, this is a retransmission. Cannot use tcp_rexmit
253 * bitfield value due to CR 6876830.
255 tcps_retransmit
= T
&& probename
== "send" && arg4
!= NULL
&&
256 ntohl(*(uint32_t
*)((tcph_t
*)arg4
)->th_seq
) >= T
->tcp_rexmit_nxt
&&
257 ntohl(*(uint32_t
*)((tcph_t
*)arg4
)->th_seq
) < T
->tcp_rexmit_max ?
262 * Note: although we specify that the old state argument used as the
263 * input to the tcplsinfo_t translator is an int32_t, it reaches us as an
264 * int64_t (since it is a probe argument) so explicitly cast it back to
265 * interpret the negatively-valued states correctly.
267 #
pragma D binding
"1.6.3" translator
268 translator tcplsinfo_t
< int64_t I
> {
269 tcps_state
= (int32_t
) I
;