summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Maguire <Alan.Maguire@Sun.COM>2010-05-27 17:29:51 -0400
committerAlan Maguire <Alan.Maguire@Sun.COM>2010-05-27 17:29:51 -0400
commit9cd928fe5e3ea4e05f64cfb380beb54b2623e7dc (patch)
tree55e1b2b427e91454fb4bd504a6dafd70813a6891
parent39cd77a06f56f308333bd7b2d8aae1b1467be113 (diff)
downloadillumos-gate-9cd928fe5e3ea4e05f64cfb380beb54b2623e7dc.tar.gz
PSARC 2010/106 DTrace TCP and UDP providers
6742331 DTrace TCP Provider 6932981 DTrace UDP provider
-rw-r--r--usr/src/cmd/dtrace/demo/Makefile17
-rw-r--r--usr/src/cmd/dtrace/demo/chapters10
-rw-r--r--usr/src/cmd/dtrace/demo/tcp/tcp1stbyte.d37
-rw-r--r--usr/src/cmd/dtrace/demo/tcp/tcpbytes.d36
-rw-r--r--usr/src/cmd/dtrace/demo/tcp/tcpbytesstat.d45
-rw-r--r--usr/src/cmd/dtrace/demo/tcp/tcpconnlat.d37
-rw-r--r--usr/src/cmd/dtrace/demo/tcp/tcpio.d32
-rw-r--r--usr/src/cmd/dtrace/demo/tcp/tcpioflags.d64
-rw-r--r--usr/src/cmd/dtrace/demo/tcp/tcpsnoop.d78
-rw-r--r--usr/src/cmd/dtrace/demo/tcp/tcpstate.d39
-rw-r--r--usr/src/cmd/dtrace/demo/tcp/tcptop.d138
-rw-r--r--usr/src/cmd/dtrace/demo/udp/udpbytes.d36
-rw-r--r--usr/src/cmd/dtrace/demo/udp/udpbytesstat.d45
-rw-r--r--usr/src/cmd/dtrace/demo/udp/udpio.d32
-rw-r--r--usr/src/cmd/dtrace/demo/udp/udpsnoop.d59
-rw-r--r--usr/src/cmd/dtrace/demo/udp/udptop.d133
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh34
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out2
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh27
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out1
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh32
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out2
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh20
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out1
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh182
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh.out18
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh172
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh.out15
-rw-r--r--usr/src/lib/libdtrace/Makefile.com13
-rw-r--r--usr/src/lib/libdtrace/common/dt_open.c11
-rw-r--r--usr/src/lib/libdtrace/common/ip.d.in80
-rw-r--r--usr/src/lib/libdtrace/common/ip.sed.in11
-rw-r--r--usr/src/lib/libdtrace/common/tcp.d.in269
-rw-r--r--usr/src/lib/libdtrace/common/tcp.sed.in53
-rw-r--r--usr/src/lib/libdtrace/common/udp.d.in73
-rw-r--r--usr/src/lib/libdtrace/common/udp.sed.in29
-rw-r--r--usr/src/pkg/manifests/developer-dtrace.mf19
-rw-r--r--usr/src/pkg/manifests/system-dtrace-tests.mf7
-rw-r--r--usr/src/uts/common/dtrace/sdt_subr.c59
-rw-r--r--usr/src/uts/common/inet/ip.h1
-rw-r--r--usr/src/uts/common/inet/ip/ip_attr.c7
-rw-r--r--usr/src/uts/common/inet/ip/ipclassifier.c2
-rw-r--r--usr/src/uts/common/inet/tcp.h1
-rw-r--r--usr/src/uts/common/inet/tcp/tcp.c54
-rw-r--r--usr/src/uts/common/inet/tcp/tcp_bind.c8
-rw-r--r--usr/src/uts/common/inet/tcp/tcp_fusion.c8
-rw-r--r--usr/src/uts/common/inet/tcp/tcp_input.c105
-rw-r--r--usr/src/uts/common/inet/tcp/tcp_output.c46
-rw-r--r--usr/src/uts/common/inet/udp/udp.c23
-rw-r--r--usr/src/uts/common/sys/sdt.h53
50 files changed, 2197 insertions, 79 deletions
diff --git a/usr/src/cmd/dtrace/demo/Makefile b/usr/src/cmd/dtrace/demo/Makefile
index caa35d2395..c55a43b4f2 100644
--- a/usr/src/cmd/dtrace/demo/Makefile
+++ b/usr/src/cmd/dtrace/demo/Makefile
@@ -19,8 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
#
include ../../Makefile.cmd
@@ -83,12 +82,26 @@ DFILES = \
specopen.d \
ssd.d \
syscall.d \
+ tcp1stbyte.d \
+ tcpbytes.d \
+ tcpbytesstat.d \
+ tcpconnlat.d \
+ tcpio.d \
+ tcpioflags.d \
+ tcpsnoop.d \
+ tcpstate.d \
+ tcptop.d \
tick.d \
ticktime.d \
time.d \
tracewrite.d \
trunc.d \
trussrw.d \
+ udpbytes.d \
+ udpbytesstat.d \
+ udpio.d \
+ udpsnoop.d \
+ udptop.d \
userfunc.d \
whatfor.d \
whatlock.d \
diff --git a/usr/src/cmd/dtrace/demo/chapters b/usr/src/cmd/dtrace/demo/chapters
index 09a277af7e..2160a0cfe0 100644
--- a/usr/src/cmd/dtrace/demo/chapters
+++ b/usr/src/cmd/dtrace/demo/chapters
@@ -113,3 +113,13 @@ title: ip Provider
index: 101
url: http://wikis.sun.com/display/DTrace/ip+Provider
+name: tcp
+title: tcp Provider
+index: 102
+url: http://wikis.sun.com/display/DTrace/tcp+Provider
+
+name: udp
+title: udp Provider
+index: 103
+url: http://wikis.sun.com/display/DTrace/udp+Provider
+
diff --git a/usr/src/cmd/dtrace/demo/tcp/tcp1stbyte.d b/usr/src/cmd/dtrace/demo/tcp/tcp1stbyte.d
new file mode 100644
index 0000000000..94001296fa
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/tcp/tcp1stbyte.d
@@ -0,0 +1,37 @@
+#!/usr/sbin/dtrace -s
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+tcp:::connect-established
+{
+ start[args[1]->cs_cid] = timestamp;
+}
+
+tcp:::receive
+/start[args[1]->cs_cid] && (args[2]->ip_plength - args[4]->tcp_offset) > 0/
+{
+ @latency["1st Byte Latency (ns)", args[2]->ip_saddr] =
+ quantize(timestamp - start[args[1]->cs_cid]);
+ start[args[1]->cs_cid] = 0;
+}
diff --git a/usr/src/cmd/dtrace/demo/tcp/tcpbytes.d b/usr/src/cmd/dtrace/demo/tcp/tcpbytes.d
new file mode 100644
index 0000000000..7fb68de973
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/tcp/tcpbytes.d
@@ -0,0 +1,36 @@
+#!/usr/sbin/dtrace -s
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+tcp:::receive
+{
+ @bytes[args[2]->ip_saddr, args[4]->tcp_dport] =
+ sum(args[2]->ip_plength - args[4]->tcp_offset);
+}
+
+tcp:::send
+{
+ @bytes[args[2]->ip_daddr, args[4]->tcp_sport] =
+ sum(args[2]->ip_plength - args[4]->tcp_offset);
+}
diff --git a/usr/src/cmd/dtrace/demo/tcp/tcpbytesstat.d b/usr/src/cmd/dtrace/demo/tcp/tcpbytesstat.d
new file mode 100644
index 0000000000..ecd9b04455
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/tcp/tcpbytesstat.d
@@ -0,0 +1,45 @@
+#!/usr/sbin/dtrace -s
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#pragma D option quiet
+
+tcp:::receive
+{
+ @bytes[args[2]->ip_saddr, args[4]->tcp_dport] =
+ sum(args[2]->ip_plength - args[4]->tcp_offset);
+}
+
+tcp:::send
+{
+ @bytes[args[2]->ip_daddr, args[4]->tcp_sport] =
+ sum(args[2]->ip_plength - args[4]->tcp_offset);
+}
+
+profile:::tick-1sec
+{
+ printf("\n %-32s %16s\n", "HOST", "BYTES/s");
+ printa(" %-32s %@16d\n", @bytes);
+ trunc(@bytes);
+}
diff --git a/usr/src/cmd/dtrace/demo/tcp/tcpconnlat.d b/usr/src/cmd/dtrace/demo/tcp/tcpconnlat.d
new file mode 100644
index 0000000000..bc395f9711
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/tcp/tcpconnlat.d
@@ -0,0 +1,37 @@
+#!/usr/sbin/dtrace -s
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+tcp:::connect-request
+{
+ start[args[1]->cs_cid] = timestamp;
+}
+
+tcp:::connect-established
+/start[args[1]->cs_cid] /
+{
+ @latency["Connect Latency (ns)", args[3]->tcps_raddr] =
+ quantize(timestamp - start[args[1]->cs_cid]);
+ start[args[1]->cs_cid] = 0;
+}
diff --git a/usr/src/cmd/dtrace/demo/tcp/tcpio.d b/usr/src/cmd/dtrace/demo/tcp/tcpio.d
new file mode 100644
index 0000000000..b3628430b4
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/tcp/tcpio.d
@@ -0,0 +1,32 @@
+#!/usr/sbin/dtrace -s
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+tcp:::send,
+tcp:::receive
+{
+ printf("%15s:%-5d -> %15s:%-5d",
+ args[2]->ip_saddr, args[4]->tcp_sport,
+ args[2]->ip_daddr, args[4]->tcp_dport);
+}
diff --git a/usr/src/cmd/dtrace/demo/tcp/tcpioflags.d b/usr/src/cmd/dtrace/demo/tcp/tcpioflags.d
new file mode 100644
index 0000000000..cdfbd2aa2b
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/tcp/tcpioflags.d
@@ -0,0 +1,64 @@
+#!/usr/sbin/dtrace -s
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+dtrace:::BEGIN
+{
+ printf(" %15s:%-5s %15s:%-5s %6s %s\n",
+ "LADDR", "PORT", "RADDR", "PORT", "BYTES", "FLAGS");
+}
+
+tcp:::send
+{
+ this->length = args[2]->ip_plength - args[4]->tcp_offset;
+ printf(" %15s:%-5d -> %15s:%-5d %6d (",
+ args[2]->ip_saddr, args[4]->tcp_sport,
+ args[2]->ip_daddr, args[4]->tcp_dport, this->length);
+}
+
+tcp:::receive
+{
+ this->length = args[2]->ip_plength - args[4]->tcp_offset;
+ printf(" %15s:%-5d <- %15s:%-5d %6d (",
+ args[2]->ip_daddr, args[4]->tcp_dport,
+ args[2]->ip_saddr, args[4]->tcp_sport, this->length);
+}
+
+tcp:::send,
+tcp:::receive
+{
+ 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 & TH_ECE ? "ECE|" : "");
+ printf("%s", args[4]->tcp_flags & TH_CWR ? "CWR|" : "");
+ printf("%s", args[4]->tcp_flags == 0 ? "null " : "");
+ printf("\b)\n");
+}
diff --git a/usr/src/cmd/dtrace/demo/tcp/tcpsnoop.d b/usr/src/cmd/dtrace/demo/tcp/tcpsnoop.d
new file mode 100644
index 0000000000..9d44519e80
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/tcp/tcpsnoop.d
@@ -0,0 +1,78 @@
+#!/usr/sbin/dtrace -s
+/*
+ * tcpsnoop - snoop TCP network packets by process.
+ * Written using DTrace tcp Provider.
+ *
+ * This analyses TCP network packets and prints the responsible PID plus
+ * standard details such as IP address and port. This captures traffic
+ * from existing and newly created TCP connections. It can help identify
+ * which processes are causing TCP traffic.
+ *
+ * SEE ALSO: snoop -rS
+ *
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Portions Copyright 2010 Brendan Gregg
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+dtrace:::BEGIN
+{
+ printf("%6s %6s %15s:%-5s %15s:%-5s %6s %s\n",
+ "TIME", "PID", "LADDR", "PORT", "RADDR", "PORT", "BYTES", "FLAGS");
+}
+
+tcp:::send
+{
+ this->length = args[2]->ip_plength - args[4]->tcp_offset;
+ printf("%6d %6d %15s:%-5d -> %15s:%-5d %6d (",
+ timestamp/1000, args[1]->cs_pid, args[2]->ip_saddr,
+ args[4]->tcp_sport, args[2]->ip_daddr, args[4]->tcp_dport,
+ this->length);
+}
+
+tcp:::receive
+{
+ this->length = args[2]->ip_plength - args[4]->tcp_offset;
+ printf("%6d %6d %15s:%-5d <- %15s:%-5d %6d (",
+ timestamp/1000, args[1]->cs_pid, args[2]->ip_daddr,
+ args[4]->tcp_dport, args[2]->ip_saddr, args[4]->tcp_sport,
+ this->length);
+}
+
+tcp:::send,
+tcp:::receive
+{
+ 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 & TH_ECE ? "ECE|" : "");
+ printf("%s", args[4]->tcp_flags & TH_CWR ? "CWR|" : "");
+ printf("%s", args[4]->tcp_flags == 0 ? "null " : "");
+ printf("\b)\n");
+}
diff --git a/usr/src/cmd/dtrace/demo/tcp/tcpstate.d b/usr/src/cmd/dtrace/demo/tcp/tcpstate.d
new file mode 100644
index 0000000000..38f0470a08
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/tcp/tcpstate.d
@@ -0,0 +1,39 @@
+#!/usr/sbin/dtrace -s
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("%-10s %-10s %-20s %-20s\n", "C", "PID", "PREV", "NEW");
+}
+
+
+tcp:::state-change
+{
+ printf("%-10d %-10d %-20s -> %-20s\n", cpu, args[1]->cs_pid,
+ tcp_state_string[args[5]->tcps_state],
+ tcp_state_string[args[3]->tcps_state]);
+}
diff --git a/usr/src/cmd/dtrace/demo/tcp/tcptop.d b/usr/src/cmd/dtrace/demo/tcp/tcptop.d
new file mode 100644
index 0000000000..450f496ebc
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/tcp/tcptop.d
@@ -0,0 +1,138 @@
+#!/usr/sbin/dtrace -s
+/*
+ * tcptop: display top TCP network packets by process.
+ * Written using DTrace tcp Provider.
+ *
+ * Usage: dtrace -s tcptop.d [count] [interval]
+ *
+ * This analyses TCP network packets and prints the responsible PID plus
+ * standard details such as IP address and port. This captures traffic
+ * of newly created TCP connections that were established while this program
+ * was running along with traffic from existing connections. It can help
+ * identify which processes is causing TCP traffic.
+ *
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Portions Copyright 2010 Brendan Gregg
+ */
+
+#pragma D option quiet
+#pragma D option defaultargs
+#pragma D option switchrate=10hz
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ /* starting values */
+ counts = $1 ? $1 : 10;
+ secs = $2 ? $2 : 5;
+ TCP_out = 0;
+ TCP_in = 0;
+
+ printf("Sampling... Please wait.\n");
+}
+
+
+tcp:::send
+/ args[1]->cs_pid != -1 /
+{
+ @out[args[1]->cs_zoneid, args[1]->cs_pid, args[2]->ip_saddr,
+ args[4]->tcp_sport, args[2]->ip_daddr, args[4]->tcp_dport] =
+ sum(args[2]->ip_plength - args[4]->tcp_offset);
+}
+
+tcp:::receive
+/ args[1]->cs_pid != -1 /
+{
+ @out[args[1]->cs_zoneid, args[1]->cs_pid, args[2]->ip_daddr,
+ args[4]->tcp_dport, args[2]->ip_saddr, args[4]->tcp_sport] =
+ sum(args[2]->ip_plength - args[4]->tcp_offset);
+}
+
+/*
+ * TCP Systemwide Stats
+ */
+mib:::tcpOutDataBytes { TCP_out += args[0]; }
+mib:::tcpRetransBytes { TCP_out += args[0]; }
+mib:::tcpInDataInorderBytes { TCP_in += args[0]; }
+mib:::tcpInDataDupBytes { TCP_in += args[0]; }
+mib:::tcpInDataUnorderBytes { TCP_in += args[0]; }
+
+profile:::tick-1sec
+/secs != 0/
+{
+ secs--;
+}
+
+/*
+ * Print Report
+ */
+profile:::tick-1sec
+/secs == 0/
+{
+ /* fetch 1 min load average */
+ this->load1a = `hp_avenrun[0] / 65536;
+ this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
+
+ /* convert TCP counters to Kb */
+ TCP_out /= 1024;
+ TCP_in /= 1024;
+
+ /* print status */
+ printf("%Y, load: %d.%02d, TCPin: %6d Kb, TCPout: %6d Kb\n\n",
+ walltimestamp, this->load1a, this->load1b, TCP_in, TCP_out);
+
+ /* print headers */
+ printf("%6s %6s %-15s %5s %-15s %5s %9s\n",
+ "ZONE", "PID", "LADDR", "LPORT", "RADDR", "RPORT", "SIZE");
+
+ /* print data */
+ printa("%6d %6d %-15s %5d %-15s %5d %@9d\n", @out);
+ printf("\n");
+
+ /* clear data */
+ trunc(@out);
+ TCP_in = 0;
+ TCP_out = 0;
+ secs = 5;
+ counts--;
+}
+
+/*
+ * End of program
+ */
+profile:::tick-1sec
+/counts == 0/
+{
+ exit(0);
+}
+
+/*
+ * Cleanup for Ctrl-C
+ */
+dtrace:::END
+{
+ trunc(@out);
+}
diff --git a/usr/src/cmd/dtrace/demo/udp/udpbytes.d b/usr/src/cmd/dtrace/demo/udp/udpbytes.d
new file mode 100644
index 0000000000..29d85fcd6c
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/udp/udpbytes.d
@@ -0,0 +1,36 @@
+#!/usr/sbin/dtrace -s
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+udp:::receive
+{
+ @bytes[args[2]->ip_saddr, args[4]->udp_dport] =
+ sum(args[4]->udp_length);
+}
+
+udp:::send
+{
+ @bytes[args[2]->ip_daddr, args[4]->udp_sport] =
+ sum(args[4]->udp_length);
+}
diff --git a/usr/src/cmd/dtrace/demo/udp/udpbytesstat.d b/usr/src/cmd/dtrace/demo/udp/udpbytesstat.d
new file mode 100644
index 0000000000..58fa826a25
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/udp/udpbytesstat.d
@@ -0,0 +1,45 @@
+#!/usr/sbin/dtrace -s
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#pragma D option quiet
+
+udp:::receive
+{
+ @bytes[args[2]->ip_saddr, args[4]->udp_dport] =
+ sum(args[4]->udp_length);
+}
+
+udp:::send
+{
+ @bytes[args[2]->ip_daddr, args[4]->udp_sport] =
+ sum(args[4]->udp_length);
+}
+
+profile:::tick-1sec
+{
+ printf("\n %-32s %16s\n", "HOST", "BYTES/s");
+ printa(" %-32s %@16d\n", @bytes);
+ trunc(@bytes);
+}
diff --git a/usr/src/cmd/dtrace/demo/udp/udpio.d b/usr/src/cmd/dtrace/demo/udp/udpio.d
new file mode 100644
index 0000000000..78b3f48260
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/udp/udpio.d
@@ -0,0 +1,32 @@
+#!/usr/sbin/dtrace -s
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+udp:::send,
+udp:::receive
+{
+ printf("%15s:%-5d -> %15s:%-5d",
+ args[2]->ip_saddr, args[4]->udp_sport,
+ args[2]->ip_daddr, args[4]->udp_dport);
+}
diff --git a/usr/src/cmd/dtrace/demo/udp/udpsnoop.d b/usr/src/cmd/dtrace/demo/udp/udpsnoop.d
new file mode 100644
index 0000000000..fffc2904c0
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/udp/udpsnoop.d
@@ -0,0 +1,59 @@
+#!/usr/sbin/dtrace -s
+/*
+ * udpsnoop - snoop UDP network packets by process.
+ * Written using DTrace udp Provider.
+ *
+ * This analyses UDP network packets and prints the responsible PID plus
+ * standard details such as IP address and port. This captures traffic
+ * from existing and newly created UDP connections. It can help identify
+ * which processes are causing UDP traffic.
+ *
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Portions Copyright 2010 Brendan Gregg
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+dtrace:::BEGIN
+{
+ printf("%6s %6s %15s:%-5s %15s:%-5s %6s\n",
+ "TIME", "PID", "LADDR", "PORT", "RADDR", "PORT", "BYTES");
+}
+
+udp:::send
+{
+ printf("%6d %6d %15s:%-5d -> %15s:%-5d %6d\n",
+ timestamp/1000, args[1]->cs_pid, args[2]->ip_saddr,
+ args[4]->udp_sport, args[2]->ip_daddr, args[4]->udp_dport,
+ args[4]->udp_length);
+}
+
+udp:::receive
+{
+ printf("%6d %6d %15s:%-5d <- %15s:%-5d %6d\n",
+ timestamp/1000, args[1]->cs_pid, args[2]->ip_daddr,
+ args[4]->udp_dport, args[2]->ip_saddr, args[4]->udp_sport,
+ args[4]->udp_length);
+}
diff --git a/usr/src/cmd/dtrace/demo/udp/udptop.d b/usr/src/cmd/dtrace/demo/udp/udptop.d
new file mode 100644
index 0000000000..a626e5710f
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/udp/udptop.d
@@ -0,0 +1,133 @@
+#!/usr/sbin/dtrace -s
+/*
+ * udptop: display top UDP network packets by process.
+ * Written using DTrace udp Provider.
+ *
+ * Usage: dtrace -s udptop.d [count] [interval]
+ *
+ * This analyses UDP network packets and prints the responsible PID plus
+ * standard details such as IP address and port. This captures traffic
+ * of newly created UDP connections that were established while this program
+ * was running along with traffic from existing connections. It can help
+ * identify which processes is causing UDP traffic.
+ *
+ * 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
+ *
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Portions Copyright 2010 Brendan Gregg
+ */
+
+#pragma D option quiet
+#pragma D option defaultargs
+#pragma D option switchrate=10hz
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+ /* starting values */
+ counts = $1 ? $1 : 10;
+ secs = $2 ? $2 : 5;
+ UDP_out = 0;
+ UDP_in = 0;
+
+ printf("Sampling... Please wait.\n");
+}
+
+
+udp:::send
+/ args[1]->cs_pid != -1 /
+{
+ @out[args[1]->cs_zoneid, args[1]->cs_pid, args[2]->ip_saddr,
+ args[4]->udp_sport, args[2]->ip_daddr, args[4]->udp_dport] =
+ sum(args[4]->udp_length);
+}
+
+udp:::receive
+/ args[1]->cs_pid != -1 /
+{
+ @out[args[1]->cs_zoneid, args[1]->cs_pid, args[2]->ip_daddr,
+ args[4]->udp_dport, args[2]->ip_saddr, args[4]->udp_sport] =
+ sum(args[4]->udp_length);
+}
+
+/*
+ * UDP Systemwide Stats
+ */
+mib:::udpHCOutDatagrams { UDP_out += args[0]; }
+mib:::udpHCInDatagrams { UDP_in += args[0]; }
+
+profile:::tick-1sec
+/secs != 0/
+{
+ secs--;
+}
+
+/*
+ * Print Report
+ */
+profile:::tick-1sec
+/secs == 0/
+{
+ /* fetch 1 min load average */
+ this->load1a = `hp_avenrun[0] / 65536;
+ this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536;
+
+ /* print status */
+ printf(%Y, load: %d.%02d, UDP datagrams in: %6d, ",
+ walltimestamp, this->load1a, this->load1b, UDP_in);
+ printf("UDP datagrams out: %6d\n\n", UDP_out);
+
+ /* print headers */
+ printf("%6s %6s %-15s %5s %-15s %5s %9s\n",
+ "ZONE", "PID", "LADDR", "LPORT", "RADDR", "RPORT", "SIZE");
+
+ /* print data */
+ printa("%6d %6d %-15s %5d %-15s %5d %@9d\n", @out);
+ printf("\n");
+
+ /* clear data */
+ trunc(@out);
+ UDP_in = 0;
+ UDP_out = 0;
+ secs = 5;
+ counts--;
+}
+
+/*
+ * End of program
+ */
+profile:::tick-1sec
+/counts == 0/
+{
+ exit(0);
+}
+
+/*
+ * Cleanup for Ctrl-C
+ */
+dtrace:::END
+{
+ trunc(@out);
+}
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh
index 32ed78b47f..6fa8c35bf3 100755
--- a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh
@@ -21,13 +21,11 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-#pragma ident "%Z%%M% %I% %E% SMI"
#
-# Test ip:::{send,receive} of IPv4 TCP to a remote host.
+# Test {ip,tcp}:::{send,receive} of IPv4 TCP to local host.
#
# This may fail due to:
#
@@ -42,8 +40,10 @@
# following packet counts were traced:
#
# 3 x ip:::send (2 during the TCP handshake, then a FIN)
+# 3 x tcp:::send (2 during the TCP handshake, then a FIN)
# 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK)
-#
+# 2 x tcp:::receive (1 during the TCP handshake, then the FIN ACK)
+
# The actual count tested is 5 each way, since we are tracing both
# source and destination events.
#
@@ -78,28 +78,42 @@ EOPERL
$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
BEGIN
{
- send = receive = 0;
+ ipsend = tcpsend = ipreceive = tcpreceive = 0;
}
ip:::send
/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
args[4]->ipv4_protocol == IPPROTO_TCP/
{
- send++;
+ ipsend++;
+}
+
+tcp:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
+{
+ tcpsend++;
}
ip:::receive
/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
args[4]->ipv4_protocol == IPPROTO_TCP/
{
- receive++;
+ ipreceive++;
+}
+
+tcp:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
+{
+ tcpreceive++;
}
END
{
printf("Minimum TCP events seen\n\n");
- printf("ip:::send - %s\n", send >= 5 ? "yes" : "no");
- printf("ip:::receive - %s\n", receive >= 5 ? "yes" : "no");
+ printf("ip:::send - %s\n", ipsend >= 5 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 5 ? "yes" : "no");
+ printf("tcp:::send - %s\n", tcpsend >= 5 ? "yes" : "no");
+ printf("tcp:::receive - %s\n", tcpreceive >= 5 ? "yes" : "no");
}
EODTRACE
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out
index 18ed9477a0..2a85b98b6b 100644
--- a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out
@@ -2,4 +2,6 @@ Minimum TCP events seen
ip:::send - yes
ip:::receive - yes
+tcp:::send - yes
+tcp:::receive - yes
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh
index 6ffc9bc3b2..fa8f7acfc7 100755
--- a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh
@@ -21,10 +21,8 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-#pragma ident "%Z%%M% %I% %E% SMI"
#
# Test ip:::{send,receive} of IPv4 UDP to a local address.
@@ -42,8 +40,14 @@
# following counts were traced:
#
# 1 x ip:::send (UDP sent to ping's base UDP port)
+# 1 x udp:::send (UDP sent to ping's base UDP port)
# 1 x ip:::receive (UDP received)
#
+# No udp:::receive event is expected as the response ping -U elicits is
+# an ICMP PORT_UNREACHABLE response rather than a UDP packet, and locally
+# the echo request UDP packet only reaches IP, so the udp:::receive probe
+# is not triggered by it.
+#
if (( $# != 1 )); then
print -u2 "expected one argument: <dtrace-path>"
@@ -56,27 +60,34 @@ local=127.0.0.1
$dtrace -c "/usr/sbin/ping -U $local" -qs /dev/stdin <<EOF | grep -v 'is alive'
BEGIN
{
- send = receive = 0;
+ ipsend = udpsend = ipreceive = 0;
}
ip:::send
/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
args[4]->ipv4_protocol == IPPROTO_UDP/
{
- send++;
+ ipsend++;
+}
+
+udp:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
+{
+ udpsend++;
}
ip:::receive
/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
args[4]->ipv4_protocol == IPPROTO_UDP/
{
- receive++;
+ ipreceive++;
}
END
{
printf("Minimum UDP events seen\n\n");
- printf("ip:::send - %s\n", send >= 1 ? "yes" : "no");
- printf("ip:::receive - %s\n", receive >= 1 ? "yes" : "no");
+ printf("ip:::send - %s\n", ipsend >= 1 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 1 ? "yes" : "no");
+ printf("udp:::send - %s\n", udpsend >= 1 ? "yes" : "no");
}
EOF
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out
index eef72522ae..bca55327ef 100644
--- a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out
@@ -2,4 +2,5 @@ Minimum UDP events seen
ip:::send - yes
ip:::receive - yes
+udp:::send - yes
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh
index b55515287a..89a0cdb95e 100755
--- a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh
@@ -21,13 +21,11 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-#pragma ident "%Z%%M% %I% %E% SMI"
#
-# Test ip:::{send,receive} of IPv4 TCP to a remote host.
+# Test {tcp,ip}:::{send,receive} of IPv4 TCP to a remote host.
#
# This may fail due to:
#
@@ -42,7 +40,9 @@
# following packet counts were traced:
#
# 3 x ip:::send (2 during the TCP handshake, then a FIN)
+# 3 x tcp:::send (2 during the TCP handshake, then a FIN)
# 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK)
+# 2 x tcp:::receive (1 during the TCP handshake, then the FIN ACK)
#
if (( $# != 1 )); then
@@ -81,28 +81,42 @@ EOPERL
$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
BEGIN
{
- send = receive = 0;
+ ipsend = tcpsend = ipreceive = tcpreceive = 0;
}
ip:::send
/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
args[4]->ipv4_protocol == IPPROTO_TCP/
{
- send++;
+ ipsend++;
+}
+
+tcp:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest"/
+{
+ tcpsend++;
}
ip:::receive
/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
args[4]->ipv4_protocol == IPPROTO_TCP/
{
- receive++;
+ ipreceive++;
+}
+
+tcp:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source"/
+{
+ tcpreceive++;
}
END
{
printf("Minimum TCP events seen\n\n");
- printf("ip:::send - %s\n", send >= 3 ? "yes" : "no");
- printf("ip:::receive - %s\n", receive >= 2 ? "yes" : "no");
+ printf("ip:::send - %s\n", ipsend >= 3 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 2 ? "yes" : "no");
+ printf("tcp:::send - %s\n", tcpsend >= 3 ? "yes" : "no");
+ printf("tcp:::receive - %s\n", tcpreceive >= 2 ? "yes" : "no");
}
EODTRACE
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out
index 18ed9477a0..2a85b98b6b 100644
--- a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out
@@ -2,4 +2,6 @@ Minimum TCP events seen
ip:::send - yes
ip:::receive - yes
+tcp:::send - yes
+tcp:::receive - yes
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh
index 0e82fd8621..b0893c8161 100755
--- a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh
@@ -21,13 +21,11 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-#pragma ident "%Z%%M% %I% %E% SMI"
#
-# Test ip:::{send,receive} of IPv4 UDP to a remote host.
+# Test {udp,ip}:::{send,receive} of IPv4 UDP to a remote host.
#
# This may fail due to:
#
@@ -42,6 +40,7 @@
# following counts were traced:
#
# 1 x ip:::send (UDP sent to ping's base UDP port)
+# 1 x udp:::send (UDP sent to ping's base UDP port)
#
if (( $# != 1 )); then
@@ -64,19 +63,26 @@ fi
$dtrace -c "/usr/sbin/ping -U $dest" -qs /dev/stdin <<EOF | grep -v 'is alive'
BEGIN
{
- send = 0;
+ ipsend = udpsend = 0;
}
ip:::send
/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
args[4]->ipv4_protocol == IPPROTO_UDP/
{
- send++;
+ ipsend++;
+}
+
+udp:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest"/
+{
+ udpsend++;
}
END
{
printf("Minimum UDP events seen\n\n");
- printf("ip:::send - %s\n", send >= 1 ? "yes" : "no");
+ printf("ip:::send - %s\n", ipsend >= 1 ? "yes" : "no");
+ printf("udp:::send - %s\n", udpsend >= 1 ? "yes" : "no");
}
EOF
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out
index 71de28cebe..bdbbe1fd65 100644
--- a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out
@@ -1,4 +1,5 @@
Minimum UDP events seen
ip:::send - yes
+udp:::send - yes
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh
new file mode 100644
index 0000000000..8a65ce6f8d
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh
@@ -0,0 +1,182 @@
+#!/usr/bin/ksh
+#
+# 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
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# Test tcp:::state-change and tcp:::{send,receive} by connecting to
+# the local ssh service and sending a test message. This should result
+# in a "Protocol mismatch" response and a close of the connection.
+# A number of state transition events along with tcp fusion send and
+# receive events for the message should result.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. The lo0 interface missing or not up.
+# 3. The local ssh service is not online.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test performs a TCP connection to the ssh service (port 22) and
+# checks that at least the following packet counts were traced:
+#
+# 3 x ip:::send (2 during the TCP handshake, then a FIN)
+# 4 x tcp:::send (2 during the TCP handshake, 1 message then a FIN)
+# 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK)
+# 3 x tcp:::receive (1 during the TCP handshake, 1 message then the FIN ACK)
+#
+# The actual ip count tested is 5 each way, since we are tracing both
+# source and destination events. The actual tcp count tested is 7
+# each way, since the TCP fusion send/receive events will not reach IP.
+#
+# For this test to work, we are assuming that the TCP handshake and
+# TCP close will enter the IP code path and not use tcp fusion.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+local=127.0.0.1
+tcpport=22
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.pl <<-EOPERL
+ use IO::Socket;
+ my \$s = IO::Socket::INET->new(
+ Proto => "tcp",
+ PeerAddr => "$local",
+ PeerPort => $tcpport,
+ Timeout => 3);
+ die "Could not connect to host $local port $tcpport" unless \$s;
+ print \$s "testing state machine transitions";
+ close \$s;
+EOPERL
+
+$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ ipsend = tcpsend = ipreceive = tcpreceive = 0;
+ connreq = connest = connaccept = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ ipsend++;
+}
+
+tcp:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ (args[4]->tcp_sport == $tcpport || args[4]->tcp_dport == $tcpport)/
+{
+ tcpsend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ ipreceive++;
+}
+
+tcp:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ (args[4]->tcp_sport == $tcpport || args[4]->tcp_dport == $tcpport)/
+{
+ tcpreceive++;
+}
+
+tcp:::state-change
+{
+ state_event[args[3]->tcps_state]++;
+}
+
+tcp:::connect-request
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->tcp_dport == $tcpport/
+{
+ connreq++;
+}
+
+tcp:::connect-established
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->tcp_sport == $tcpport/
+{
+ connest++;
+}
+
+tcp:::accept-established
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->tcp_dport == $tcpport/
+{
+ connaccept++;
+}
+
+END
+{
+ printf("Minimum TCP events seen\n\n");
+ printf("ip:::send - %s\n", ipsend >= 5 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 5 ? "yes" : "no");
+ printf("tcp:::send - %s\n", tcpsend >= 7 ? "yes" : "no");
+ printf("tcp:::receive - %s\n", tcpreceive >= 7 ? "yes" : "no");
+ printf("tcp:::state-change to syn-sent - %s\n",
+ state_event[TCP_STATE_SYN_SENT] >=1 ? "yes" : "no");
+ printf("tcp:::state-change to syn-received - %s\n",
+ state_event[TCP_STATE_SYN_RECEIVED] >=1 ? "yes" : "no");
+ printf("tcp:::state-change to established - %s\n",
+ state_event[TCP_STATE_ESTABLISHED] >= 2 ? "yes" : "no");
+ printf("tcp:::state-change to fin-wait-1 - %s\n",
+ state_event[TCP_STATE_FIN_WAIT_1] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to close-wait - %s\n",
+ state_event[TCP_STATE_CLOSE_WAIT] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to fin-wait-2 - %s\n",
+ state_event[TCP_STATE_FIN_WAIT_2] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to last-ack - %s\n",
+ state_event[TCP_STATE_LAST_ACK] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to time-wait - %s\n",
+ state_event[TCP_STATE_TIME_WAIT] >= 1 ? "yes" : "no");
+ printf("tcp:::connect-request - %s\n",
+ connreq >=1 ? "yes" : "no");
+ printf("tcp:::connect-established - %s\n",
+ connest >=1 ? "yes" : "no");
+ printf("tcp:::accept-established - %s\n",
+ connaccept >=1 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/usr/bin/rm -rf $DIR
+
+exit $status
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh.out
new file mode 100644
index 0000000000..ea1c27e502
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh.out
@@ -0,0 +1,18 @@
+Minimum TCP events seen
+
+ip:::send - yes
+ip:::receive - yes
+tcp:::send - yes
+tcp:::receive - yes
+tcp:::state-change to syn-sent - yes
+tcp:::state-change to syn-received - yes
+tcp:::state-change to established - yes
+tcp:::state-change to fin-wait-1 - yes
+tcp:::state-change to close-wait - yes
+tcp:::state-change to fin-wait-2 - yes
+tcp:::state-change to last-ack - yes
+tcp:::state-change to time-wait - yes
+tcp:::connect-request - yes
+tcp:::connect-established - yes
+tcp:::accept-established - yes
+
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh
new file mode 100644
index 0000000000..b6b9545d4e
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh
@@ -0,0 +1,172 @@
+#!/usr/bin/ksh
+#
+# 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
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# Test tcp:::state-change and tcp:::{send,receive} by connecting to
+# the remote ssh service and sending a test message. This should result
+# in a "Protocol mismatch" response and a close of the connection.
+# A number of state transition events along with tcp send and receive
+# events for the message should result.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. The lo0 interface missing or not up.
+# 3. The remote ssh service is not online.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test performs a TCP connection to the ssh service (port 22) and
+# checks that at least the following packet counts were traced:
+#
+# 4 x ip:::send (2 during the TCP handshake, the message, then a FIN)
+# 4 x tcp:::send (2 during the TCP handshake, the messages, then a FIN)
+# 3 x ip:::receive (1 during the TCP handshake, the response, then the FIN ACK)
+# 3 x tcp:::receive (1 during the TCP handshake, the response, then the FIN ACK)
+#
+# For this test to work, we are assuming that the TCP handshake and
+# TCP close will enter the IP code path and not use tcp fusion.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+getaddr=./get.ipv4remote.pl
+tcpport=22
+DIR=/var/tmp/dtest.$$
+
+if [[ ! -x $getaddr ]]; then
+ print -u2 "could not find or execute sub program: $getaddr"
+ exit 3
+fi
+$getaddr $tcpport | read source dest
+if (( $? != 0 )); then
+ exit 4
+fi
+
+mkdir $DIR
+cd $DIR
+
+cat > test.pl <<-EOPERL
+ use IO::Socket;
+ my \$s = IO::Socket::INET->new(
+ Proto => "tcp",
+ PeerAddr => "$dest",
+ PeerPort => $tcpport,
+ Timeout => 3);
+ die "Could not connect to host $dest port $tcpport" unless \$s;
+ print \$s "testing state machine transitions";
+ close \$s;
+EOPERL
+
+$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ ipsend = tcpsend = ipreceive = tcpreceive = 0;
+ connreq = connest = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ ipsend++;
+}
+
+tcp:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->tcp_dport == $tcpport/
+{
+ tcpsend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ ipreceive++;
+}
+
+tcp:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->tcp_sport == $tcpport/
+{
+ tcpreceive++;
+}
+
+tcp:::state-change
+{
+ state_event[args[3]->tcps_state]++;
+}
+
+tcp:::connect-request
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->tcp_dport == $tcpport/
+{
+ connreq++;
+}
+
+tcp:::connect-established
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->tcp_sport == $tcpport/
+{
+ connest++;
+}
+
+END
+{
+ printf("Minimum TCP events seen\n\n");
+ printf("ip:::send - %s\n", ipsend >= 4 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 3 ? "yes" : "no");
+ printf("tcp:::send - %s\n", tcpsend >= 4 ? "yes" : "no");
+ printf("tcp:::receive - %s\n", tcpreceive >= 3 ? "yes" : "no");
+ printf("tcp:::state-change to syn-sent - %s\n",
+ state_event[TCP_STATE_SYN_SENT] >=1 ? "yes" : "no");
+ printf("tcp:::state-change to established - %s\n",
+ state_event[TCP_STATE_ESTABLISHED] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to fin-wait-1 - %s\n",
+ state_event[TCP_STATE_FIN_WAIT_1] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to fin-wait-2 - %s\n",
+ state_event[TCP_STATE_FIN_WAIT_2] >= 1 ? "yes" : "no");
+ printf("tcp:::state-change to time-wait - %s\n",
+ state_event[TCP_STATE_TIME_WAIT] >= 1 ? "yes" : "no");
+ printf("tcp:::connect-request - %s\n",
+ connreq >=1 ? "yes" : "no");
+ printf("tcp:::connect-established - %s\n",
+ connest >=1 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/usr/bin/rm -rf $DIR
+
+exit $status
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh.out
new file mode 100644
index 0000000000..27388fba65
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh.out
@@ -0,0 +1,15 @@
+Minimum TCP events seen
+
+ip:::send - yes
+ip:::receive - yes
+tcp:::send - yes
+tcp:::receive - yes
+tcp:::state-change to syn-sent - yes
+tcp:::state-change to established - yes
+tcp:::state-change to fin-wait-1 - yes
+tcp:::state-change to close-wait - yes
+tcp:::state-change to fin-wait-2 - yes
+tcp:::state-change to time-wait - yes
+tcp:::connect-request - yes
+tcp:::connect-established - yes
+
diff --git a/usr/src/lib/libdtrace/Makefile.com b/usr/src/lib/libdtrace/Makefile.com
index 34c85f6102..5c90a02b98 100644
--- a/usr/src/lib/libdtrace/Makefile.com
+++ b/usr/src/lib/libdtrace/Makefile.com
@@ -19,8 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
#
#
@@ -87,6 +86,8 @@ DLIBSRCS += \
scsi.d \
srp.d \
sysevent.d \
+ tcp.d \
+ udp.d \
unistd.d
include ../../Makefile.lib
@@ -104,6 +105,8 @@ CLEANFILES += ../common/net.sed ../common/net.d
CLEANFILES += ../common/errno.d ../common/signal.d
CLEANFILES += ../common/dt_errtags.c ../common/dt_names.c
CLEANFILES += ../common/sysevent.sed ../common/sysevent.d
+CLEANFILES += ../common/tcp.sed ../common/tcp.d
+CLEANFILES += ../common/udp.sed ../common/udp.d
CLOBBERFILES += drti.o
@@ -182,6 +185,12 @@ pics/dt_lex.o pics/dt_grammar.o := CCVERBOSE =
../common/sysevent.d: ../common/sysevent.sed ../common/sysevent.d.in
sed -f ../common/sysevent.sed < ../common/sysevent.d.in > $@
+../common/tcp.d: ..//common/tcp.sed ../common/tcp.d.in
+ sed -f ../common/tcp.sed < ../common/tcp.d.in > $@
+
+../common/udp.d: ../common/udp.sed ../common/udp.d.in
+ sed -f ../common/udp.sed < ../common/udp.d.in > $@
+
pics/%.o: ../$(MACH)/%.c
$(COMPILE.c) -o $@ $<
$(POST_PROCESS_O)
diff --git a/usr/src/lib/libdtrace/common/dt_open.c b/usr/src/lib/libdtrace/common/dt_open.c
index da84511a78..2b9cd7c414 100644
--- a/usr/src/lib/libdtrace/common/dt_open.c
+++ b/usr/src/lib/libdtrace/common/dt_open.c
@@ -20,12 +20,9 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/modctl.h>
#include <sys/systeminfo.h>
@@ -105,8 +102,9 @@
#define DT_VERS_1_6 DT_VERSION_NUMBER(1, 6, 0)
#define DT_VERS_1_6_1 DT_VERSION_NUMBER(1, 6, 1)
#define DT_VERS_1_6_2 DT_VERSION_NUMBER(1, 6, 2)
-#define DT_VERS_LATEST DT_VERS_1_6_2
-#define DT_VERS_STRING "Sun D 1.6.2"
+#define DT_VERS_1_6_3 DT_VERSION_NUMBER(1, 6, 3)
+#define DT_VERS_LATEST DT_VERS_1_6_3
+#define DT_VERS_STRING "Sun D 1.6.3"
const dt_version_t _dtrace_versions[] = {
DT_VERS_1_0, /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
@@ -121,6 +119,7 @@ const dt_version_t _dtrace_versions[] = {
DT_VERS_1_6, /* D API 1.6 */
DT_VERS_1_6_1, /* D API 1.6.1 */
DT_VERS_1_6_2, /* D API 1.6.2 */
+ DT_VERS_1_6_3, /* D API 1.6.3 */
0
};
diff --git a/usr/src/lib/libdtrace/common/ip.d.in b/usr/src/lib/libdtrace/common/ip.d.in
index 3bd58e7c68..f1e6332529 100644
--- a/usr/src/lib/libdtrace/common/ip.d.in
+++ b/usr/src/lib/libdtrace/common/ip.d.in
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#pragma D depends_on module ip
@@ -98,12 +97,13 @@ typedef struct pktinfo {
} pktinfo_t;
/*
- * csinfo is where connection state info can be made available if
- * connection IDs become supported by the kernel in the future.
- * The cs_addr member is currently always NULL.
+ * csinfo is where connection state info is made available.
*/
typedef struct csinfo {
uintptr_t cs_addr;
+ uint64_t cs_cid;
+ pid_t cs_pid;
+ zoneid_t cs_zoneid;
} csinfo_t;
/*
@@ -181,6 +181,17 @@ typedef uintptr_t void_ip_t;
*/
typedef ill_t __dtrace_ipsr_ill_t;
+/*
+ * __dtrace_tcp_void_ip_t is used by the translator to take either the
+ * non-NULL void_ip_t * passed in or, if it is NULL, uses arg3 (tcp_t *)
+ * from the tcp:::send and tcp:::recieve probes to translate to an ipinfo_t.
+ * When no headers are available in the TCP fusion case for tcp:::send
+ * and tcp:::receive case, this allows us to present the consumer with header
+ * data based on the tcp_t * content in order to hide the implementation
+ * details of TCP fusion.
+ */
+typedef void * __dtrace_tcp_void_ip_t;
+
#pragma D binding "1.5" translator
translator pktinfo_t < mblk_t *M > {
pkt_addr = NULL;
@@ -191,6 +202,21 @@ translator csinfo_t < conn_t *C > {
cs_addr = NULL;
};
+#pragma D binding "1.6.3" translator
+translator csinfo_t < ip_xmit_attr_t *C > {
+ cs_addr = (uintptr_t)C;
+ cs_cid = C ? C->ixa_conn_id : NULL;
+ cs_pid = C ? C->ixa_cpid : -1;
+ cs_zoneid = C ?
+ (C->ixa_ipst == NULL || C->ixa_ipst->ips_netstack == NULL ||
+ C->ixa_ipst->ips_netstack->netstack_stackid ==
+ @GLOBAL_NETSTACKID@ ||
+ C->ixa_cred == NULL ||
+ C->ixa_cred->cr_zone == NULL ||
+ C->ixa_cred->cr_uid == -1 ?
+ C->ixa_zoneid : C->ixa_cred->cr_zone->zone_id) : -1;
+};
+
#pragma D binding "1.5" translator
translator ipinfo_t < ipha_t *I > {
ip_ver = I->ipha_version_and_hdr_length >> 4;
@@ -233,6 +259,50 @@ translator ifinfo_t < __dtrace_ipsr_ill_t *I > {
if_addr = (uintptr_t)I;
};
+/*
+ * Translate to an ipinfo_t * from either the non-NULL void_ip_t * passed in,
+ * or use arg3 (tcp_t *) to fabricate ip header info.
+ */
+#pragma D binding "1.6.3" translator
+translator ipinfo_t < __dtrace_tcp_void_ip_t *I > {
+ ip_ver = I != NULL ? *(uint8_t *)I >> 4 :
+ arg3 != NULL ? ((tcp_t *)arg3)->tcp_connp->conn_ipversion : 0;
+ ip_plength =
+ I != NULL && *(uint8_t *)I >> 4 == 4 ?
+ ntohs(((ipha_t *)I)->ipha_length) -
+ ((((ipha_t *)I)->ipha_version_and_hdr_length & 0xf) << 2) :
+ I != NULL && *(uint8_t *)I >> 4 == 6 ?
+ ntohs(((ip6_t *)I)->ip6_ctlun.ip6_un1.ip6_un1_plen) :
+ I != NULL ? 0 :
+ arg3 != NULL && probename == "send" ?
+ ((tcp_t *)arg3)->tcp_last_sent_len + @TCP_MIN_HEADER_LENGTH@ :
+ arg3 != NULL && probename == "receive" ?
+ ((tcp_t *)arg3)->tcp_last_recv_len + @TCP_MIN_HEADER_LENGTH@ :
+ 0;
+ ip_saddr =
+ I != NULL && *(uint8_t *)I >> 4 == 4 ?
+ inet_ntoa(&((ipha_t *)I)->ipha_src) :
+ I != NULL && *(uint8_t *)I >> 4 == 6 ?
+ inet_ntoa6(&((ip6_t *)I)->ip6_src) :
+ I != NULL ? "<unknown>" :
+ arg3 != NULL && probename == "send" ?
+ inet_ntoa6(&((tcp_t *)arg3)->tcp_connp->connua_v6addr.connua_laddr):
+ arg3 != NULL && probename == "receive" ?
+ inet_ntoa6(&((tcp_t *)arg3)->tcp_connp->connua_v6addr.connua_faddr):
+ "<unknown>";
+ ip_daddr =
+ I != NULL && *(uint8_t *)I >> 4 == 4 ?
+ inet_ntoa(&((ipha_t *)I)->ipha_dst) :
+ I != NULL && *(uint8_t *)I >> 4 == 6 ?
+ inet_ntoa6(&((ip6_t *)I)->ip6_dst) :
+ I != NULL ? "<unknown>" :
+ arg3 != NULL && probename == "send" ?
+ inet_ntoa6(&((tcp_t *)arg3)->tcp_connp->connua_v6addr.connua_faddr):
+ arg3 != NULL && probename == "receive" ?
+ inet_ntoa6(&((tcp_t *)arg3)->tcp_connp->connua_v6addr.connua_laddr):
+ "<unknown>";
+};
+
#pragma D binding "1.5" translator
translator ipv4info_t < ipha_t *I > {
ipv4_ver = I != NULL ? I->ipha_version_and_hdr_length >> 4 : 0;
diff --git a/usr/src/lib/libdtrace/common/ip.sed.in b/usr/src/lib/libdtrace/common/ip.sed.in
index 663de0344b..5d514e36b6 100644
--- a/usr/src/lib/libdtrace/common/ip.sed.in
+++ b/usr/src/lib/libdtrace/common/ip.sed.in
@@ -19,12 +19,9 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* This file is a sed script which is first preprocessed by cpp or cc -E to
* define a set of sed directives which replace #define tokens with their
@@ -33,9 +30,11 @@
* Refer to the rules in libdtrace/Makefile.com for more information.
*/
+#include <sys/netstack.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <inet/ip.h>
+#include <inet/tcp.h>
#define SED_REPLACE(x) s/#x/x/g
@@ -73,3 +72,7 @@ SED_REPLACE(IPPROTO_PIM)
SED_REPLACE(IPPROTO_SCTP)
SED_REPLACE(IPPROTO_RAW)
SED_REPLACE(IPPROTO_MAX)
+
+SED_REPLACE(TCP_MIN_HEADER_LENGTH)
+
+SED_REPLACE(GLOBAL_NETSTACKID)
diff --git a/usr/src/lib/libdtrace/common/tcp.d.in b/usr/src/lib/libdtrace/common/tcp.d.in
new file mode 100644
index 0000000000..2733e52699
--- /dev/null
+++ b/usr/src/lib/libdtrace/common/tcp.d.in
@@ -0,0 +1,269 @@
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#pragma D depends_on module unix
+#pragma D depends_on provider tcp
+
+inline int TH_FIN = @TH_FIN@;
+#pragma D binding "1.6.3" TH_FIN
+inline int TH_SYN = @TH_SYN@;
+#pragma D binding "1.6.3" TH_SYN
+inline int TH_RST = @TH_RST@;
+#pragma D binding "1.6.3" TH_RST
+inline int TH_PUSH = @TH_PUSH@;
+#pragma D binding "1.6.3" TH_PUSH
+inline int TH_ACK = @TH_ACK@;
+#pragma D binding "1.6.3" TH_ACK
+inline int TH_URG = @TH_URG@;
+#pragma D binding "1.6.3" TH_URG
+inline int TH_ECE = @TH_ECE@;
+#pragma D binding "1.6.3" TH_ECE
+inline int TH_CWR = @TH_CWR@;
+#pragma D binding "1.6.3" TH_CWR
+
+inline int32_t TCP_STATE_CLOSED = @TCPS_CLOSED@;
+#pragma D binding "1.6.3" TCP_STATE_CLOSED
+inline int32_t TCP_STATE_IDLE = @TCPS_IDLE@;
+#pragma D binding "1.6.3" TCP_STATE_IDLE
+inline int32_t TCP_STATE_BOUND = @TCPS_BOUND@;
+#pragma D binding "1.6.3" TCP_STATE_BOUND
+inline int32_t TCP_STATE_LISTEN = @TCPS_LISTEN@;
+#pragma D binding "1.6.3" TCP_STATE_LISTEN
+inline int32_t TCP_STATE_SYN_SENT = @TCPS_SYN_SENT@;
+#pragma D binding "1.6.3" TCP_STATE_SYN_SENT
+inline int32_t TCP_STATE_SYN_RECEIVED = @TCPS_SYN_RCVD@;
+#pragma D binding "1.6.3" TCP_STATE_SYN_RECEIVED
+inline int32_t TCP_STATE_ESTABLISHED = @TCPS_ESTABLISHED@;
+#pragma D binding "1.6.3" TCP_STATE_ESTABLISHED
+inline int32_t TCP_STATE_CLOSE_WAIT = @TCPS_CLOSE_WAIT@;
+#pragma D binding "1.6.3" TCP_STATE_CLOSE_WAIT
+inline int32_t TCP_STATE_FIN_WAIT_1 = @TCPS_FIN_WAIT_1@;
+#pragma D binding "1.6.3" TCP_STATE_FIN_WAIT_1
+inline int32_t TCP_STATE_CLOSING = @TCPS_CLOSING@;
+#pragma D binding "1.6.3" TCP_STATE_CLOSING
+inline int32_t TCP_STATE_LAST_ACK = @TCPS_LAST_ACK@;
+#pragma D binding "1.6.3" TCP_STATE_LAST_ACK
+inline int32_t TCP_STATE_FIN_WAIT_2 = @TCPS_FIN_WAIT_2@;
+#pragma D binding "1.6.3" TCP_STATE_FIN_WAIT_2
+inline int32_t TCP_STATE_TIME_WAIT = @TCPS_TIME_WAIT@;
+#pragma D binding "1.6.3" TCP_STATE_TIME_WAIT
+
+/*
+ * Convert a TCP state value to a string.
+ */
+inline string tcp_state_string[int32_t state] =
+ state == TCP_STATE_CLOSED ? "state-closed" :
+ state == TCP_STATE_IDLE ? "state-idle" :
+ state == TCP_STATE_BOUND ? "state-bound" :
+ state == TCP_STATE_LISTEN ? "state-listen" :
+ state == TCP_STATE_SYN_SENT ? "state-syn-sent" :
+ state == TCP_STATE_SYN_RECEIVED ? "state-syn-received" :
+ state == TCP_STATE_ESTABLISHED ? "state-established" :
+ state == TCP_STATE_CLOSE_WAIT ? "state-close-wait" :
+ state == TCP_STATE_FIN_WAIT_1 ? "state-fin-wait-1" :
+ state == TCP_STATE_CLOSING ? "state-closing" :
+ state == TCP_STATE_LAST_ACK ? "state-last-ack" :
+ state == TCP_STATE_FIN_WAIT_2 ? "state-fin-wait-2" :
+ state == TCP_STATE_TIME_WAIT ? "state-time-wait" :
+ "<unknown>";
+#pragma D binding "1.6.3" tcp_state_string
+
+/*
+ * 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 */
+ tcph_t *tcp_hdr; /* raw TCP header */
+} tcpinfo_t;
+
+/*
+ * 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_suna; /* sequence # sent but unacked */
+ 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 */
+ int32_t tcps_snd_ws; /* send window scaling */
+ uint32_t 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 */
+ 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 */
+} tcpsinfo_t;
+
+/*
+ * tcplsinfo provides the old tcp state for state changes.
+ */
+typedef struct tcplsinfo {
+ int32_t tcps_state; /* previous TCP state */
+} tcplsinfo_t;
+
+/*
+ * __dtrace_tcp_tcph_t is used by the tcpinfo_t * translator to take either
+ * the non-NULL tcph_t * passed in or, if it is NULL, uses arg3 (tcp_t *)
+ * from the tcp:::send and tcp:::recieve probes and translates the tcp_t *
+ * into the tcpinfo_t. When no headers are available - as is the case for
+ * TCP fusion tcp:::send and tcp:::receive - this allows us to present the
+ * consumer with header data based on tcp_t * content and hide TCP fusion
+ * implementation details.
+ */
+typedef tcph_t * __dtrace_tcp_tcph_t;
+
+#pragma D binding "1.6.3" translator
+translator tcpinfo_t < tcph_t *T > {
+ tcp_sport = ntohs(*(uint16_t *)T->th_lport);
+ tcp_dport = ntohs(*(uint16_t *)T->th_fport);
+ tcp_seq = ntohl(*(uint32_t *)T->th_seq);
+ tcp_ack = ntohl(*(uint32_t *)T->th_ack);
+ tcp_offset = (*(uint8_t *)T->th_offset_and_rsrvd & 0xf0) >> 2;
+ tcp_flags = *(uint8_t *)T->th_flags;
+ tcp_window = ntohs(*(uint16_t *)T->th_win);
+ tcp_checksum = ntohs(*(uint16_t *)T->th_sum);
+ tcp_urgent = ntohs(*(uint16_t *)T->th_urp);
+ tcp_hdr = T;
+};
+
+#pragma D binding "1.6.3" translator
+translator tcpinfo_t < __dtrace_tcp_tcph_t *T > {
+ tcp_sport =
+ T != NULL ? ntohs(*(uint16_t *)((tcph_t *)T)->th_lport) :
+ arg3 != NULL && probename == "send" ?
+ ntohs(((tcp_t *)arg3)->tcp_connp->u_port.connu_ports.connu_lport) :
+ arg3 != NULL && probename == "receive" ?
+ ntohs(((tcp_t *)arg3)->tcp_connp->u_port.connu_ports.connu_fport) :
+ 0;
+ tcp_dport =
+ T != NULL ? ntohs(*(uint16_t *)((tcph_t *)T)->th_fport) :
+ arg3 != NULL && probename == "send" ?
+ ntohs(((tcp_t *)arg3)->tcp_connp->u_port.connu_ports.connu_fport) :
+ arg3 != NULL && probename == "receive" ?
+ ntohs(((tcp_t *)arg3)->tcp_connp->u_port.connu_ports.connu_lport) :
+ 0;
+ tcp_seq =
+ T != NULL ? ntohl(*(uint32_t *)((tcph_t *)T)->th_seq) :
+ arg3 != NULL && probename == "send" ?
+ ((tcp_t *)arg3)->tcp_snxt - ((tcp_t *)arg3)->tcp_last_sent_len :
+ arg3 != NULL && probename == "receive" ?
+ ((tcp_t *)arg3)->tcp_rnxt - ((tcp_t *)arg3)->tcp_last_recv_len :
+ 0;
+ tcp_ack =
+ T != NULL ? ntohl(*(uint32_t *)((tcph_t *)T)->th_ack) :
+ arg3 != NULL && probename == "send" ?
+ ((tcp_t *)arg3)->tcp_rnxt :
+ arg3 != NULL && probename == "receive" ?
+ ((tcp_t *)arg3)->tcp_snxt :
+ 0;
+ tcp_offset = T != NULL ?
+ (*(uint8_t *)((tcph_t *)T)->th_offset_and_rsrvd & 0xf0) >> 2 :
+ @TCP_MIN_HEADER_LENGTH@;
+ tcp_flags = T != NULL ? *(uint8_t *)((tcph_t *)T)->th_flags : TH_ACK;
+ tcp_window = T != NULL ? ntohs(*(uint16_t *)((tcph_t *)T)->th_win) :
+ arg3 != NULL ? ((tcp_t *)arg3)->tcp_swnd : 0;
+ tcp_checksum = T != NULL ? ntohs(*(uint16_t *)((tcph_t *)T)->th_sum) :
+ 0;
+ tcp_urgent = T != NULL ? ntohs(*(uint16_t *)((tcph_t *)T)->th_urp) : 0;
+ tcp_hdr = NULL;
+};
+
+#pragma D binding "1.6.3" translator
+translator tcpsinfo_t < tcp_t *T > {
+ tcps_addr = (uintptr_t)T;
+ /*
+ * The following two members should just use tcp_t->tcp_loopback
+ * and tcp_t->tcp_active_open, however these are bit fields and
+ * can't be used until CR 6876830 is fixed. Meanwhile we source
+ * them a different way.
+ */
+ tcps_local = T ? T->tcp_ipha ?
+ T->tcp_ipha->ipha_src == T->tcp_ipha->ipha_dst : 1 : 0;
+ tcps_active = T ? !T->tcp_saved_listener : 0;
+ tcps_lport = T ?
+ ntohs(T->tcp_connp->u_port.connu_ports.connu_lport) : 0;
+ tcps_rport = T ?
+ ntohs(T->tcp_connp->u_port.connu_ports.connu_fport) : 0;
+ tcps_laddr = T ?
+ inet_ntoa6(&T->tcp_connp->connua_v6addr.connua_laddr) : "<unknown>";
+ tcps_raddr = T ?
+ inet_ntoa6(&T->tcp_connp->connua_v6addr.connua_faddr) : "<unknown>";
+ tcps_state = T ? T->tcp_state : TCP_STATE_CLOSED;
+ tcps_iss = T ? T->tcp_iss : 0;
+ tcps_suna = T ? T->tcp_suna : 0;
+ tcps_snxt = T ? T->tcp_snxt : 0;
+ tcps_rack = T ? T->tcp_rack : 0;
+ tcps_rnxt = T ? T->tcp_rnxt : 0;
+ tcps_swnd = T ? T->tcp_swnd : 0;
+ tcps_snd_ws = T ? T->tcp_snd_ws : 0;
+ tcps_rwnd = T ? T->tcp_rwnd : 0;
+ tcps_rcv_ws = T ? T->tcp_rcv_ws : 0;
+ tcps_cwnd = T ? T->tcp_cwnd : 0;
+ tcps_cwnd_ssthresh = T ? T->tcp_cwnd_ssthresh : 0;
+ tcps_sack_fack = T ? T->tcp_sack_info.tcp_fack : 0;
+ tcps_sack_snxt = T ? T->tcp_sack_info.tcp_sack_snxt : 0;
+ tcps_rto = T ? T->tcp_rto : 0;
+ tcps_mss = T ? T->tcp_mss : 0;
+ /*
+ * Determine if send is a retransmission by comparing the seq # to
+ * tcp_rexmit_nxt/tcp_rexmit_max - if the value is >= rexmit_nxt and
+ * < rexmit_max, this is a retransmission. Cannot use tcp_rexmit
+ * bitfield value due to CR 6876830.
+ */
+ tcps_retransmit = T && probename == "send" && arg4 != NULL &&
+ ntohl(*(uint32_t *)((tcph_t *)arg4)->th_seq) >= T->tcp_rexmit_nxt &&
+ ntohl(*(uint32_t *)((tcph_t *)arg4)->th_seq) < T->tcp_rexmit_max ?
+ 1 : 0;
+};
+
+/*
+ * Note: although we specify that the old state argument used as the
+ * input to the tcplsinfo_t translator is an int32_t, it reaches us as an
+ * int64_t (since it is a probe argument) so explicitly cast it back to
+ * interpret the negatively-valued states correctly.
+ */
+#pragma D binding "1.6.3" translator
+translator tcplsinfo_t < int64_t I > {
+ tcps_state = (int32_t) I;
+};
diff --git a/usr/src/lib/libdtrace/common/tcp.sed.in b/usr/src/lib/libdtrace/common/tcp.sed.in
new file mode 100644
index 0000000000..230264be37
--- /dev/null
+++ b/usr/src/lib/libdtrace/common/tcp.sed.in
@@ -0,0 +1,53 @@
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <inet/tcp.h>
+#include <sys/netstack.h>
+
+#define SED_REPLACE(x) s/#x/x/g
+
+SED_REPLACE(TH_FIN)
+SED_REPLACE(TH_SYN)
+SED_REPLACE(TH_RST)
+SED_REPLACE(TH_PUSH)
+SED_REPLACE(TH_ACK)
+SED_REPLACE(TH_URG)
+SED_REPLACE(TH_ECE)
+SED_REPLACE(TH_CWR)
+
+SED_REPLACE(TCPS_CLOSED)
+SED_REPLACE(TCPS_IDLE)
+SED_REPLACE(TCPS_BOUND)
+SED_REPLACE(TCPS_LISTEN)
+SED_REPLACE(TCPS_SYN_SENT)
+SED_REPLACE(TCPS_SYN_RCVD)
+SED_REPLACE(TCPS_ESTABLISHED)
+SED_REPLACE(TCPS_CLOSE_WAIT)
+SED_REPLACE(TCPS_FIN_WAIT_1)
+SED_REPLACE(TCPS_CLOSING)
+SED_REPLACE(TCPS_LAST_ACK)
+SED_REPLACE(TCPS_FIN_WAIT_2)
+SED_REPLACE(TCPS_TIME_WAIT)
+
+SED_REPLACE(TCP_MIN_HEADER_LENGTH)
diff --git a/usr/src/lib/libdtrace/common/udp.d.in b/usr/src/lib/libdtrace/common/udp.d.in
new file mode 100644
index 0000000000..c2159016f3
--- /dev/null
+++ b/usr/src/lib/libdtrace/common/udp.d.in
@@ -0,0 +1,73 @@
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#pragma D depends_on module unix
+#pragma D depends_on provider udp
+
+inline int UDPH_SIZE = @UDPH_SIZE@;
+#pragma D binding "1.6.3" UDPH_SIZE
+
+/*
+ * udpinfo is the UDP header fields.
+ */
+typedef struct udpinfo {
+ uint16_t udp_sport; /* source port */
+ uint16_t udp_dport; /* destination port */
+ uint16_t udp_length; /* total length */
+ uint16_t udp_checksum; /* headers + data checksum */
+ udpha_t *udp_hdr; /* raw UDP header */
+} udpinfo_t;
+
+/*
+ * udpsinfo contains stable UDP details from udp_t.
+ */
+typedef struct udpsinfo {
+ uintptr_t udps_addr;
+ uint16_t udps_lport; /* local port */
+ uint16_t udps_rport; /* remote port */
+ string udps_laddr; /* local address, as a string */
+ string udps_raddr; /* remote address, as a string */
+} udpsinfo_t;
+
+#pragma D binding "1.6.3" translator
+translator udpinfo_t < udpha_t *U > {
+ udp_sport = ntohs(U->uha_src_port);
+ udp_dport = ntohs(U->uha_dst_port);
+ udp_length = ntohs(U->uha_length);
+ udp_checksum = ntohs(U->uha_checksum);
+ udp_hdr = U;
+};
+
+#pragma D binding "1.6.3" translator
+translator udpsinfo_t < udp_t *U > {
+ udps_addr = (uintptr_t)U;
+ udps_lport = U ?
+ ntohs(U->udp_connp->u_port.connu_ports.connu_lport) : 0;
+ udps_rport = U ?
+ ntohs(U->udp_connp->u_port.connu_ports.connu_fport) : 0;
+ udps_laddr = U ?
+ inet_ntoa6(&U->udp_connp->connua_v6addr.connua_laddr) : "<unknown>";
+ udps_raddr = U ?
+ inet_ntoa6(&U->udp_connp->connua_v6addr.connua_faddr) : "<unknown>";
+};
diff --git a/usr/src/lib/libdtrace/common/udp.sed.in b/usr/src/lib/libdtrace/common/udp.sed.in
new file mode 100644
index 0000000000..9c23a96a18
--- /dev/null
+++ b/usr/src/lib/libdtrace/common/udp.sed.in
@@ -0,0 +1,29 @@
+/*
+ * 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
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <inet/ip.h>
+
+#define SED_REPLACE(x) s/#x/x/g
+
+SED_REPLACE(UDPH_SIZE)
diff --git a/usr/src/pkg/manifests/developer-dtrace.mf b/usr/src/pkg/manifests/developer-dtrace.mf
index 305aa619f0..ac7ed967b8 100644
--- a/usr/src/pkg/manifests/developer-dtrace.mf
+++ b/usr/src/pkg/manifests/developer-dtrace.mf
@@ -20,8 +20,7 @@
#
#
-# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
#
set name=pkg.fmri value=pkg:/developer/dtrace@$(PKGVERS)
@@ -125,13 +124,27 @@ file path=usr/demo/dtrace/spec.d
file path=usr/demo/dtrace/specopen.d
file path=usr/demo/dtrace/ssd.d
file path=usr/demo/dtrace/syscall.d
+file path=usr/demo/dtrace/tcp1stbyte.d
+file path=usr/demo/dtrace/tcpbytes.d
+file path=usr/demo/dtrace/tcpbytesstat.d
+file path=usr/demo/dtrace/tcpconnlat.d
+file path=usr/demo/dtrace/tcpio.d
+file path=usr/demo/dtrace/tcpioflags.d
file path=usr/demo/dtrace/tcprst.d
+file path=usr/demo/dtrace/tcpsnoop.d
+file path=usr/demo/dtrace/tcpstate.d
+file path=usr/demo/dtrace/tcptop.d
file path=usr/demo/dtrace/tick.d
file path=usr/demo/dtrace/ticktime.d
file path=usr/demo/dtrace/time.d
file path=usr/demo/dtrace/tracewrite.d
file path=usr/demo/dtrace/trunc.d
file path=usr/demo/dtrace/trussrw.d
+file path=usr/demo/dtrace/udpbytes.d
+file path=usr/demo/dtrace/udpbytesstat.d
+file path=usr/demo/dtrace/udpio.d
+file path=usr/demo/dtrace/udpsnoop.d
+file path=usr/demo/dtrace/udptop.d
file path=usr/demo/dtrace/userfunc.d
file path=usr/demo/dtrace/whatfor.d
file path=usr/demo/dtrace/whatlock.d
@@ -180,6 +193,8 @@ file path=usr/lib/dtrace/scsi.d
file path=usr/lib/dtrace/signal.d
file path=usr/lib/dtrace/srp.d
file path=usr/lib/dtrace/sysevent.d
+file path=usr/lib/dtrace/tcp.d
+file path=usr/lib/dtrace/udp.d
file path=usr/lib/dtrace/unistd.d
file path=usr/lib/libdtrace.so.1
file path=usr/lib/libdtrace_jni.so.1
diff --git a/usr/src/pkg/manifests/system-dtrace-tests.mf b/usr/src/pkg/manifests/system-dtrace-tests.mf
index 2c834f906b..4c8cb58a13 100644
--- a/usr/src/pkg/manifests/system-dtrace-tests.mf
+++ b/usr/src/pkg/manifests/system-dtrace-tests.mf
@@ -20,8 +20,7 @@
#
#
-# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
#
set name=pkg.fmri value=pkg:/system/dtrace/tests@$(PKGVERS)
@@ -835,6 +834,10 @@ file path=opt/SUNWdtrt/tst/common/ip/tst.ipv6localicmp.ksh mode=0444
file path=opt/SUNWdtrt/tst/common/ip/tst.ipv6localicmp.ksh.out mode=0444
file path=opt/SUNWdtrt/tst/common/ip/tst.ipv6remoteicmp.ksh mode=0444
file path=opt/SUNWdtrt/tst/common/ip/tst.ipv6remoteicmp.ksh.out mode=0444
+file path=opt/SUNWdtrt/tst/common/ip/tst.localtcpstate.ksh mode=0444
+file path=opt/SUNWdtrt/tst/common/ip/tst.localtcpstate.ksh.out mode=0444
+file path=opt/SUNWdtrt/tst/common/ip/tst.remotetcpstate.ksh mode=0444
+file path=opt/SUNWdtrt/tst/common/ip/tst.remotetcpstate.ksh.out mode=0444
file path=opt/SUNWdtrt/tst/common/java_api/test.jar
file path=opt/SUNWdtrt/tst/common/java_api/tst.Abort.ksh mode=0444
file path=opt/SUNWdtrt/tst/common/java_api/tst.Abort.ksh.out mode=0444
diff --git a/usr/src/uts/common/dtrace/sdt_subr.c b/usr/src/uts/common/dtrace/sdt_subr.c
index a89403ea75..242185071b 100644
--- a/usr/src/uts/common/dtrace/sdt_subr.c
+++ b/usr/src/uts/common/dtrace/sdt_subr.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/sdt_impl.h>
@@ -106,6 +105,8 @@ sdt_provider_t sdt_providers[] = {
{ "proc", "__proc_", &stab_attr, 0 },
{ "io", "__io_", &stab_attr, 0 },
{ "ip", "__ip_", &stab_attr, 0 },
+ { "tcp", "__tcp_", &stab_attr, 0 },
+ { "udp", "__udp_", &stab_attr, 0 },
{ "mib", "__mib_", &stab_attr, 0 },
{ "fsinfo", "__fsinfo_", &fsinfo_attr, 0 },
{ "iscsi", "__iscsi_", &iscsi_attr, 0 },
@@ -888,6 +889,60 @@ sdt_argdesc_t sdt_args[] = {
{ "ip", "receive", 5, 5, "ip6_t *", "ipv6info_t *" },
{ "ip", "receive", 6, 6, "int" }, /* used by __dtrace_ipsr_ill_t */
+ { "tcp", "connect-established", 0, 0, "mblk_t *", "pktinfo_t *" },
+ { "tcp", "connect-established", 1, 1, "ip_xmit_attr_t *",
+ "csinfo_t *" },
+ { "tcp", "connect-established", 2, 2, "void_ip_t *", "ipinfo_t *" },
+ { "tcp", "connect-established", 3, 3, "tcp_t *", "tcpsinfo_t *" },
+ { "tcp", "connect-established", 4, 4, "tcph_t *", "tcpinfo_t *" },
+ { "tcp", "connect-refused", 0, 0, "mblk_t *", "pktinfo_t *" },
+ { "tcp", "connect-refused", 1, 1, "ip_xmit_attr_t *", "csinfo_t *" },
+ { "tcp", "connect-refused", 2, 2, "void_ip_t *", "ipinfo_t *" },
+ { "tcp", "connect-refused", 3, 3, "tcp_t *", "tcpsinfo_t *" },
+ { "tcp", "connect-refused", 4, 4, "tcph_t *", "tcpinfo_t *" },
+ { "tcp", "connect-request", 0, 0, "mblk_t *", "pktinfo_t *" },
+ { "tcp", "connect-request", 1, 1, "ip_xmit_attr_t *", "csinfo_t *" },
+ { "tcp", "connect-request", 2, 2, "void_ip_t *", "ipinfo_t *" },
+ { "tcp", "connect-request", 3, 3, "tcp_t *", "tcpsinfo_t *" },
+ { "tcp", "connect-request", 4, 4, "tcph_t *", "tcpinfo_t *" },
+ { "tcp", "accept-established", 0, 0, "mblk_t *", "pktinfo_t *" },
+ { "tcp", "accept-established", 1, 1, "ip_xmit_attr_t *", "csinfo_t *" },
+ { "tcp", "accept-established", 2, 2, "void_ip_t *", "ipinfo_t *" },
+ { "tcp", "accept-established", 3, 3, "tcp_t *", "tcpsinfo_t *" },
+ { "tcp", "accept-established", 4, 4, "tcph_t *", "tcpinfo_t *" },
+ { "tcp", "accept-refused", 0, 0, "mblk_t *", "pktinfo_t *" },
+ { "tcp", "accept-refused", 1, 1, "ip_xmit_attr_t *", "csinfo_t *" },
+ { "tcp", "accept-refused", 2, 2, "void_ip_t *", "ipinfo_t *" },
+ { "tcp", "accept-refused", 3, 3, "tcp_t *", "tcpsinfo_t *" },
+ { "tcp", "accept-refused", 4, 4, "tcph_t *", "tcpinfo_t *" },
+ { "tcp", "state-change", 0, 0, "void", "void" },
+ { "tcp", "state-change", 1, 1, "ip_xmit_attr_t *", "csinfo_t *" },
+ { "tcp", "state-change", 2, 2, "void", "void" },
+ { "tcp", "state-change", 3, 3, "tcp_t *", "tcpsinfo_t *" },
+ { "tcp", "state-change", 4, 4, "void", "void" },
+ { "tcp", "state-change", 5, 5, "int32_t", "tcplsinfo_t *" },
+ { "tcp", "send", 0, 0, "mblk_t *", "pktinfo_t *" },
+ { "tcp", "send", 1, 1, "ip_xmit_attr_t *", "csinfo_t *" },
+ { "tcp", "send", 2, 2, "__dtrace_tcp_void_ip_t *", "ipinfo_t *" },
+ { "tcp", "send", 3, 3, "tcp_t *", "tcpsinfo_t *" },
+ { "tcp", "send", 4, 4, "__dtrace_tcp_tcph_t *", "tcpinfo_t *" },
+ { "tcp", "receive", 0, 0, "mblk_t *", "pktinfo_t *" },
+ { "tcp", "receive", 1, 1, "ip_xmit_attr_t *", "csinfo_t *" },
+ { "tcp", "receive", 2, 2, "__dtrace_tcp_void_ip_t *", "ipinfo_t *" },
+ { "tcp", "receive", 3, 3, "tcp_t *", "tcpsinfo_t *" },
+ { "tcp", "receive", 4, 4, "__dtrace_tcp_tcph_t *", "tcpinfo_t *" },
+
+ { "udp", "send", 0, 0, "mblk_t *", "pktinfo_t *" },
+ { "udp", "send", 1, 1, "ip_xmit_attr_t *", "csinfo_t *" },
+ { "udp", "send", 2, 2, "void_ip_t *", "ipinfo_t *" },
+ { "udp", "send", 3, 3, "udp_t *", "udpsinfo_t *" },
+ { "udp", "send", 4, 4, "udpha_t *", "udpinfo_t *" },
+ { "udp", "receive", 0, 0, "mblk_t *", "pktinfo_t *" },
+ { "udp", "receive", 1, 1, "ip_xmit_attr_t *", "csinfo_t *" },
+ { "udp", "receive", 2, 2, "void_ip_t *", "ipinfo_t *" },
+ { "udp", "receive", 3, 3, "udp_t *", "udpsinfo_t *" },
+ { "udp", "receive", 4, 4, "udpha_t *", "udpinfo_t *" },
+
{ "sysevent", "post", 0, 0, "evch_bind_t *", "syseventchaninfo_t *" },
{ "sysevent", "post", 1, 1, "sysevent_impl_t *", "syseventinfo_t *" },
diff --git a/usr/src/uts/common/inet/ip.h b/usr/src/uts/common/inet/ip.h
index d5eeff5657..3199a40bcb 100644
--- a/usr/src/uts/common/inet/ip.h
+++ b/usr/src/uts/common/inet/ip.h
@@ -2106,6 +2106,7 @@ struct ip_xmit_attr_s {
uint32_t ixa_ident; /* For IPv6 fragment header */
+ uint64_t ixa_conn_id; /* Used by DTrace */
/*
* Cached LSO information.
*/
diff --git a/usr/src/uts/common/inet/ip/ip_attr.c b/usr/src/uts/common/inet/ip/ip_attr.c
index 6ffd5bbb99..342798b071 100644
--- a/usr/src/uts/common/inet/ip/ip_attr.c
+++ b/usr/src/uts/common/inet/ip/ip_attr.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1990 Mentat Inc. */
@@ -140,6 +139,7 @@ typedef struct ixamblk_s {
uint32_t ixm_ident; /* For IPv6 fragment header */
uint32_t ixm_xmit_hint;
+ uint64_t ixm_conn_id; /* Used by DTrace */
cred_t *ixm_cred; /* For getpeerucred - refhold if set */
pid_t ixm_cpid; /* For getpeerucred */
@@ -265,6 +265,7 @@ ip_xmit_attr_to_mblk(ip_xmit_attr_t *ixa)
crhold(ixa->ixa_cred);
}
ixm->ixm_cpid = ixa->ixa_cpid;
+ ixm->ixm_conn_id = ixa->ixa_conn_id;
if (ixa->ixa_flags & IXAF_IPSEC_SECURE) {
if (ixa->ixa_ipsec_ah_sa != NULL) {
@@ -404,6 +405,7 @@ ip_xmit_attr_from_mblk(mblk_t *ixamp, ip_xmit_attr_t *ixa)
ixm->ixm_cred = NULL;
}
ixa->ixa_cpid = ixm->ixm_cpid;
+ ixa->ixa_conn_id = ixm->ixm_conn_id;
ixa->ixa_ipsec_ah_sa = ixm->ixm_ipsec_ah_sa;
ixa->ixa_ipsec_esp_sa = ixm->ixm_ipsec_esp_sa;
@@ -828,6 +830,7 @@ conn_replace_ixa(conn_t *connp, ip_xmit_attr_t *ixa)
oldixa = connp->conn_ixa;
IXA_REFHOLD(ixa);
+ ixa->ixa_conn_id = oldixa->ixa_conn_id;
connp->conn_ixa = ixa;
return (oldixa);
}
diff --git a/usr/src/uts/common/inet/ip/ipclassifier.c b/usr/src/uts/common/inet/ip/ipclassifier.c
index f2ca88e5a1..3d4cbd52ae 100644
--- a/usr/src/uts/common/inet/ip/ipclassifier.c
+++ b/usr/src/uts/common/inet/ip/ipclassifier.c
@@ -586,6 +586,7 @@ ipcl_conn_create(uint32_t type, int sleep, netstack_t *ns)
netstack_hold(ns);
connp->conn_netstack = ns;
connp->conn_ixa->ixa_ipst = ns->netstack_ip;
+ connp->conn_ixa->ixa_conn_id = (long)connp;
ipcl_globalhash_insert(connp);
return (connp);
@@ -621,6 +622,7 @@ ipcl_conn_create(uint32_t type, int sleep, netstack_t *ns)
netstack_hold(ns);
connp->conn_netstack = ns;
connp->conn_ixa->ixa_ipst = ns->netstack_ip;
+ connp->conn_ixa->ixa_conn_id = (long)connp;
ipcl_globalhash_insert(connp);
return (connp);
}
diff --git a/usr/src/uts/common/inet/tcp.h b/usr/src/uts/common/inet/tcp.h
index befce69047..23dbb1a687 100644
--- a/usr/src/uts/common/inet/tcp.h
+++ b/usr/src/uts/common/inet/tcp.h
@@ -348,6 +348,7 @@ typedef struct tcp_s {
tcpha_t *tcp_tcpha; /* TCP header in conn_ht_iphc */
uint16_t tcp_last_sent_len; /* Record length for nagle */
+ uint16_t tcp_last_recv_len; /* Used by DTrace */
uint16_t tcp_dupack_cnt; /* # of consequtive duplicate acks */
kmutex_t *tcp_acceptor_lockp; /* Ptr to tf_lock */
diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c
index f0a86e257c..51ee3be794 100644
--- a/usr/src/uts/common/inet/tcp/tcp.c
+++ b/usr/src/uts/common/inet/tcp/tcp.c
@@ -872,7 +872,13 @@ tcp_clean_death(tcp_t *tcp, int err)
if (!tcp->tcp_tconnind_started) {
CONN_DEC_REF(connp);
} else {
+ int32_t oldstate = tcp->tcp_state;
+
tcp->tcp_state = TCPS_BOUND;
+ DTRACE_TCP6(state__change, void, NULL,
+ ip_xmit_attr_t *, connp->conn_ixa,
+ void, NULL, tcp_t *, tcp, void, NULL,
+ int32_t, oldstate);
}
} else {
tcp_close_detached(tcp);
@@ -1212,6 +1218,7 @@ tcp_closei_local(tcp_t *tcp)
{
conn_t *connp = tcp->tcp_connp;
tcp_stack_t *tcps = tcp->tcp_tcps;
+ int32_t oldstate;
if (!TCP_IS_SOCKET(tcp))
tcp_acceptor_hash_remove(tcp);
@@ -1301,6 +1308,12 @@ tcp_closei_local(tcp_t *tcp)
(void) tcp_time_wait_remove(tcp, NULL);
CL_INET_DISCONNECT(connp);
ipcl_hash_remove(connp);
+ oldstate = tcp->tcp_state;
+ tcp->tcp_state = TCPS_CLOSED;
+ /* Need to probe before ixa_cleanup() is called */
+ DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
+ connp->conn_ixa, void, NULL, tcp_t *, tcp, void, NULL,
+ int32_t, oldstate);
ixa_cleanup(connp->conn_ixa);
/*
@@ -1313,7 +1326,6 @@ tcp_closei_local(tcp_t *tcp)
ASSERT(tcp->tcp_time_wait_next == NULL);
ASSERT(tcp->tcp_time_wait_prev == NULL);
ASSERT(tcp->tcp_time_wait_expire == 0);
- tcp->tcp_state = TCPS_CLOSED;
/* Release any SSL context */
if (tcp->tcp_kssl_ent != NULL) {
@@ -1763,9 +1775,15 @@ tcp_disconnect_common(tcp_t *tcp, t_scalar_t seqnum)
}
if (tcp->tcp_conn_req_max && lconnp == NULL) {
tcp->tcp_state = TCPS_LISTEN;
+ DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
+ connp->conn_ixa, void, NULL, tcp_t *, tcp, void,
+ NULL, int32_t, old_state);
} else if (old_state > TCPS_BOUND) {
tcp->tcp_conn_req_max = 0;
tcp->tcp_state = TCPS_BOUND;
+ DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
+ connp->conn_ixa, void, NULL, tcp_t *, tcp, void,
+ NULL, int32_t, old_state);
/*
* If this end point is not going to become a listener,
@@ -1854,6 +1872,7 @@ tcp_reinit(tcp_t *tcp)
mblk_t *mp;
tcp_stack_t *tcps = tcp->tcp_tcps;
conn_t *connp = tcp->tcp_connp;
+ int32_t oldstate;
/* tcp_reinit should never be called for detached tcp_t's */
ASSERT(tcp->tcp_listener == NULL);
@@ -1958,6 +1977,7 @@ tcp_reinit(tcp_t *tcp)
connp->conn_laddr_v6 = connp->conn_bound_addr_v6;
connp->conn_saddr_v6 = connp->conn_bound_addr_v6;
+ oldstate = tcp->tcp_state;
if (tcp->tcp_conn_req_max != 0) {
/*
@@ -2003,6 +2023,10 @@ tcp_reinit(tcp_t *tcp)
*/
tcp_init_values(tcp);
+ DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
+ connp->conn_ixa, void, NULL, tcp_t *, tcp, void, NULL,
+ int32_t, oldstate);
+
ASSERT(tcp->tcp_ptpbhn != NULL);
tcp->tcp_rwnd = connp->conn_rcvbuf;
tcp->tcp_mss = connp->conn_ipversion != IPV4_VERSION ?
@@ -2648,6 +2672,7 @@ tcp_create_common(cred_t *credp, boolean_t isv6, boolean_t issocket,
tcps->tcps_wroff_xtra;
SOCK_CONNID_INIT(tcp->tcp_connid);
+ /* DTrace ignores this - it isn't a tcp:::state-change */
tcp->tcp_state = TCPS_IDLE;
tcp_init_values(tcp);
return (connp);
@@ -2993,6 +3018,7 @@ int
tcp_do_unbind(conn_t *connp)
{
tcp_t *tcp = connp->conn_tcp;
+ int32_t oldstate;
switch (tcp->tcp_state) {
case TCPS_BOUND:
@@ -3018,7 +3044,11 @@ tcp_do_unbind(conn_t *connp)
connp->conn_laddr_v6 = ipv6_all_zeros;
connp->conn_saddr_v6 = ipv6_all_zeros;
tcp_bind_hash_remove(tcp);
+ oldstate = tcp->tcp_state;
tcp->tcp_state = TCPS_IDLE;
+ DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
+ connp->conn_ixa, void, NULL, tcp_t *, tcp, void, NULL,
+ int32_t, oldstate);
ip_unbind(connp);
bzero(&connp->conn_ports, sizeof (connp->conn_ports));
@@ -4574,6 +4604,11 @@ tcp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
if (tcps->tcps_ecn_permitted == 2)
tcp->tcp_ecn_ok = B_TRUE;
+ /* Trace change from BOUND -> SYN_SENT here */
+ DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
+ connp->conn_ixa, void, NULL, tcp_t *, tcp, void, NULL,
+ int32_t, TCPS_BOUND);
+
TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
syn_mp = tcp_xmit_mp(tcp, NULL, 0, NULL, NULL,
tcp->tcp_iss, B_FALSE, NULL, B_FALSE);
@@ -4584,6 +4619,15 @@ tcp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
* this thread issues a "connected" up call.
*/
SOCK_CONNID_BUMP(tcp->tcp_connid);
+ /*
+ * DTrace sending the first SYN as a
+ * tcp:::connect-request event.
+ */
+ DTRACE_TCP5(connect__request, mblk_t *, NULL,
+ ip_xmit_attr_t *, connp->conn_ixa,
+ void_ip_t *, syn_mp->b_rptr, tcp_t *, tcp,
+ tcph_t *,
+ &syn_mp->b_rptr[connp->conn_ixa->ixa_ip_hdr_length]);
tcp_send_data(tcp, syn_mp);
}
@@ -4607,6 +4651,7 @@ tcp_do_listen(conn_t *connp, struct sockaddr *sa, socklen_t len,
tcp_t *tcp = connp->conn_tcp;
int error = 0;
tcp_stack_t *tcps = tcp->tcp_tcps;
+ int32_t oldstate;
/* All Solaris components should pass a cred for this operation. */
ASSERT(cr != NULL);
@@ -4674,6 +4719,9 @@ do_listen:
*/
if (tcp->tcp_state != TCPS_LISTEN) {
tcp->tcp_state = TCPS_LISTEN;
+ DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
+ connp->conn_ixa, void, NULL, tcp_t *, tcp,
+ void, NULL, int32_t, TCPS_BOUND);
/* Initialize the chain. Don't need the eager_lock */
tcp->tcp_eager_next_q0 = tcp->tcp_eager_prev_q0 = tcp;
tcp->tcp_eager_next_drop_q0 = tcp;
@@ -4699,7 +4747,11 @@ do_listen:
error = ip_laddr_fanout_insert(connp);
if (error != 0) {
/* Undo the bind - release the port number */
+ oldstate = tcp->tcp_state;
tcp->tcp_state = TCPS_IDLE;
+ DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
+ connp->conn_ixa, void, NULL, tcp_t *, tcp, void, NULL,
+ int32_t, oldstate);
connp->conn_bound_addr_v6 = ipv6_all_zeros;
connp->conn_laddr_v6 = ipv6_all_zeros;
diff --git a/usr/src/uts/common/inet/tcp/tcp_bind.c b/usr/src/uts/common/inet/tcp/tcp_bind.c
index 5d91fe7a7f..058b1960dc 100644
--- a/usr/src/uts/common/inet/tcp/tcp_bind.c
+++ b/usr/src/uts/common/inet/tcp/tcp_bind.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/types.h>
@@ -880,6 +879,11 @@ tcp_bindi(tcp_t *tcp, in_port_t port, const in6_addr_t *laddr,
* number.
*/
tcp->tcp_state = TCPS_BOUND;
+ DTRACE_TCP6(state__change, void, NULL,
+ ip_xmit_attr_t *, connp->conn_ixa,
+ void, NULL, tcp_t *, tcp, void, NULL,
+ int32_t, TCPS_IDLE);
+
connp->conn_lport = htons(port);
ASSERT(&tcps->tcps_bind_fanout[TCP_BIND_HASH(
diff --git a/usr/src/uts/common/inet/tcp/tcp_fusion.c b/usr/src/uts/common/inet/tcp/tcp_fusion.c
index aad533de2b..c8f50cee8f 100644
--- a/usr/src/uts/common/inet/tcp/tcp_fusion.c
+++ b/usr/src/uts/common/inet/tcp/tcp_fusion.c
@@ -642,6 +642,7 @@ tcp_fuse_output(tcp_t *tcp, mblk_t *mp, uint32_t send_size)
tcp->tcp_snxt += send_size;
tcp->tcp_suna = tcp->tcp_snxt;
peer_tcp->tcp_rnxt += recv_size;
+ peer_tcp->tcp_last_recv_len = recv_size;
peer_tcp->tcp_rack = peer_tcp->tcp_rnxt;
TCPS_BUMP_MIB(tcps, tcpOutDataSegs);
@@ -654,7 +655,12 @@ tcp_fuse_output(tcp_t *tcp, mblk_t *mp, uint32_t send_size)
BUMP_LOCAL(tcp->tcp_obsegs);
BUMP_LOCAL(peer_tcp->tcp_ibsegs);
- DTRACE_PROBE2(tcp__fuse__output, tcp_t *, tcp, uint_t, send_size);
+ DTRACE_TCP5(send, void, NULL, ip_xmit_attr_t *, connp->conn_ixa,
+ __dtrace_tcp_void_ip_t *, NULL, tcp_t *, tcp,
+ __dtrace_tcp_tcph_t *, NULL);
+ DTRACE_TCP5(receive, void, NULL, ip_xmit_attr_t *,
+ peer_connp->conn_ixa, __dtrace_tcp_void_ip_t *, NULL,
+ tcp_t *, peer_tcp, __dtrace_tcp_tcph_t *, NULL);
if (!IPCL_IS_NONSTR(peer_tcp->tcp_connp) &&
!TCP_IS_DETACHED(peer_tcp)) {
diff --git a/usr/src/uts/common/inet/tcp/tcp_input.c b/usr/src/uts/common/inet/tcp/tcp_input.c
index 48289425ff..14f34a1591 100644
--- a/usr/src/uts/common/inet/tcp/tcp_input.c
+++ b/usr/src/uts/common/inet/tcp/tcp_input.c
@@ -1322,6 +1322,10 @@ tcp_input_listener(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
tcpha = (tcpha_t *)&mp->b_rptr[ip_hdr_len];
flags = (unsigned int)tcpha->tha_flags & 0xFF;
+ DTRACE_TCP5(receive, mblk_t *, NULL, ip_xmit_attr_t *, lconnp->conn_ixa,
+ __dtrace_tcp_void_ip_t *, mp->b_rptr, tcp_t *, listener,
+ __dtrace_tcp_tcph_t *, tcpha);
+
if (!(flags & TH_SYN)) {
if ((flags & TH_RST) || (flags & TH_URG)) {
freemsg(mp);
@@ -1653,13 +1657,6 @@ tcp_input_listener(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
goto error3;
}
- /*
- * No need to check for multicast destination since ip will only pass
- * up multicasts to those that have expressed interest
- * TODO: what about rejecting broadcasts?
- * Also check that source is not a multicast or broadcast address.
- */
- eager->tcp_state = TCPS_SYN_RCVD;
SOCK_CONNID_BUMP(eager->tcp_connid);
/*
@@ -1770,6 +1767,10 @@ tcp_input_listener(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
eager->tcp_tcpha->tha_ack = htonl(eager->tcp_rnxt);
TCPS_BUMP_MIB(tcps, tcpPassiveOpens);
eager->tcp_state = TCPS_SYN_RCVD;
+ DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
+ econnp->conn_ixa, void, NULL, tcp_t *, eager, void, NULL,
+ int32_t, TCPS_LISTEN);
+
mp1 = tcp_xmit_mp(eager, eager->tcp_xmit_head, eager->tcp_mss,
NULL, NULL, eager->tcp_iss, B_FALSE, NULL, B_FALSE);
if (mp1 == NULL) {
@@ -1825,6 +1826,10 @@ tcp_input_listener(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
* only used by one thread at a time.
*/
if (econnp->conn_sqp == lconnp->conn_sqp) {
+ DTRACE_TCP5(send, mblk_t *, NULL, ip_xmit_attr_t *,
+ econnp->conn_ixa, __dtrace_tcp_void_ip_t *, mp1->b_rptr,
+ tcp_t *, eager, __dtrace_tcp_tcph_t *,
+ &mp1->b_rptr[econnp->conn_ixa->ixa_ip_hdr_length]);
(void) conn_ip_output(mp1, econnp->conn_ixa);
CONN_DEC_REF(econnp);
} else {
@@ -2344,6 +2349,10 @@ tcp_input_data(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
mp1->b_datap->db_type == M_DATA);
}
+ DTRACE_TCP5(receive, mblk_t *, NULL, ip_xmit_attr_t *, connp->conn_ixa,
+ __dtrace_tcp_void_ip_t *, iphdr, tcp_t *, tcp,
+ __dtrace_tcp_tcph_t *, tcpha);
+
if (tcp->tcp_state == TCPS_TIME_WAIT) {
tcp_time_wait_processing(tcp, mp, seg_seq, seg_ack,
seg_len, tcpha, ira);
@@ -2443,9 +2452,14 @@ tcp_input_data(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
ASSERT(tcp->tcp_suna + 1 == seg_ack);
}
if (flags & TH_RST) {
- freemsg(mp);
- if (flags & TH_ACK)
+ if (flags & TH_ACK) {
+ DTRACE_TCP5(connect__refused, mblk_t *, NULL,
+ ip_xmit_attr_t *, connp->conn_ixa,
+ void_ip_t *, iphdr, tcp_t *, tcp,
+ tcph_t *, tcpha);
(void) tcp_clean_death(tcp, ECONNREFUSED);
+ }
+ freemsg(mp);
return;
}
if (!(flags & TH_SYN)) {
@@ -2504,7 +2518,9 @@ tcp_input_data(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
/*
* tcp_sendmsg() checks tcp_state without entering
* the squeue so tcp_state should be updated before
- * sending up connection confirmation
+ * sending up connection confirmation. Probe the
+ * state change below when we are sure the connection
+ * confirmation has been sent.
*/
tcp->tcp_state = TCPS_ESTABLISHED;
if (!tcp_conn_con(tcp, iphdr, mp,
@@ -2559,6 +2575,18 @@ tcp_input_data(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
flags |= TH_ACK_NEEDED;
/*
+ * Trace connect-established here.
+ */
+ DTRACE_TCP5(connect__established, mblk_t *, NULL,
+ ip_xmit_attr_t *, tcp->tcp_connp->conn_ixa,
+ void_ip_t *, iphdr, tcp_t *, tcp, tcph_t *, tcpha);
+
+ /* Trace change from SYN_SENT -> ESTABLISHED here */
+ DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
+ connp->conn_ixa, void, NULL, tcp_t *, tcp,
+ void, NULL, int32_t, TCPS_SYN_SENT);
+
+ /*
* Special case for loopback. At this point we have
* received SYN-ACK from the remote endpoint. In
* order to ensure that both endpoints reach the
@@ -2654,6 +2682,9 @@ tcp_input_data(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
break;
}
tcp->tcp_state = TCPS_SYN_RCVD;
+ DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
+ connp->conn_ixa, void_ip_t *, NULL, tcp_t *, tcp,
+ tcph_t *, NULL, int32_t, TCPS_SYN_SENT);
mp1 = tcp_xmit_mp(tcp, tcp->tcp_xmit_head, tcp->tcp_mss,
NULL, NULL, tcp->tcp_iss, B_FALSE, NULL, B_FALSE);
if (mp1 != NULL) {
@@ -3628,7 +3659,9 @@ process_ack:
*
* tcp_sendmsg() checks tcp_state without entering
* the squeue so tcp_state should be updated before
- * sending up connection confirmation.
+ * sending up connection confirmation. Probe the state
+ * change below when we are sure sending of the confirmation
+ * has succeeded.
*/
tcp->tcp_state = TCPS_ESTABLISHED;
@@ -3646,6 +3679,21 @@ process_ack:
TCP_STAT(tcps, tcp_fusion_unfusable);
tcp->tcp_unfusable = B_TRUE;
}
+ /*
+ * For simultaneous active open, trace receipt of final
+ * ACK as tcp:::connect-established.
+ */
+ DTRACE_TCP5(connect__established, mblk_t *, NULL,
+ ip_xmit_attr_t *, connp->conn_ixa, void_ip_t *,
+ iphdr, tcp_t *, tcp, tcph_t *, tcpha);
+ } else {
+ /*
+ * For passive open, trace receipt of final ACK as
+ * tcp:::accept-established.
+ */
+ DTRACE_TCP5(accept__established, mlbk_t *, NULL,
+ ip_xmit_attr_t *, connp->conn_ixa, void_ip_t *,
+ iphdr, tcp_t *, tcp, tcph_t *, tcpha);
}
TCPS_CONN_INC(tcps);
@@ -3688,6 +3736,11 @@ process_ack:
tcp->tcp_swl2 = seg_ack;
tcp->tcp_valid_bits &= ~TCP_ISS_VALID;
+ /* Trace change from SYN_RCVD -> ESTABLISHED here */
+ DTRACE_TCP6(state__change, void, NULL, ip_xmit_attr_t *,
+ connp->conn_ixa, void, NULL, tcp_t *, tcp, void, NULL,
+ int32_t, TCPS_SYN_RCVD);
+
/* Fuse when both sides are in ESTABLISHED state */
if (tcp->tcp_loopback && do_tcp_fusion)
tcp_fuse(tcp, iphdr, tcpha);
@@ -4353,6 +4406,10 @@ est:
case TCPS_FIN_WAIT_1:
if (tcp->tcp_fin_acked) {
tcp->tcp_state = TCPS_FIN_WAIT_2;
+ DTRACE_TCP6(state__change, void, NULL,
+ ip_xmit_attr_t *, connp->conn_ixa,
+ void, NULL, tcp_t *, tcp, void, NULL,
+ int32_t, TCPS_FIN_WAIT_1);
/*
* We implement the non-standard BSD/SunOS
* FIN_WAIT_2 flushing algorithm.
@@ -4383,8 +4440,13 @@ est:
}
goto xmit_check;
case TCPS_CLOSING:
- if (tcp->tcp_fin_acked)
+ if (tcp->tcp_fin_acked) {
SET_TIME_WAIT(tcps, tcp, connp);
+ DTRACE_TCP6(state__change, void, NULL,
+ ip_xmit_attr_t *, connp->conn_ixa, void,
+ NULL, tcp_t *, tcp, void, NULL, int32_t,
+ TCPS_CLOSING);
+ }
/*FALLTHRU*/
case TCPS_CLOSE_WAIT:
freemsg(mp);
@@ -4414,18 +4476,37 @@ est:
flags |= TH_ORDREL_NEEDED;
switch (tcp->tcp_state) {
case TCPS_SYN_RCVD:
+ tcp->tcp_state = TCPS_CLOSE_WAIT;
+ DTRACE_TCP6(state__change, void, NULL,
+ ip_xmit_attr_t *, connp->conn_ixa,
+ void, NULL, tcp_t *, tcp, void, NULL,
+ int32_t, TCPS_SYN_RCVD);
+ /* Keepalive? */
+ break;
case TCPS_ESTABLISHED:
tcp->tcp_state = TCPS_CLOSE_WAIT;
+ DTRACE_TCP6(state__change, void, NULL,
+ ip_xmit_attr_t *, connp->conn_ixa,
+ void, NULL, tcp_t *, tcp, void, NULL,
+ int32_t, TCPS_ESTABLISHED);
/* Keepalive? */
break;
case TCPS_FIN_WAIT_1:
if (!tcp->tcp_fin_acked) {
tcp->tcp_state = TCPS_CLOSING;
+ DTRACE_TCP6(state__change, void, NULL,
+ ip_xmit_attr_t *, connp->conn_ixa,
+ void, NULL, tcp_t *, tcp, void,
+ NULL, int32_t, TCPS_FIN_WAIT_1);
break;
}
/* FALLTHRU */
case TCPS_FIN_WAIT_2:
SET_TIME_WAIT(tcps, tcp, connp);
+ DTRACE_TCP6(state__change, void, NULL,
+ ip_xmit_attr_t *, connp->conn_ixa, void,
+ NULL, tcp_t *, tcp, void, NULL, int32_t,
+ TCPS_FIN_WAIT_2);
if (seg_len) {
/*
* implies data piggybacked on FIN.
diff --git a/usr/src/uts/common/inet/tcp/tcp_output.c b/usr/src/uts/common/inet/tcp/tcp_output.c
index 3cca3e1983..a93c5bce9e 100644
--- a/usr/src/uts/common/inet/tcp/tcp_output.c
+++ b/usr/src/uts/common/inet/tcp/tcp_output.c
@@ -1693,6 +1693,11 @@ tcp_send_data(tcp_t *tcp, mblk_t *mp)
return;
}
+ DTRACE_TCP5(send, mblk_t *, NULL, ip_xmit_attr_t *, connp->conn_ixa,
+ __dtrace_tcp_void_ip_t *, mp->b_rptr, tcp_t *, tcp,
+ __dtrace_tcp_tcph_t *,
+ &mp->b_rptr[connp->conn_ixa->ixa_ip_hdr_length]);
+
ASSERT(connp->conn_ixa->ixa_notify_cookie == connp->conn_tcp);
(void) conn_ip_output(mp, connp->conn_ixa);
}
@@ -2586,6 +2591,21 @@ tcp_xmit_early_reset(char *str, mblk_t *mp, uint32_t seq, uint32_t ack, int ctl,
tcpha->tha_sum = htons(sizeof (tcpha_t));
tcpha->tha_flags = (uint8_t)ctl;
if (ctl & TH_RST) {
+ if (ctl & TH_ACK) {
+ /*
+ * Probe connection rejection here.
+ * tcp_xmit_listeners_reset() drops non-SYN segments
+ * that do not specify TH_ACK in their flags without
+ * calling this function. As a consequence, if this
+ * function is called with a TH_RST|TH_ACK ctl argument,
+ * it is being called in response to a SYN segment
+ * and thus the tcp:::accept-refused probe point
+ * is valid here.
+ */
+ DTRACE_TCP5(accept__refused, mblk_t *, NULL,
+ void, NULL, void_ip_t *, mp->b_rptr, tcp_t *, NULL,
+ tcph_t *, tcpha);
+ }
TCPS_BUMP_MIB(tcps, tcpOutRsts);
TCPS_BUMP_MIB(tcps, tcpOutControl);
}
@@ -2616,6 +2636,10 @@ tcp_xmit_early_reset(char *str, mblk_t *mp, uint32_t seq, uint32_t ack, int ctl,
ixa->ixa_flags |= IXAF_NO_IPSEC;
}
+ DTRACE_TCP5(send, mblk_t *, NULL, ip_xmit_attr_t *, ixa,
+ __dtrace_tcp_void_ip_t *, mp->b_rptr, tcp_t *, NULL,
+ __dtrace_tcp_tcph_t *, tcpha);
+
/*
* NOTE: one might consider tracing a TCP packet here, but
* this function has no active TCP state and no tcp structure
@@ -2658,6 +2682,14 @@ tcp_xmit_listeners_reset(mblk_t *mp, ip_recv_attr_t *ira, ip_stack_t *ipst,
TCP_STAT(tcps, tcp_no_listener);
+ /*
+ * DTrace this "unknown" segment as a tcp:::receive, as we did
+ * just receive something that was TCP.
+ */
+ DTRACE_TCP5(receive, mblk_t *, NULL, ip_xmit_attr_t *, NULL,
+ __dtrace_tcp_void_ip_t *, mp->b_rptr, tcp_t *, NULL,
+ __dtrace_tcp_tcph_t *, &mp->b_rptr[ip_hdr_len]);
+
if (IPH_HDR_VERSION(mp->b_rptr) == IPV4_VERSION) {
policy_present = ipss->ipsec_inbound_v4_policy_present;
ipha = (ipha_t *)mp->b_rptr;
@@ -3031,11 +3063,25 @@ tcp_xmit_mp(tcp_t *tcp, mblk_t *mp, int32_t max_to_send, int32_t *offset,
tcp->tcp_fin_sent = B_TRUE;
switch (tcp->tcp_state) {
case TCPS_SYN_RCVD:
+ tcp->tcp_state = TCPS_FIN_WAIT_1;
+ DTRACE_TCP6(state__change, void, NULL,
+ ip_xmit_attr_t *, ixa, void, NULL,
+ tcp_t *, tcp, void, NULL,
+ int32_t, TCPS_SYN_RCVD);
+ break;
case TCPS_ESTABLISHED:
tcp->tcp_state = TCPS_FIN_WAIT_1;
+ DTRACE_TCP6(state__change, void, NULL,
+ ip_xmit_attr_t *, ixa, void, NULL,
+ tcp_t *, tcp, void, NULL,
+ int32_t, TCPS_ESTABLISHED);
break;
case TCPS_CLOSE_WAIT:
tcp->tcp_state = TCPS_LAST_ACK;
+ DTRACE_TCP6(state__change, void, NULL,
+ ip_xmit_attr_t *, ixa, void, NULL,
+ tcp_t *, tcp, void, NULL,
+ int32_t, TCPS_CLOSE_WAIT);
break;
}
if (tcp->tcp_suna == tcp->tcp_snxt)
diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c
index 707499eaf5..3b8b46a911 100644
--- a/usr/src/uts/common/inet/udp/udp.c
+++ b/usr/src/uts/common/inet/udp/udp.c
@@ -2427,6 +2427,13 @@ udp_input(void *arg1, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
}
}
+ /*
+ * DTrace this UDP input as udp:::receive (this is for IPv4, IPv6 and
+ * loopback traffic).
+ */
+ DTRACE_UDP5(receive, mblk_t *, NULL, ip_xmit_attr_t *, connp->conn_ixa,
+ void_ip_t *, rptr, udp_t *, udp, udpha_t *, udpha);
+
/* Walk past the headers unless IP_RECVHDR was set. */
if (!udp->udp_rcvhdr) {
mp->b_rptr = rptr + hdr_length;
@@ -3135,6 +3142,10 @@ udp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp,
/* We're done. Pass the packet to ip. */
BUMP_MIB(&us->us_udp_mib, udpHCOutDatagrams);
+ DTRACE_UDP5(send, mblk_t *, NULL, ip_xmit_attr_t *, ixa,
+ void_ip_t *, mp->b_rptr, udp_t *, udp, udpha_t *,
+ &mp->b_rptr[ixa->ixa_ip_hdr_length]);
+
error = conn_ip_output(mp, ixa);
/* No udpOutErrors if an error since IP increases its error counter */
switch (error) {
@@ -3285,6 +3296,10 @@ udp_output_connected(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid)
/* We're done. Pass the packet to ip. */
BUMP_MIB(&us->us_udp_mib, udpHCOutDatagrams);
+ DTRACE_UDP5(send, mblk_t *, NULL, ip_xmit_attr_t *, ixa,
+ void_ip_t *, mp->b_rptr, udp_t *, udp, udpha_t *,
+ &mp->b_rptr[ixa->ixa_ip_hdr_length]);
+
error = conn_ip_output(mp, ixa);
/* No udpOutErrors if an error since IP increases its error counter */
switch (error) {
@@ -3411,6 +3426,10 @@ udp_output_lastdst(conn_t *connp, mblk_t *mp, cred_t *cr, pid_t pid,
/* We're done. Pass the packet to ip. */
BUMP_MIB(&us->us_udp_mib, udpHCOutDatagrams);
+ DTRACE_UDP5(send, mblk_t *, NULL, ip_xmit_attr_t *, ixa,
+ void_ip_t *, mp->b_rptr, udp_t *, udp, udpha_t *,
+ &mp->b_rptr[ixa->ixa_ip_hdr_length]);
+
error = conn_ip_output(mp, ixa);
/* No udpOutErrors if an error since IP increases its error counter */
switch (error) {
@@ -4212,6 +4231,10 @@ udp_output_newdst(conn_t *connp, mblk_t *data_mp, sin_t *sin, sin6_t *sin6,
/* We're done. Pass the packet to ip. */
BUMP_MIB(&us->us_udp_mib, udpHCOutDatagrams);
+ DTRACE_UDP5(send, mblk_t *, NULL, ip_xmit_attr_t *, ixa,
+ void_ip_t *, data_mp->b_rptr, udp_t *, udp, udpha_t *,
+ &data_mp->b_rptr[ixa->ixa_ip_hdr_length]);
+
error = conn_ip_output(data_mp, ixa);
/* No udpOutErrors if an error since IP increases its error counter */
switch (error) {
diff --git a/usr/src/uts/common/sys/sdt.h b/usr/src/uts/common/sys/sdt.h
index 6ca064c978..6fafae82e3 100644
--- a/usr/src/uts/common/sys/sdt.h
+++ b/usr/src/uts/common/sys/sdt.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _SYS_SDT_H
@@ -281,6 +280,56 @@ extern "C" {
type3, arg3, type4, arg4, type5, arg5, type6, arg6, \
type7, arg7);
+#define DTRACE_TCP(name) \
+ DTRACE_PROBE(__tcp_##name);
+
+#define DTRACE_TCP1(name, type1, arg1) \
+ DTRACE_PROBE1(__tcp_##name, type1, arg1);
+
+#define DTRACE_TCP2(name, type1, arg1, type2, arg2) \
+ DTRACE_PROBE2(__tcp_##name, type1, arg1, type2, arg2);
+
+#define DTRACE_TCP3(name, type1, arg1, type2, arg2, type3, arg3) \
+ DTRACE_PROBE3(__tcp_##name, type1, arg1, type2, arg2, type3, arg3);
+
+#define DTRACE_TCP4(name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4) \
+ DTRACE_PROBE4(__tcp_##name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4);
+
+#define DTRACE_TCP5(name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4, type5, arg5) \
+ DTRACE_PROBE5(__tcp_##name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4, type5, arg5);
+
+#define DTRACE_TCP6(name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4, type5, arg5, type6, arg6) \
+ DTRACE_PROBE6(__tcp_##name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4, type5, arg5, type6, arg6);
+
+#define DTRACE_UDP(name) \
+ DTRACE_PROBE(__udp_##name);
+
+#define DTRACE_UDP1(name, type1, arg1) \
+ DTRACE_PROBE1(__udp_##name, type1, arg1);
+
+#define DTRACE_UDP2(name, type1, arg1, type2, arg2) \
+ DTRACE_PROBE2(__udp_##name, type1, arg1, type2, arg2);
+
+#define DTRACE_UDP3(name, type1, arg1, type2, arg2, type3, arg3) \
+ DTRACE_PROBE3(__udp_##name, type1, arg1, type2, arg2, type3, arg3);
+
+#define DTRACE_UDP4(name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4) \
+ DTRACE_PROBE4(__udp_##name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4);
+
+#define DTRACE_UDP5(name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4, type5, arg5) \
+ DTRACE_PROBE5(__udp_##name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4, type5, arg5);
+
+
#define DTRACE_SYSEVENT2(name, type1, arg1, type2, arg2) \
DTRACE_PROBE2(__sysevent_##name, type1, arg1, type2, arg2);