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]
24 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
25 * Copyright (c) 2013 Mark Johnston <markj@freebsd.org>
28 #pragma D depends_on library ip.d
29 #pragma D depends_on module kernel
30 #pragma D depends_on provider tcp
33 * Convert a TCP state value to a string.
35 #pragma D binding "1.6.3" TCPS_CLOSED
36 inline int TCPS_CLOSED = 0;
37 #pragma D binding "1.6.3" TCPS_LISTEN
38 inline int TCPS_LISTEN = 1;
39 #pragma D binding "1.6.3" TCPS_SYN_SENT
40 inline int TCPS_SYN_SENT = 2;
41 #pragma D binding "1.6.3" TCPS_SYN_RECEIVED
42 inline int TCPS_SYN_RECEIVED = 3;
43 #pragma D binding "1.6.3" TCPS_ESTABLISHED
44 inline int TCPS_ESTABLISHED = 4;
45 #pragma D binding "1.6.3" TCPS_CLOSE_WAIT
46 inline int TCPS_CLOSE_WAIT = 5;
47 #pragma D binding "1.6.3" TCPS_FIN_WAIT_1
48 inline int TCPS_FIN_WAIT_1 = 6;
49 #pragma D binding "1.6.3" TCPS_CLOSING
50 inline int TCPS_CLOSING = 7;
51 #pragma D binding "1.6.3" TCPS_LAST_ACK
52 inline int TCPS_LAST_ACK = 8;
53 #pragma D binding "1.6.3" TCPS_FIN_WAIT_2
54 inline int TCPS_FIN_WAIT_2 = 9;
55 #pragma D binding "1.6.3" TCPS_TIME_WAIT
56 inline int TCPS_TIME_WAIT = 10;
59 * For compatibility also provide the names used by Solaris.
61 #pragma D binding "1.13" TCP_STATE_CLOSED
62 inline int TCP_STATE_CLOSED = TCPS_CLOSED;
63 #pragma D binding "1.13" TCP_STATE_LISTEN
64 inline int TCP_STATE_LISTEN = TCPS_LISTEN;
65 #pragma D binding "1.13" TCP_STATE_SYN_SENT
66 inline int TCP_STATE_SYN_SENT = TCPS_SYN_SENT;
67 #pragma D binding "1.13" TCP_STATE_SYN_RECEIVED
68 inline int TCP_STATE_SYN_RECEIVED = TCPS_SYN_RECEIVED;
69 #pragma D binding "1.13" TCP_STATE_ESTABLISHED
70 inline int TCP_STATE_ESTABLISHED = TCPS_ESTABLISHED;
71 #pragma D binding "1.13" TCP_STATE_CLOSE_WAIT
72 inline int TCP_STATE_CLOSE_WAIT = TCPS_CLOSE_WAIT;
73 #pragma D binding "1.13" TCP_STATE_FIN_WAIT_1
74 inline int TCP_STATE_FIN_WAIT_1 = TCPS_FIN_WAIT_1;
75 #pragma D binding "1.13" TCP_STATE_CLOSING
76 inline int TCP_STATE_CLOSING = TCPS_CLOSING;
77 #pragma D binding "1.13" TCP_STATE_LAST_ACK
78 inline int TCP_STATE_LAST_ACK = TCPS_LAST_ACK;
79 #pragma D binding "1.13" TCP_STATE_FIN_WAIT_2
80 inline int TCP_STATE_FIN_WAIT_2 = TCPS_FIN_WAIT_2;
81 #pragma D binding "1.13" TCP_STATE_TIME_WAIT
82 inline int TCP_STATE_TIME_WAIT = TCPS_TIME_WAIT;
84 /* TCP segment flags. */
85 #pragma D binding "1.6.3" TH_FIN
86 inline uint8_t TH_FIN = 0x01;
87 #pragma D binding "1.6.3" TH_SYN
88 inline uint8_t TH_SYN = 0x02;
89 #pragma D binding "1.6.3" TH_RST
90 inline uint8_t TH_RST = 0x04;
91 #pragma D binding "1.6.3" TH_PUSH
92 inline uint8_t TH_PUSH = 0x08;
93 #pragma D binding "1.6.3" TH_ACK
94 inline uint8_t TH_ACK = 0x10;
95 #pragma D binding "1.6.3" TH_URG
96 inline uint8_t TH_URG = 0x20;
97 #pragma D binding "1.6.3" TH_ECE
98 inline uint8_t TH_ECE = 0x40;
99 #pragma D binding "1.6.3" TH_CWR
100 inline uint8_t TH_CWR = 0x80;
102 /* TCP connection state strings. */
103 #pragma D binding "1.6.3" tcp_state_string
104 inline string tcp_state_string[int32_t state] =
105 state == TCPS_CLOSED ? "state-closed" :
106 state == TCPS_LISTEN ? "state-listen" :
107 state == TCPS_SYN_SENT ? "state-syn-sent" :
108 state == TCPS_SYN_RECEIVED ? "state-syn-received" :
109 state == TCPS_ESTABLISHED ? "state-established" :
110 state == TCPS_CLOSE_WAIT ? "state-close-wait" :
111 state == TCPS_FIN_WAIT_1 ? "state-fin-wait-1" :
112 state == TCPS_CLOSING ? "state-closing" :
113 state == TCPS_LAST_ACK ? "state-last-ack" :
114 state == TCPS_FIN_WAIT_2 ? "state-fin-wait-2" :
115 state == TCPS_TIME_WAIT ? "state-time-wait" :
119 * tcpsinfo contains stable TCP details from tcp_t.
121 typedef struct tcpsinfo {
123 int tcps_local; /* is delivered locally, boolean */
124 int tcps_active; /* active open (from here), boolean */
125 uint16_t tcps_lport; /* local port */
126 uint16_t tcps_rport; /* remote port */
127 string tcps_laddr; /* local address, as a string */
128 string tcps_raddr; /* remote address, as a string */
129 int32_t tcps_state; /* TCP state */
130 uint32_t tcps_iss; /* Initial sequence # sent */
131 uint32_t tcps_irs; /* Initial sequence # received */
132 uint32_t tcps_suna; /* sequence # sent but unacked */
133 uint32_t tcps_smax; /* highest sequence number sent */
134 uint32_t tcps_snxt; /* next sequence # to send */
135 uint32_t tcps_rack; /* sequence # we have acked */
136 uint32_t tcps_rnxt; /* next sequence # expected */
137 u_long tcps_swnd; /* send window size */
138 int32_t tcps_snd_ws; /* send window scaling */
139 uint32_t tcps_swl1; /* window update seg seq number */
140 uint32_t tcps_swl2; /* window update seg ack number */
141 uint32_t tcps_rup; /* receive urgent pointer */
142 uint32_t tcps_radv; /* advertised window */
143 u_long tcps_rwnd; /* receive window size */
144 int32_t tcps_rcv_ws; /* receive window scaling */
145 u_long tcps_cwnd; /* congestion window */
146 u_long tcps_cwnd_ssthresh; /* threshold for congestion avoidance */
147 uint32_t tcps_srecover; /* for use in NewReno Fast Recovery */
148 uint32_t tcps_sack_fack; /* SACK sequence # we have acked */
149 uint32_t tcps_sack_snxt; /* next SACK seq # for retransmission */
150 uint32_t tcps_rto; /* round-trip timeout, msec */
151 uint32_t tcps_mss; /* max segment size */
152 int tcps_retransmit; /* retransmit send event, boolean */
153 int tcps_srtt; /* smoothed RTT in units of (TCP_RTT_SCALE*hz) */
154 int tcps_debug; /* socket has SO_DEBUG set */
155 int tcps_cookie; /* expose the socket's SO_USER_COOKIE */
156 int32_t tcps_dupacks; /* consecutive dup acks received */
157 uint32_t tcps_rtttime; /* RTT measurement start time */
158 uint32_t tcps_rtseq; /* sequence # being timed */
159 uint32_t tcps_ts_recent; /* timestamp echo data */
163 * tcplsinfo provides the old tcp state for state changes.
165 typedef struct tcplsinfo {
166 int32_t tcps_state; /* previous TCP state */
170 * tcpinfo is the TCP header fields.
172 typedef struct tcpinfo {
173 uint16_t tcp_sport; /* source port */
174 uint16_t tcp_dport; /* destination port */
175 uint32_t tcp_seq; /* sequence number */
176 uint32_t tcp_ack; /* acknowledgment number */
177 uint8_t tcp_offset; /* data offset, in bytes */
178 uint8_t tcp_flags; /* flags */
179 uint16_t tcp_window; /* window size */
180 uint16_t tcp_checksum; /* checksum */
181 uint16_t tcp_urgent; /* urgent data pointer */
182 struct tcphdr *tcp_hdr; /* raw TCP header */
186 * A clone of tcpinfo_t used to handle the fact that the TCP input path
187 * overwrites some fields of the TCP header with their host-order equivalents.
188 * Unfortunately, DTrace doesn't let us simply typedef a new name for struct
189 * tcpinfo and define a separate translator for it.
191 typedef struct tcpinfoh {
192 uint16_t tcp_sport; /* source port */
193 uint16_t tcp_dport; /* destination port */
194 uint32_t tcp_seq; /* sequence number */
195 uint32_t tcp_ack; /* acknowledgment number */
196 uint8_t tcp_offset; /* data offset, in bytes */
197 uint8_t tcp_flags; /* flags */
198 uint16_t tcp_window; /* window size */
199 uint16_t tcp_checksum; /* checksum */
200 uint16_t tcp_urgent; /* urgent data pointer */
201 struct tcphdr *tcp_hdr; /* raw TCP header */
204 #pragma D binding "1.6.3" translator
205 translator csinfo_t < struct tcpcb *p > {
207 cs_cid = (uint64_t)(p == NULL ? 0 : p->t_inpcb);
212 #pragma D binding "1.6.3" translator
213 translator tcpsinfo_t < struct tcpcb *p > {
214 tcps_addr = (uintptr_t)p;
215 tcps_local = -1; /* XXX */
216 tcps_active = -1; /* XXX */
217 tcps_lport = p == NULL ? 0 : ntohs(p->t_inpcb->inp_inc.inc_ie.ie_lport);
218 tcps_rport = p == NULL ? 0 : ntohs(p->t_inpcb->inp_inc.inc_ie.ie_fport);
219 tcps_laddr = p == NULL ? "<unknown>" :
220 p->t_inpcb->inp_vflag == INP_IPV4 ?
221 inet_ntoa(&p->t_inpcb->inp_inc.inc_ie.ie_dependladdr.id46_addr.ia46_addr4.s_addr) :
222 inet_ntoa6(&p->t_inpcb->inp_inc.inc_ie.ie_dependladdr.id6_addr);
223 tcps_raddr = p == NULL ? "<unknown>" :
224 p->t_inpcb->inp_vflag == INP_IPV4 ?
225 inet_ntoa(&p->t_inpcb->inp_inc.inc_ie.ie_dependfaddr.id46_addr.ia46_addr4.s_addr) :
226 inet_ntoa6(&p->t_inpcb->inp_inc.inc_ie.ie_dependfaddr.id6_addr);
227 tcps_state = p == NULL ? -1 : p->t_state;
228 tcps_iss = p == NULL ? 0 : p->iss;
229 tcps_irs = p == NULL ? 0 : p->irs;
230 tcps_suna = p == NULL ? 0 : p->snd_una;
231 tcps_smax = p == NULL ? 0 : p->snd_max;
232 tcps_snxt = p == NULL ? 0 : p->snd_nxt;
233 tcps_rack = p == NULL ? 0 : p->last_ack_sent;
234 tcps_rnxt = p == NULL ? 0 : p->rcv_nxt;
235 tcps_swnd = p == NULL ? -1 : p->snd_wnd;
236 tcps_snd_ws = p == NULL ? -1 : p->snd_scale;
237 tcps_swl1 = p == NULL ? -1 : p->snd_wl1;
238 tcps_swl2 = p == NULL ? -1 : p->snd_wl2;
239 tcps_radv = p == NULL ? -1 : p->rcv_adv;
240 tcps_rwnd = p == NULL ? -1 : p->rcv_wnd;
241 tcps_rup = p == NULL ? -1 : p->rcv_up;
242 tcps_rcv_ws = p == NULL ? -1 : p->rcv_scale;
243 tcps_cwnd = p == NULL ? -1 : p->snd_cwnd;
244 tcps_cwnd_ssthresh = p == NULL ? -1 : p->snd_ssthresh;
245 tcps_srecover = p == NULL ? -1 : p->snd_recover;
246 tcps_sack_fack = p == NULL ? 0 : p->snd_fack;
247 tcps_sack_snxt = p == NULL ? 0 : p->sack_newdata;
248 tcps_rto = p == NULL ? -1 : (p->t_rxtcur * 1000) / `hz;
249 tcps_mss = p == NULL ? -1 : p->t_maxseg;
250 tcps_retransmit = p == NULL ? -1 : p->t_rxtshift > 0 ? 1 : 0;
251 tcps_srtt = p == NULL ? -1 : p->t_srtt; /* smoothed RTT in units of (TCP_RTT_SCALE*hz) */
252 tcps_debug = p == NULL ? 0 :
253 p->t_inpcb->inp_socket->so_options & 1;
254 tcps_cookie = p == NULL ? -1 :
255 p->t_inpcb->inp_socket->so_user_cookie;
256 tcps_dupacks = p == NULL ? -1 : p->t_dupacks;
257 tcps_rtttime = p == NULL ? -1 : p->t_rtttime;
258 tcps_rtseq = p == NULL ? -1 : p->t_rtseq;
259 tcps_ts_recent = p == NULL ? -1 : p->ts_recent;
262 #pragma D binding "1.6.3" translator
263 translator tcpinfo_t < struct tcphdr *p > {
264 tcp_sport = p == NULL ? 0 : ntohs(p->th_sport);
265 tcp_dport = p == NULL ? 0 : ntohs(p->th_dport);
266 tcp_seq = p == NULL ? -1 : ntohl(p->th_seq);
267 tcp_ack = p == NULL ? -1 : ntohl(p->th_ack);
268 tcp_offset = p == NULL ? -1 : (p->th_off >> 2);
269 tcp_flags = p == NULL ? 0 : p->th_flags;
270 tcp_window = p == NULL ? 0 : ntohs(p->th_win);
271 tcp_checksum = p == NULL ? 0 : ntohs(p->th_sum);
272 tcp_urgent = p == NULL ? 0 : ntohs(p->th_urp);
273 tcp_hdr = (struct tcphdr *)p;
277 * This translator differs from the one for tcpinfo_t in that the sequence
278 * number, acknowledgement number, window size and urgent pointer are already
279 * in host order and thus don't need to be converted.
281 #pragma D binding "1.6.3" translator
282 translator tcpinfoh_t < struct tcphdr *p > {
283 tcp_sport = p == NULL ? 0 : ntohs(p->th_sport);
284 tcp_dport = p == NULL ? 0 : ntohs(p->th_dport);
285 tcp_seq = p == NULL ? -1 : p->th_seq;
286 tcp_ack = p == NULL ? -1 : p->th_ack;
287 tcp_offset = p == NULL ? -1 : (p->th_off >> 2);
288 tcp_flags = p == NULL ? 0 : p->th_flags;
289 tcp_window = p == NULL ? 0 : p->th_win;
290 tcp_checksum = p == NULL ? 0 : ntohs(p->th_sum);
291 tcp_urgent = p == NULL ? 0 : p->th_urp;
292 tcp_hdr = (struct tcphdr *)p;
295 #pragma D binding "1.6.3" translator
296 translator tcplsinfo_t < int s > {
301 /* Support for TCP debug */
303 #pragma D binding "1.12.1" TA_INPUT
304 inline int TA_INPUT = 0;
305 #pragma D binding "1.12.1" TA_OUTPUT
306 inline int TA_OUTPUT = 1;
307 #pragma D binding "1.12.1" TA_USER
308 inline int TA_USER = 2;
309 #pragma D binding "1.12.1" TA_RESPOND
310 inline int TA_RESPOND = 3;
311 #pragma D binding "1.12.1" TA_DROP
312 inline int TA_DROP = 4;
314 /* direction strings. */
316 #pragma D binding "1.12.1" tcpdebug_dir_string
317 inline string tcpdebug_dir_string[uint8_t direction] =
318 direction == TA_INPUT ? "input" :
319 direction == TA_OUTPUT ? "output" :
320 direction == TA_USER ? "user" :
321 direction == TA_RESPOND ? "respond" :
322 direction == TA_OUTPUT ? "drop" :
325 #pragma D binding "1.12.1" tcpflag_string
326 inline string tcpflag_string[uint8_t flags] =
327 flags & TH_FIN ? "FIN" :
328 flags & TH_SYN ? "SYN" :
329 flags & TH_RST ? "RST" :
330 flags & TH_PUSH ? "PUSH" :
331 flags & TH_ACK ? "ACK" :
332 flags & TH_URG ? "URG" :
333 flags & TH_ECE ? "ECE" :
334 flags & TH_CWR ? "CWR" :
337 #pragma D binding "1.12.1" PRU_ATTACH
338 inline int PRU_ATTACH = 0;
339 #pragma D binding "1.12.1" PRU_DETACH
340 inline int PRU_DETACH = 1;
341 #pragma D binding "1.12.1" PRU_BIND
342 inline int PRU_BIND = 2;
343 #pragma D binding "1.12.1" PRU_LISTEN
344 inline int PRU_LISTEN = 3;
345 #pragma D binding "1.12.1" PRU_CONNECT
346 inline int PRU_CONNECT = 4;
347 #pragma D binding "1.12.1" PRU_ACCEPT
348 inline int PRU_ACCEPT = 5 ;
349 #pragma D binding "1.12.1" PRU_DISCONNECT
350 inline int PRU_DISCONNECT = 6;
351 #pragma D binding "1.12.1" PRU_SHUTDOWN
352 inline int PRU_SHUTDOWN = 7;
353 #pragma D binding "1.12.1" PRU_RCVD
354 inline int PRU_RCVD = 8;
355 #pragma D binding "1.12.1" PRU_SEND
356 inline int PRU_SEND = 9;
357 #pragma D binding "1.12.1" PRU_ABORT
358 inline int PRU_ABORT = 10;
359 #pragma D binding "1.12.1" PRU_CONTROL
360 inline int PRU_CONTROL = 11;
361 #pragma D binding "1.12.1" PRU_SENSE
362 inline int PRU_SENSE = 12;
363 #pragma D binding "1.12.1" PRU_RCVOOB
364 inline int PRU_RCVOOB = 13;
365 #pragma D binding "1.12.1" PRU_SENDOOB
366 inline int PRU_SENDOOB = 14;
367 #pragma D binding "1.12.1" PRU_SOCKADDR
368 inline int PRU_SOCKADDR = 15;
369 #pragma D binding "1.12.1" PRU_PEERADDR
370 inline int PRU_PEERADDR = 16;
371 #pragma D binding "1.12.1" PRU_CONNECT2
372 inline int PRU_CONNECT2 = 17;
373 #pragma D binding "1.12.1" PRU_FASTTIMO
374 inline int PRU_FASTTIMO = 18;
375 #pragma D binding "1.12.1" PRU_SLOWTIMO
376 inline int PRU_SLOWTIMO = 19;
377 #pragma D binding "1.12.1" PRU_PROTORCV
378 inline int PRU_PROTORCV = 20;
379 #pragma D binding "1.12.1" PRU_PROTOSEND
380 inline int PRU_PROTOSEND = 21;
381 #pragma D binding "1.12.1" PRU_SEND_EOF
382 inline int PRU_SEND_EOF = 22;
383 #pragma D binding "1.12.1" PRU_SOSETLABEL
384 inline int PRU_SOSETLABEL = 23;
385 #pragma D binding "1.12.1" PRU_CLOSE
386 inline int PRU_CLOSE = 24;
387 #pragma D binding "1.12.1" PRU_FLUSH
388 inline int PRU_FLUSH = 25;
390 #pragma D binding "1.12.1" prureq_string
391 inline string prureq_string[uint8_t req] =
392 req == PRU_ATTACH ? "ATTACH" :
393 req == PRU_DETACH ? "DETACH" :
394 req == PRU_BIND ? "BIND" :
395 req == PRU_LISTEN ? "LISTEN" :
396 req == PRU_CONNECT ? "CONNECT" :
397 req == PRU_ACCEPT ? "ACCEPT" :
398 req == PRU_DISCONNECT ? "DISCONNECT" :
399 req == PRU_SHUTDOWN ? "SHUTDOWN" :
400 req == PRU_RCVD ? "RCVD" :
401 req == PRU_SEND ? "SEND" :
402 req == PRU_ABORT ? "ABORT" :
403 req == PRU_CONTROL ? "CONTROL" :
404 req == PRU_SENSE ? "SENSE" :
405 req == PRU_RCVOOB ? "RCVOOB" :
406 req == PRU_SENDOOB ? "SENDOOB" :
407 req == PRU_SOCKADDR ? "SOCKADDR" :
408 req == PRU_PEERADDR ? "PEERADDR" :
409 req == PRU_CONNECT2 ? "CONNECT2" :
410 req == PRU_FASTTIMO ? "FASTTIMO" :
411 req == PRU_SLOWTIMO ? "SLOWTIMO" :
412 req == PRU_PROTORCV ? "PROTORCV" :
413 req == PRU_PROTOSEND ? "PROTOSEND" :
414 req == PRU_SEND ? "SEND_EOF" :
415 req == PRU_SOSETLABEL ? "SOSETLABEL" :
416 req == PRU_CLOSE ? "CLOSE" :
417 req == PRU_FLUSH ? "FLUSE" :