svn commit: r338213 - in head: cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip cddl/lib/libdtrace cddl/usr.sbin/dtrace/tests/common/ip cddl/usr.sbin/dtrace/tests/tools share/man/man4 sys/net...
Michael Tuexen
tuexen at FreeBSD.org
Wed Aug 22 21:23:36 UTC 2018
Author: tuexen
Date: Wed Aug 22 21:23:32 2018
New Revision: 338213
URL: https://svnweb.freebsd.org/changeset/base/338213
Log:
Add support for send, receive and state-change DTrace providers for
SCTP. They are based on what is specified in the Solaris DTrace manual
for Solaris 11.4.
Reviewed by: 0mp, dteske, markj
Relnotes: yes
Differential Revision: https://reviews.freebsd.org/D16839
Added:
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localsctp.ksh (contents, props changed)
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localsctp.ksh.out
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotesctp.ksh (contents, props changed)
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotesctp.ksh.out
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localsctpstate.ksh (contents, props changed)
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localsctpstate.ksh.out
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotesctpstate.ksh (contents, props changed)
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotesctpstate.ksh.out
head/cddl/lib/libdtrace/sctp.d (contents, props changed)
Modified:
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl
head/cddl/lib/libdtrace/Makefile
head/cddl/usr.sbin/dtrace/tests/common/ip/Makefile
head/cddl/usr.sbin/dtrace/tests/tools/exclude.sh
head/share/man/man4/dtrace_sctp.4
head/sys/netinet/in_kdtrace.c
head/sys/netinet/in_kdtrace.h
head/sys/netinet/sctp_dtrace_define.h
head/sys/netinet/sctp_input.c
head/sys/netinet/sctp_output.c
head/sys/netinet/sctputil.c
Modified: head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl Wed Aug 22 21:22:40 2018 (r338212)
+++ head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl Wed Aug 22 21:23:32 2018 (r338213)
@@ -27,11 +27,12 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#
-# get.ipv4remote.pl [tcpport]
+# get.ipv4remote.pl [port] [proto]
#
# Find an IPv4 reachable remote host using both ifconfig(1M) and ping(1M).
-# If a tcpport is specified, return a host that is also listening on this
-# TCP port. Print the local address and the remote address, or an
+# If a port is specified, return a host that is also listening on this
+# port. If the port is specified, the protocol can also be specified and
+# defaults to tcp. Print the local address and the remote address, or an
# error message if no suitable remote host was found. Exit status is 0 if
# a host was found.
#
@@ -41,7 +42,8 @@ use IO::Socket;
my $MAXHOSTS = 32; # max hosts to port scan
my $TIMEOUT = 3; # connection timeout
-my $tcpport = @ARGV == 1 ? $ARGV[0] : 0;
+my $port = @ARGV >= 1 ? $ARGV[0] : 0;
+my $proto = @ARGV == 2 ? $ARGV[1] : "tcp";
#
# Determine local IP address
@@ -79,14 +81,15 @@ while (<PING>) {
if (/bytes from (.*): / and not defined $Broadcast{$1}) {
my $addr = $1;
- if ($tcpport != 0) {
+ if ($port != 0) {
#
# Test TCP
#
my $socket = IO::Socket::INET->new(
- Proto => "tcp",
+ Type => SOCK_STREAM,
+ Proto => $proto,
PeerAddr => $addr,
- PeerPort => $tcpport,
+ PeerPort => $port,
Timeout => $TIMEOUT,
);
next unless $socket;
Added: head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localsctp.ksh
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localsctp.ksh Wed Aug 22 21:23:32 2018 (r338213)
@@ -0,0 +1,137 @@
+#!/usr/bin/env 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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# Test {ip,sctp}:::{send,receive} of IPv4 SCTP to local host.
+#
+# 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. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test performs a SCTP association and checks that at least the
+# following packet counts were traced:
+#
+# 7 x ip:::send (4 during the setup, 3 during the teardown)
+# 7 x sctp:::send (4 during the setup, 3 during the teardown)
+# 7 x ip:::receive (4 during the setup, 3 during the teardown)
+# 7 x sctp:::receive (4 during the setup, 3 during the teardown)
+
+# The actual count tested is 7 each way, since we are tracing both
+# source and destination events.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+local=127.0.0.1
+DIR=/var/tmp/dtest.$$
+
+sctpport=1024
+bound=5000
+while [ $sctpport -lt $bound ]; do
+ ncat --sctp -z $local $sctpport > /dev/null || break
+ sctpport=$(($sctpport + 1))
+done
+if [ $sctpport -eq $bound ]; then
+ echo "couldn't find an available SCTP port"
+ exit 1
+fi
+
+mkdir $DIR
+cd $DIR
+
+# ncat will exit when the association is closed.
+ncat --sctp --listen $local $sctpport &
+
+cat > test.pl <<-EOPERL
+ use IO::Socket;
+ my \$s = IO::Socket::INET->new(
+ Type => SOCK_STREAM,
+ Proto => "sctp",
+ LocalAddr => "$local",
+ PeerAddr => "$local",
+ PeerPort => $sctpport,
+ Timeout => 3);
+ die "Could not connect to host $local port $sctpport \$@" unless \$s;
+ close \$s;
+ sleep(2);
+EOPERL
+
+$dtrace -c 'perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ ipsend = sctpsend = ipreceive = sctpreceive = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_SCTP/
+{
+ ipsend++;
+}
+
+sctp:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
+{
+ sctpsend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_SCTP/
+{
+ ipreceive++;
+}
+
+sctp:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
+{
+ sctpreceive++;
+}
+
+END
+{
+ printf("Minimum SCTP events seen\n\n");
+ printf("ip:::send (%d) - %s\n", ipsend, ipsend >= 7 ? "yes" : "no");
+ printf("ip:::receive (%d) - %s\n", ipreceive, ipreceive >= 7 ? "yes" : "no");
+ printf("sctp:::send (%d) - %s\n", sctpsend, sctpsend >= 7 ? "yes" : "no");
+ printf("sctp:::receive (%d) - %s\n", sctpreceive, sctpreceive >= 7 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
Added: head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localsctp.ksh.out
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localsctp.ksh.out Wed Aug 22 21:23:32 2018 (r338213)
@@ -0,0 +1,7 @@
+Minimum SCTP events seen
+
+ip:::send - yes
+ip:::receive - yes
+sctp:::send - yes
+sctp:::receive - yes
+
Added: head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotesctp.ksh
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotesctp.ksh Wed Aug 22 21:23:32 2018 (r338213)
@@ -0,0 +1,130 @@
+#!/usr/bin/env ksh93
+#
+# 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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# Test {sctp,ip}:::{send,receive} of IPv4 SCTP to a remote host.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. No physical network interface is plumbed and up.
+# 3. No other hosts on this subnet are reachable and listening on ssh.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test performs an SCTP association and checks that at least the
+# following packet counts were traced:
+#
+# 4 x ip:::send (2 during setup, 2 during teardown)
+# 4 x sctp:::send (2 during connection setup, 2 during connection teardown)
+# 3 x ip:::receive (2 during setup, 1 during teardown)
+# 3 x sctp:::receive (2 during setup, 1 during teardown)
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+getaddr=./get.ipv4remote.pl
+sctpport=80
+DIR=/var/tmp/dtest.$$
+
+if [[ ! -x $getaddr ]]; then
+ print -u2 "could not find or execute sub program: $getaddr"
+ exit 3
+fi
+$getaddr $sctpport sctp | 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(
+ Type => SOCK_STREAM,
+ Proto => "sctp",
+ LocalAddr => "$source",
+ PeerAddr => "$dest",
+ PeerPort => $sctpport,
+ Timeout => 3);
+ die "Could not connect to host $dest port $sctpport \$@" unless \$s;
+ close \$s;
+ sleep(2);
+EOPERL
+
+$dtrace -c 'perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ ipsend = sctpsend = ipreceive = sctpreceive = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->ipv4_protocol == IPPROTO_SCTP/
+{
+ ipsend++;
+}
+
+sctp:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest"/
+{
+ sctpsend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->ipv4_protocol == IPPROTO_SCTP/
+{
+ ipreceive++;
+}
+
+sctp:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source"/
+{
+ sctpreceive++;
+}
+
+END
+{
+ printf("Minimum SCTP events seen\n\n");
+ printf("ip:::send - %s\n", ipsend >= 4 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 3 ? "yes" : "no");
+ printf("sctp:::send - %s\n", sctpsend >= 4 ? "yes" : "no");
+ printf("sctp:::receive - %s\n", sctpreceive >= 3 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
Added: head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotesctp.ksh.out
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotesctp.ksh.out Wed Aug 22 21:23:32 2018 (r338213)
@@ -0,0 +1,7 @@
+Minimum SCTP events seen
+
+ip:::send - yes
+ip:::receive - yes
+sctp:::send - yes
+sctp:::receive - yes
+
Added: head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localsctpstate.ksh
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localsctpstate.ksh Wed Aug 22 21:23:32 2018 (r338213)
@@ -0,0 +1,159 @@
+#!/usr/bin/env 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 sctp:::state-change and sctp:::{send,receive} by connecting to
+# the local discard service.
+# A number of state transition events along with SCTP 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. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test performs a SCTP connection and checks that at least the
+# following packet counts were traced:
+#
+# 7 x ip:::send (4 during the setup, 3 during the teardown)
+# 7 x sctp:::send (4 during the setup, 3 during the teardown)
+# 7 x ip:::receive (4 during the setup, 3 during the teardown)
+# 7 x sctp:::receive (4 during the setup, 3 during the teardown)
+#
+# The actual count tested is 7 each way, since we are tracing both
+# source and destination events.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+local=127.0.0.1
+DIR=/var/tmp/dtest.$$
+
+sctpport=1024
+bound=5000
+while [ $sctpport -lt $bound ]; do
+ ncat --sctp -z $local $sctpport > /dev/null || break
+ sctpport=$(($sctpport + 1))
+done
+if [ $sctpport -eq $bound ]; then
+ echo "couldn't find an available SCTP port"
+ exit 1
+fi
+
+mkdir $DIR
+cd $DIR
+
+# ncat will exit when the association is closed.
+ncat --sctp --listen $local $sctpport &
+
+cat > test.pl <<-EOPERL
+ use IO::Socket;
+ my \$s = IO::Socket::INET->new(
+ Type => SOCK_STREAM,
+ Proto => "sctp",
+ LocalAddr => "$local",
+ PeerAddr => "$local",
+ PeerPort => $sctpport,
+ Timeout => 3);
+ die "Could not connect to host $local port $sctpport \$@" unless \$s;
+ close \$s;
+ sleep(2);
+EOPERL
+
+$dtrace -c 'perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ ipsend = sctpsend = ipreceive = sctpreceive = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_SCTP/
+{
+ ipsend++;
+}
+
+sctp:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ (args[4]->sctp_sport == $sctpport || args[4]->sctp_dport == $sctpport)/
+{
+ sctpsend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_SCTP/
+{
+ ipreceive++;
+}
+
+sctp:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ (args[4]->sctp_sport == $sctpport || args[4]->sctp_dport == $sctpport)/
+{
+ sctpreceive++;
+}
+
+sctp:::state-change
+{
+ state_event[args[3]->sctps_state]++;
+}
+
+END
+{
+ printf("Minimum SCTP events seen\n\n");
+ printf("ip:::send - %s\n", ipsend >= 7 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 7 ? "yes" : "no");
+ printf("sctp:::send - %s\n", sctpsend >= 7 ? "yes" : "no");
+ printf("sctp:::receive - %s\n", sctpreceive >= 7 ? "yes" : "no");
+ printf("sctp:::state-change to cookie-wait - %s\n",
+ state_event[SCTP_STATE_COOKIE_WAIT] >=1 ? "yes" : "no");
+ printf("sctp:::state-change to cookie-echoed - %s\n",
+ state_event[SCTP_STATE_COOKIE_ECHOED] >=1 ? "yes" : "no");
+ printf("sctp:::state-change to established - %s\n",
+ state_event[SCTP_STATE_ESTABLISHED] >= 2 ? "yes" : "no");
+ printf("sctp:::state-change to shutdown-sent - %s\n",
+ state_event[SCTP_STATE_SHUTDOWN_SENT] >= 1 ? "yes" : "no");
+ printf("sctp:::state-change to shutdown-received - %s\n",
+ state_event[SCTP_STATE_SHUTDOWN_RECEIVED] >= 1 ? "yes" : "no");
+ printf("sctp:::state-change to shutdown-ack-sent - %s\n",
+ state_event[SCTP_STATE_SHUTDOWN_ACK_SENT] >= 1 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
Added: head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localsctpstate.ksh.out
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localsctpstate.ksh.out Wed Aug 22 21:23:32 2018 (r338213)
@@ -0,0 +1,12 @@
+Minimum SCTP events seen
+
+ip:::send - yes
+ip:::receive - yes
+sctp:::send - yes
+sctp:::receive - yes
+sctp:::state-change to cookie-wait - yes
+sctp:::state-change to cookie-echoed - yes
+sctp:::state-change to established - yes
+sctp:::state-change to shutdown-sent - yes
+sctp:::state-change to shutdown-received - yes
+sctp:::state-change to shutdown-ack-sent - yes
Added: head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotesctpstate.ksh
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotesctpstate.ksh Wed Aug 22 21:23:32 2018 (r338213)
@@ -0,0 +1,149 @@
+#!/usr/bin/env ksh93
+#
+# 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 sctp:::state-change and sctp:::{send,receive} by connecting to
+# the remote http service.
+# A number of state transition events along with sctp 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 SCTP association to the http service (port 80) and
+# checks that at least the following packet counts were traced:
+#
+# 4 x ip:::send (2 during setup, 2 during teardown)
+# 4 x sctp:::send (2 during setup, 2 during teardown)
+# 3 x ip:::receive (2 during setup, 1 during teardown)
+# 3 x sctp:::receive (2 during setup, 1 during teardown)
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+getaddr=./get.ipv4remote.pl
+sctpport=80
+DIR=/var/tmp/dtest.$$
+
+if [[ ! -x $getaddr ]]; then
+ print -u2 "could not find or execute sub program: $getaddr"
+ exit 3
+fi
+$getaddr $sctpport sctp | 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(
+ Type => SOCK_STREAM,
+ Proto => "sctp",
+ LocalAddr => "$source",
+ PeerAddr => "$dest",
+ PeerPort => $sctpport,
+ Timeout => 3);
+ die "Could not connect to host $dest port $sctpport \$@" unless \$s;
+ close \$s;
+ sleep(2);
+EOPERL
+
+$dtrace -c 'perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ ipsend = sctpsend = ipreceive = sctpreceive = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->ipv4_protocol == IPPROTO_SCTP/
+{
+ ipsend++;
+}
+
+sctp:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->sctp_dport == $sctpport/
+{
+ sctpsend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->ipv4_protocol == IPPROTO_SCTP/
+{
+ ipreceive++;
+}
+
+sctp:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->sctp_sport == $sctpport/
+{
+ sctpreceive++;
+}
+
+sctp:::state-change
+{
+ state_event[args[3]->sctps_state]++;
+}
+
+END
+{
+ printf("Minimum SCTP events seen\n\n");
+ printf("ip:::send - %s\n", ipsend >= 4 ? "yes" : "no");
+ printf("ip:::receive - %s\n", ipreceive >= 3 ? "yes" : "no");
+ printf("sctp:::send - %s\n", sctpsend >= 4 ? "yes" : "no");
+ printf("sctp:::receive - %s\n", sctpreceive >= 3 ? "yes" : "no");
+ printf("sctp:::state-change to cookie-wait - %s\n",
+ state_event[SCTP_STATE_COOKIE_WAIT] >=1 ? "yes" : "no");
+ printf("sctp:::state-change to cookie-echoed - %s\n",
+ state_event[SCTP_STATE_COOKIE_ECHOED] >= 1 ? "yes" : "no");
+ printf("sctp:::state-change to established - %s\n",
+ state_event[SCTP_STATE_ESTABLISHED] >= 1 ? "yes" : "no");
+ printf("sctp:::state-change to shutdown-sent - %s\n",
+ state_event[SCTP_STATE_SHUTDOWN-SENT] >= 1 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/bin/rm -rf $DIR
+
+exit $status
Added: head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotesctpstate.ksh.out
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotesctpstate.ksh.out Wed Aug 22 21:23:32 2018 (r338213)
@@ -0,0 +1,12 @@
+Minimum SCTP events seen
+
+ip:::send - yes
+ip:::receive - yes
+SCTP:::send - yes
+sctp:::receive - yes
+sctp:::state-change to cookie-wait - yes
+sctp:::state-change to cookie-echoed - yes
+sctp:::state-change to established - yes
+sctp:::state-change to shutdown-sent - yes
+sctp:::state-change to closed - yes
+
Modified: head/cddl/lib/libdtrace/Makefile
==============================================================================
--- head/cddl/lib/libdtrace/Makefile Wed Aug 22 21:22:40 2018 (r338212)
+++ head/cddl/lib/libdtrace/Makefile Wed Aug 22 21:23:32 2018 (r338213)
@@ -51,6 +51,7 @@ DSRCS= errno.d \
io.d \
ip.d \
psinfo.d \
+ sctp.d \
siftr.d \
signal.d \
tcp.d \
Added: head/cddl/lib/libdtrace/sctp.d
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/cddl/lib/libdtrace/sctp.d Wed Aug 22 21:23:32 2018 (r338213)
@@ -0,0 +1,171 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * $FreeBSD$
+ */
+/*
+ * Copyright (c) 2018 Michael Tuexen <tuexen at FreeBSD.org>
+ */
+
+#pragma D depends_on library ip.d
+#pragma D depends_on library socket.d
+#pragma D depends_on module kernel
+#pragma D depends_on provider sctp
+
+#pragma D binding "1.13" SCTP_STATE_MASK
+inline int32_t SCTP_STATE_MASK = 0x0000007f;
+#pragma D binding "1.13" SCTP_STATE_SHUTDOWN_PENDING
+inline int32_t SCTP_STATE_SHUTDOWN_PENDING = 0x00000080;
+#pragma D binding "1.13" SCTP_STATE_CLOSED_SOCKET
+inline int32_t SCTP_STATE_CLOSED_SOCKET = 0x00000100;
+#pragma D binding "1.13" SCTP_STATE_ABOUT_TO_BE_FREED
+inline int32_t SCTP_STATE_ABOUT_TO_BE_FREED = 0x00000200;
+#pragma D binding "1.13" SCTP_STATE_ABOUT_TO_BE_FREED
+inline int32_t SCTP_STATE_PARTIAL_MSG_LEFT = 0x00000400;
+#pragma D binding "1.13" SCTP_STATE_PARTIAL_MSG_LEFT
+inline int32_t SCTP_STATE_WAS_ABORTED = 0x00000800;
+#pragma D binding "1.13" SCTP_STATE_IN_ACCEPT_QUEUE
+inline int32_t SCTP_STATE_IN_ACCEPT_QUEUE = 0x00001000;
+#pragma D binding "1.13" SCTP_STATE_BOUND
+inline int32_t SCTP_STATE_BOUND = 0x00001000;
+#pragma D binding "1.13" SCTP_STATE_EMPTY
+inline int32_t SCTP_STATE_EMPTY = 0x00000000;
+#pragma D binding "1.13" SCTP_STATE_CLOSED
+inline int32_t SCTP_STATE_CLOSED = 0x00000000;
+#pragma D binding "1.13" SCTP_STATE_INUSE
+inline int32_t SCTP_STATE_INUSE = 0x00000001;
+#pragma D binding "1.13" SCTP_STATE_COOKIE_WAIT
+inline int32_t SCTP_STATE_COOKIE_WAIT = 0x00000002;
+#pragma D binding "1.13" SCTP_STATE_COOKIE_ECHOED
+inline int32_t SCTP_STATE_COOKIE_ECHOED = 0x00000004;
+#pragma D binding "1.13" SCTP_STATE_ESTABLISHED
+inline int32_t SCTP_STATE_ESTABLISHED = 0x00000008;
+#pragma D binding "1.13" SCTP_STATE_OPEN
+inline int32_t SCTP_STATE_OPEN = 0x00000008;
+#pragma D binding "1.13" SCTP_STATE_SHUTDOWN_SENT
+inline int32_t SCTP_STATE_SHUTDOWN_SENT = 0x00000010;
+#pragma D binding "1.13" SCTP_STATE_SHUTDOWN_RECEIVED
+inline int32_t SCTP_STATE_SHUTDOWN_RECEIVED = 0x00000020;
+#pragma D binding "1.13" SCTP_STATE_SHUTDOWN_ACK_SENT
+inline int32_t SCTP_STATE_SHUTDOWN_ACK_SENT = 0x00000040;
+
+/* SCTP association state strings. */
+#pragma D binding "1.13" sctp_state_string
+inline string sctp_state_string[int32_t state] =
+ state & SCTP_STATE_ABOUT_TO_BE_FREED ? "state-closed" :
+ state & SCTP_STATE_SHUTDOWN_PENDING ? "state-shutdown-pending" :
+ (state & SCTP_STATE_MASK) == SCTP_STATE_EMPTY ? "state-closed" :
+ (state & SCTP_STATE_MASK) == SCTP_STATE_INUSE ? "state-closed" :
+ (state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT ? "state-cookie-wait" :
+ (state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED ? "state-cookie-echoed" :
+ (state & SCTP_STATE_MASK) == SCTP_STATE_OPEN ? "state-established" :
+ (state & SCTP_STATE_MASK) == SCTP_STATE_SHUTDOWN_SENT ? "state-shutdown-sent" :
+ (state & SCTP_STATE_MASK) == SCTP_STATE_SHUTDOWN_RECEIVED ? "state-shutdown-received" :
+ (state & SCTP_STATE_MASK) == SCTP_STATE_SHUTDOWN_ACK_SENT ? "state-shutdown-ack-sent" :
+ "<unknown>";
+
+/*
+ * sctpsinfo contains stable SCTP details.
+ */
+typedef struct sctpsinfo {
+ uintptr_t sctps_addr; /* pointer to struct sctp_tcb */
+ int sctps_num_raddrs; /* number of remote addresses */
+ uintptr_t sctps_raddrs; /* pointer to struct sctp_nets */
+ int sctps_num_laddrs; /* number of local addresses */
+ uintptr_t sctps_laddrs; /* pointer to struct sctp_laddr */
+ uint16_t sctps_lport; /* local port */
+ uint16_t sctps_rport; /* remote port */
+ string sctps_laddr; /* local address, as a string */
+ string sctps_raddr; /* remote address, as a string */
+ int32_t sctps_state;
+} sctpsinfo_t;
+
+/*
+ * sctplsinfo provides the old SCTP state for state changes.
+ */
+typedef struct sctplsinfo {
+ int32_t sctps_state; /* previous SCTP state */
+} sctplsinfo_t;
+
+/*
+ * sctpinfo is the SCTP header fields.
+ */
+typedef struct sctpinfo {
+ uint16_t sctp_sport; /* source port */
+ uint16_t sctp_dport; /* destination port */
+ uint32_t sctp_verify; /* verification tag */
+ uint32_t sctp_checksum; /* CRC32C of the SCTP packet */
+ struct sctphdr *sctp_hdr; /* raw SCTP header */
+} sctpinfo_t;
+
+#pragma D binding "1.13" translator
+translator csinfo_t < struct sctp_tcb *p > {
+ cs_addr = NULL;
+ cs_cid = (uint64_t)p;
+ cs_pid = 0;
+ cs_zoneid = 0;
+};
+
+#pragma D binding "1.13" translator
+translator sctpsinfo_t < struct sctp_tcb *p > {
+ sctps_addr = (uintptr_t)p;
+ sctps_num_raddrs = p == NULL ? -1 : p->asoc.numnets;
+ sctps_raddrs = p == NULL ? NULL : (uintptr_t)(p->asoc.nets.tqh_first);
+ sctps_num_laddrs = p == NULL ? -1 :
+ p->sctp_ep == NULL ? -1 :
+ p->sctp_ep->laddr_count;
+ sctps_laddrs = p == NULL ? NULL :
+ p->sctp_ep == NULL ? NULL :
+ (uintptr_t)(p->sctp_ep->sctp_addr_list.lh_first);
+ sctps_lport = p == NULL ? 0 :
+ p->sctp_ep == NULL ? 0 :
+ ntohs(p->sctp_ep->ip_inp.inp.inp_inc.inc_ie.ie_lport);
+ sctps_rport = p == NULL ? 0 : ntohs(p->rport);
+ sctps_laddr = p == NULL ? "<unknown>" :
+ p->asoc.primary_destination == NULL ? "<unknown>" :
+ p->asoc.primary_destination->ro._s_addr == NULL ? "<unknown>" :
+ p->asoc.primary_destination->ro._s_addr->address.sa.sa_family == AF_INET ?
+ inet_ntoa(&p->asoc.primary_destination->ro._s_addr->address.sin.sin_addr.s_addr) :
+ p->asoc.primary_destination->ro._s_addr->address.sa.sa_family == AF_INET6 ?
+ inet_ntoa6(&p->asoc.primary_destination->ro._s_addr->address.sin6.sin6_addr) :
+ "<unknown>";
+ sctps_raddr = p == NULL ? "<unknown>" :
+ p->asoc.primary_destination == NULL ? "<unknown>" :
+ p->asoc.primary_destination->ro._l_addr.sa.sa_family == AF_INET ?
+ inet_ntoa(&p->asoc.primary_destination->ro._l_addr.sin.sin_addr.s_addr) :
+ p->asoc.primary_destination->ro._l_addr.sa.sa_family == AF_INET6 ?
+ inet_ntoa6(&p->asoc.primary_destination->ro._l_addr.sin6.sin6_addr) :
+ "<unknown>";
+ sctps_state = p == NULL ? SCTP_STATE_CLOSED : p->asoc.state;
+};
+
+#pragma D binding "1.13" translator
+translator sctpinfo_t < struct sctphdr *p > {
+ sctp_sport = p == NULL ? 0 : ntohs(p->src_port);
+ sctp_dport = p == NULL ? 0 : ntohs(p->dest_port);
+ sctp_verify = p == NULL ? 0 : ntohl(p->v_tag);
+ sctp_checksum = p == NULL ? 0 : ntohl(p->checksum);
+ sctp_hdr = p;
+};
+
+#pragma D binding "1.13" translator
+translator sctplsinfo_t < int state > {
+ sctps_state = state;
+};
Modified: head/cddl/usr.sbin/dtrace/tests/common/ip/Makefile
==============================================================================
--- head/cddl/usr.sbin/dtrace/tests/common/ip/Makefile Wed Aug 22 21:22:40 2018 (r338212)
+++ head/cddl/usr.sbin/dtrace/tests/common/ip/Makefile Wed Aug 22 21:23:32 2018 (r338213)
@@ -9,6 +9,8 @@ PACKAGE= tests
${PACKAGE}FILES= \
tst.ipv4localicmp.ksh \
tst.ipv4localicmp.ksh.out \
+ tst.ipv4localsctp.ksh \
+ tst.ipv4localsctp.ksh.out \
tst.ipv4localtcp.ksh \
tst.ipv4localtcp.ksh.out \
tst.ipv4localudp.ksh \
@@ -17,6 +19,8 @@ ${PACKAGE}FILES= \
tst.ipv4localudplite.ksh.out \
tst.ipv4remoteicmp.ksh \
tst.ipv4remoteicmp.ksh.out \
+ tst.ipv4remotesctp.ksh \
+ tst.ipv4remotesctp.ksh.out \
tst.ipv4remotetcp.ksh \
tst.ipv4remotetcp.ksh.out \
tst.ipv4remoteudp.ksh \
@@ -27,8 +31,12 @@ ${PACKAGE}FILES= \
tst.ipv6localicmp.ksh.out \
tst.ipv6remoteicmp.ksh \
tst.ipv6remoteicmp.ksh.out \
+ tst.localsctpstate.ksh \
+ tst.localsctpstate.ksh.out \
tst.localtcpstate.ksh \
tst.localtcpstate.ksh.out \
+ tst.remotesctpstate.ksh \
+ tst.remotesctpstate.ksh.out \
tst.remotetcpstate.ksh \
tst.remotetcpstate.ksh.out \
Modified: head/cddl/usr.sbin/dtrace/tests/tools/exclude.sh
==============================================================================
--- head/cddl/usr.sbin/dtrace/tests/tools/exclude.sh Wed Aug 22 21:22:40 2018 (r338212)
+++ head/cddl/usr.sbin/dtrace/tests/tools/exclude.sh Wed Aug 22 21:23:32 2018 (r338213)
@@ -117,11 +117,13 @@ exclude SKIP common/builtinvar/tst.ipl.d
exclude SKIP common/builtinvar/tst.ipl1.d
# These tests rely on being able to find a host via broadcast pings.
+exclude EXFAIL common/ip/tst.ipv4remotesctp.ksh
exclude EXFAIL common/ip/tst.ipv4remotetcp.ksh
exclude EXFAIL common/ip/tst.ipv4remoteudp.ksh
exclude EXFAIL common/ip/tst.ipv4remoteudplite.ksh
exclude EXFAIL common/ip/tst.ipv6remoteicmp.ksh
exclude EXFAIL common/ip/tst.ipv4remoteicmp.ksh
+exclude EXFAIL common/ip/tst.remotesctpstate.ksh
exclude EXFAIL common/ip/tst.remotetcpstate.ksh
# Tries to enable pid$target:libc::entry, though there's no "libc" module.
Modified: head/share/man/man4/dtrace_sctp.4
==============================================================================
--- head/share/man/man4/dtrace_sctp.4 Wed Aug 22 21:22:40 2018 (r338212)
+++ head/share/man/man4/dtrace_sctp.4 Wed Aug 22 21:23:32 2018 (r338213)
@@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 1, 2018
+.Dd August 22, 2018
.Dt DTRACE_SCTP 4
.Os
.Sh NAME
@@ -44,6 +44,12 @@ protocol
.Fn sctp:rwnd:assoc:val uint32_t uint32_t int int
.Fn sctp:flightsize:net:val uint32_t uint32_t uintptr_t int int
.Fn sctp:flightsize:assoc:val uint32_t uint32_t int int
+.Fn sctp:::receive "pktinfo_t *" "csinfo_t *" "ipinfo_t *" "sctpsinfo_t *" \
+ "sctpinfo_t *"
+.Fn sctp:::send "pktinfo_t *" "csinfo_t *" "ipinfo_t *" "sctpsinfo_t *" \
+ "sctpinfo_t *"
+.Fn sctp:::state-change "void *" "csinfo_t *" "void *" "sctpsinfo_t *" \
+ "void *" "sctplsinfo_t *"
.Sh DESCRIPTION
The DTrace
.Nm sctp
@@ -105,14 +111,105 @@ probe fires when a remotely-initiated active SCTP open
At this point the new connection is in the ESTABLISHED state, and the probe
arguments expose the headers associated with the final ACK of the four-way
handshake.
+.Pp
+The
+.Fn sctp:::send
+and
+.Fn sctp:::receive
+probes fire when the host sends or receives an SCTP packet, respectively.
+As with the
+.Xr dtrace_udp 4
+provider,
+.Nm sctp
+probes fire only for packets sent by or to the local host; forwarded packets are
+handled in the IP layer and are only visible to the
+.Xr dtrace_ip 4
+provider.
+.Pp
+The
+.Fn sctp:::state-change
+probe fires upon local SCTP association state transitions.
+Its first, third and fifth arguments are currently always
+.Dv NULL .
+Its last argument describes the from-state in the transition, and the to-state
+can be obtained from
+.Dv args[3]->sctps_state .
.\" .Sh ARGUMENTS
-.\" .Sh FILES
-.\" .Sh EXAMPLES
-.\" .Sh COMPATIBILITY
-.\" This provider has not been tested for compatiblity with the
-.\" .Nm sctp
-.\" provider in Solaris
-.\" .Pq if one exists .
+.Sh FILES
+.Bl -tag -width "/usr/lib/dtrace/sctp.d" -compact
+.It Pa /usr/lib/dtrace/sctp.d
+DTrace type and translator definitions for the
+.Nm sctp
+provider.
+.El
+.Sh EXAMPLES
+A script that logs SCTP packets in real time:
+.Bd -literal -offset indent
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+dtrace:::BEGIN
+{
+ printf(" %3s %15s:%-5s %15s:%-5s\n", "CPU",
+ "LADDR", "LPORT", "RADDR", "RPORT");
+}
+
+sctp:::send
+{
+ printf(" %3d %16s:%-5d -> %16s:%-5d\n", cpu,
+ args[2]->ip_saddr, args[4]->sctp_sport,
+ args[2]->ip_daddr, args[4]->sctp_dport);
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-head
mailing list