xref: /freebsd/cddl/lib/libdtrace/tcp.d (revision 57f6086735175ec16d6ba1b51128a7ae2dadd373)
1*57f60867SMark Johnston /*
2*57f60867SMark Johnston  * CDDL HEADER START
3*57f60867SMark Johnston  *
4*57f60867SMark Johnston  * The contents of this file are subject to the terms of the
5*57f60867SMark Johnston  * Common Development and Distribution License (the "License").
6*57f60867SMark Johnston  * You may not use this file except in compliance with the License.
7*57f60867SMark Johnston  *
8*57f60867SMark Johnston  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*57f60867SMark Johnston  * or http://www.opensolaris.org/os/licensing.
10*57f60867SMark Johnston  * See the License for the specific language governing permissions
11*57f60867SMark Johnston  * and limitations under the License.
12*57f60867SMark Johnston  *
13*57f60867SMark Johnston  * When distributing Covered Code, include this CDDL HEADER in each
14*57f60867SMark Johnston  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*57f60867SMark Johnston  * If applicable, add the following below this CDDL HEADER, with the
16*57f60867SMark Johnston  * fields enclosed by brackets "[]" replaced with your own identifying
17*57f60867SMark Johnston  * information: Portions Copyright [yyyy] [name of copyright owner]
18*57f60867SMark Johnston  *
19*57f60867SMark Johnston  * CDDL HEADER END
20*57f60867SMark Johnston  *
21*57f60867SMark Johnston  * $FreeBSD$
22*57f60867SMark Johnston  */
23*57f60867SMark Johnston /*
24*57f60867SMark Johnston  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
25*57f60867SMark Johnston  * Copyright (c) 2013 Mark Johnston <markj@freebsd.org>
26*57f60867SMark Johnston  */
27*57f60867SMark Johnston 
28*57f60867SMark Johnston #pragma D depends_on library ip.d
29*57f60867SMark Johnston #pragma D depends_on provider tcp
30*57f60867SMark Johnston 
31*57f60867SMark Johnston /*
32*57f60867SMark Johnston  * Convert a TCP state value to a string.
33*57f60867SMark Johnston  */
34*57f60867SMark Johnston #pragma D binding "1.0" TCPS_CLOSED
35*57f60867SMark Johnston inline int TCPS_CLOSED =	0;
36*57f60867SMark Johnston #pragma D binding "1.0" TCPS_LISTEN
37*57f60867SMark Johnston inline int TCPS_LISTEN =	1;
38*57f60867SMark Johnston #pragma D binding "1.0" TCPS_SYN_SENT
39*57f60867SMark Johnston inline int TCPS_SYN_SENT =	2;
40*57f60867SMark Johnston #pragma D binding "1.0" TCPS_SYN_RECEIVED
41*57f60867SMark Johnston inline int TCPS_SYN_RECEIVED =	3;
42*57f60867SMark Johnston #pragma D binding "1.0" TCPS_ESTABLISHED
43*57f60867SMark Johnston inline int TCPS_ESTABLISHED =	4;
44*57f60867SMark Johnston #pragma D binding "1.0" TCPS_CLOSE_WAIT
45*57f60867SMark Johnston inline int TCPS_CLOSE_WAIT =	5;
46*57f60867SMark Johnston #pragma D binding "1.0" TCPS_FIN_WAIT_1
47*57f60867SMark Johnston inline int TCPS_FIN_WAIT_1 =	6;
48*57f60867SMark Johnston #pragma D binding "1.0" TCPS_CLOSING
49*57f60867SMark Johnston inline int TCPS_CLOSING =	7;
50*57f60867SMark Johnston #pragma D binding "1.0" TCPS_LAST_ACK
51*57f60867SMark Johnston inline int TCPS_LAST_ACK =	8;
52*57f60867SMark Johnston #pragma D binding "1.0" TCPS_FIN_WAIT_2
53*57f60867SMark Johnston inline int TCPS_FIN_WAIT_2 =	9;
54*57f60867SMark Johnston #pragma D binding "1.0" TCPS_TIME_WAIT
55*57f60867SMark Johnston inline int TCPS_TIME_WAIT =	10;
56*57f60867SMark Johnston 
57*57f60867SMark Johnston /* TCP segment flags. */
58*57f60867SMark Johnston #pragma D binding "1.0" TH_FIN
59*57f60867SMark Johnston inline uint8_t TH_FIN =		0x01;
60*57f60867SMark Johnston #pragma D binding "1.0" TH_SYN
61*57f60867SMark Johnston inline uint8_t TH_SYN =		0x02;
62*57f60867SMark Johnston #pragma D binding "1.0" TH_RST
63*57f60867SMark Johnston inline uint8_t TH_RST =		0x04;
64*57f60867SMark Johnston #pragma D binding "1.0" TH_PUSH
65*57f60867SMark Johnston inline uint8_t TH_PUSH =	0x08;
66*57f60867SMark Johnston #pragma D binding "1.0" TH_ACK
67*57f60867SMark Johnston inline uint8_t TH_ACK =		0x10;
68*57f60867SMark Johnston #pragma D binding "1.0" TH_URG
69*57f60867SMark Johnston inline uint8_t TH_URG =		0x20;
70*57f60867SMark Johnston #pragma D binding "1.0" TH_ECE
71*57f60867SMark Johnston inline uint8_t TH_ECE =		0x40;
72*57f60867SMark Johnston #pragma D binding "1.0" TH_CWR
73*57f60867SMark Johnston inline uint8_t TH_CWR =		0x80;
74*57f60867SMark Johnston 
75*57f60867SMark Johnston /* TCP connection state strings. */
76*57f60867SMark Johnston #pragma D binding "1.0" tcp_state_string
77*57f60867SMark Johnston inline string tcp_state_string[int32_t state] =
78*57f60867SMark Johnston 	state == TCPS_CLOSED ?		"state-closed" :
79*57f60867SMark Johnston 	state == TCPS_LISTEN ?		"state-listen" :
80*57f60867SMark Johnston 	state == TCPS_SYN_SENT ?	"state-syn-sent" :
81*57f60867SMark Johnston 	state == TCPS_SYN_RECEIVED ?	"state-syn-received" :
82*57f60867SMark Johnston 	state == TCPS_ESTABLISHED ?	"state-established" :
83*57f60867SMark Johnston 	state == TCPS_CLOSE_WAIT ?	"state-close-wait" :
84*57f60867SMark Johnston 	state == TCPS_FIN_WAIT_1 ?	"state-fin-wait-1" :
85*57f60867SMark Johnston 	state == TCPS_CLOSING ?		"state-closing" :
86*57f60867SMark Johnston 	state == TCPS_LAST_ACK ?	"state-last-ack" :
87*57f60867SMark Johnston 	state == TCPS_FIN_WAIT_2 ?	"state-fin-wait-2" :
88*57f60867SMark Johnston 	state == TCPS_TIME_WAIT ?	"state-time-wait" :
89*57f60867SMark Johnston 	"<unknown>";
90*57f60867SMark Johnston 
91*57f60867SMark Johnston /*
92*57f60867SMark Johnston  * tcpsinfo contains stable TCP details from tcp_t.
93*57f60867SMark Johnston  */
94*57f60867SMark Johnston typedef struct tcpsinfo {
95*57f60867SMark Johnston 	uintptr_t tcps_addr;
96*57f60867SMark Johnston 	int tcps_local;			/* is delivered locally, boolean */
97*57f60867SMark Johnston 	int tcps_active;		/* active open (from here), boolean */
98*57f60867SMark Johnston 	uint16_t tcps_lport;		/* local port */
99*57f60867SMark Johnston 	uint16_t tcps_rport;		/* remote port */
100*57f60867SMark Johnston 	string tcps_laddr;		/* local address, as a string */
101*57f60867SMark Johnston 	string tcps_raddr;		/* remote address, as a string */
102*57f60867SMark Johnston 	int32_t tcps_state;		/* TCP state */
103*57f60867SMark Johnston 	uint32_t tcps_iss;		/* Initial sequence # sent */
104*57f60867SMark Johnston 	uint32_t tcps_suna;		/* sequence # sent but unacked */
105*57f60867SMark Johnston 	uint32_t tcps_snxt;		/* next sequence # to send */
106*57f60867SMark Johnston 	uint32_t tcps_rack;		/* sequence # we have acked */
107*57f60867SMark Johnston 	uint32_t tcps_rnxt;		/* next sequence # expected */
108*57f60867SMark Johnston 	uint32_t tcps_swnd;		/* send window size */
109*57f60867SMark Johnston 	int32_t tcps_snd_ws;		/* send window scaling */
110*57f60867SMark Johnston 	uint32_t tcps_rwnd;		/* receive window size */
111*57f60867SMark Johnston 	int32_t tcps_rcv_ws;		/* receive window scaling */
112*57f60867SMark Johnston 	uint32_t tcps_cwnd;		/* congestion window */
113*57f60867SMark Johnston 	uint32_t tcps_cwnd_ssthresh;	/* threshold for congestion avoidance */
114*57f60867SMark Johnston 	uint32_t tcps_sack_fack;	/* SACK sequence # we have acked */
115*57f60867SMark Johnston 	uint32_t tcps_sack_snxt;	/* next SACK seq # for retransmission */
116*57f60867SMark Johnston 	uint32_t tcps_rto;		/* round-trip timeout, msec */
117*57f60867SMark Johnston 	uint32_t tcps_mss;		/* max segment size */
118*57f60867SMark Johnston 	int tcps_retransmit;		/* retransmit send event, boolean */
119*57f60867SMark Johnston } tcpsinfo_t;
120*57f60867SMark Johnston 
121*57f60867SMark Johnston /*
122*57f60867SMark Johnston  * tcplsinfo provides the old tcp state for state changes.
123*57f60867SMark Johnston  */
124*57f60867SMark Johnston typedef struct tcplsinfo {
125*57f60867SMark Johnston 	int32_t tcps_state;		/* previous TCP state */
126*57f60867SMark Johnston } tcplsinfo_t;
127*57f60867SMark Johnston 
128*57f60867SMark Johnston /*
129*57f60867SMark Johnston  * tcpinfo is the TCP header fields.
130*57f60867SMark Johnston  */
131*57f60867SMark Johnston typedef struct tcpinfo {
132*57f60867SMark Johnston 	uint16_t tcp_sport;		/* source port */
133*57f60867SMark Johnston 	uint16_t tcp_dport;		/* destination port */
134*57f60867SMark Johnston 	uint32_t tcp_seq;		/* sequence number */
135*57f60867SMark Johnston 	uint32_t tcp_ack;		/* acknowledgment number */
136*57f60867SMark Johnston 	uint8_t tcp_offset;		/* data offset, in bytes */
137*57f60867SMark Johnston 	uint8_t tcp_flags;		/* flags */
138*57f60867SMark Johnston 	uint16_t tcp_window;		/* window size */
139*57f60867SMark Johnston 	uint16_t tcp_checksum;		/* checksum */
140*57f60867SMark Johnston 	uint16_t tcp_urgent;		/* urgent data pointer */
141*57f60867SMark Johnston 	struct tcphdr *tcp_hdr;		/* raw TCP header */
142*57f60867SMark Johnston } tcpinfo_t;
143*57f60867SMark Johnston 
144*57f60867SMark Johnston #pragma D binding "1.0" translator
145*57f60867SMark Johnston translator csinfo_t < struct tcpcb *p > {
146*57f60867SMark Johnston 	cs_addr =	NULL;
147*57f60867SMark Johnston 	cs_cid =	(uint64_t)p;
148*57f60867SMark Johnston 	cs_pid =	0;
149*57f60867SMark Johnston 	cs_zoneid =	0;
150*57f60867SMark Johnston };
151*57f60867SMark Johnston 
152*57f60867SMark Johnston #pragma D binding "1.0" translator
153*57f60867SMark Johnston translator tcpsinfo_t < struct tcpcb *p > {
154*57f60867SMark Johnston 	tcps_addr =		(uintptr_t)p;
155*57f60867SMark Johnston 	tcps_local =		-1; /* XXX */
156*57f60867SMark Johnston 	tcps_active =		-1; /* XXX */
157*57f60867SMark Johnston 	tcps_lport =		p == NULL ? 0 : ntohs(p->t_inpcb->inp_inc.inc_ie.ie_lport);
158*57f60867SMark Johnston 	tcps_rport =		p == NULL ? 0 : ntohs(p->t_inpcb->inp_inc.inc_ie.ie_fport);
159*57f60867SMark Johnston 	tcps_laddr =		p == NULL ? 0 :
160*57f60867SMark Johnston 	    p->t_inpcb->inp_vflag == INP_IPV4 ?
161*57f60867SMark Johnston 	    inet_ntoa(&p->t_inpcb->inp_inc.inc_ie.ie_dependladdr.ie46_local.ia46_addr4.s_addr) :
162*57f60867SMark Johnston 	    inet_ntoa6(&p->t_inpcb->inp_inc.inc_ie.ie_dependladdr.ie6_local);
163*57f60867SMark Johnston 	tcps_raddr =		p == NULL ? 0 :
164*57f60867SMark Johnston 	    p->t_inpcb->inp_vflag == INP_IPV4 ?
165*57f60867SMark Johnston 	    inet_ntoa(&p->t_inpcb->inp_inc.inc_ie.ie_dependfaddr.ie46_foreign.ia46_addr4.s_addr) :
166*57f60867SMark Johnston 	    inet_ntoa6(&p->t_inpcb->inp_inc.inc_ie.ie_dependfaddr.ie6_foreign);
167*57f60867SMark Johnston 	tcps_state =		p == NULL ? -1 : p->t_state;
168*57f60867SMark Johnston 	tcps_iss =		p == NULL ? 0  : p->iss;
169*57f60867SMark Johnston 	tcps_suna =		p == NULL ? 0  : p->snd_una;
170*57f60867SMark Johnston 	tcps_snxt =		p == NULL ? 0  : p->snd_nxt;
171*57f60867SMark Johnston 	tcps_rack =		p == NULL ? 0  : p->last_ack_sent;
172*57f60867SMark Johnston 	tcps_rnxt =		p == NULL ? 0  : p->rcv_nxt;
173*57f60867SMark Johnston 	tcps_swnd =		p == NULL ? -1  : p->snd_wnd;
174*57f60867SMark Johnston 	tcps_snd_ws =		p == NULL ? -1  : p->snd_scale;
175*57f60867SMark Johnston 	tcps_rwnd =		p == NULL ? -1  : p->rcv_wnd;
176*57f60867SMark Johnston 	tcps_rcv_ws =		p == NULL ? -1  : p->rcv_scale;
177*57f60867SMark Johnston 	tcps_cwnd =		p == NULL ? -1  : p->snd_cwnd;
178*57f60867SMark Johnston 	tcps_cwnd_ssthresh =	p == NULL ? -1  : p->snd_ssthresh;
179*57f60867SMark Johnston 	tcps_sack_fack =	p == NULL ? 0  : p->snd_fack;
180*57f60867SMark Johnston 	tcps_sack_snxt =	p == NULL ? 0  : p->sack_newdata;
181*57f60867SMark Johnston 	tcps_rto =		p == NULL ? -1  : p->t_rxtcur / 1000; /* XXX */
182*57f60867SMark Johnston 	tcps_mss =		p == NULL ? -1  : p->t_maxseg;
183*57f60867SMark Johnston 	tcps_retransmit =	-1; /* XXX */
184*57f60867SMark Johnston };
185*57f60867SMark Johnston 
186*57f60867SMark Johnston #pragma D binding "1.0" translator
187*57f60867SMark Johnston translator tcpinfo_t < struct tcphdr *p > {
188*57f60867SMark Johnston 	tcp_sport =	p == NULL ? 0  : ntohs(p->th_sport);
189*57f60867SMark Johnston 	tcp_dport =	p == NULL ? 0  : ntohs(p->th_dport);
190*57f60867SMark Johnston 	tcp_seq =	p == NULL ? -1 : ntohl(p->th_seq);
191*57f60867SMark Johnston 	tcp_ack =	p == NULL ? -1 : ntohl(p->th_ack);
192*57f60867SMark Johnston 	tcp_offset =	p == NULL ? -1 : (p->th_off >> 2);
193*57f60867SMark Johnston 	tcp_flags =	p == NULL ? 0  : p->th_flags;
194*57f60867SMark Johnston 	tcp_window =	p == NULL ? 0  : ntohs(p->th_win);
195*57f60867SMark Johnston 	tcp_checksum =	p == NULL ? 0  : ntohs(p->th_sum);
196*57f60867SMark Johnston 	tcp_urgent =	p == NULL ? 0  : ntohs(p->th_urp);
197*57f60867SMark Johnston 	tcp_hdr =	(struct tcphdr *)p;
198*57f60867SMark Johnston };
199*57f60867SMark Johnston 
200*57f60867SMark Johnston #pragma D binding "1.0" translator
201*57f60867SMark Johnston translator tcplsinfo_t < int s > {
202*57f60867SMark Johnston 	tcps_state =	s;
203*57f60867SMark Johnston };
204