]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - cddl/lib/libdtrace/tcp.d
Upgrade to version 3.1.4
[FreeBSD/FreeBSD.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 module kernel
30 #pragma D depends_on provider tcp
31
32 /*
33  * Convert a TCP state value to a string.
34  */
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;
57
58 /*
59  * For compatibility also provide the names used by Solaris.
60  */
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;
83
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;
101
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" :
116         "<unknown>";
117
118 /*
119  * tcpsinfo contains stable TCP details from tcp_t.
120  */
121 typedef struct tcpsinfo {
122         uintptr_t tcps_addr;
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 */
160 } tcpsinfo_t;
161
162 /*
163  * tcplsinfo provides the old tcp state for state changes.
164  */
165 typedef struct tcplsinfo {
166         int32_t tcps_state;             /* previous TCP state */
167 } tcplsinfo_t;
168
169 /*
170  * tcpinfo is the TCP header fields.
171  */
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 */
183 } tcpinfo_t;
184
185 /*
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.
190  */
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 */
202 } tcpinfoh_t;
203
204 #pragma D binding "1.6.3" translator
205 translator csinfo_t < struct tcpcb *p > {
206         cs_addr =       NULL;
207         cs_cid =        (uint64_t)(p == NULL ? 0 : p->t_inpcb);
208         cs_pid =        0;
209         cs_zoneid =     0;
210 };
211
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->snd_recover;
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;
260 };
261
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;
274 };
275
276 /*
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.
280  */
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;
293 };
294
295 #pragma D binding "1.6.3" translator
296 translator tcplsinfo_t < int s > {
297         tcps_state =    s;
298 };
299
300
301 /* Support for TCP debug */
302
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;
313
314 /* direction strings. */
315
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" :
323         "unknown" ;
324
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" :
335         "unknown" ;
336
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;
389
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" :
418         "unknown" ;