From owner-svn-src-all@freebsd.org Wed Aug 22 21:23:36 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id CC58C10964DB; Wed, 22 Aug 2018 21:23:35 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 800D18D648; Wed, 22 Aug 2018 21:23:35 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 60E68188DB; Wed, 22 Aug 2018 21:23:35 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w7MLNZSR021617; Wed, 22 Aug 2018 21:23:35 GMT (envelope-from tuexen@FreeBSD.org) Received: (from tuexen@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w7MLNWqJ021602; Wed, 22 Aug 2018 21:23:32 GMT (envelope-from tuexen@FreeBSD.org) Message-Id: <201808222123.w7MLNWqJ021602@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: tuexen set sender to tuexen@FreeBSD.org using -f From: Michael Tuexen Date: Wed, 22 Aug 2018 21:23:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: 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... X-SVN-Group: head X-SVN-Commit-Author: tuexen X-SVN-Commit-Paths: 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/netinet X-SVN-Commit-Revision: 338213 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 22 Aug 2018 21:23:36 -0000 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 () { 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: " + 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 <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: " + 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 <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: " + 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 <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: " + 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 <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 + */ + +#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" : + ""; + +/* + * 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 ? "" : + p->asoc.primary_destination == NULL ? "" : + p->asoc.primary_destination->ro._s_addr == NULL ? "" : + 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) : + ""; + sctps_raddr = p == NULL ? "" : + p->asoc.primary_destination == NULL ? "" : + 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) : + ""; + 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 ***