1.\" Copyright (c) 2015 Mark Johnston <markj@FreeBSD.org> 2.\" All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions and the following disclaimer. 9.\" 2. Redistributions in binary form must reproduce the above copyright 10.\" notice, this list of conditions and the following disclaimer in the 11.\" documentation and/or other materials provided with the distribution. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23.\" SUCH DAMAGE. 24.\" 25.\" $FreeBSD$ 26.\" 27.Dd August 1, 2018 28.Dt DTRACE_TCP 4 29.Os 30.Sh NAME 31.Nm dtrace_tcp 32.Nd a DTrace provider for tracing events related to the 33.Xr tcp 4 34protocol 35.Sh SYNOPSIS 36.Fn tcp:::accept-established "pktinfo_t *" "csinfo_t *" "ipinfo_t *" \ 37 "tcpsinfo_t *" "tcpinfo_t *" 38.Fn tcp:::accept-refused "pktinfo_t *" "csinfo_t *" "ipinfo_t *" \ 39 "tcpsinfo_t *" "tcpinfo_t *" 40.Fn tcp:::connect-established "pktinfo_t *" "csinfo_t *" "ipinfo_t *" \ 41 "tcpsinfo_t *" "tcpinfo_t *" 42.Fn tcp:::connect-refused "pktinfo_t *" "csinfo_t *" "ipinfo_t *" \ 43 "tcpsinfo_t *" "tcpinfo_t *" 44.Fn tcp:::connect-request "pktinfo_t *" "csinfo_t *" "ipinfo_t *" \ 45 "tcpsinfo_t *" "tcpinfo_t *" 46.Fn tcp:::receive "pktinfo_t *" "csinfo_t *" "ipinfo_t *" "tcpsinfo_t *" \ 47 "tcpinfo_t *" 48.Fn tcp:::send "pktinfo_t *" "csinfo_t *" "ipinfo_t *" "tcpsinfo_t *" \ 49 "tcpinfo_t *" 50.Fn tcp:::state-change "void *" "csinfo_t *" "void *" "tcpsinfo_t *" "void *" \ 51 "tcplsinfo_t *" 52.Sh DESCRIPTION 53The DTrace 54.Nm tcp 55provider allows users to trace events in the 56.Xr tcp 4 57protocol implementation. 58This provider is similar to the 59.Xr dtrace_ip 4 60and 61.Xr dtrace_udp 4 62providers, but additionally contains probes corresponding to protocol events at 63a level higher than packet reception and transmission. 64All 65.Nm tcp 66probes except for 67.Fn tcp:::state-change 68have the same number and type of arguments. 69The last three arguments are used to describe a TCP segment: the 70.Vt ipinfo_t 71argument exposes the version-agnostic fields of the IP header, while the 72.Vt tcpinfo_t 73argument exposes the TCP header, and the 74.Vt tcpsinfo_t 75argument describes details of the corresponding TCP connection state, if any. 76Their fields are described in the ARGUMENTS section. 77.Pp 78The 79.Fn tcp:::accept-established 80probe fires when a remotely-initiated active TCP open succeeds. 81At this point the new connection is in the ESTABLISHED state, and the probe 82arguments expose the headers associated with the final ACK of the three-way 83handshake. 84The 85.Fn tcp:::accept-refused 86probe fires when a SYN arrives on a port without a listening socket. 87The probe arguments expose the headers associated with the RST to be transmitted 88to the remote host in response to the SYN segment. 89.Pp 90The 91.Fn tcp:::connect-established , 92.Fn tcp:::connect-refused , 93and 94.Fn tcp:::connect-request 95probes are similar to the 96.Ql accept 97probes, except that they correspond to locally-initiated TCP connections. 98The 99.Fn tcp:::connect-established 100probe fires when the SYN-ACK segment of a three-way handshake is received from 101the remote host and a final ACK is prepared for transmission. 102This occurs immediately after the local connection state transitions from 103SYN-SENT to ESTABLISHED. 104The probe arguments describe the headers associated with the received SYN-ACK 105segment. 106The 107.Fn tcp:::connect-refused 108probe fires when the local host receives a RST segment in response to a SYN 109segment, indicating that the remote host refused to open a connection. 110The probe arguments describe the IP and TCP headers associated with the received 111RST segment. 112The 113.Fn tcp:::connect-request 114probe fires as the kernel prepares to transmit the initial SYN segment of a 115three-way handshake. 116.Pp 117The 118.Fn tcp:::send 119and 120.Fn tcp:::receive 121probes fire when the host sends or receives a TCP packet, respectively. 122As with the 123.Xr dtrace_udp 4 124provider, 125.Nm tcp 126probes fire only for packets sent by or to the local host; forwarded packets are 127handled in the IP layer and are only visible to the 128.Xr dtrace_ip 4 129provider. 130.Pp 131The 132.Fn tcp:::state-change 133probe fires upon local TCP connection state transitions. 134Its first, third and fifth arguments are currently always 135.Dv NULL . 136Its last argument describes the from-state in the transition, and the to-state 137can be obtained from 138.Dv args[3]->tcps_state . 139.Sh ARGUMENTS 140The 141.Vt pktinfo_t 142argument is currently unimplemented and is included for compatibility with other 143implementations of this provider. 144Its fields are: 145.Bl -tag -width "uinptr_t pkt_addr" -offset indent 146.It Vt uinptr_t pkt_addr 147Always set to 0. 148.El 149.Pp 150The 151.Vt csinfo_t 152argument is currently unimplemented and is included for compatibility with other 153implementations of this provider. 154Its fields are: 155.Bl -tag -width "uintptr_t cs_addr" -offset indent 156.It Vt uintptr_t cs_addr 157Always set to 0. 158.It Vt uint64_t cs_cid 159A pointer to the 160.Vt struct inpcb 161for this packet, or 162.Dv NULL . 163.It Vt pid_t cs_pid 164Always set to 0. 165.El 166.Pp 167The 168.Vt ipinfo_t 169type is a version-agnostic representation of fields from an IP header. 170Its fields are described in the 171.Xr dtrace_ip 4 172manual page. 173.Pp 174The 175.Vt tcpsinfo_t 176type is used to provide a stable representation of TCP connection state. 177Some 178.Nm tcp 179probes, such as 180.Fn tcp:::accept-refused , 181fire in a context where there is no TCP connection; this argument is 182.Dv NULL 183in that case. 184Its fields are: 185.Bl -tag -width "uint16_t tcps_lport" -offset indent 186.It Vt uintptr_t tcps_addr 187The address of the corresponding TCP control block. 188This is currently a pointer to a 189.Vt struct tcpcb . 190.It Vt int tcps_local 191A boolean indicating whether the connection is local to the host. 192Currently unimplemented and always set to -1. 193.It Vt int tcps_active 194A boolean indicating whether the connection was initiated by the local host. 195Currently unimplemented and always set to -1. 196.It Vt uint16_t tcps_lport 197Local TCP port. 198.It Vt uint16_t tcps_rport 199Remote TCP port. 200.It Vt string tcps_laddr 201Local address. 202.It Vt string tcps_raddr 203Remote address. 204.It Vt int32_t tcps_state 205Current TCP state. 206The valid TCP state values are given by the constants prefixed with 207.Ql TCPS_ 208in 209.Pa /usr/lib/dtrace/tcp.d . 210.It Vt uint32_t tcps_iss 211Initial send sequence number. 212.It Vt uint32_t tcps_suna 213Initial sequence number of sent but unacknowledged data. 214.It Vt uint32_t tcps_snxt 215Next sequence number for send. 216.It Vt uint32_t tcps_rack 217Sequence number of received and acknowledged data. 218.It Vt uint32_t tcps_rnxt 219Next expected sequence number for receive. 220.It Vt u_long tcps_swnd 221TCP send window size. 222.It Vt int32_t tcps_snd_ws 223Window scaling factor for the TCP send window. 224.It Vt u_long tcps_rwnd 225TCP receive window size. 226.It Vt int32_t tcps_rcv_ws 227Window scaling factor for the TCP receive window. 228.It Vt u_long tcps_cwnd 229TCP congestion window size. 230.It Vt u_long tcps_cwnd_ssthresh 231Congestion window threshold at which slow start ends and congestion avoidance 232begins. 233.It Vt uint32_t tcps_sack_fack 234Last sequence number selectively acknowledged by the receiver. 235.It Vt uint32_t tcps_sack_snxt 236Next selectively acknowledge sequence number at which to begin retransmitting. 237.It Vt uint32_t tcps_rto 238Round-trip timeout, in milliseconds. 239.It Vt uint32_t tcps_mss 240Maximum segment size. 241.It Vt int tcps_retransmit 242A boolean indicating that the local sender is retransmitting data. 243.It Vt int tcps_srtt 244Smoothed round-trip time. 245.El 246.Pp 247The 248.Vt tcpinfo_t 249type exposes the fields in a TCP segment header in host order. 250Its fields are: 251.Bl -tag -width "struct tcphdr *tcp_hdr" -offset indent 252.It Vt uint16_t tcp_sport 253Source TCP port. 254.It Vt uint16_t tcp_dport 255Destination TCP port. 256.It Vt uint32_t tcp_seq 257Sequence number. 258.It Vt uint32_t tcp_ack 259Acknowledgement number. 260.It Vt uint8_t tcp_offset 261Data offset, in bytes. 262.It Vt uint8_t tcp_flags 263TCP flags. 264.It Vt uint16_t tcp_window 265TCP window size. 266.It Vt uint16_t tcp_checksum 267Checksum. 268.It Vt uint16_t tcp_urgent 269Urgent data pointer. 270.It Vt struct tcphdr *tcp_hdr 271A pointer to the raw TCP header. 272.El 273.Pp 274The 275.Vt tcplsinfo_t 276type is used by the 277.Fn tcp:::state-change 278probe to provide the from-state of a transition. 279Its fields are: 280.Bl -tag -width "int32_t tcps_state" -offset indent 281.It Vt int32_t tcps_state 282A TCP state. 283The valid TCP state values are given by the constants prefixed with 284.Ql TCPS_ 285in 286.Pa /usr/lib/dtrace/tcp.d . 287.El 288.Sh FILES 289.Bl -tag -width "/usr/lib/dtrace/tcp.d" -compact 290.It Pa /usr/lib/dtrace/tcp.d 291DTrace type and translator definitions for the 292.Nm tcp 293provider. 294.El 295.Sh EXAMPLES 296The following script logs TCP segments in real time: 297.Bd -literal -offset indent 298#pragma D option quiet 299#pragma D option switchrate=10hz 300 301dtrace:::BEGIN 302{ 303 printf(" %3s %15s:%-5s %15s:%-5s %6s %s\\n", "CPU", 304 "LADDR", "LPORT", "RADDR", "RPORT", "BYTES", "FLAGS"); 305} 306 307tcp:::send 308{ 309 this->length = args[2]->ip_plength - args[4]->tcp_offset; 310 printf(" %3d %16s:%-5d -> %16s:%-5d %6d (", cpu, args[2]->ip_saddr, 311 args[4]->tcp_sport, args[2]->ip_daddr, args[4]->tcp_dport, 312 this->length); 313 printf("%s", args[4]->tcp_flags & TH_FIN ? "FIN|" : ""); 314 printf("%s", args[4]->tcp_flags & TH_SYN ? "SYN|" : ""); 315 printf("%s", args[4]->tcp_flags & TH_RST ? "RST|" : ""); 316 printf("%s", args[4]->tcp_flags & TH_PUSH ? "PUSH|" : ""); 317 printf("%s", args[4]->tcp_flags & TH_ACK ? "ACK|" : ""); 318 printf("%s", args[4]->tcp_flags & TH_URG ? "URG|" : ""); 319 printf("%s", args[4]->tcp_flags == 0 ? "null " : ""); 320 printf("\b)\\n"); 321} 322 323tcp:::receive 324{ 325 this->length = args[2]->ip_plength - args[4]->tcp_offset; 326 printf(" %3d %16s:%-5d <- %16s:%-5d %6d (", cpu, 327 args[2]->ip_daddr, args[4]->tcp_dport, args[2]->ip_saddr, 328 args[4]->tcp_sport, this->length); 329 printf("%s", args[4]->tcp_flags & TH_FIN ? "FIN|" : ""); 330 printf("%s", args[4]->tcp_flags & TH_SYN ? "SYN|" : ""); 331 printf("%s", args[4]->tcp_flags & TH_RST ? "RST|" : ""); 332 printf("%s", args[4]->tcp_flags & TH_PUSH ? "PUSH|" : ""); 333 printf("%s", args[4]->tcp_flags & TH_ACK ? "ACK|" : ""); 334 printf("%s", args[4]->tcp_flags & TH_URG ? "URG|" : ""); 335 printf("%s", args[4]->tcp_flags == 0 ? "null " : ""); 336 printf("\b)\\n"); 337} 338.Ed 339The following script logs TCP connection state changes as they occur: 340.Bd -literal -offset indent 341#pragma D option quiet 342#pragma D option switchrate=25hz 343 344int last[int]; 345 346dtrace:::BEGIN 347{ 348 printf(" %12s %-20s %-20s %s\\n", 349 "DELTA(us)", "OLD", "NEW", "TIMESTAMP"); 350} 351 352tcp:::state-change 353{ 354 this->elapsed = (timestamp - last[args[1]->cs_cid]) / 1000; 355 printf(" %12d %-20s -> %-20s %d\\n", this->elapsed, 356 tcp_state_string[args[5]->tcps_state], 357 tcp_state_string[args[3]->tcps_state], timestamp); 358 last[args[1]->cs_cid] = timestamp; 359} 360 361tcp:::state-change 362/last[args[1]->cs_cid] == 0/ 363{ 364 printf(" %12s %-20s -> %-20s %d\\n", "-", 365 tcp_state_string[args[5]->tcps_state], 366 tcp_state_string[args[3]->tcps_state], timestamp); 367 last[args[1]->cs_cid] = timestamp; 368} 369.Ed 370.Sh COMPATIBILITY 371This provider is compatible with the 372.Nm tcp 373provider in Solaris. 374.Sh SEE ALSO 375.Xr dtrace 1 , 376.Xr dtrace_ip 4 , 377.Xr dtrace_sctp 4 , 378.Xr dtrace_udp 4 , 379.Xr dtrace_udplite 4 , 380.Xr tcp 4 , 381.Xr SDT 9 382.Sh HISTORY 383The 384.Nm tcp 385provider first appeared in 386.Fx 38710.0. 388.Sh AUTHORS 389This manual page was written by 390.An Mark Johnston Aq Mt markj@FreeBSD.org . 391.Sh BUGS 392The 393.Vt tcps_local 394and 395.Vt tcps_active 396fields of 397.Vt tcpsinfo_t 398are not filled in by the translator. 399