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
This commit is contained in:
parent
376a4e3255
commit
1e88cc8b59
@ -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;
|
||||
|
137
cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localsctp.ksh
Executable file
137
cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localsctp.ksh
Executable file
@ -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
|
@ -0,0 +1,7 @@
|
||||
Minimum SCTP events seen
|
||||
|
||||
ip:::send - yes
|
||||
ip:::receive - yes
|
||||
sctp:::send - yes
|
||||
sctp:::receive - yes
|
||||
|
130
cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotesctp.ksh
Executable file
130
cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotesctp.ksh
Executable file
@ -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
|
@ -0,0 +1,7 @@
|
||||
Minimum SCTP events seen
|
||||
|
||||
ip:::send - yes
|
||||
ip:::receive - yes
|
||||
sctp:::send - yes
|
||||
sctp:::receive - yes
|
||||
|
159
cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localsctpstate.ksh
Executable file
159
cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localsctpstate.ksh
Executable file
@ -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
|
@ -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
|
149
cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotesctpstate.ksh
Executable file
149
cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotesctpstate.ksh
Executable file
@ -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
|
@ -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
|
||||
|
@ -51,6 +51,7 @@ DSRCS= errno.d \
|
||||
io.d \
|
||||
ip.d \
|
||||
psinfo.d \
|
||||
sctp.d \
|
||||
siftr.d \
|
||||
signal.d \
|
||||
tcp.d \
|
||||
|
171
cddl/lib/libdtrace/sctp.d
Normal file
171
cddl/lib/libdtrace/sctp.d
Normal file
@ -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@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;
|
||||
};
|
@ -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 \
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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 succeeds.
|
||||
At this point the new connection is in the ESTABLISHED state, and the probe
|
||||
arguments expose the headers associated with the final ACK of the 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);
|
||||
}
|
||||
|
||||
sctp:::receive
|
||||
{
|
||||
printf(" %3d %16s:%-5d <- %16s:%-5d\n", cpu,
|
||||
args[2]->ip_daddr, args[4]->sctp_dport,
|
||||
args[2]->ip_saddr, args[4]->sctp_sport);
|
||||
}
|
||||
.Ed
|
||||
A script that logs SCTP association state changes as they occur:
|
||||
.Bd -literal -offset indent
|
||||
#pragma D option quiet
|
||||
#pragma D option switchrate=10
|
||||
|
||||
int last[int];
|
||||
|
||||
dtrace:::BEGIN
|
||||
{
|
||||
printf(" %3s %12s %-25s %-25s\n",
|
||||
"CPU", "DELTA(us)", "OLD", "NEW");
|
||||
}
|
||||
|
||||
sctp:::state-change
|
||||
/ last[args[1]->cs_cid] /
|
||||
{
|
||||
this->elapsed = (timestamp - last[args[1]->cs_cid]) / 1000;
|
||||
printf(" %3d %12d %-25s -> %-25s\n", cpu, this->elapsed,
|
||||
sctp_state_string[args[5]->sctps_state],
|
||||
sctp_state_string[args[3]->sctps_state]);
|
||||
last[args[1]->cs_cid] = timestamp;
|
||||
}
|
||||
|
||||
sctp:::state-change
|
||||
/ last[args[1]->cs_cid] == 0 /
|
||||
{
|
||||
printf(" %3d %12s %-25s -> %-25s\n", cpu, "-",
|
||||
sctp_state_string[args[5]->sctps_state],
|
||||
sctp_state_string[args[3]->sctps_state]);
|
||||
last[args[1]->cs_cid] = timestamp;
|
||||
}
|
||||
.Ed
|
||||
.Sh COMPATIBILITY
|
||||
The
|
||||
.Fn sctp:::send ,
|
||||
.Fn sctp:::receive ,
|
||||
and
|
||||
.Fn sctp:::state-change
|
||||
probes are compatible with the
|
||||
.Nm sctp
|
||||
provider in Solaris.
|
||||
All other probes are only available in FreeBSD.
|
||||
.Sh SEE ALSO
|
||||
.Xr dtrace 1 ,
|
||||
.Xr dtrace_ip 4 ,
|
||||
|
@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sdt.h>
|
||||
|
||||
SDT_PROVIDER_DEFINE(ip);
|
||||
SDT_PROVIDER_DEFINE(sctp);
|
||||
SDT_PROVIDER_DEFINE(tcp);
|
||||
SDT_PROVIDER_DEFINE(udp);
|
||||
SDT_PROVIDER_DEFINE(udplite);
|
||||
@ -56,6 +57,28 @@ SDT_PROBE_DEFINE6_XLATE(ip, , , send,
|
||||
"struct ip *", "ipv4info_t *",
|
||||
"struct ip6_hdr *", "ipv6info_t *");
|
||||
|
||||
SDT_PROBE_DEFINE5_XLATE(sctp, , , receive,
|
||||
"void *", "pktinfo_t *",
|
||||
"struct sctp_tcb *", "csinfo_t *",
|
||||
"struct mbuf *", "ipinfo_t *",
|
||||
"struct sctp_tcb *", "sctpsinfo_t *" ,
|
||||
"struct sctphdr *", "sctpinfo_t *");
|
||||
|
||||
SDT_PROBE_DEFINE5_XLATE(sctp, , , send,
|
||||
"void *", "pktinfo_t *",
|
||||
"struct sctp_tcb *", "csinfo_t *",
|
||||
"uint8_t *", "ipinfo_t *",
|
||||
"struct sctp_tcb *", "sctpsinfo_t *" ,
|
||||
"struct sctphdr *", "sctpinfo_t *");
|
||||
|
||||
SDT_PROBE_DEFINE6_XLATE(sctp, , , state__change,
|
||||
"void *", "void *",
|
||||
"struct sctp_tcb *", "csinfo_t *",
|
||||
"void *", "void *",
|
||||
"struct sctp_tcb *", "sctpsinfo_t *",
|
||||
"void *", "void *",
|
||||
"int", "sctplsinfo_t *");
|
||||
|
||||
SDT_PROBE_DEFINE5_XLATE(tcp, , , accept__established,
|
||||
"void *", "pktinfo_t *",
|
||||
"struct tcpcb *", "csinfo_t *",
|
||||
|
@ -48,8 +48,21 @@
|
||||
SDT_PROBE5(tcp, , , probe, arg0, arg1, arg2, arg3, arg4)
|
||||
#define TCP_PROBE6(probe, arg0, arg1, arg2, arg3, arg4, arg5) \
|
||||
SDT_PROBE6(tcp, , , probe, arg0, arg1, arg2, arg3, arg4, arg5)
|
||||
#define SCTP_PROBE1(probe, arg0) \
|
||||
SDT_PROBE1(sctp, , , probe, arg0)
|
||||
#define SCTP_PROBE2(probe, arg0, arg1) \
|
||||
SDT_PROBE2(sctp, , , probe, arg0, arg1)
|
||||
#define SCTP_PROBE3(probe, arg0, arg1, arg2) \
|
||||
SDT_PROBE3(sctp, , , probe, arg0, arg1, arg2)
|
||||
#define SCTP_PROBE4(probe, arg0, arg1, arg2, arg3) \
|
||||
SDT_PROBE4(sctp, , , probe, arg0, arg1, arg2, arg3)
|
||||
#define SCTP_PROBE5(probe, arg0, arg1, arg2, arg3, arg4) \
|
||||
SDT_PROBE5(sctp, , , probe, arg0, arg1, arg2, arg3, arg4)
|
||||
#define SCTP_PROBE6(probe, arg0, arg1, arg2, arg3, arg4, arg5) \
|
||||
SDT_PROBE6(sctp, , , probe, arg0, arg1, arg2, arg3, arg4, arg5)
|
||||
|
||||
SDT_PROVIDER_DECLARE(ip);
|
||||
SDT_PROVIDER_DECLARE(sctp);
|
||||
SDT_PROVIDER_DECLARE(tcp);
|
||||
SDT_PROVIDER_DECLARE(udp);
|
||||
SDT_PROVIDER_DECLARE(udplite);
|
||||
@ -57,6 +70,10 @@ SDT_PROVIDER_DECLARE(udplite);
|
||||
SDT_PROBE_DECLARE(ip, , , receive);
|
||||
SDT_PROBE_DECLARE(ip, , , send);
|
||||
|
||||
SDT_PROBE_DECLARE(sctp, , , receive);
|
||||
SDT_PROBE_DECLARE(sctp, , , send);
|
||||
SDT_PROBE_DECLARE(sctp, , , state__change);
|
||||
|
||||
SDT_PROBE_DECLARE(tcp, , , accept__established);
|
||||
SDT_PROBE_DECLARE(tcp, , , accept__refused);
|
||||
SDT_PROBE_DECLARE(tcp, , , connect__established);
|
||||
|
@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sdt.h>
|
||||
|
||||
SDT_PROVIDER_DEFINE(sctp);
|
||||
SDT_PROVIDER_DECLARE(sctp);
|
||||
|
||||
/********************************************************/
|
||||
/* Cwnd probe - tracks changes in the congestion window on a netp */
|
||||
|
@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
|
||||
#if defined(INET) || defined(INET6)
|
||||
#include <netinet/udp.h>
|
||||
#endif
|
||||
#include <netinet/in_kdtrace.h>
|
||||
#include <sys/smp.h>
|
||||
|
||||
|
||||
@ -5569,6 +5570,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
|
||||
net->flowtype = mflowtype;
|
||||
net->flowid = mflowid;
|
||||
}
|
||||
SCTP_PROBE5(receive, NULL, stcb, m, stcb, sh);
|
||||
if ((inp != NULL) && (stcb != NULL)) {
|
||||
sctp_send_packet_dropped(stcb, net, m, length, iphlen, 1);
|
||||
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED);
|
||||
@ -5609,6 +5611,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
|
||||
net->flowid = mflowid;
|
||||
}
|
||||
if (inp == NULL) {
|
||||
SCTP_PROBE5(receive, NULL, stcb, m, stcb, sh);
|
||||
SCTP_STAT_INCR(sctps_noport);
|
||||
if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0) {
|
||||
goto out;
|
||||
@ -5657,6 +5660,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
|
||||
*/
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
stcb = NULL;
|
||||
SCTP_PROBE5(receive, NULL, stcb, m, stcb, sh);
|
||||
snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __func__);
|
||||
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
|
||||
msg);
|
||||
@ -5713,11 +5717,13 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
|
||||
if ((stcb != NULL) &&
|
||||
sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks)) {
|
||||
/* "silently" ignore */
|
||||
SCTP_PROBE5(receive, NULL, stcb, m, stcb, sh);
|
||||
SCTP_STAT_INCR(sctps_recvauthmissing);
|
||||
goto out;
|
||||
}
|
||||
if (stcb == NULL) {
|
||||
/* out of the blue DATA chunk */
|
||||
SCTP_PROBE5(receive, NULL, NULL, m, NULL, sh);
|
||||
snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __func__);
|
||||
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
|
||||
msg);
|
||||
@ -5728,11 +5734,13 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
|
||||
}
|
||||
if (stcb->asoc.my_vtag != ntohl(sh->v_tag)) {
|
||||
/* v_tag mismatch! */
|
||||
SCTP_PROBE5(receive, NULL, stcb, m, stcb, sh);
|
||||
SCTP_STAT_INCR(sctps_badvtag);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
SCTP_PROBE5(receive, NULL, stcb, m, stcb, sh);
|
||||
if (stcb == NULL) {
|
||||
/*
|
||||
* no valid TCB for this packet, or we found it's a bad
|
||||
|
@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
#include <netinet/udp_var.h>
|
||||
#include <machine/in_cksum.h>
|
||||
#include <netinet/in_kdtrace.h>
|
||||
|
||||
|
||||
|
||||
@ -4251,6 +4252,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
SCTP_SOCKET_UNLOCK(so, 0);
|
||||
}
|
||||
#endif
|
||||
SCTP_PROBE5(send, NULL, stcb, ip, stcb, sctphdr);
|
||||
SCTP_IP_OUTPUT(ret, o_pak, ro, stcb, vrf_id);
|
||||
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
|
||||
if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
|
||||
@ -4584,6 +4586,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
|
||||
sctp_packet_log(o_pak);
|
||||
#endif
|
||||
SCTP_PROBE5(send, NULL, stcb, ip6h, stcb, sctphdr);
|
||||
SCTP_IP6_OUTPUT(ret, o_pak, (struct route_in6 *)ro, &ifp, stcb, vrf_id);
|
||||
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
|
||||
if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
|
||||
@ -11252,6 +11255,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
|
||||
sctp_packet_log(o_pak);
|
||||
}
|
||||
#endif
|
||||
SCTP_PROBE5(send, NULL, NULL, ip, NULL, shout);
|
||||
SCTP_IP_OUTPUT(ret, o_pak, NULL, NULL, vrf_id);
|
||||
break;
|
||||
#endif
|
||||
@ -11274,6 +11278,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
|
||||
sctp_packet_log(o_pak);
|
||||
}
|
||||
#endif
|
||||
SCTP_PROBE5(send, NULL, NULL, ip6, NULL, shout);
|
||||
SCTP_IP6_OUTPUT(ret, o_pak, NULL, NULL, NULL, vrf_id);
|
||||
break;
|
||||
#endif
|
||||
|
@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/udp_var.h>
|
||||
#include <netinet/in_kdtrace.h>
|
||||
#include <sys/proc.h>
|
||||
#ifdef INET6
|
||||
#include <netinet/icmp6.h>
|
||||
@ -7385,6 +7386,10 @@ sctp_hc_get_mtu(union sctp_sockstore *addr, uint16_t fibnum)
|
||||
void
|
||||
sctp_set_state(struct sctp_tcb *stcb, int new_state)
|
||||
{
|
||||
#if defined(KDTRACE_HOOKS)
|
||||
int old_state = stcb->asoc.state;
|
||||
#endif
|
||||
|
||||
KASSERT((new_state & ~SCTP_STATE_MASK) == 0,
|
||||
("sctp_set_state: Can't set substate (new_state = %x)",
|
||||
new_state));
|
||||
@ -7394,13 +7399,32 @@ sctp_set_state(struct sctp_tcb *stcb, int new_state)
|
||||
(new_state == SCTP_STATE_SHUTDOWN_ACK_SENT)) {
|
||||
SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING);
|
||||
}
|
||||
#if defined(KDTRACE_HOOKS)
|
||||
if (((old_state & SCTP_STATE_MASK) != new_state) &&
|
||||
!(((old_state & SCTP_STATE_MASK) == SCTP_STATE_EMPTY) &&
|
||||
(new_state == SCTP_STATE_INUSE))) {
|
||||
SCTP_PROBE6(state__change, NULL, stcb, NULL, stcb, NULL, old_state);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sctp_add_substate(struct sctp_tcb *stcb, int substate)
|
||||
{
|
||||
#if defined(KDTRACE_HOOKS)
|
||||
int old_state = stcb->asoc.state;
|
||||
#endif
|
||||
|
||||
KASSERT((substate & SCTP_STATE_MASK) == 0,
|
||||
("sctp_add_substate: Can't set state (substate = %x)",
|
||||
substate));
|
||||
stcb->asoc.state |= substate;
|
||||
#if defined(KDTRACE_HOOKS)
|
||||
if (((substate & SCTP_STATE_ABOUT_TO_BE_FREED) &&
|
||||
((old_state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) ||
|
||||
((substate & SCTP_STATE_SHUTDOWN_PENDING) &&
|
||||
((old_state & SCTP_STATE_SHUTDOWN_PENDING) == 0))) {
|
||||
SCTP_PROBE6(state__change, NULL, stcb, NULL, stcb, NULL, old_state);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user