1#!/usr/bin/env ksh
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23#
24# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
25#
26
27#
28# Test {ip,sctp}:::{send,receive} of IPv4 SCTP to local host.
29#
30# This may fail due to:
31#
32# 1. A change to the ip stack breaking expected probe behavior,
33#    which is the reason we are testing.
34# 2. The lo0 interface missing or not up.
35# 3. An unlikely race causes the unlocked global send/receive
36#    variables to be corrupted.
37#
38# This test performs a SCTP association and checks that at least the
39# following packet counts were traced:
40#
41# 7 x ip:::send (4 during the setup, 3 during the teardown)
42# 7 x sctp:::send (4 during the setup, 3 during the teardown)
43# 7 x ip:::receive (4 during the setup, 3 during the teardown)
44# 7 x sctp:::receive (4 during the setup, 3 during the teardown)
45
46# The actual count tested is 7 each way, since we are tracing both
47# source and destination events.
48#
49
50if (( $# != 1 )); then
51	print -u2 "expected one argument: <dtrace-path>"
52	exit 2
53fi
54
55dtrace=$1
56local=127.0.0.1
57DIR=/var/tmp/dtest.$$
58
59sctpport=1024
60bound=5000
61
62mkdir $DIR
63cd $DIR
64
65cat > client.pl <<-EOPERL
66	use IO::Socket;
67	my \$s = IO::Socket::INET->new(
68	    Type => SOCK_STREAM,
69	    Proto => "sctp",
70	    LocalAddr => "$local",
71	    PeerAddr => "$local",
72	    PeerPort => \$ARGV[0],
73	    Timeout => 3);
74	die "Could not connect to host $local port \$ARGV[0] \$@" unless \$s;
75	close \$s;
76	sleep(\$ARGV[1]);
77EOPERL
78
79while [ $sctpport -lt $bound ]; do
80	perl client.pl $sctpport 0 2>&- || break
81	sctpport=$(($sctpport + 1))
82done
83if [ $sctpport -eq $bound ]; then
84	echo "couldn't find an available SCTP port"
85	exit 1
86fi
87
88cat > server.pl <<-EOPERL
89	use IO::Socket;
90	my \$l = IO::Socket::INET->new(
91	    Type => SOCK_STREAM,
92	    Proto => "sctp",
93	    LocalAddr => "$local",
94	    LocalPort => $sctpport,
95	    Listen => 1,
96	    Reuse => 1);
97	die "Could not listen on $local port $sctpport \$@" unless \$l;
98	my \$c = \$l->accept();
99	close \$l;
100	while (<\$c>) {};
101	close \$c;
102EOPERL
103
104perl server.pl &
105
106$dtrace -c "perl client.pl $sctpport 2" -qs /dev/stdin <<EODTRACE
107BEGIN
108{
109	ipsend = sctpsend = ipreceive = sctpreceive = 0;
110}
111
112ip:::send
113/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
114    args[4]->ipv4_protocol == IPPROTO_SCTP/
115{
116	ipsend++;
117}
118
119sctp:::send
120/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
121{
122	sctpsend++;
123}
124
125ip:::receive
126/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
127    args[4]->ipv4_protocol == IPPROTO_SCTP/
128{
129	ipreceive++;
130}
131
132sctp:::receive
133/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
134{
135	sctpreceive++;
136}
137
138END
139{
140	printf("Minimum SCTP events seen\n\n");
141	printf("ip:::send - %s\n", ipsend >= 7 ? "yes" : "no");
142	printf("ip:::receive - %s\n", ipreceive >= 7 ? "yes" : "no");
143	printf("sctp:::send - %s\n", sctpsend >= 7 ? "yes" : "no");
144	printf("sctp:::receive - %s\n", sctpreceive >= 7 ? "yes" : "no");
145}
146EODTRACE
147
148status=$?
149
150cd /
151/bin/rm -rf $DIR
152
153exit $status
154