[Nagiosplug-devel] network management plugins

Guy Van Den Bergh guy.vandenbergh at belnet.be
Wed Sep 4 10:48:06 CEST 2002


Hi guys,

I've written a few plugins useful for network management. They all
written in perl, and using snmp for talking to the routers. They are in
attachment:

check_xinterface: an 'extended' plugin for monitoring router interfaces
via snmp. It only uses standard mibs for maximum vendor independence.
	
check_cisco_env: for monitoring environment of cisco routers
(temperature, power supply, ...)

check_juniper_env: about the same for juniper routers.

They perform well in a production environment, but I've had some memory
leaks when using the embedded perl interpreter. So I've switched off the
interpreter :)

Take a look at it and maybe they are useful for the main plugin
distribution.

Off course any comments are welcome...

Best regards,
-- 
Guy Van Den Bergh
BELNET -- Network Engineer

Wetenschapsstraat 4
B-1000 Brussel
Tel. +32 2 790.33.33
Fax. +32 2 790.33.34
-------------- next part --------------
#!/usr/bin/perl -wT
#
# check_xinterface - nagios plugin 
#
# largely based upon check_ifoperstatus.pl plugin by Christoph Kron
# 
#
#
#
# Copyright (C) 2002 Guy Van Den Bergh
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
#
# Report bugs to: guy at belnet.be
#

# design of the plugin:
#  check admin status: if down, then warning; exit
#  check operational status: if down, then critical; exit
#  check last change, if within 'tolerance' (-l or --last-change option),
#    then warning
#  get performance data: bits in/out, etc... (implementation to be scheduled later)
#  performance data could be checked against older values (bw drops e.g.)

use strict;

use Net::SNMP;
use Getopt::Long;
&Getopt::Long::config('auto_abbrev');


my $status;
my $TIMEOUT = 60;

my %ERRORS = ('UNKNOWN' , '-1',
              'OK' , '0',
              'WARNING', '1',
              'CRITICAL', '2');

my %ciscoEnvMonState = 	('1','normal(1)',
			 '2','warning(2)',
			 '3','critical(3)',
			 '4','shutdown(4)',
			 '5','notPresent(5)',
			 '6','notFunctioning(6)');

my $state = "UNKNOWN";
my $answer = "";
my $snmpkey = 1;
my $community = "public";
my $port = 161;
my $t_oid;
my @snmpoids;
my %error_oids;
my $snmpCiscoVoltageStatus;
my $snmpCiscoTemperatureStatus;
my $snmpCiscoFanStatus;
my $snmpCiscoSupplyStatus;
my $hostname;
my $session;
my $error;
my $response;
my $value;
my $oid;
my @voltage_errors;
my @temperature_errors;
my @fan_errors;
my @supply_errors;


sub usage {
  printf "\nMissing arguments!\n";
  printf "\n";
  printf "Perl Check Cisco Environment plugin for Nagios\n";
  printf "checks status of temperature, fans, ...\n";
  printf "usage: \n";
  printf "check_cisco_env -c <READCOMMUNITY> -p <PORT> <HOSTNAME>";
  printf "\nCopyright (C) 2002 Guy Van Den Bergh\n";
  printf "check_cisco_env comes with ABSOLUTELY NO WARRANTY\n";
  printf "This programm is licensed under the terms of the ";
  printf "GNU General Public License\n(check source code for details)\n";
  printf "\n\n";
  exit $ERRORS{"UNKNOWN"};
}

# Just in case of problems, let's not hang Nagios
$SIG{'ALRM'} = sub {
     print ("ERROR: No snmp response from $hostname (alarm)\n");
     exit $ERRORS{"UNKNOWN"};
};
alarm($TIMEOUT);


$status = GetOptions("community=s",\$community,
                     "port=i",\$port);
if ($status == 0)
{
        &usage;
}
  
   #shift;
   $hostname  = shift || &usage;

   ($session, $error) = Net::SNMP->session(
      -hostname  => $hostname,
      -community => $community,
      -port      => $port
   );

   if (!defined($session)) {
      $state='UNKNOWN';
      $answer=$error;
      print ("$state: $answer");
      exit $ERRORS{$state};
   }

   $snmpCiscoVoltageStatus = '.1.3.6.1.4.1.9.9.13.1.2.1.7';
   $snmpCiscoTemperatureStatus = '.1.3.6.1.4.1.9.9.13.1.3.1.6';
   $snmpCiscoFanStatus = '.1.3.6.1.4.1.9.9.13.1.4.1.3';
   $snmpCiscoSupplyStatus = '.1.3.6.1.4.1.9.9.13.1.5.1.3';


   push(@snmpoids,$snmpCiscoVoltageStatus);
   push(@snmpoids,$snmpCiscoTemperatureStatus);
   push(@snmpoids,$snmpCiscoFanStatus);
   push(@snmpoids,$snmpCiscoSupplyStatus);
   #
   # These four oids all have the same syntax,
   # which makes it easy for scripting all four oids at the same time!
   #

   $answer = "No data returned (Environment MIB not supported)";
   # This will be overwritten when there IS data returned!

   TABLE:
   foreach $t_oid (@snmpoids) {
   #
   # Now get all relevant oids, and set the plugin output status accordingly.
   #

      if (!defined($response = $session->get_table($t_oid))) {
         $error_oids{$t_oid} = $session->error;
         next TABLE;
      }

      while ( ($oid, $value) = each %$response ) {

         if ($value == 1 || $value == 5 || $value == 6) {
           # normal, notPresent or notFunctioning
           $state = 'OK' if $state =~ /UNKNOWN/;
           $answer = "All environment variables normal." if $state eq 'OK';
         } elsif ($value == 2) {
           # warning
	   $error_oids{$oid} = $ciscoEnvMonState{$value};
           $state = 'WARNING' unless $state =~ /CRITICAL/;
         } elsif ($value == 3 || $value == 4) {
           # critical or shutdown
           $error_oids{$oid} = $ciscoEnvMonState{$value};
           $state = 'CRITICAL'
         }

      }
   }

   $session->close;

## Here is the place for introducing artificial errors (for debugging).


#
# Now parse all erroneous responses:
#

unless ($state eq 'OK' or $state eq 'UNKNOWN') {

   while ( ($oid, $value) = each %error_oids ) {

      $value =~ s/\(\d\)//;

      if ($oid =~ /$snmpCiscoVoltageStatus\./) {
         $oid =~ s/$snmpCiscoVoltageStatus\.//;
         push(@voltage_errors, "$value (instance $oid)");

      } elsif($oid =~ /$snmpCiscoTemperatureStatus\./) {
         $oid =~ s/$snmpCiscoTemperatureStatus\.//;
         push(@temperature_errors, "$value (instance $oid)");

      } elsif ($oid =~ /$snmpCiscoFanStatus\./) {
         $oid =~ s/$snmpCiscoFanStatus\.//;
         push(@fan_errors, "$value (fan $oid)");

      } elsif ($oid =~ /$snmpCiscoSupplyStatus\./) {
         $oid =~ s/$snmpCiscoSupplyStatus\.//;
         push(@supply_errors, "$value (PS $oid)");
      }
   }

   #
   # And now the final formatting of the output:
   #

   my $voltage_errors_s = join ";", @voltage_errors if defined $voltage_errors[0];
   my $temperature_errors_s = join ";", @temperature_errors if defined $temperature_errors[0];
   my $fan_errors_s = join ";", @fan_errors if defined $fan_errors[0];
   my $supply_errors_s = join ";", @supply_errors if defined $supply_errors[0];

   $answer = "Problems with:<BR>";
   $answer .= "Voltage: " . $voltage_errors_s . "<BR>" if defined $voltage_errors_s;
   $answer .= "Temperature: " . $temperature_errors_s . "<BR>" if defined $temperature_errors_s;
   $answer .= "Fans: " . $fan_errors_s . "<BR>" if defined $fan_errors_s;
   $answer .= "Power Supply: " . $supply_errors_s ."<BR>" if defined $supply_errors_s;
}

print ("$answer\n");
exit $ERRORS{$state};

-------------- next part --------------
#!/usr/bin/perl -wT
#
# check_juniper_env - nagios plugin 
#
# largely based upon check_ifoperstatus.pl plugin by Christoph Kron
# 
#
#
#
# Copyright (C) 2002 Guy Van Den Bergh
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
#
# Report bugs to: guy at belnet.be
#

# design of the plugin:
#  check admin status: if down, then warning; exit
#  check operational status: if down, then critical; exit
#  check last change, if within 'tolerance' (-l or --last-change option),
#    then warning
#  get performance data: bits in/out, etc... (implementation to be scheduled later)
#  performance data could be checked against older values (bw drops e.g.)

use strict;

use Net::SNMP;
use Getopt::Long;
&Getopt::Long::config('auto_abbrev');


my $status;
my $TIMEOUT = 15;

my %ERRORS = ('UNKNOWN' , '-1',
              'OK' , '0',
              'WARNING', '1',
              'CRITICAL', '2');

my %jnxOperatingState =	('1','unknown(1)',
			 '2','running(2)',
			 '3','ready(3)',
			 '4','reset(4)',
			 '5','runningAtFullSpeed(5)',
			 '6','down(6)',
			 '7','standby(7)');

my $state = "UNKNOWN";
my $answer = "";
my $snmpkey = 1;
my $community = "public";
my $port = 161;
my $t_oid;
my %error_oids;
my $snmpJnxOperatingDescr;
my $snmpJnxOperatingState;
my $snmpJnxOperatingTemp;
my $snmpJnxOperatingCPU;
my $hostname;
my $session;
my $error;
my $response;
my $temp_w;
my $temp_c;
my $cpu_w;
my $cpu_c;
my $value;
my $descr;
my $oid;
my @state_errors;
my @temp_errors;
my @cpu_errors;


sub usage {
  printf "\nMissing arguments!\n";
  printf "\n";
  printf "Perl Check Juniper Environment plugin for Nagios\n";
  printf "checks status of temperature, fans, ...\n";
  printf "usage: \n";
  printf "check_juniper_env --community <READCOMMUNITY> --port <PORT> --temp <warn-temp:critical-temp> --load <warn-cpu:critical-cpu> <HOSTNAME>";
  printf "\nCopyright (C) 2002 Guy Van Den Bergh\n";
  printf "check_juniper_env comes with ABSOLUTELY NO WARRANTY\n";
  printf "This programm is licensed under the terms of the ";
  printf "GNU General Public License\n(check source code for details)\n";
  printf "\n\n";
  exit $ERRORS{"UNKNOWN"};
}

# Just in case of problems, let's not hang Nagios
$SIG{'ALRM'} = sub {
     print ("ERROR: No snmp response from $hostname (alarm)\n");
     exit $ERRORS{"UNKNOWN"};
};
alarm($TIMEOUT);


$status = GetOptions("community=s",\$community,
                     "port=i",\$port,
                     "temp=s",\$temp_w,
                     "load=s",\$cpu_w);
if ($status == 0)
{
        &usage;
}

if ($temp_w =~ /\d+:\d+/ and $cpu_w =~ /\d+:\d+/) {
   ($temp_w, $temp_c) = split /:/, $temp_w;
   ($cpu_w, $cpu_c) = split /:/, $cpu_w;

   if ($temp_w > $temp_c) {
      print "Critical temp is below warning level\n\n";
      &usage;
   } elsif ($cpu_w > $cpu_c) {
      print "Critical CPU is below warning level\n\n";
      &usage;
   }
} else {
   &usage;
}
  
   #shift;
   $hostname  = shift || &usage;

   ($session, $error) = Net::SNMP->session(
      -hostname  => $hostname,
      -community => $community,
      -port      => $port
   );

   if (!defined($session)) {
      $state='UNKNOWN';
      $answer=$error;
      print ("$state: $answer");
      exit $ERRORS{$state};
   }

   $snmpJnxOperatingDescr = '.1.3.6.1.4.1.2636.3.1.13.1.5';
   $snmpJnxOperatingState = '.1.3.6.1.4.1.2636.3.1.13.1.6';
   $snmpJnxOperatingTemp =  '.1.3.6.1.4.1.2636.3.1.13.1.7';
   $snmpJnxOperatingCPU =   '.1.3.6.1.4.1.2636.3.1.13.1.8';

   $answer = "No data returned (Environment MIB not supported)";
   # This will be overwritten when there IS data returned!

   #
   # get all jnxOperatingState values (see %jnxOperatingState).
   #

   if (!defined($response = $session->get_table($snmpJnxOperatingState))) {
         $error_oids{$snmpJnxOperatingState} = $session->error;
      }

   while ( ($oid, $value) = each %$response ) {

      if ($value == 1 || $value == 2 || $value == 3 || $value == 7) {
        # unknown, running, ready or standby
        $state = 'OK' if $state =~ /UNKNOWN/;
        $answer = "All environment variables normal." if $state =~ /UNKNOWN/;
      } elsif ($value == 4 || $value == 5) {
        # reset or runningAtFullSpeed
        $error_oids{$oid} = $jnxOperatingState{$value};
        $state = 'WARNING' unless $state =~ /CRITICAL/;
      } elsif ($value == 6) {
        # down
        $error_oids{$oid} = $jnxOperatingState{$value};
        $state = 'CRITICAL'
      }
   }

   #
   # get all temperature values
   #

   if (!defined($response = $session->get_table($snmpJnxOperatingTemp))) {
         $error_oids{$snmpJnxOperatingTemp} = $session->error;
      }

   while ( ($oid, $value) = each %$response ) {

      if ($value < $temp_w) {
        $state = 'OK' if $state =~ /UNKNOWN/;
        $answer = "All environment variables normal." if $state =~ /UNKNOWN/;
      } elsif ($value < $temp_c) {
        $error_oids{$oid} = " $value ?C";
        $state = 'WARNING' unless $state =~ /CRITICAL/;
      } else {
        $error_oids{$oid} = " $value ?C";
        $state = 'CRITICAL'
      }
   }

   #
   # get all cpu values
   #

   if (!defined($response = $session->get_table($snmpJnxOperatingCPU))) {
         $error_oids{$snmpJnxOperatingCPU} = $session->error;
      }

   while ( ($oid, $value) = each %$response ) {

      if ($value < $cpu_w) {
        $state = 'OK' if $state =~ /UNKNOWN/;
        $answer = "All environment variables normal." if $state =~ /UNKNOWN/;
      } elsif ($value < $cpu_c) {
        $error_oids{$oid} = " $value%";
        $state = 'WARNING' unless $state =~ /CRITICAL/;
      } else {
        $error_oids{$oid} = " $value%";
        $state = 'CRITICAL'
      }
   }

## Here is the place for introducing artificial errors (for debugging).

unless ($state eq 'OK' or $state eq 'UNKNOWN') {

   while ( ($oid, $value) = each %error_oids ) {


      if ($oid =~ /$snmpJnxOperatingState\./) {

         $value =~ s/\(\d\)//;
         $oid =~ s/$snmpJnxOperatingState\.//;

         if ($response = $session->get_request($snmpJnxOperatingDescr.".$oid")) {
            $descr = $$response{$snmpJnxOperatingDescr.".$oid"};
         } else {
            $descr = "instance $oid";
         }
         push(@state_errors, "$descr is $value");

      } elsif ($oid =~ /$snmpJnxOperatingTemp\./) {

         $oid =~ s/$snmpJnxOperatingTemp\.//;

         if ($response = $session->get_request($snmpJnxOperatingDescr.".$oid")) {
            $descr = $$response{$snmpJnxOperatingDescr.".$oid"};
         } else {
            $descr = "instance $oid";
         }
         push(@temp_errors, " $descr : $value");

      } elsif ($oid =~ /$snmpJnxOperatingCPU\./) {

         $oid =~ s/$snmpJnxOperatingCPU\.//;

         if ($response = $session->get_request($snmpJnxOperatingDescr.".$oid")) {
            $descr = $$response{$snmpJnxOperatingDescr.".$oid"};
         } else {
            $descr = "instance $oid";
         }
         push(@cpu_errors, " $descr : $value");
      }
   }

   my $state_errors_s = join ";", @state_errors if defined $state_errors[0];
   my $temp_errors_s = join ";", @temp_errors if defined $temp_errors[0];
   my $cpu_errors_s = join ";", @cpu_errors if defined $cpu_errors[0];

   $answer = "Problems with:<BR>";
   $answer .= "State: " . $state_errors_s . "<BR>" if defined $state_errors_s;
   $answer .= "Temperature: " . $temp_errors_s . "<BR>" if defined $temp_errors_s;
   $answer .= "CPU: " . $cpu_errors_s . "<BR>" if defined $cpu_errors_s;

   $session->close;
}

print ("$answer\n");
exit $ERRORS{$state};

-------------- next part --------------
#!/usr/bin/perl -wT
#
# check_xinterface - nagios plugin 
#
# largely based upon check_ifoperstatus.pl plugin by Christoph Kron
# 
#
#
#
# Copyright (C) 2002 Guy Van Den Bergh
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
#
# Report bugs to: guy at belnet.be
#

# design of the plugin:
#  get index for interface from -i option (format: <ifName>::<ifIndex>)
#  check whether ifName matches ifIndex: if not: warning; exit
#  check admin status: if down, then warning; exit
#  check operational status: if down, then critical; exit
#  check last change, if within 'tolerance' (-l or --last-change option),
#    then warning
#  get performance data: bits in/out, etc... (implementation to be scheduled later)
#  performance data could be checked against older values (bw drops e.g.)

use strict;

use Net::SNMP;
use Getopt::Long;
&Getopt::Long::config('auto_abbrev');

my @cmdline = @ARGV;


my $status;
my $TIMEOUT = 15;

my %ERRORS = ('OK' , '0',
              'WARNING', '1',
              'CRITICAL', '2',
              'UNKNOWN', '3');

my %ifOperStatus = 	('1','up',
			 '2','down',
			 '3','testing',
			 '4','unknown',
			 '5','dormant',
			 '6','notPresent');

my $state = "UNKNOWN";
my $answer = "(No output. Bug?)";
my $ifName;
my $ifIndex;
my $ifDescr;
my $community = "public";
my $port = 161;
my @snmpoids;
my $snmpIfName;
my $snmpIfDescr;
my $snmpIfAlias;
my $snmpIfAdminStatus;
my $snmpIfOperStatus;
my $hostname;
my $session;
my $error;
my $response;


sub usage {
  printf "\nMissing arguments!\n";
  printf "\n";
  printf "Perl eXtended Check Interface plugin for Nagios\n";
  printf "checks status of specified interface\n";
  printf "When the interface state changed within the last check interval, a WARNING is returned. \n\n";
  printf "usage: \n";
  printf "check_xinterface -i <ifIndex> -n <ifName> -c <READCOMMUNITY> -p <PORT> <HOSTNAME>\n";
  printf "\nCopyright (C) 2002 Guy Van Den Bergh\n";
  printf "check_xinterface comes with ABSOLUTELY NO WARRANTY\n";
  printf "This programm is licensed under the terms of the ";
  printf "GNU General Public License\n(check source code for details)\n";
  printf "\n\n";
  exit $ERRORS{"UNKNOWN"};
}

# Just in case of problems, let's not hang Nagios
$SIG{'ALRM'} = sub {
     print ("ERROR: No snmp response from $hostname (alarm)\n");
     exit $ERRORS{"UNKNOWN"};
};
alarm($TIMEOUT);


$status = GetOptions("index=s",\$ifIndex,
                     "name=s",\$ifName,
                     "community=s",\$community,
                     "port:i",\$port);
if ($status == 0)
{
        &usage;
}

if (not defined $ifIndex) {
	print ("ERROR: No snmp ifIndex supplied (@cmdline)\n");
	exit $ERRORS{"UNKNOWN"};
}

if (not defined $ifName) {
	print ("ERROR: No snmp ifName supplied (@cmdline)\n");
	exit $ERRORS{"UNKNOWN"};
}
  
   $hostname  = shift || &usage;

   ($session, $error) = Net::SNMP->session(
      -hostname  => $hostname,
      -community => $community,
      -port      => $port
   );

   if (!defined($session)) {
      $state='UNKNOWN';
      $answer=$error;
      print ("$state: $answer");
      exit $ERRORS{$state};
   }

   $snmpIfAdminStatus	= '.1.3.6.1.2.1.2.2.1.7.' . $ifIndex;
   $snmpIfOperStatus	= '.1.3.6.1.2.1.2.2.1.8.' . $ifIndex;
   $snmpIfName		= '.1.3.6.1.2.1.31.1.1.1.1.' . $ifIndex;
   $snmpIfDescr		= '.1.3.6.1.2.1.2.2.1.2.' . $ifIndex;
   $snmpIfAlias		= '.1.3.6.1.2.1.31.1.1.1.18.' . $ifIndex;

   push(@snmpoids,$snmpIfName);
   push(@snmpoids,$snmpIfDescr);
   push(@snmpoids,$snmpIfAdminStatus);
   push(@snmpoids,$snmpIfOperStatus);

   if (!defined($response = $session->get_request(@snmpoids))) {
      $answer=$session->error;
      $session->close;
      $state = 'WARNING';
      print ("$state: SNMP error: $answer\n");
      exit $ERRORS{$state};
   }

   if ( not ($response->{$snmpIfName} eq $ifName) ) {
      $state = 'UNKNOWN';
      $answer = "Interface name ($ifName) doesn't match snmp value ($response->{$snmpIfName}) (index $ifIndex)";

   } elsif ( not ($response->{$snmpIfAdminStatus} == 1) ) {
      $state = 'WARNING';
      $answer = "Interface $ifName (index $ifIndex) is administratively down.";

   } elsif ( not ($response->{$snmpIfOperStatus} == 1) ) {
      $state = 'CRITICAL';
      $answer = "Interface $ifName (index $ifIndex) is down.";
   } else {
      $state = 'OK';
      $answer = "Interface $ifName (index $ifIndex) is up.";
   }

# Get ifAlias if available.
@snmpoids = ($snmpIfAlias);

$ifDescr = $response->{$snmpIfDescr} if defined $response->{$snmpIfDescr};

if (defined($response = $session->get_request(@snmpoids))
    and defined $response->{$snmpIfAlias}
    and length ($response->{$snmpIfAlias}) > 0) {

   $answer .= "<BR>ifAlias: $response->{$snmpIfAlias}";

} elsif (defined $ifDescr
         and length ($ifDescr) > 0) {

   $answer .= "<BR>ifDescr: $ifDescr";
}

$session->close;

print ("$state: $answer\n");
exit $ERRORS{$state};



More information about the Devel mailing list