Index: head/cddl/lib/libdtrace/tcp.d =================================================================== --- head/cddl/lib/libdtrace/tcp.d (revision 298086) +++ head/cddl/lib/libdtrace/tcp.d (revision 298087) @@ -1,389 +1,389 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * $FreeBSD$ */ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013 Mark Johnston */ #pragma D depends_on library ip.d #pragma D depends_on module kernel #pragma D depends_on provider tcp /* * Convert a TCP state value to a string. */ #pragma D binding "1.6.3" TCPS_CLOSED inline int TCPS_CLOSED = 0; #pragma D binding "1.6.3" TCPS_LISTEN inline int TCPS_LISTEN = 1; #pragma D binding "1.6.3" TCPS_SYN_SENT inline int TCPS_SYN_SENT = 2; #pragma D binding "1.6.3" TCPS_SYN_RECEIVED inline int TCPS_SYN_RECEIVED = 3; #pragma D binding "1.6.3" TCPS_ESTABLISHED inline int TCPS_ESTABLISHED = 4; #pragma D binding "1.6.3" TCPS_CLOSE_WAIT inline int TCPS_CLOSE_WAIT = 5; #pragma D binding "1.6.3" TCPS_FIN_WAIT_1 inline int TCPS_FIN_WAIT_1 = 6; #pragma D binding "1.6.3" TCPS_CLOSING inline int TCPS_CLOSING = 7; #pragma D binding "1.6.3" TCPS_LAST_ACK inline int TCPS_LAST_ACK = 8; #pragma D binding "1.6.3" TCPS_FIN_WAIT_2 inline int TCPS_FIN_WAIT_2 = 9; #pragma D binding "1.6.3" TCPS_TIME_WAIT inline int TCPS_TIME_WAIT = 10; /* TCP segment flags. */ #pragma D binding "1.6.3" TH_FIN inline uint8_t TH_FIN = 0x01; #pragma D binding "1.6.3" TH_SYN inline uint8_t TH_SYN = 0x02; #pragma D binding "1.6.3" TH_RST inline uint8_t TH_RST = 0x04; #pragma D binding "1.6.3" TH_PUSH inline uint8_t TH_PUSH = 0x08; #pragma D binding "1.6.3" TH_ACK inline uint8_t TH_ACK = 0x10; #pragma D binding "1.6.3" TH_URG inline uint8_t TH_URG = 0x20; #pragma D binding "1.6.3" TH_ECE inline uint8_t TH_ECE = 0x40; #pragma D binding "1.6.3" TH_CWR inline uint8_t TH_CWR = 0x80; /* TCP connection state strings. */ #pragma D binding "1.6.3" tcp_state_string inline string tcp_state_string[int32_t state] = state == TCPS_CLOSED ? "state-closed" : state == TCPS_LISTEN ? "state-listen" : state == TCPS_SYN_SENT ? "state-syn-sent" : state == TCPS_SYN_RECEIVED ? "state-syn-received" : state == TCPS_ESTABLISHED ? "state-established" : state == TCPS_CLOSE_WAIT ? "state-close-wait" : state == TCPS_FIN_WAIT_1 ? "state-fin-wait-1" : state == TCPS_CLOSING ? "state-closing" : state == TCPS_LAST_ACK ? "state-last-ack" : state == TCPS_FIN_WAIT_2 ? "state-fin-wait-2" : state == TCPS_TIME_WAIT ? "state-time-wait" : ""; /* * tcpsinfo contains stable TCP details from tcp_t. */ typedef struct tcpsinfo { uintptr_t tcps_addr; int tcps_local; /* is delivered locally, boolean */ int tcps_active; /* active open (from here), boolean */ uint16_t tcps_lport; /* local port */ uint16_t tcps_rport; /* remote port */ string tcps_laddr; /* local address, as a string */ string tcps_raddr; /* remote address, as a string */ int32_t tcps_state; /* TCP state */ uint32_t tcps_iss; /* Initial sequence # sent */ uint32_t tcps_irs; /* Initial sequence # received */ uint32_t tcps_suna; /* sequence # sent but unacked */ uint32_t tcps_smax; /* highest sequence number sent */ uint32_t tcps_snxt; /* next sequence # to send */ uint32_t tcps_rack; /* sequence # we have acked */ uint32_t tcps_rnxt; /* next sequence # expected */ - uint32_t tcps_swnd; /* send window size */ + u_long tcps_swnd; /* send window size */ int32_t tcps_snd_ws; /* send window scaling */ uint32_t tcps_swl1; /* window update seg seq number */ uint32_t tcps_swl2; /* window update seg ack number */ uint32_t tcps_rup; /* receive urgent pointer */ uint32_t tcps_radv; /* advertised window */ - uint32_t tcps_rwnd; /* receive window size */ + u_long tcps_rwnd; /* receive window size */ int32_t tcps_rcv_ws; /* receive window scaling */ - uint32_t tcps_cwnd; /* congestion window */ - uint32_t tcps_cwnd_ssthresh; /* threshold for congestion avoidance */ + u_long tcps_cwnd; /* congestion window */ + u_long tcps_cwnd_ssthresh; /* threshold for congestion avoidance */ uint32_t tcps_srecover; /* for use in NewReno Fast Recovery */ uint32_t tcps_sack_fack; /* SACK sequence # we have acked */ uint32_t tcps_sack_snxt; /* next SACK seq # for retransmission */ uint32_t tcps_rto; /* round-trip timeout, msec */ uint32_t tcps_mss; /* max segment size */ int tcps_retransmit; /* retransmit send event, boolean */ int tcps_srtt; /* smoothed RTT in units of (TCP_RTT_SCALE*hz) */ int tcps_debug; /* socket has SO_DEBUG set */ int32_t tcps_dupacks; /* consecutive dup acks received */ uint32_t tcps_rtttime; /* RTT measurement start time */ uint32_t tcps_rtseq; /* sequence # being timed */ uint32_t tcps_ts_recent; /* timestamp echo data */ } tcpsinfo_t; /* * tcplsinfo provides the old tcp state for state changes. */ typedef struct tcplsinfo { int32_t tcps_state; /* previous TCP state */ } tcplsinfo_t; /* * tcpinfo is the TCP header fields. */ typedef struct tcpinfo { uint16_t tcp_sport; /* source port */ uint16_t tcp_dport; /* destination port */ uint32_t tcp_seq; /* sequence number */ uint32_t tcp_ack; /* acknowledgment number */ uint8_t tcp_offset; /* data offset, in bytes */ uint8_t tcp_flags; /* flags */ uint16_t tcp_window; /* window size */ uint16_t tcp_checksum; /* checksum */ uint16_t tcp_urgent; /* urgent data pointer */ struct tcphdr *tcp_hdr; /* raw TCP header */ } tcpinfo_t; /* * A clone of tcpinfo_t used to handle the fact that the TCP input path * overwrites some fields of the TCP header with their host-order equivalents. * Unfortunately, DTrace doesn't let us simply typedef a new name for struct * tcpinfo and define a separate translator for it. */ typedef struct tcpinfoh { uint16_t tcp_sport; /* source port */ uint16_t tcp_dport; /* destination port */ uint32_t tcp_seq; /* sequence number */ uint32_t tcp_ack; /* acknowledgment number */ uint8_t tcp_offset; /* data offset, in bytes */ uint8_t tcp_flags; /* flags */ uint16_t tcp_window; /* window size */ uint16_t tcp_checksum; /* checksum */ uint16_t tcp_urgent; /* urgent data pointer */ struct tcphdr *tcp_hdr; /* raw TCP header */ } tcpinfoh_t; #pragma D binding "1.6.3" translator translator csinfo_t < struct tcpcb *p > { cs_addr = NULL; cs_cid = (uint64_t)(p == NULL ? 0 : p->t_inpcb); cs_pid = 0; cs_zoneid = 0; }; #pragma D binding "1.6.3" translator translator tcpsinfo_t < struct tcpcb *p > { tcps_addr = (uintptr_t)p; tcps_local = -1; /* XXX */ tcps_active = -1; /* XXX */ tcps_lport = p == NULL ? 0 : ntohs(p->t_inpcb->inp_inc.inc_ie.ie_lport); tcps_rport = p == NULL ? 0 : ntohs(p->t_inpcb->inp_inc.inc_ie.ie_fport); tcps_laddr = p == NULL ? 0 : p->t_inpcb->inp_vflag == INP_IPV4 ? inet_ntoa(&p->t_inpcb->inp_inc.inc_ie.ie_dependladdr.ie46_local.ia46_addr4.s_addr) : inet_ntoa6(&p->t_inpcb->inp_inc.inc_ie.ie_dependladdr.ie6_local); tcps_raddr = p == NULL ? 0 : p->t_inpcb->inp_vflag == INP_IPV4 ? inet_ntoa(&p->t_inpcb->inp_inc.inc_ie.ie_dependfaddr.ie46_foreign.ia46_addr4.s_addr) : inet_ntoa6(&p->t_inpcb->inp_inc.inc_ie.ie_dependfaddr.ie6_foreign); tcps_state = p == NULL ? -1 : p->t_state; tcps_iss = p == NULL ? 0 : p->iss; tcps_irs = p == NULL ? 0 : p->irs; tcps_suna = p == NULL ? 0 : p->snd_una; tcps_smax = p == NULL ? 0 : p->snd_max; tcps_snxt = p == NULL ? 0 : p->snd_nxt; tcps_rack = p == NULL ? 0 : p->last_ack_sent; tcps_rnxt = p == NULL ? 0 : p->rcv_nxt; tcps_swnd = p == NULL ? -1 : p->snd_wnd; tcps_snd_ws = p == NULL ? -1 : p->snd_scale; tcps_swl1 = p == NULL ? -1 : p->snd_wl1; tcps_swl2 = p == NULL ? -1 : p->snd_wl2; tcps_radv = p == NULL ? -1 : p->rcv_adv; tcps_rwnd = p == NULL ? -1 : p->rcv_wnd; tcps_rup = p == NULL ? -1 : p->rcv_up; tcps_rcv_ws = p == NULL ? -1 : p->rcv_scale; tcps_cwnd = p == NULL ? -1 : p->snd_cwnd; tcps_cwnd_ssthresh = p == NULL ? -1 : p->snd_ssthresh; tcps_srecover = p == NULL ? -1 : p->snd_recover; tcps_sack_fack = p == NULL ? 0 : p->snd_fack; tcps_sack_snxt = p == NULL ? 0 : p->sack_newdata; tcps_rto = p == NULL ? -1 : (p->t_rxtcur * 1000) / `hz; tcps_mss = p == NULL ? -1 : p->t_maxseg; tcps_retransmit = p == NULL ? -1 : p->t_rxtshift > 0 ? 1 : 0; tcps_srtt = p == NULL ? -1 : p->t_srtt; /* smoothed RTT in units of (TCP_RTT_SCALE*hz) */ tcps_debug = p == NULL ? 0 : p->t_inpcb->inp_socket->so_options & 1; tcps_dupacks = p == NULL ? -1 : p->t_dupacks; tcps_rtttime = p == NULL ? -1 : p->t_rtttime; tcps_rtseq = p == NULL ? -1 : p->t_rtseq; tcps_ts_recent = p == NULL ? -1 : p->ts_recent; }; #pragma D binding "1.6.3" translator translator tcpinfo_t < struct tcphdr *p > { tcp_sport = p == NULL ? 0 : ntohs(p->th_sport); tcp_dport = p == NULL ? 0 : ntohs(p->th_dport); tcp_seq = p == NULL ? -1 : ntohl(p->th_seq); tcp_ack = p == NULL ? -1 : ntohl(p->th_ack); tcp_offset = p == NULL ? -1 : (p->th_off >> 2); tcp_flags = p == NULL ? 0 : p->th_flags; tcp_window = p == NULL ? 0 : ntohs(p->th_win); tcp_checksum = p == NULL ? 0 : ntohs(p->th_sum); tcp_urgent = p == NULL ? 0 : ntohs(p->th_urp); tcp_hdr = (struct tcphdr *)p; }; /* * This translator differs from the one for tcpinfo_t in that the sequence * number, acknowledgement number, window size and urgent pointer are already * in host order and thus don't need to be converted. */ #pragma D binding "1.6.3" translator translator tcpinfoh_t < struct tcphdr *p > { tcp_sport = p == NULL ? 0 : ntohs(p->th_sport); tcp_dport = p == NULL ? 0 : ntohs(p->th_dport); tcp_seq = p == NULL ? -1 : p->th_seq; tcp_ack = p == NULL ? -1 : p->th_ack; tcp_offset = p == NULL ? -1 : (p->th_off >> 2); tcp_flags = p == NULL ? 0 : p->th_flags; tcp_window = p == NULL ? 0 : (p->th_win); tcp_checksum = p == NULL ? 0 : ntohs(p->th_sum); tcp_urgent = p == NULL ? 0 : p->th_urp; tcp_hdr = (struct tcphdr *)p; }; #pragma D binding "1.6.3" translator translator tcplsinfo_t < int s > { tcps_state = s; }; /* Support for TCP debug */ #pragma D binding "1.12.1" TA_INPUT inline int TA_INPUT = 0; #pragma D binding "1.12.1" TA_OUTPUT inline int TA_OUTPUT = 1; #pragma D binding "1.12.1" TA_USER inline int TA_USER = 2; #pragma D binding "1.12.1" TA_RESPOND inline int TA_RESPOND = 3; #pragma D binding "1.12.1" TA_DROP inline int TA_DROP = 4; /* direction strings. */ #pragma D binding "1.12.1" tcpdebug_dir_string inline string tcpdebug_dir_string[uint8_t direction] = direction == TA_INPUT ? "input" : direction == TA_OUTPUT ? "output" : direction == TA_USER ? "user" : direction == TA_RESPOND ? "respond" : direction == TA_OUTPUT ? "drop" : "unknown" ; #pragma D binding "1.12.1" tcpflag_string inline string tcpflag_string[uint8_t flags] = flags & TH_FIN ? "FIN" : flags & TH_SYN ? "SYN" : flags & TH_RST ? "RST" : flags & TH_PUSH ? "PUSH" : flags & TH_ACK ? "ACK" : flags & TH_URG ? "URG" : flags & TH_ECE ? "ECE" : flags & TH_CWR ? "CWR" : "unknown" ; #pragma D binding "1.12.1" PRU_ATTACH inline int PRU_ATTACH = 0; #pragma D binding "1.12.1" PRU_DETACH inline int PRU_DETACH = 1; #pragma D binding "1.12.1" PRU_BIND inline int PRU_BIND = 2; #pragma D binding "1.12.1" PRU_LISTEN inline int PRU_LISTEN = 3; #pragma D binding "1.12.1" PRU_CONNECT inline int PRU_CONNECT = 4; #pragma D binding "1.12.1" PRU_ACCEPT inline int PRU_ACCEPT = 5 ; #pragma D binding "1.12.1" PRU_DISCONNECT inline int PRU_DISCONNECT= 6; #pragma D binding "1.12.1" PRU_SHUTDOWN inline int PRU_SHUTDOWN = 7; #pragma D binding "1.12.1" PRU_RCVD inline int PRU_RCVD = 8; #pragma D binding "1.12.1" PRU_SEND inline int PRU_SEND = 9; #pragma D binding "1.12.1" PRU_ABORT inline int PRU_ABORT = 10; #pragma D binding "1.12.1" PRU_CONTROL inline int PRU_CONTROL = 11; #pragma D binding "1.12.1" PRU_SENSE inline int PRU_SENSE = 12; #pragma D binding "1.12.1" PRU_RCVOOB inline int PRU_RCVOOB = 13; #pragma D binding "1.12.1" PRU_SENDOOB inline int PRU_SENDOOB = 14; #pragma D binding "1.12.1" PRU_SOCKADDR inline int PRU_SOCKADDR = 15; #pragma D binding "1.12.1" PRU_PEERADDR inline int PRU_PEERADDR = 16; #pragma D binding "1.12.1" PRU_CONNECT2 inline int PRU_CONNECT2 = 17; #pragma D binding "1.12.1" PRU_FASTTIMO inline int PRU_FASTTIMO = 18; #pragma D binding "1.12.1" PRU_SLOWTIMO inline int PRU_SLOWTIMO = 19; #pragma D binding "1.12.1" PRU_PROTORCV inline int PRU_PROTORCV = 20; #pragma D binding "1.12.1" PRU_PROTOSEND inline int PRU_PROTOSEND = 21; #pragma D binding "1.12.1" PRU_SEND_EOF inline int PRU_SEND_EOF = 22; #pragma D binding "1.12.1" PRU_SOSETLABEL inline int PRU_SOSETLABEL = 23; #pragma D binding "1.12.1" PRU_CLOSE inline int PRU_CLOSE = 24; #pragma D binding "1.12.1" PRU_FLUSH inline int PRU_FLUSH = 25; #pragma D binding "1.12.1" prureq_string inline string prureq_string[uint8_t req] = req == PRU_ATTACH ? "ATTACH" : req == PRU_DETACH ? "DETACH" : req == PRU_BIND ? "BIND" : req == PRU_LISTEN ? "LISTEN" : req == PRU_CONNECT ? "CONNECT" : req == PRU_ACCEPT ? "ACCEPT" : req == PRU_DISCONNECT ? "DISCONNECT" : req == PRU_SHUTDOWN ? "SHUTDOWN" : req == PRU_RCVD ? "RCVD" : req == PRU_SEND ? "SEND" : req == PRU_ABORT ? "ABORT" : req == PRU_CONTROL ? "CONTROL" : req == PRU_SENSE ? "SENSE" : req == PRU_RCVOOB ? "RCVOOB" : req == PRU_SENDOOB ? "SENDOOB" : req == PRU_SOCKADDR ? "SOCKADDR" : req == PRU_PEERADDR ? "PEERADDR" : req == PRU_CONNECT2 ? "CONNECT2" : req == PRU_FASTTIMO ? "FASTTIMO" : req == PRU_SLOWTIMO ? "SLOWTIMO" : req == PRU_PROTORCV ? "PROTORCV" : req == PRU_PROTOSEND ? "PROTOSEND" : req == PRU_SEND ? "SEND_EOF" : req == PRU_SOSETLABEL ? "SOSETLABEL" : req == PRU_CLOSE ? "CLOSE" : req == PRU_FLUSH ? "FLUSE" : "unknown" ; Index: head/share/man/man4/dtrace_tcp.4 =================================================================== --- head/share/man/man4/dtrace_tcp.4 (revision 298086) +++ head/share/man/man4/dtrace_tcp.4 (revision 298087) @@ -1,396 +1,396 @@ .\" Copyright (c) 2015 Mark Johnston .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .\" -.Dd July 5, 2015 +.Dd April 15, 2016 .Dt DTRACE_TCP 4 .Os .Sh NAME .Nm dtrace_tcp .Nd a DTrace provider for tracing events related to the .Xr tcp 4 protocol .Sh SYNOPSIS .Fn tcp:::accept-established "pktinfo_t *" "csinfo_t *" "ipinfo_t *" \ "tcpsinfo_t *" "tcpinfo_t *" .Fn tcp:::accept-refused "pktinfo_t *" "csinfo_t *" "ipinfo_t *" \ "tcpsinfo_t *" "tcpinfo_t *" .Fn tcp:::connect-established "pktinfo_t *" "csinfo_t *" "ipinfo_t *" \ "tcpsinfo_t *" "tcpinfo_t *" .Fn tcp:::connect-refused "pktinfo_t *" "csinfo_t *" "ipinfo_t *" \ "tcpsinfo_t *" "tcpinfo_t *" .Fn tcp:::connect-request "pktinfo_t *" "csinfo_t *" "ipinfo_t *" \ "tcpsinfo_t *" "tcpinfo_t *" .Fn tcp:::receive "pktinfo_t *" "csinfo_t *" "ipinfo_t *" "tcpsinfo_t *" \ "tcpinfo_t *" .Fn tcp:::send "pktinfo_t *" "csinfo_t *" "ipinfo_t *" "tcpsinfo_t *" \ "tcpinfo_t *" .Fn tcp:::state-change "void *" "csinfo_t *" "void *" "tcpsinfo_t *" "void *" \ "tcplsinfo_t *" .Sh DESCRIPTION The DTrace .Nm tcp provider allows users to trace events in the .Xr tcp 4 protocol implementation. This provider is similar to the .Xr dtrace_ip 4 and .Xr dtrace_udp 4 providers, but additionally contains probes corresponding to protocol events at a level higher than packet reception and transmission. All .Nm tcp probes except for .Fn tcp:::state-change have the same number and type of arguments. The last three arguments are used to describe a TCP segment: the .Vt ipinfo_t argument exposes the version-agnostic fields of the IP header, while the .Vt tcpinfo_t argument exposes the TCP header, and the .Vt tcpsinfo_t argument describes details of the corresponding TCP connection state, if any. Their fields are described in the ARGUMENTS section. .Pp The .Fn tcp:::accept-established probe fires when a remotely-initiated active TCP open succeeds. At this point the new connection is in the ESTABLISHED state, and the probe arguments expose the headers associated with the final ACK of the three-way handshake. The .Fn tcp:::accept-refused probe fires when a SYN arrives on a port without a listening socket. The probe arguments expose the headers associated with the RST to be transmitted to the remote host in response to the SYN segment. .Pp The .Fn tcp:::connect-established , .Fn tcp:::connect-refused , and .Fn tcp:::connect-request probes are similar to the .Ql accept probes, except that they correspond to locally-initiated TCP connections. The .Fn tcp:::connect-established probe fires when the SYN-ACK segment of a three-way handshake is received from the remote host and a final ACK is prepared for transmission. This occurs immediately after the local connection state transitions from SYN-SENT to ESTABLISHED. The probe arguments describe the headers associated with the received SYN-ACK segment. The .Fn tcp:::connect-refused probe fires when the local host receives a RST segment in response to a SYN segment, indicating that the remote host refused to open a connection. The probe arguments describe the IP and TCP headers associated with the received RST segment. The .Fn tcp:::connect-request probe fires as the kernel prepares to transmit the initial SYN segment of a three-way handshake. .Pp The .Fn tcp:::send and .Fn tcp:::receive probes fire when the host sends or receives a TCP packet, respectively. As with the .Xr dtrace_udp 4 provider, .Nm tcp probes fire only for packets sent by or to the local host; forwarded packets are handled in the IP layer and are only visible to the .Xr dtrace_ip 4 provider. .Pp The .Fn tcp:::state-change probe fires upon local TCP connection state transitions. Its first, third and fifth arguments are currently always .Dv NULL . Its last argument describes the from-state in the transition, and the to-state can be obtained from .Dv args[2]->tcps_state . .Sh ARGUMENTS The .Vt pktinfo_t argument is currently unimplemented and is included for compatibility with other implementations of this provider. Its fields are: .Bl -tag -width "uinptr_t pkt_addr" -offset indent .It Vt uinptr_t pkt_addr Always set to 0. .El .Pp The .Vt csinfo_t argument is currently unimplemented and is included for compatibility with other implementations of this provider. Its fields are: .Bl -tag -width "uintptr_t cs_addr" -offset indent .It Vt uintptr_t cs_addr Always set to 0. .It Vt uint64_t cs_cid A pointer to the .Vt struct inpcb for this packet, or .Dv NULL . .It Vt pid_t cs_pid Always set to 0. .El .Pp The .Vt ipinfo_t type is a version-agnostic representation of fields from an IP header. Its fields are described in the .Xr dtrace_ip 4 manual page. .Pp The .Vt tcpsinfo_t type is used to provide a stable representation of TCP connection state. Some .Nm tcp probes, such as .Fn tcp:::accept-refused , fire in a context where there is no TCP connection; this argument is .Dv NULL in that case. Its fields are: .Bl -tag -width "uint16_t tcps_lport" -offset indent .It Vt uintptr_t tcps_addr The address of the corresponding TCP control block. This is currently a pointer to a .Vt struct tcpcb . .It Vt int tcps_local A boolean indicating whether the connection is local to the host. Currently unimplemented and always set to -1. .It Vt int tcps_active A boolean indicating whether the connection was initiated by the local host. Currently unimplemented and always set to -1. .It Vt uint16_t tcps_lport Local TCP port. .It Vt uint16_t tcps_rport Remote TCP port. .It Vt string tcps_laddr Local address. .It Vt string tcps_raddr Remote address. .It Vt int32_t tcps_state Current TCP state. The valid TCP state values are given by the constants prefixed with .Ql TCPS_ in .Pa /usr/lib/dtrace/tcp.d . .It Vt uint32_t tcps_iss Initial send sequence number. .It Vt uint32_t tcps_suna Initial sequence number of sent but unacknowledged data. .It Vt uint32_t tcps_snxt Next sequence number for send. .It Vt uint32_t tcps_rack Sequence number of received and acknowledged data. .It Vt uint32_t tcps_rnxt Next expected sequence number for receive. -.It Vt uint32_t tcps_swnd +.It Vt u_long tcps_swnd TCP send window size. .It Vt int32_t tcps_snd_ws Window scaling factor for the TCP send window. -.It Vt uint32_t tcps_rwnd +.It Vt u_long tcps_rwnd TCP receive window size. .It Vt int32_t tcps_rcv_ws Window scaling factor for the TCP receive window. -.It Vt uint32_t tcps_cwnd +.It Vt u_long tcps_cwnd TCP congestion window size. -.It Vt uint32_t tcps_cwnd_ssthresh +.It Vt u_long tcps_cwnd_ssthresh Congestion window threshold at which slow start ends and congestion avoidance begins. .It Vt uint32_t tcps_sack_fack Last sequence number selectively acknowledged by the receiver. .It Vt uint32_t tcps_sack_snxt Next selectively acknowledge sequence number at which to begin retransmitting. .It Vt uint32_t tcps_rto Round-trip timeout, in milliseconds. .It Vt uint32_t tcps_mss Maximum segment size. .It Vt int tcps_retransmit A boolean indicating that the local sender is retransmitting data. .It Vt int tcps_srtt Smoothed round-trip time. .El .Pp The .Vt tcpinfo_t type exposes the fields in a TCP segment header in host order. Its fields are: .Bl -tag -width "struct tcphdr *tcp_hdr" -offset indent .It Vt uint16_t tcp_sport Source TCP port. .It Vt uint16_t tcp_dport Destination TCP port. .It Vt uint32_t tcp_seq Sequence number. .It Vt uint32_t tcp_ack Acknowledgement number. .It Vt uint8_t tcp_offset Data offset, in bytes. .It Vt uint8_t tcp_flags TCP flags. .It Vt uint16_t tcp_window TCP window size. .It Vt uint16_t tcp_checksum Checksum. .It Vt uint16_t tcp_urgent Urgent data pointer. .It Vt struct tcphdr *tcp_hdr A pointer to the raw TCP header. .El .Pp The .Vt tcplsinfo_t type is used by the .Fn tcp:::state-change probe to provide the from-state of a transition. Its fields are: .Bl -tag -width "int32_t tcps_state" -offset indent .It Vt int32_t tcps_state A TCP state. The valid TCP state values are given by the constants prefixed with .Ql TCPS_ in .Pa /usr/lib/dtrace/tcp.d . .El .Sh FILES .Bl -tag -width "/usr/lib/dtrace/tcp.d" -compact .It Pa /usr/lib/dtrace/tcp.d DTrace type and translator definitions for the .Nm tcp provider. .El .Sh EXAMPLES The following script logs TCP segments in real time: .Bd -literal -offset indent #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf(" %3s %15s:%-5s %15s:%-5s %6s %s\\n", "CPU", "LADDR", "LPORT", "RADDR", "RPORT", "BYTES", "FLAGS"); } tcp:::send { this->length = args[2]->ip_plength - args[4]->tcp_offset; printf(" %3d %16s:%-5d -> %16s:%-5d %6d (", cpu, args[2]->ip_saddr, args[4]->tcp_sport, args[2]->ip_daddr, args[4]->tcp_dport, this->length); printf("%s", args[4]->tcp_flags & TH_FIN ? "FIN|" : ""); printf("%s", args[4]->tcp_flags & TH_SYN ? "SYN|" : ""); printf("%s", args[4]->tcp_flags & TH_RST ? "RST|" : ""); printf("%s", args[4]->tcp_flags & TH_PUSH ? "PUSH|" : ""); printf("%s", args[4]->tcp_flags & TH_ACK ? "ACK|" : ""); printf("%s", args[4]->tcp_flags & TH_URG ? "URG|" : ""); printf("%s", args[4]->tcp_flags == 0 ? "null " : ""); printf("\b)\\n"); } tcp:::receive { this->length = args[2]->ip_plength - args[4]->tcp_offset; printf(" %3d %16s:%-5d <- %16s:%-5d %6d (", cpu, args[2]->ip_daddr, args[4]->tcp_dport, args[2]->ip_saddr, args[4]->tcp_sport, this->length); printf("%s", args[4]->tcp_flags & TH_FIN ? "FIN|" : ""); printf("%s", args[4]->tcp_flags & TH_SYN ? "SYN|" : ""); printf("%s", args[4]->tcp_flags & TH_RST ? "RST|" : ""); printf("%s", args[4]->tcp_flags & TH_PUSH ? "PUSH|" : ""); printf("%s", args[4]->tcp_flags & TH_ACK ? "ACK|" : ""); printf("%s", args[4]->tcp_flags & TH_URG ? "URG|" : ""); printf("%s", args[4]->tcp_flags == 0 ? "null " : ""); printf("\b)\\n"); } .Ed The following script logs TCP connection state changes as they occur: .Bd -literal -offset indent #pragma D option quiet #pragma D option switchrate=25hz int last[int]; dtrace:::BEGIN { printf(" %12s %-20s %-20s %s\\n", "DELTA(us)", "OLD", "NEW", "TIMESTAMP"); } tcp:::state-change { this->elapsed = (timestamp - last[args[1]->cs_cid]) / 1000; printf(" %12d %-20s -> %-20s %d\\n", this->elapsed, tcp_state_string[args[5]->tcps_state], tcp_state_string[args[3]->tcps_state], timestamp); last[args[1]->cs_cid] = timestamp; } tcp:::state-change /last[args[1]->cs_cid] == 0/ { printf(" %12s %-20s -> %-20s %d\\n", "-", tcp_state_string[args[5]->tcps_state], tcp_state_string[args[3]->tcps_state], timestamp); last[args[1]->cs_cid] = timestamp; } .Ed .Sh COMPATIBILITY This provider is compatible with the .Nm tcp provider in Solaris. .Sh SEE ALSO .Xr dtrace 1 , .Xr dtrace_ip 4 , .Xr dtrace_udp 4 , .Xr tcp 4 , .Xr SDT 9 .Sh HISTORY The .Nm tcp provider first appeared in .Fx 10.0. .Sh AUTHORS This manual page was written by .An Mark Johnston Aq Mt markj@FreeBSD.org . .Sh BUGS The .Vt tcps_local and .Vt tcps_active fields of .Vt tcpsinfo_t are not filled in by the translator.