Security and Technology Ramblings…

For a while now, I have been looking for a simple perl script that would watch a set of hosts/IP addresses and report back an up/down status, min, current and max ping times.

Never found one, so I threw something together below. Feel free to use it the need fits.

Oh, and keep in mind, I’m relatively new to perl. So, I would welcome some feedback or constructive criticism on my coding. Let me know how I should have done it differently.

Screen Output:

Code:



#!/opt/local/bin/perl
################################################
#Script:   pingchart                           #
#Author:   John Penrod                         #
#Contact:  penrodcc -at- gmail.com             #
#Version:  1.17                                 #
#Date:     20110604                            #
################################################
use Net::Ping;
use Term::Screen;
use Term::ReadKey;
ReadMode 4;
my $time = 1; #Sleep between pings
my $initiallength = 0;

open (FILE, "<", "hostfile") or die "Host File Missing!";
  while (<FILE>) {
  chomp;
  push (@host_array, $_);
  }
close (FILE);

foreach my $host (@host_array) {
  $host =~ chomp($host);
  $length = length ($host);
  if ( $length > $initiallength ) {
    $initiallength = $length;
    }
  }

  $length = $initiallength;

my %hash;
my $row = 0;
my $status = "U"; #Default HOST status.
my $currentpingount = 1;
my $dropped = 0;

foreach my $host (@host_array) {
  #           host   min      max  current total avg  
  $hash{$row} = [ $host, 1000000, 0, 0, 0, 0];
  $row++;
  }

$p = Net::Ping->new(icmp,2);
$p->hires();
$scr = new Term::Screen ; unless ($scr) { die " Can not setup screen \n"; }
$scr->clrscr();

while (not( defined ($key = ReadKey(-1)))) {
  $scr->at(0,0) ->puts("Ping Tester - Press Q to quit.");
  $scr->at(2,0) ->puts("Host");     $scr->at(3,0) ->puts("----");
  $scr->at(2,$length+5) ->puts("Status");  $scr->at(3,$length+5) ->puts("------");
  $scr->at(2,$length+25) ->puts("Drop"); $scr->at(3,$length+25) ->puts("----");
  $scr->at(2,$length+33) ->puts("Minimum"); $scr->at(3,$length+33) ->puts("-------");
  $scr->at(2,$length+43) ->puts("Current"); $scr->at(3,$length+43) ->puts("-------");
  $scr->at(2,$length+53) ->puts("Maximum"); $scr->at(3,$length+53) ->puts("-------");
  #$scr->at(2,$length+70) ->puts("Average"); $scr->at(3,$length+70) ->puts("-------");
  our $line = 4;
  for my $h (keys %hash) {
        ($host,$min,$max,$currentping,$totalpings,$average) = @{$hash{$h}};
    ($ret, $duration, $ip) = $p->ping($host, 5.5);  
          $duration2 = 1000 * $duration;
          $duration3 = sprintf("%.2f", "$duration2");
                if ( $duration3 > 5000 ) {
                        $status = "D";
      $totalpings++;
                  $scr->at($line,0)  ->puts("$host");
                  $percent = ($currentping/$totalpings)*100;
                  $percent2 = sprintf("%.2f%%", "$percent");
                  $scr->at($line,$length+5) ->puts("$status $currentping\/$totalpings \($percent2\)");
      $dropped   = $totalpings-$currentping;
                        $scr->at($line,$length+25) ->puts("$dropped");
                        $scr->at($line,$length+33) ->puts("  -  ");
                        $scr->at($line,$length+43) ->puts("  -  ");
                        $scr->at($line,$length+53) ->puts("  -     ");
      @{$hash{$h}} = ("$host", "$min", "$max", "$currentping", "$totalpings", "$average");
                        }
                else    {
      $status = "U";
                        $currentping++;
                        $totalpings++;
      if ( $duration3 <= $min ) {
        $min = $duration3;
        }
      if ( $duration3 >= $max ) {
        $max = $duration3;
        }
      $dropped   = $totalpings-$currentping;
      if ( $dropped > 0) {
                          $max = "Infinite";
                          }
                  $scr->at($line,0)  ->puts("$host");
                  $percent = ($currentping/$totalpings)*100;
                  $percent2 = sprintf("%.2f%%", "$percent");
                  $scr->at($line,$length+5) ->puts("$status $currentping\/$totalpings \($percent2\)");
      $dropped   = $totalpings-$currentping;
                        $scr->at($line,$length+25) ->puts("$dropped");
                        $scr->at($line,$length+33) ->puts("$min");
                        $scr->at($line,$length+43) ->puts("$duration3");
                        $scr->at($line,$length+53) ->puts("$max");
                        @{$hash{$h}} = ("$host", "$min", "$max", "$currentping", "$totalpings", "$average");

    }
    $line++;
     }    
  sleep $time;
}
$line++;
$scr->at($line,0) ->puts("");
ReadMode 0; 
$p->close();

Leave a Reply