#!/usr/bin/perl
# 
############################## check_cisco_free_interfaces #############################
#										       #
# Description : Count the number of free interfaces more than X days on a cisco switch #
# Date : Feb 20 2008                                                                   #
# Author  : Archinard Johan		                                               #
#										       #
########################################################################################
#
# Help : ./check_cisco_interfaces_libres -h
#

use lib qw ( /usr/local/nagios/lib );
use Net::SNMP;
use Getopt::Std;

$script    = "check_cisco_interfaces_libres";
$script_version = "1.0";

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

$number_of_interfaces = 0;
@target_interface_index = (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_ifInOctets		= ".1.3.6.1.2.1.2.2.1.10.";	# need to append integer for specific interface
$oid_ifOutOctets	= ".1.3.6.1.2.1.2.2.1.16.";	# need to append integer for specific interface

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

$returnstring = "";

$warning = 5;
$critical = 2;
$community = "public"; 		# Default community string
$configfilepath = "/usr/local/nagios/etc";


# Do we have enough information?
if (@ARGV < 1) {
     print "Too few arguments\n";
     usage();
}

getopts("h:H:C:d:w:c:");
if ($opt_h){
    usage();
    exit(0);
}
if ($opt_H){
    $hostname = $opt_H;
    # print "Hostname $opt_H\n";
}
else {
    print "No hostname specified\n";
    usage();
    exit(0);
}
if ($opt_C){
    $community = $opt_C;
}
if ($opt_d){
    $delais = $opt_d;
}
else {
    print "pas de delais spécifié\n";
    usage();
    exit(0);
}
if ($opt_w){
    $warning = $opt_w;
}
if ($opt_c){
    $critical = $opt_c;
}
else {
    # print "Using community $community\n";
}


# Create the SNMP session

$oid_sysDescr = ".1.3.6.1.2.1.1.1.0";		# Used to check whether SNMP is actually responding

$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;
    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 interfaces libres sur le switch";
    }
    else {
	if ($nb_if_libre > $critical) {
		$status = 1;
		$returnstring = "$nb_if_libre interfaces libres sur le switch";
    	}
	else {
		$status = 2;
		$returnstring = "$nb_if_libre interfaces libres sur le switch";
	}
    }
}
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]);
	    }
        }
    }
    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()->{$_};
        }
    }
    ############################

    $oid_temp = $oid_ifInOctets . $target_interface_index[$count];    
    if (!defined($s->get_request($oid_temp))) {
    }
    else {
        foreach ($s->var_bind_names()) {
            $ifinoctets = $s->var_bind_list()->{$_};
        }
    }
    ############################

    $oid_temp = $oid_ifOutOctets . $target_interface_index[$count];    
    if (!defined($s->get_request($oid_temp))) {
    }
    else {
        foreach ($s->var_bind_names()) {
            $ifoutoctets = $s->var_bind_list()->{$_};
        }
    }
    ############################
        
    if (($ifadminstatus eq "2") || ($ifoperstatus eq "2")) {
	@res = split(/\ /,$iflastchange);
	if ((($res[0] > $delais) && ($res[1] == "days,")) || (($ifinoctets == 0) && ($ifoutoctets == 0))) {
		return 1;
	}
	else {
		return 0;
	}
    }
    else {
	return 0;
	print "le port $count n'est pas libre\n";
    }

}

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

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

Monitors status of specific Ethernet interface. 

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

Options: -H 	Hostname or IP address
         -C 	Community (default is public)
	 -d 	delais en jours de non utilisation
	 -w	Warning ports libres - defaut 5
	 -c	Critical ports libres - defaut 2
	
USAGE
     exit 1;
}



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

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


