On Tue, Apr 30, 2002 at 07:30:22AM +0000, SXren Neigaard wrote:
> 
> Oh yes I'm very interested in that script. Sorry for the late answer, but I 
> have been on holiday :)
> 
> What does that actually mean, if no IP replies? How does that work - do I 
> configure a list of IP's to monitor?
> 

Yes you configure several IPs in your hostlist. Recent versions of
fping.monitor included in mon or my script below have an option
to report failure _only_ when all targets fail.

You append this option to the scripts call in yopur watch definition.

Here is an example:

hostgroup link-provider www.provider.net ns.provider.net 

watch link-provider
    service link
        interval 5m
        monitor icmp.monitor -l
        period SMS: wd {Sun-Sat} hr {7am-10pm}
            alertevery 1h summary
            alertafter 2
            comp_alerts
            alert sms.alert 0123456
            upalert sms.alert 0123456
        period MAIL: wd {Sun-Sat}
            alertevery 1h summary
            alertafter 2
            comp_alerts
            alert mail.alert [EMAIL PROTECTED]
            upalert mail.alert [EMAIL PROTECTED]

-- 
 Alles Gute / best wishes  
     Dietmar Goldbeck                E-Mail: [EMAIL PROTECTED]
Reporter (to Mahatma Gandhi): Mr Gandhi, what do you think of Western
Civilization?  Gandhi: I think it would be a good idea.
#!/usr/bin/perl -w
#
# icmp statistic
# For use with "mon".
#
# Dietmar Goldbeck <[EMAIL PROTECTED]>
# Stand 18.04.2002 
#
# Arguments are "host [host...]"
# 
# Options are 
#
# -l link Test, returns OK if _at_ _least_ one target responds
# -t <msecs> Timeout in milliseconds for maximum round trip time  
#            Default is 5000msec, meaning RTT practically untested
# -n <packets> Number of packets used for fping and mtr measurements
# -p <percentage> 
#            maximum acceptable packet loss Percentage (default is 15)
# -v         Verbose, gives debugging output 
#
use Getopt::Std;
use Net::Ping;
use Time::HiRes qw(gettimeofday);
#
use strict;
use vars qw($opt_l $opt_n $opt_p $opt_t $opt_v
            $TIMEOUT $PACKETS $MAXLOSS 
            $linkTest $verbose $icmpTimeout $bytes
            @hosts $host
            @failures @details
            $p
            $euidorig $uidorig
                );


#make perl -w happy:
$opt_l='';$opt_n=''; $opt_p=''; $opt_t=''; 
$opt_v='';
### dont use root when not needed
$euidorig=$>;
$uidorig=$<;
$>=$<;
###
# needed for perl suid
$ENV{'PATH'} = "/bin:/usr/bin:/usr/sbin:/usr/local/bin";    

getopts ("ln:p:t:v");
if($opt_t =~ /([0-9]+)/) {
    $TIMEOUT = $1;
} else {
    $TIMEOUT = 5000;
}

if($opt_p =~ /([0-9]+)/) {
    $MAXLOSS = $1;
} else {
    $MAXLOSS = 15;
}

if($opt_n =~ /([0-9]+)/) {
    $PACKETS = $1;
} else {
    $PACKETS = 15;
}
$linkTest = $opt_l || 0;
$verbose = $opt_v || 0;
$icmpTimeout = 2;
$bytes = 8;

@hosts = ();
foreach $host (@ARGV) {
    #
    # Check hostname, because running suid
    if ($host !~ /([a-z0-9\.\-]+)/) {
        push (@failures, $host);
        push (@details, "invalid hostname $host\n");
    } else {
        push(@hosts, $1);
    }
}

#print STDERR "DEBUG \@hosts = @hosts\n";

@failures = ();
@details = ();
$>=$euidorig;
$p = Net::Ping->new("icmp", $icmpTimeout, $bytes);
$>=$uidorig;
#print STDERR "DEBUG: und los\n";

if($linkTest > 0) {
    linkPing(@hosts);
}

foreach $host (@hosts) {
    my($lpOK);
    my($OK, $detail);
    #
    $lpOK = linkPing( ( $host ) );
    #! $verbose || print STDERR "linkPing($host) returned $lpOK\n";
    if(!$lpOK) {
        ($OK, $detail) = &fping($host, $TIMEOUT, $MAXLOSS, $PACKETS);   
        if (!defined ($OK) || $OK == 0) {
            push (@failures, $host);
            if(defined($detail)) {
                push (@details, $detail);
            }
        }
    }
}

if (! @failures) {
  exit(0);
} else {
  &someUnreachable(@hosts);
  print (join(" ", @failures));
  print "\n";
  print (join("\n", @details));
  print "\n";
  exit 1;
}

sub someUnreachable {
    my(@hosts) = @_;
    my($host);
    #
    if($linkTest == 1 && $#hosts > $#failures) {
        exit 0;
    } else {
        foreach $host (@failures) {
            push(@details, &mtr($host));
        }
    }     
}

sub mtr {
    my($host) = @_;
    my($tr);
    #
    $tr = "mtr to $host\n" . `mtr -t -n -c $PACKETS -r  $host 2>&1`;
    return $tr;
}

sub fping {
  my($host, $timeout, $maxloss, $packets) = @_;
  my($fping);
  my($h);
  my(@rttList, $rtt);
  my($sumrtt) = 0;
  my($avgrtt);
  my($losscount) = 0;
  my($Preceived) = 0;
  my($lossP);
  #
  # needed for perl suid
  $fping = `fping -p 2000 -C $packets -q $host 2>&1`;
  #
  if($verbose) 
    { print STDERR "fping -p 2000 -C $packets -q $host\n$fping\n"; }
  #
  if($fping =~ /^([^\:])+:\s+(.*)$/) {
    @rttList = split(/\s/, $2);
  } else {
    return(0, "fping error for $host\n");
  } 
  foreach $rtt (@rttList) {
    if($rtt =~ /\-/) {
      $losscount++;
    } else {
      $rtt = int($rtt);
      $sumrtt += $rtt;
      $Preceived++;
    }
  }
  #print "DEBUG: losscount=$losscount maxrtt=$maxrtt\n";
  if (($Preceived + $losscount) < $packets) {
    return(0, "fping error for $host\n");
  } elsif ($Preceived == 0) {
    return (0, "$host unreachable (100% loss)\n");
  } else {
    $lossP = $losscount * 100 / $packets;
    $avgrtt = $sumrtt / $Preceived;
    if($maxloss < $lossP) {
      return (0, "high Packet loss ($lossP%) for $host\n");
    } elsif ($timeout < $avgrtt) {
      return (0, "Average RTT exceeds $timeout for $host\n");
    } else {
      return 1;
    }
  }
}

sub linkPing {
  my(@hosts) = @_;
  my($start);
  my($rtt);
  my($link) = 1;
  my($reachable);
  #
  #print STDERR "DEBUG linkPing \@hosts = @hosts\n";
  foreach $host (@hosts) {      
    $start = now();
    $reachable = $p->ping($host);
    $rtt = now() - $start;
    if($reachable && $rtt < $TIMEOUT / 1000.0) {
      if($verbose) {
        $rtt = now() - $start;
        print STDERR "$host: $rtt s\n";
      }
      if ($linkTest) { exit 0 };
    } else {
      $link = 0;
      if($verbose) {
        if(! $reachable) {
          print STDERR "$host: no answer\n";
        } else {
          print STDERR "$host: RTT exceeds timeout\n";
        }
      }
    }
  }
  return $link;
}
  
sub now {
    my(@t) = gettimeofday();
    return $t[0] + ($t[1] / 1000000.0);
}

Reply via email to