Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Ping Stress Test

by foxops (Monk)
on Oct 12, 2002 at 20:47 UTC ( [id://204814]=perlcraft: print w/replies, xml ) Need Help??

   1: ###########################
   2: ##Ping Stress Test
   3: ##desertfoxps@earthlink.net
   4: ##
   5: ## This is my first script, so it isn't as good as it could be,
   6: ## but its still pretty solid.
   7: ##
   8: ## The purpose is simply to ping a host with larger and larger
   9: ## pings until it fails.  It can be used to stress test any device
  10: ## that accepts ICMP, for fragment DOS.  Relevant information is
  11: ## dumped into a log file named after the host.
  12: ##
  13: ## An unmodified PING.EXE is required for Windows users (as Microsoft
  14: ## modified PING.EXE so that it cannot send large buffers), I don't know
  15: ## if *nix's PING.EXE will work /shrug.
  16: 
  17: use strict;
  18: my ($size,$RAW,@INFO,$TIME,$host,$fails);
  19: 
  20: $fails = 0; #Zero the var
  21: $size = 0; #Zero the var, of change to resume tests
  22: $host = '10.10.10.1'; #IP address of test subject
  23: 
  24: 
  25: while ($size = $size + 1) { #Increment buffer size
  26: open (DATA,"ssping -n 1 -l $size -w 1000 $host |"); #Call ping (I use SSPING.EXE
  27: @INFO = <DATA>;
  28: $RAW = join "", @INFO;
  29: $RAW =~ /time[<|=](.....)/gm; #Grab latency
  30: $TIME = $1;
  31:  if ($RAW =~ /Request/gs) { #Search for Request (as in Request timed out)
  32: 
  33:  open (DATA,"ssping -n 1 -l $size -w 2000 $host |"); #Double check the host
  34:  @INFO = <DATA>;
  35: 	$RAW = join "", @INFO;
  36:   if ($RAW =~ /Request/gs) { #Yup, it bit off to much
  37:   print "$host Failed at $size\n";
  38:   open LOG, ">>$host.log" or die $!;
  39:   print LOG "$host Failed at $size\n";
  40:   close LOG;
  41:   $fails = $fails + 1; #Increment fails
  42: 
  43:    if ($fails>=20) { #If to many consecutive fails...
  44:    print "Encountered Maximum amount of consecutive fails.\n";
  45:    exit;
  46:    }
  47:    goto END;
  48: 			
  49:   }
  50:   $fails = 0; #Zero the fails, as this was only a hiccup in traffic
  51:   print "$size    $TIME *Hiccup*\n"; #Host responded to second attempt
  52:   goto END;
  53: 		
  54:  }
  55:  print "$size    $TIME\n"; #Print good reply to screen
  56:  END:
  57: }

Replies are listed 'Best First'.
Re: Ping Stress Test
by Aristotle (Chancellor) on Oct 13, 2002 at 09:44 UTC

    Yuck, please don't use goto. Perl has next and last, which means you nearly never need the evil goto. Also, you could have saved a couple temporary variables in various places; f.ex $RAW = join "", <DATA>; would have let you get away without @INFO. (Even better would have been to write $RAW = do { local $/; <DATA> }; .) print ".."; exit; is nearly always better written as die "..";.

    Update { I forgot to mention: you should really check out Mark-Jason Dominus' excellent Program Repair Shop and Red Flags article series on Perl.com }

    That said, I would have used Net::Ping (as already suggested), and I'd also use one of the Getopt::* modules to make the script more flexible. Here's one possible rendition:

    #!/usr/bin/perl -w use strict; use Net::Ping 2.13; # earlier versions do not return ping time use Getopt::Std; my %opt = ( i => 1, m => 65536, p => "udp", r => 20, t => 1, ); getopts("a:i:m:p:t:r:", \%opt) and $opt{a} or die << "USAGE"; usage: $0 -a addr [-i minsize] [-m maxsize] [-p proto] [-r retr] [-t t +imeout] -a destination address -i initial ping size in bytes [default: 1] -m max ping size in bytes [default: 63536] -p protocol: tcp, udp, icmp [default: udp] -r maximum nr. or retries [default: 20] -t timeout in seconds [default: 1] USAGE my ($addr, $bytes, $maxsize, $proto, $timeout, $retries) = @opt{qw(a i m p t r)}; $Net::Ping::max_datasize = 65536; # we want to send huge packets until($bytes > $maxsize) { my $p = Net::Ping->new($proto, $timeout, $bytes); $p->hires(1); # precise ping times my ($success, $time); my $retry = 0; ($success, $time) = $p->ping($addr) until $success or (++$retry > $retries); die "Sorry, host $addr not found or network problem.\n" if not defined $success; die "Host $addr seems to have died at $bytes bytes packet size.\n" if $success == 0; printf "%3.2f msec for $bytes bytes packet size", $time; print " (traffic hiccuped, $retry tries)" if $retry > 1; print "\n"; ++$bytes; };
    Update: now tested. I also just noticed that the documentation of Net::Ping says you can only set the data size to 1024 bytes at most. There's a constant for that limit in the module however; I added a line to remove that limit.

    Makeshifts last the longest.

Re: Ping Stress Test
by jjdraco (Scribe) on Oct 12, 2002 at 22:51 UTC
    I've never messed around with any of the Net modules before, but you should take a look at Net::Ping.
    I think that would work better for you. But I could be wrong.

    jjdraco
    learning Perl one statement at a time.
      Last time I tested Net::Ping it crashed on me sometimes, so I had to roll my own.

      Update: This node is causing me some --, so perhaps I should explain myself. I used the Net::Ping in a script that built a tree of DNSinformation to make sure a DNS server was alive before I fetched data from it (this was an internal network), and I experienced problems with the Net::Ping module, that caused the program to abort and/or fail to report correctly if the server responded or not. I don't remember anything more, this was 2 years ago, and I didn't file a bug report on it. Perhaps it's better now.

Re: Ping Stress Test
by TStanley (Canon) on Oct 13, 2002 at 01:29 UTC
    As jjdraco mentions above, the Net::Ping module is a good one to use for this, and would greatly simplify your script. One thing to note however, is that you might need to be the root user on some *nix systems, if you are sending ICMP packets. Otherwise, you can use UDP by default.

    TStanley
    --------
    It is God's job to forgive Osama Bin Laden. It is our job to arrange the meeting -- General Norman Schwartzkopf
Re: Ping Stress Test
by foxops (Monk) on Oct 13, 2002 at 15:51 UTC
    Thanks everyone, I had a feeling that net::ping had a limit set on it - and I didn't feel like searching through the code to find it :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (5)
As of 2024-04-25 15:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found