1#!/usr/bin/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,tcp}:::{send,receive} of IPv4 TCP 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. The local ssh service is not online. 36# 4. An unlikely race causes the unlocked global send/receive 37# variables to be corrupted. 38# 39# This test performs a TCP connection and checks that at least the 40# following packet counts were traced: 41# 42# 3 x ip:::send (2 during the TCP handshake, then a FIN) 43# 3 x tcp:::send (2 during the TCP handshake, then a FIN) 44# 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK) 45# 2 x tcp:::receive (1 during the TCP handshake, then the FIN ACK) 46 47# The actual count tested is 5 each way, since we are tracing both 48# source and destination events. 49# 50# For this test to work, we are assuming that the TCP handshake and 51# TCP close will enter the IP code path and not use tcp fusion. 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} 97 98ip:::send 99/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && 100 args[4]->ipv4_protocol == IPPROTO_TCP/ 101{ 102 ipsend++; 103} 104 105tcp:::send 106/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/ 107{ 108 tcpsend++; 109} 110 111ip:::receive 112/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && 113 args[4]->ipv4_protocol == IPPROTO_TCP/ 114{ 115 ipreceive++; 116} 117 118tcp:::receive 119/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/ 120{ 121 tcpreceive++; 122} 123 124END 125{ 126 printf("Minimum TCP events seen\n\n"); 127 printf("ip:::send - %s\n", ipsend >= 5 ? "yes" : "no"); 128 printf("ip:::receive - %s\n", ipreceive >= 5 ? "yes" : "no"); 129 printf("tcp:::send - %s\n", tcpsend >= 5 ? "yes" : "no"); 130 printf("tcp:::receive - %s\n", tcpreceive >= 5 ? "yes" : "no"); 131} 132EODTRACE 133 134status=$? 135 136cd / 137/bin/rm -rf $DIR 138 139exit $status 140