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) 2010, Oracle and/or its affiliates. All rights reserved. 25# 26 27# 28# Test tcp:::state-change and tcp:::{send,receive} by connecting to 29# the local ssh service and sending a test message. This should result 30# in a "Protocol mismatch" response and a close of the connection. 31# A number of state transition events along with tcp fusion send and 32# receive events for the message should result. 33# 34# This may fail due to: 35# 36# 1. A change to the ip stack breaking expected probe behavior, 37# which is the reason we are testing. 38# 2. The lo0 interface missing or not up. 39# 3. An unlikely race causes the unlocked global send/receive 40# variables to be corrupted. 41# 42# This test performs a TCP connection and checks that at least the 43# following packet counts were traced: 44# 45# 7 x ip:::send (3 during the setup, 4 during the teardown) 46# 7 x tcp:::send (3 during the setup, 4 during the teardown) 47# 7 x ip:::receive (3 during the setup, 4 during the teardown) 48# 7 x tcp:::receive (3 during the setup, 4 during the teardown) 49# 50# The actual count tested is 7 each way, since we are tracing both 51# source and destination events. 52# 53 54if (( $# != 1 )); then 55 print -u2 "expected one argument: <dtrace-path>" 56 exit 2 57fi 58 59dtrace=$1 60local=127.0.0.1 61DIR=/var/tmp/dtest.$$ 62 63tcpport=1024 64bound=5000 65while [ $tcpport -lt $bound ]; do 66 nc -z $local $tcpport >/dev/null || break 67 tcpport=$(($tcpport + 1)) 68done 69if [ $tcpport -eq $bound ]; then 70 echo "couldn't find an available TCP port" 71 exit 1 72fi 73 74mkdir $DIR 75cd $DIR 76 77# nc will exit when the connection is closed. 78nc -l $local $tcpport & 79 80cat > test.pl <<-EOPERL 81 use IO::Socket; 82 my \$s = IO::Socket::INET->new( 83 Proto => "tcp", 84 PeerAddr => "$local", 85 PeerPort => $tcpport, 86 Timeout => 3); 87 die "Could not connect to host $local port $tcpport" unless \$s; 88 close \$s; 89 sleep(2); 90EOPERL 91 92$dtrace -c 'perl test.pl' -qs /dev/stdin <<EODTRACE 93BEGIN 94{ 95 ipsend = tcpsend = ipreceive = tcpreceive = 0; 96 connreq = connest = connaccept = 0; 97} 98 99ip:::send 100/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && 101 args[4]->ipv4_protocol == IPPROTO_TCP/ 102{ 103 ipsend++; 104} 105 106tcp:::send 107/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && 108 (args[4]->tcp_sport == $tcpport || args[4]->tcp_dport == $tcpport)/ 109{ 110 tcpsend++; 111} 112 113ip:::receive 114/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && 115 args[4]->ipv4_protocol == IPPROTO_TCP/ 116{ 117 ipreceive++; 118} 119 120tcp:::receive 121/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && 122 (args[4]->tcp_sport == $tcpport || args[4]->tcp_dport == $tcpport)/ 123{ 124 tcpreceive++; 125} 126 127tcp:::state-change 128{ 129 state_event[args[3]->tcps_state]++; 130} 131 132tcp:::connect-request 133/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && 134 args[4]->tcp_dport == $tcpport/ 135{ 136 connreq++; 137} 138 139tcp:::connect-established 140/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && 141 args[4]->tcp_sport == $tcpport/ 142{ 143 connest++; 144} 145 146tcp:::accept-established 147/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && 148 args[4]->tcp_dport == $tcpport/ 149{ 150 connaccept++; 151} 152 153END 154{ 155 printf("Minimum TCP events seen\n\n"); 156 printf("ip:::send - %s\n", ipsend >= 7 ? "yes" : "no"); 157 printf("ip:::receive - %s\n", ipreceive >= 7 ? "yes" : "no"); 158 printf("tcp:::send - %s\n", tcpsend >= 7 ? "yes" : "no"); 159 printf("tcp:::receive - %s\n", tcpreceive >= 7 ? "yes" : "no"); 160 printf("tcp:::state-change to syn-sent - %s\n", 161 state_event[TCP_STATE_SYN_SENT] >=1 ? "yes" : "no"); 162 printf("tcp:::state-change to syn-received - %s\n", 163 state_event[TCP_STATE_SYN_RECEIVED] >=1 ? "yes" : "no"); 164 printf("tcp:::state-change to established - %s\n", 165 state_event[TCP_STATE_ESTABLISHED] >= 2 ? "yes" : "no"); 166 printf("tcp:::state-change to fin-wait-1 - %s\n", 167 state_event[TCP_STATE_FIN_WAIT_1] >= 1 ? "yes" : "no"); 168 printf("tcp:::state-change to close-wait - %s\n", 169 state_event[TCP_STATE_CLOSE_WAIT] >= 1 ? "yes" : "no"); 170 printf("tcp:::state-change to fin-wait-2 - %s\n", 171 state_event[TCP_STATE_FIN_WAIT_2] >= 1 ? "yes" : "no"); 172 printf("tcp:::state-change to last-ack - %s\n", 173 state_event[TCP_STATE_LAST_ACK] >= 1 ? "yes" : "no"); 174 printf("tcp:::state-change to time-wait - %s\n", 175 state_event[TCP_STATE_TIME_WAIT] >= 1 ? "yes" : "no"); 176 printf("tcp:::connect-request - %s\n", 177 connreq >=1 ? "yes" : "no"); 178 printf("tcp:::connect-established - %s\n", 179 connest >=1 ? "yes" : "no"); 180 printf("tcp:::accept-established - %s\n", 181 connaccept >=1 ? "yes" : "no"); 182} 183EODTRACE 184 185status=$? 186 187cd / 188/bin/rm -rf $DIR 189 190exit $status 191