]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - cddl/lib/libdtrace/tcp.d
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / cddl / lib / libdtrace / tcp.d
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  *
21  * $FreeBSD$
22  */
23 /*
24  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
25  * Copyright (c) 2013 Mark Johnston <markj@freebsd.org>
26  */
27
28 #pragma D depends_on library ip.d
29 #pragma D depends_on provider tcp
30
31 /*
32  * Convert a TCP state value to a string.
33  */
34 #pragma D binding "1.0" TCPS_CLOSED
35 inline int TCPS_CLOSED =        0;
36 #pragma D binding "1.0" TCPS_LISTEN
37 inline int TCPS_LISTEN =        1;
38 #pragma D binding "1.0" TCPS_SYN_SENT
39 inline int TCPS_SYN_SENT =      2;
40 #pragma D binding "1.0" TCPS_SYN_RECEIVED
41 inline int TCPS_SYN_RECEIVED =  3;
42 #pragma D binding "1.0" TCPS_ESTABLISHED
43 inline int TCPS_ESTABLISHED =   4;
44 #pragma D binding "1.0" TCPS_CLOSE_WAIT
45 inline int TCPS_CLOSE_WAIT =    5;
46 #pragma D binding "1.0" TCPS_FIN_WAIT_1
47 inline int TCPS_FIN_WAIT_1 =    6;
48 #pragma D binding "1.0" TCPS_CLOSING
49 inline int TCPS_CLOSING =       7;
50 #pragma D binding "1.0" TCPS_LAST_ACK
51 inline int TCPS_LAST_ACK =      8;
52 #pragma D binding "1.0" TCPS_FIN_WAIT_2
53 inline int TCPS_FIN_WAIT_2 =    9;
54 #pragma D binding "1.0" TCPS_TIME_WAIT
55 inline int TCPS_TIME_WAIT =     10;
56
57 /* TCP segment flags. */
58 #pragma D binding "1.0" TH_FIN
59 inline uint8_t TH_FIN =         0x01;
60 #pragma D binding "1.0" TH_SYN
61 inline uint8_t TH_SYN =         0x02;
62 #pragma D binding "1.0" TH_RST
63 inline uint8_t TH_RST =         0x04;
64 #pragma D binding "1.0" TH_PUSH
65 inline uint8_t TH_PUSH =        0x08;
66 #pragma D binding "1.0" TH_ACK
67 inline uint8_t TH_ACK =         0x10;
68 #pragma D binding "1.0" TH_URG
69 inline uint8_t TH_URG =         0x20;
70 #pragma D binding "1.0" TH_ECE
71 inline uint8_t TH_ECE =         0x40;
72 #pragma D binding "1.0" TH_CWR
73 inline uint8_t TH_CWR =         0x80;
74
75 /* TCP connection state strings. */
76 #pragma D binding "1.0" tcp_state_string
77 inline string tcp_state_string[int32_t state] =
78         state == TCPS_CLOSED ?          "state-closed" :
79         state == TCPS_LISTEN ?          "state-listen" :
80         state == TCPS_SYN_SENT ?        "state-syn-sent" :
81         state == TCPS_SYN_RECEIVED ?    "state-syn-received" :
82         state == TCPS_ESTABLISHED ?     "state-established" :
83         state == TCPS_CLOSE_WAIT ?      "state-close-wait" :
84         state == TCPS_FIN_WAIT_1 ?      "state-fin-wait-1" :
85         state == TCPS_CLOSING ?         "state-closing" :
86         state == TCPS_LAST_ACK ?        "state-last-ack" :
87         state == TCPS_FIN_WAIT_2 ?      "state-fin-wait-2" :
88         state == TCPS_TIME_WAIT ?       "state-time-wait" :
89         "<unknown>";
90
91 /*
92  * tcpsinfo contains stable TCP details from tcp_t.
93  */
94 typedef struct tcpsinfo {
95         uintptr_t tcps_addr;
96         int tcps_local;                 /* is delivered locally, boolean */
97         int tcps_active;                /* active open (from here), boolean */
98         uint16_t tcps_lport;            /* local port */
99         uint16_t tcps_rport;            /* remote port */
100         string tcps_laddr;              /* local address, as a string */
101         string tcps_raddr;              /* remote address, as a string */
102         int32_t tcps_state;             /* TCP state */
103         uint32_t tcps_iss;              /* Initial sequence # sent */
104         uint32_t tcps_suna;             /* sequence # sent but unacked */
105         uint32_t tcps_snxt;             /* next sequence # to send */
106         uint32_t tcps_rack;             /* sequence # we have acked */
107         uint32_t tcps_rnxt;             /* next sequence # expected */
108         uint32_t tcps_swnd;             /* send window size */
109         int32_t tcps_snd_ws;            /* send window scaling */
110         uint32_t tcps_rwnd;             /* receive window size */
111         int32_t tcps_rcv_ws;            /* receive window scaling */
112         uint32_t tcps_cwnd;             /* congestion window */
113         uint32_t tcps_cwnd_ssthresh;    /* threshold for congestion avoidance */
114         uint32_t tcps_sack_fack;        /* SACK sequence # we have acked */
115         uint32_t tcps_sack_snxt;        /* next SACK seq # for retransmission */
116         uint32_t tcps_rto;              /* round-trip timeout, msec */
117         uint32_t tcps_mss;              /* max segment size */
118         int tcps_retransmit;            /* retransmit send event, boolean */
119         int tcps_srtt;                  /* smoothed RTT in units of (TCP_RTT_SCALE*hz) */
120 } tcpsinfo_t;
121
122 /*
123  * tcplsinfo provides the old tcp state for state changes.
124  */
125 typedef struct tcplsinfo {
126         int32_t tcps_state;             /* previous TCP state */
127 } tcplsinfo_t;
128
129 /*
130  * tcpinfo is the TCP header fields.
131  */
132 typedef struct tcpinfo {
133         uint16_t tcp_sport;             /* source port */
134         uint16_t tcp_dport;             /* destination port */
135         uint32_t tcp_seq;               /* sequence number */
136         uint32_t tcp_ack;               /* acknowledgment number */
137         uint8_t tcp_offset;             /* data offset, in bytes */
138         uint8_t tcp_flags;              /* flags */
139         uint16_t tcp_window;            /* window size */
140         uint16_t tcp_checksum;          /* checksum */
141         uint16_t tcp_urgent;            /* urgent data pointer */
142         struct tcphdr *tcp_hdr;         /* raw TCP header */
143 } tcpinfo_t;
144
145 /*
146  * A clone of tcpinfo_t used to handle the fact that the TCP input path
147  * overwrites some fields of the TCP header with their host-order equivalents.
148  * Unfortunately, DTrace doesn't let us simply typedef a new name for struct
149  * tcpinfo and define a separate translator for it.
150  */
151 typedef struct tcpinfoh {
152         uint16_t tcp_sport;             /* source port */
153         uint16_t tcp_dport;             /* destination port */
154         uint32_t tcp_seq;               /* sequence number */
155         uint32_t tcp_ack;               /* acknowledgment number */
156         uint8_t tcp_offset;             /* data offset, in bytes */
157         uint8_t tcp_flags;              /* flags */
158         uint16_t tcp_window;            /* window size */
159         uint16_t tcp_checksum;          /* checksum */
160         uint16_t tcp_urgent;            /* urgent data pointer */
161         struct tcphdr *tcp_hdr;         /* raw TCP header */
162 } tcpinfoh_t;
163
164 #pragma D binding "1.0" translator
165 translator csinfo_t < struct tcpcb *p > {
166         cs_addr =       NULL;
167         cs_cid =        (uint64_t)(p == NULL ? 0 : p->t_inpcb);
168         cs_pid =        0;
169         cs_zoneid =     0;
170 };
171
172 #pragma D binding "1.0" translator
173 translator tcpsinfo_t < struct tcpcb *p > {
174         tcps_addr =             (uintptr_t)p;
175         tcps_local =            -1; /* XXX */
176         tcps_active =           -1; /* XXX */
177         tcps_lport =            p == NULL ? 0 : ntohs(p->t_inpcb->inp_inc.inc_ie.ie_lport);
178         tcps_rport =            p == NULL ? 0 : ntohs(p->t_inpcb->inp_inc.inc_ie.ie_fport);
179         tcps_laddr =            p == NULL ? 0 :
180             p->t_inpcb->inp_vflag == INP_IPV4 ?
181             inet_ntoa(&p->t_inpcb->inp_inc.inc_ie.ie_dependladdr.ie46_local.ia46_addr4.s_addr) :
182             inet_ntoa6(&p->t_inpcb->inp_inc.inc_ie.ie_dependladdr.ie6_local);
183         tcps_raddr =            p == NULL ? 0 :
184             p->t_inpcb->inp_vflag == INP_IPV4 ?
185             inet_ntoa(&p->t_inpcb->inp_inc.inc_ie.ie_dependfaddr.ie46_foreign.ia46_addr4.s_addr) :
186             inet_ntoa6(&p->t_inpcb->inp_inc.inc_ie.ie_dependfaddr.ie6_foreign);
187         tcps_state =            p == NULL ? -1 : p->t_state;
188         tcps_iss =              p == NULL ? 0  : p->iss;
189         tcps_suna =             p == NULL ? 0  : p->snd_una;
190         tcps_snxt =             p == NULL ? 0  : p->snd_nxt;
191         tcps_rack =             p == NULL ? 0  : p->last_ack_sent;
192         tcps_rnxt =             p == NULL ? 0  : p->rcv_nxt;
193         tcps_swnd =             p == NULL ? -1  : p->snd_wnd;
194         tcps_snd_ws =           p == NULL ? -1  : p->snd_scale;
195         tcps_rwnd =             p == NULL ? -1  : p->rcv_wnd;
196         tcps_rcv_ws =           p == NULL ? -1  : p->rcv_scale;
197         tcps_cwnd =             p == NULL ? -1  : p->snd_cwnd;
198         tcps_cwnd_ssthresh =    p == NULL ? -1  : p->snd_ssthresh;
199         tcps_sack_fack =        p == NULL ? 0  : p->snd_fack;
200         tcps_sack_snxt =        p == NULL ? 0  : p->sack_newdata;
201         tcps_rto =              p == NULL ? -1 : (p->t_rxtcur * 1000) / `hz;
202         tcps_mss =              p == NULL ? -1  : p->t_maxseg;
203         tcps_retransmit =       p == NULL ? -1 : p->t_rxtshift > 0 ? 1 : 0;
204         tcps_srtt =             p == NULL ? -1  : p->t_srtt;   /* smoothed RTT in units of (TCP_RTT_SCALE*hz) */
205 };
206
207 #pragma D binding "1.0" translator
208 translator tcpinfo_t < struct tcphdr *p > {
209         tcp_sport =     p == NULL ? 0  : ntohs(p->th_sport);
210         tcp_dport =     p == NULL ? 0  : ntohs(p->th_dport);
211         tcp_seq =       p == NULL ? -1 : ntohl(p->th_seq);
212         tcp_ack =       p == NULL ? -1 : ntohl(p->th_ack);
213         tcp_offset =    p == NULL ? -1 : (p->th_off >> 2);
214         tcp_flags =     p == NULL ? 0  : p->th_flags;
215         tcp_window =    p == NULL ? 0  : ntohs(p->th_win);
216         tcp_checksum =  p == NULL ? 0  : ntohs(p->th_sum);
217         tcp_urgent =    p == NULL ? 0  : ntohs(p->th_urp);
218         tcp_hdr =       (struct tcphdr *)p;
219 };
220
221 /*
222  * This translator differs from the one for tcpinfo_t in that the sequence
223  * number, acknowledgement number, window size and urgent pointer are already
224  * in host order and thus don't need to be converted.
225  */
226 #pragma D binding "1.0" translator
227 translator tcpinfoh_t < struct tcphdr *p > {
228         tcp_sport =     p == NULL ? 0  : ntohs(p->th_sport);
229         tcp_dport =     p == NULL ? 0  : ntohs(p->th_dport);
230         tcp_seq =       p == NULL ? -1 : p->th_seq;
231         tcp_ack =       p == NULL ? -1 : p->th_ack;
232         tcp_offset =    p == NULL ? -1 : (p->th_off >> 2);
233         tcp_flags =     p == NULL ? 0  : p->th_flags;
234         tcp_window =    p == NULL ? 0  : (p->th_win);
235         tcp_checksum =  p == NULL ? 0  : ntohs(p->th_sum);
236         tcp_urgent =    p == NULL ? 0  : p->th_urp;
237         tcp_hdr =       (struct tcphdr *)p;
238 };
239
240 #pragma D binding "1.0" translator
241 translator tcplsinfo_t < int s > {
242         tcps_state =    s;
243 };