Nagios Plugin made in Perl

About writing shell scripts and making the most of your shell
Forum rules
Topics in this forum are automatically closed 6 months after creation.
Locked
jmdeking

Nagios Plugin made in Perl

Post by jmdeking »

Hi all,

I stumbled upon a great Perl script for Nagios.

What it does is reading out SNMP values on a Cisco switch and interpret those value's to show the results of which interfaces are not use for a number of days.

Now here comes the catch, the script uses the OID 1.3.6.1.2.1.1.3.0 (sysUpTime) but the sysUpTime is a 32-bit counter and will roll over after 496 days.

But i can poll snmpEngineId (.1.3.6.1.6.3.10.2.1.3) which returns the uptime in seconds and should not roll over for 135 years.

Now is the question how can i make the perl script interpret the seconds to days and show me the right results, i've try'd a few perl scripts to caculate seconds to days and try'd to implement it with no luck (duh) i just dont have enough experience with perl.

Can anyone on this forum help out?

Code: Select all

#!/usr/bin/perl
# 
############################## check_snmp_free_interfaces.pl ##############################
#										       #
# Description : Count the number of free interfaces more than X days on a switch       #
# Date : Apr 08 2011                                                                   #
# Author  : R. Lorenzini		                                               #
#										       #
########################################################################################
#
# Help : ./check_snmp_free_interfaces.pl -h
#

use Net::SNMP;
use Getopt::Long;

Getopt::Long::Configure('bundling');
GetOptions
    ("h"   => \$opt_h, "help"         => \$opt_h,
     "H=s" => \$opt_H, "hostname=s"     => \$opt_H,
     "C=s" => \$opt_C, "community=s"     => \$opt_C,
     "w=s" => \$opt_w, "warning=s"     => \$opt_w,
     "c=s" => \$opt_c, "warning=s"     => \$opt_c,
     "d=s" => \$opt_d, "delay=s"	     => \$opt_d,
     "e"   => \$opt_e, "extended"         => \$opt_e);
	

$script    = "check_snmp_free_interfaces.pl";
$script_version = "1.0";

# SNMP options
$version = "2c";
$timeout = 2;

$number_of_interfaces = 0;
@target_interface_index = (0);
@target_interface_descr = (0);
$target_interface = "ethernet";

$oid_ifnumber		= ".1.3.6.1.2.1.2.1.0";	
$oid_sysdescr 		= ".1.3.6.1.2.1.1.1.0";
$oid_ifdescr 		= ".1.3.6.1.2.1.2.2.1.2";	# need to append integer for specific interface
$oid_ifadminstatus	= ".1.3.6.1.2.1.2.2.1.7.";	# need to append integer for specific interface
$oid_ifoperstatus	= ".1.3.6.1.2.1.2.2.1.8.";	# need to append integer for specific interface
$oid_iflastchange	= ".1.3.6.1.2.1.2.2.1.9.";	# need to append integer for specific interface
$oid_uptime		= ".1.3.6.1.2.1.1.3.0";

$ifadminstatus		= "n/a";
$ifoperstatus		= "n/a";
$iflastchange		= "n/a";

$returnstring = "";

$warning = 5;
$critical = 2;
$community = "public"; 		# Default community string

if ($opt_h){
    usage();
    exit(0);
}
if ($opt_H){
    $hostname = $opt_H;
}
else {
    print "No specified hostname\n";
    usage();
    exit(0);
}
if ($opt_C){
    $community = $opt_C;
}
if ($opt_d){
    $delais = $opt_d;
}
else {
    print "No specified delay\n";
    usage();
    exit(0);
}
if ($opt_w){
    $warning = $opt_w;
}
if ($opt_c){
    $critical = $opt_c;
}

# Create the SNMP session

$version = "1";
($s, $e) = Net::SNMP->session(
   -community    =>  $community,
   -hostname     =>  $hostname,
   -version      =>  $version,
   -timeout      =>  $timeout,
);

if (!defined($s->get_request($oid_sysdescr))) {
  # If we can't connect using SNMPv1 lets try as SNMPv2
  $s->close();
  sleep 0.5;
  $version = "2c";
  ($s, $e) = Net::SNMP->session(
    -community    =>  $community,
    -hostname     =>  $hostname,
    -version      =>  $version,
    -timeout      =>  $timeout,
  );
  if (!defined($s->get_request($oid_sysdescr))) {
    print "Agent not responding, tried SNMP v1 and v2\n";
    exit(1);
  }
}


if (find_match() == 0){
    $nb_if_libre = 0;
    $count = 1;
    $res = $s->get_request(-varbindlist => [ $oid_uptime ],);
    @SysUptime = split(/\ /,$res->{$oid_uptime});
    if ( $SysUptime[0] < $delais ) {
        $status = 1;
                $returnstring = "Switch uptime lower than defined delay (Uptime is $SysUptime[0] days)";
    }
    else {
    	while ($count < ($#target_interface_index + 1)) {
		if (probe_interface() == 1) {
			$nb_if_libre = $nb_if_libre + 1;
		}
		$count = $count + 1 ;
    	}
    	if ($nb_if_libre > $warning) {
		$status = 0;
		$returnstring = "$nb_if_libre free interfaces on this switch | free_ports=$nb_if_libre";
    	}
   	else {
		if ($nb_if_libre > $critical) {
			$status = 1;
			$returnstring = "$nb_if_libre free interfaces on this switch | free_ports=$nb_if_libre";
    		}
		else {
			$status = 2;
			$returnstring = "$nb_if_libre free interfaces on this switch | free_ports=$nb_if_libre";
		}
    	}
    }
}
else {
    $status = 2;
    print "Interface $target_interface not found on device $hostname\n";
    exit $status;
}

# Close the session
$s->close();

if($status == 0){
    print "OK - $returnstring\n";
    exit $status;
}
elsif($status == 1){
    print "Warning - $returnstring\n";
    exit $status;
}
elsif($status == 2){
    print "CRITICAL - $returnstring\n";
    exit $status;
}
else{
    print "Plugin error! SNMP status unknown\n";
    exit $status;
}

exit 2;


#################################################
# Finds match for supplied interface name
#################################################

sub find_match {

    if (!defined($s->get_request($oid_ifnumber))) {
        if (!defined($s->get_request($oid_sysdescr))) {
            print "Status is a Warning Level - SNMP agent not responding\n";
            exit 1;
        }
        else {
            print "Status is a Warning Level - SNMP OID does not exist\n";
            exit 1;
        }
    }
    
    if (!defined($s->get_table($oid_ifdescr))){
    }
    else {
	foreach ($s->var_bind_names()) {
            $temp_interface_descr = $s->var_bind_list()->{$_};
	    if (index(lc($temp_interface_descr),lc($target_interface)) != -1) {
		@res = split(/\./,$_);
		push (@target_interface_index, $res[$#res]);
		push(@target_interface_descr,$temp_interface_descr);
	    }
        }
    }
    if ($#target_interface_index == 0){
        return 1;
    }
    else {
        return 0;
    }
}

####################################################################
# Gathers data about target interface                              #
####################################################################


sub probe_interface {

    $oid_temp = $oid_ifadminstatus . $target_interface_index[$count];    
    if (!defined($s->get_request($oid_temp))) {
    }
    else {
        foreach ($s->var_bind_names()) {
            $ifadminstatus = $s->var_bind_list()->{$_};
        }
    }
    ############################
        
    $oid_temp = $oid_ifoperstatus . $target_interface_index[$count];    
    if (!defined($s->get_request($oid_temp))) {
    }
    else {
        foreach ($s->var_bind_names()) {
            $ifoperstatus = $s->var_bind_list()->{$_};
	}
    }
    ############################
        
    $oid_temp = $oid_iflastchange . $target_interface_index[$count];    
    if (!defined($s->get_request($oid_temp))) {
    }
    else {
        foreach ($s->var_bind_names()) {
            $iflastchange = $s->var_bind_list()->{$_};
        }
    }
    ############################

    if (($ifadminstatus eq "2") || ($ifoperstatus eq "2")) {
	@lastchange = split(/\ /,$iflastchange);
	if ($lastchange[1] eq "days,") {
		$res = $SysUptime[0] - $lastchange[0];
	}
	else {
		$res = $SysUptime[0];
	}
	if ($res > $delais)
	  {
		if ($opt_e) {
			print "Interface ",$target_interface_descr[$count]," is free for ",$res," days.\n";
		}
		return 1;
	} 
	else {
		return 0;
		
	}
    }
    else {
	return 0;
    }

}

####################################################################
# help and usage information                                       #
####################################################################

sub usage {
    print << "USAGE";
--------------------------------------------------------------------
$script v$script_version

Return the number of interfaces down for more than X days.. 

Usage: $script -H <hostname> -c <community> [...]

Options: -H 	Hostname or IP address
         -C 	Community (default is public)
	 -d 	Number of days since interfaces are down
	 -w	Warning free interfaces - default 5
	 -c	Critical free interfaces - default 2
	 -e     Extended view
	
USAGE
     exit 1;
}



####################################################################
# Appends string to existing $returnstring                         #
####################################################################

sub append {
    my $appendstring =    @_[0];    
    $returnstring = "$returnstring$appendstring";
}

Last edited by LockBot on Wed Dec 28, 2022 7:16 am, edited 1 time in total.
Reason: Topic automatically closed 6 months after creation. New replies are no longer allowed.
pgmer6809
Level 4
Level 4
Posts: 228
Joined: Sun Mar 04, 2012 9:06 pm

Re: Nagios Plugin made in Perl U mean Time calcs

Post by pgmer6809 »

1. Your title is a bit unhelpful. What is Nagios? Why would someone on a Linux Mint forum care?
If I understand your post correctly, What you really want is help with time calculations in Perl. So your title should say that.

2. CPAN is your friend. One of Perl's big strengths is CPAN which has been built up over the last 20 years. NEVER write perl code before checking CPAN.
Go here: http://search.cpan.org

3. I am not sure what you are trying to do with the time. If you just want to accumulate uptime in seconds, and then convert seconds to years, months, days, hours and mins then a simple series of modulo divisions will work for you. So I assume it is something else.

Do you want to find out the date from which the system has been up? the last date the interface was used?
I.e. you need CalcDate = StartDate plus-or-minus seconds?

If such is the case, try looking at: http://search.cpan.org/~stbey/Date-Pcalc-6.1/Pcalc.pod
Locked

Return to “Scripts & Bash”