# $Header: osresp.pl 18-feb-2005.12:44:01 afontana Exp $ # # osresp.pl # # Copyright (c) 2001, 2005, Oracle. All rights reserved. # # NAME # osresp.pl # # DESCRIPTION # check to see if host is up. returns mavg time taken to return ping # and status of 1 is successful. otherwise status 0 with " " as # the response time. # usage: perl osresp.pl [-mode <0,1> ] [-txnname ] # [-numpackets ] # If used in advanced mode (-mode 1), a transaction name MUST be # specified. In this mode the output will contain the transaction name, # the beacon name, and the packet drop rate (%). Also in this mode if # the ping fails, instead of returning an error message, the value -1 # is returned in the status field. # # NOTES # # # MODIFIED (MM/DD/YY) # afontana 02/10/05 - fix windows timeout bug # afontana 01/30/05 - fix broken Windows drop rate # afontana 01/14/05 - fix for RH 3.0 # skumar 05/25/04 - MAC OS X changes # nsharma 05/24/04 - Fix for AIX # sacgoyal 10/14/04 - for fixing bug # 3845374 # asawant 02/13/04 - NT Porting # sravindh 05/02/04 - Fix internal error in host ping test # asawant 06/27/03 - Removing call to undefined routine 'trace' # asawant 04/01/03 - Check input parameters thoroughly # asawant 12/06/02 - Fixing misselling # asawant 11/26/02 - Fixing security breach # xxu 06/25/02 - remove /usr/local/bin/perl # asawant 03/17/02 - Adding more columns for advanced mode # asawant 03/13/02 - Adding beacon name.. # asawant 02/22/02 - Adding drop rate % # asawant 02/14/02 - Adding IP.. # asawant 02/09/02 - Adding parameter to allow the script to be used by # a beacon target. # rlal 09/14/01 - Adding Linux. # aaitghez 07/02/01 - isType to osType # aaitghez 06/29/01 - sol to SOL. # aaitghez 06/19/01 - removing debug calls. # aaitghez 05/31/01 - target undefined early in script. # aaitghez 05/31/01 - adding target name to DEBUG. # aaitghez 05/31/01 - getting rid of all os dependence. # aaitghez 05/30/01 - removing os dependent code. # aaitghez 05/14/01 - perl version of osresp.tcl. # aaitghez 05/14/01 - Creation # #use strict; use Getopt::Long; # set up to accept user input use IO::Handle; require "semd_common.pl"; my $outputStr = 'em_result='; my $target; #target we are checking on $target = $ENV{EM_TARGET_NAME}; # this is the maxResponseTime for the ICMPPing $maxResponseTime = $ENV{EM_REC_MAX_RESPONSE_TIME}; my $numPackets = 5; # The number of packets to send out (default is 5) my $maxTtl = ""; # The max ttl my $mode = 0; # 1 for a more complete output. 0 is default my %cmdLine = (); # Parse the input parameters and put them in the cmdLine hash table GetOptions(\%cmdLine, "mode=i", "txnname=s", "beaconname=s", "numpackets=i", "maxttl=i"); if((exists $cmdLine{"mode"}) && (exists $cmdLine{"txnname"}) && (exists $cmdLine{"beaconname"})) { $mode = $cmdLine{"mode"}; if($mode) { $outputStr .= "$cmdLine{txnname}|$cmdLine{beaconname}|"; } } if(exists $cmdLine{"numpackets"}) { $numPackets = $cmdLine{"numpackets"}; } if(exists $cmdLine{"maxttl"}) { $maxTtl = $cmdLine{"maxttl"}; } if(($osType = get_osType()) == -1) { print "em_error=unsupported OS\n"; # EMD_DEBUG("The OS is unsupported.\n", "$target"); exit 1; } # Make sure this is a target name (security provision) # For this we check for any space in the string (including new line) and # then if this is a valid hostname (1.2.3.4 is a valid hostname too) if(($target =~ m/\s+/o) || (!gethostbyname("$target"))) { #EMD_DEBUG("Invalid hostname: $!", "$target"); print "em_error=Invalid hostname."; # This is so that the interactive UI picks up the error message print "em_error=ping: unknown host: $target "; exit 1; } # Validate remaining input parameters if($numPackets < 1) { print "em_error=Invalid number of packets."; # This is so that the interactive UI picks up the error message print "em_error=ping: bad packet count: $numPackets "; exit 1; } if((!($maxTtl eq "")) && ($maxTtl < 1)) { print "em_error=Invalid time to live."; # This is so that the interactive UI picks up the error message print "em_error=ping: bad ttl: $maxTtl "; exit 1; } my $r; # Set the ttl string appropriately (i.e. "-t $maxTttl") if (!($maxTtl eq "")) { if($osType eq "WIN") { $maxTtl = " -i $maxTtl "; } elsif ($osType eq "AIX") { $maxTtl = " -T $maxTtl "; } else { $maxTtl = " -t $maxTtl "; } } if ($osType eq "SOL") { # EMD_TRACE("Getting OS response for Sun OS.\n"); $ENV{PATH} = "/usr/bin:/usr/sbin:/usr/local/bin:/local/bin"; if(!($r = `ping -s $maxTtl $target 64 $numPackets | tail -2`)) { #EMD_DEBUG("Failed to execute ping: $!", "$target"); print "em_error=Failed to ping host"; exit 1; } } elsif ($osType eq "WIN") { # EMD_TRACE("Getting OS response for Windows.\n"); if(!($r = `ping -l 64 $maxTtl -n $numPackets $target`)) { #EMD_DEBUG("Failed to execute ping: $!", "$target"); print "em_error=Failed to ping host"; exit 1; } } elsif ($osType eq "LNX") { # EMD_TRACE("Getting OS response for Linux OS.\n"); if(!($r = `/bin/ping $target -s 64 -c $numPackets $maxTtl | tail -2`)) { #EMD_DEBUG("Failed to execute ping: $!", "$target"); print "em_error=Failed to ping host"; exit 1; } } elsif ($osType eq "OSF1" || $osType eq "MAC OS X") { # EMD_TRACE("Getting OS response for $osType.\n"); $ENV{PATH} = "/usr/bin:/usr/sbin:/sbin"; # There is no maxTtl option on Tru64 and MAC OS X if(!($r = `ping -c $numPackets -s 64 $target | tail -2`)) { # EMD_DEBUG("Failed to execute ping: $!", "$target"); print "em_error=Failed to ping host"; exit 1; } } else { # EMD_TRACE("Getting OS response for HP OS.\n"); $ENV{PATH} = "/usr/bin:/usr/sbin"; if(!($r = `ping $maxTtl $target 64 $numPackets | tail -2`)) { # EMD_DEBUG("Failed to execute ping: $!", "$target"); print "em_error=Failed to ping host"; exit 1; } } my @resLns = split(m/\n/o, $r); if ($osType eq "WIN") { # make sure we got three lines back if(@resLns < 6) { print "em_error=Failed spliting lines from result set"; exit 1; } my @origResLns = @resLns; splice(@resLns, 0, @resLns - 3); my @res = split(m/=/o, $resLns[2]); my $avg = 0; if(scalar(@res) != 4) { print "em_error=Failed spliting result line from result set"; exit 1; } else { # get the average response time ($avg) = $res[3] =~ m/\s*(\d+)ms\s*/o; } my $dropRate; # parse the package drop rate from line 3 of output unless(($dropRate) = $resLns[0] =~ m/.*,\s.*,\s.*\s\(([\d\.]+)\%\s.*/o) { # In the event of 100% drop rate, two lines are ommitted from the # bottom of the output. unless(($dropRate) = $resLns[2] =~ m/.*,\s.*,\s.*\s\(([\d\.]+)\%\s.*/o) { print "em_error=Failed parsing package drop rate"; exit 1; } $dropRate = 100; } # A Note is in order here. Win and UNIX behave differently in regards to the # packet drop rate. On Windows, if a packet is answered (TTL expired, etc.) # then it is not considered dropped (although the answering node is not the # target node). This is not the case on UNIX. To keep our users isolated # from this, we compute our own drop rate based on each packets answer. We # are (obviously) exposing the UNIX behavior (which seems correct). my $stat = 0; my $success = 0; if($dropRate != 100) { # Ensure that we did not receive a bunch of TTL expired messages (still # shown with 0% packet loss!) for($i = 3; (($i < 3 + $numPackets) && ($i < @origResLns)); $i++) { if($origResLns[$i] =~ m/.*Reply\s+from.*bytes.*time.*/o) { $stat = 1; # Found at least one postive answer! $success++; } } } if($stat == 0) { $avg = ''; $dropRate = '100.00'; } else # Calculate drop rate! { $dropRate = sprintf("%.2f", (100 * ($numPackets - $success) / $numPackets)); } if($mode) { # add the extra output columns if we are in advanced mode $outputStr .= "$avg|$stat|$dropRate||"; } else { $outputStr .= "$avg|$stat"; } } else { my @res; if(@resLns > 1) { @res = split(m/=/o, $resLns[1]); } elsif (@resLns == 1) { @res = split(m/=/o, $resLns[0]); } else { print "em_error=Failed spliting lines from result set"; exit 1; } if(scalar(@res) == 1) { $outputStr .= "|0"; } else { my @resr = split(m/\//, $res[1]); # get the average response time if(!$maxResponseTime or $maxResponseTime eq "") { $outputStr .= "$resr[1]"."|1"; } #Checks whether the parameter is a number or not elsif(!($maxResponseTime=~ /^\d+$/ || $maxResponseTime =~ /^\d+\.\d*$/)){ print "em_error=Incorrect max response time parameter = $maxResponseTime\n"; exit 1; } elsif(@resr[1] < $maxResponseTime) { $outputStr .= "$resr[1]"."|1"; } # If the response time is greater than parameterized max response time , then return warning. else { print "REC_AVG_RESP_TIME_EXCEEDED=Average Response time is greater than recommended $maxResponseTime milliseconds.\n" ; exit 1; } } # add the extra output columns if we are in advanced mode if($mode) { my $dropRate; # parse the package drop rate from line 0 of output unless(($dropRate) = ($resLns[0] =~ m/.*,\s.*,\s([\d\.]+)\%\s.*/o)) { # if the packet loss is 100% the line we need to parse is line 1 unless(($dropRate) = ($resLns[1] =~ m/.*\s([\d\.]+)\%\s.*/o)) { print "em_error=Failed parsing package drop rate"; exit 1; } } $outputStr .= "|$dropRate||"; } } print "$outputStr\n"; exit 0;