#! /usr/bin/perl -w

# Ce script génère une alarme quand des interfaces E1 sont "down".

use strict;
use Carp;
use Net::SNMP;
use Getopt::Std;
use vars qw/$opt_h $opt_c $opt_t/;
use Data::Dumper;

sub usage {
   print <<EOF;

Usage:
$0 -h host -c community -t critical_count
 -h host : hôte cible
 -c community : communauté SNMP utilisée
 -t critical_count : nombre de E1 DOWN nécessaire pour déclencher
                         une alarme "CRITICAL" (sinon une alarme "WARNING"
                         est déclenchée).

EOF
   exit(3);
}

getopt("h:c:t:");
my $host = $opt_h || usage();
my $community = $opt_c || usage();
my $critical_count = $opt_t || usage();

# On veut générer une alarme si une interface E1 est opérationnelement
# "down" alors qu'elle est administrativement "UP" :
#
# 1) On récupère la table de description des interfaces :
#       ifDescr.$if_index = "E1 x"
# 2) On récupère le status administratif :
#       ifAdminStatus.$if_index = $admin_status
# 3) On récupère le status opérationnel :
#       ifOperStatus.$if_index = $oper_status

my %e1_descr;
my %e1_admin_status;
my %e1_oper_status;

my $descr_table_oid = ".1.3.6.1.2.1.2.2.1.2";
my $oper_status_table_oid = ".1.3.6.1.2.1.2.2.1.8";
my $admin_status_table_oid = ".1.3.6.1.2.1.2.2.1.7";

my ($session, $error) =
   Net::SNMP->session(-hostname => $host, -version => "2c", -community => $community);

if (not defined($session)) {
   print "Impossible d'ouvrir une session SNMP avec $host: $error !\n";
   exit(3); # UNKNOWN
}

# 1) On récupère l'index des interfaces E1
my $result = $session->get_table(-baseoid => $descr_table_oid);

if (not defined($result)) {
    my $error = $session->error();
    print "Impossible de récupérer la table ifDescr : $error\n";
    exit(3); # UNKNOWN
}

for my $index ( keys(%{$result}) ) {
    next unless $result->{$index} =~ /E1/;
    my $descr = $result->{$index};
    ($index) = reverse split /\./, $index;
    $e1_descr{$index} = $descr;
}
    
if (! keys %e1_descr) {
    print "Aucune interface E1 détectée\n";
    exit(3); # UNKNOWN
}

for my $if_index (keys %e1_descr) {

    my $admin_status_oid = "$admin_status_table_oid.$if_index";
    my $oper_status_oid = "$oper_status_table_oid.$if_index";

    my $result = $session->get_request(-varbindlist =>
                [ $admin_status_oid, $oper_status_oid ]);

    if (not defined($result)) {
        my $error = $session->error();
        print "Impossible de récupérer le status de l'interface " .
                    "$e1_descr{$if_index} : $error\n";
        exit(3); # UNKNOWN
    }
    $e1_admin_status{$if_index} = $result->{$admin_status_oid};
    $e1_oper_status{$if_index} = $result->{$oper_status_oid};
}

# UP = 1, DOWN = 2
my @failed_if_index = 
        grep { $e1_admin_status{$_} == 1 && $e1_oper_status{$_} != 1 } keys(%e1_descr);

my $failed_e1_count = @failed_if_index;
my $e1_count = grep { $e1_admin_status{$_} == 1 } keys(%e1_descr);

if ( $failed_e1_count == 0 ) {
    print "OK: $e1_count E1 UP\n";
    exit(0); # OK
}
else {
	my @failed_if_descr = @e1_descr{@failed_if_index};

	if ( $failed_e1_count >= $critical_count ) {
    	# print "CRITICAL: ", join(" and ", @failed_if_descr), " DOWN\n";
    	print "CRITICAL: $failed_e1_count E1 DOWN\n";
    	exit(2); # CRITICAL
	}
	else {
    	# print "WARNING: ", join(" and ", @failed_if_descr), " DOWN\n";
	   print "WARNING: $failed_e1_count E1 DOWN\n";
		exit(1); # WARNING
	}

}

__END__

# snmpwalk -Of -cpassword -v2c mod-rk-22.access .iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifDescr | grep E1
 .iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifDescr.8 = STRING: E1 0
 .iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifDescr.9 = STRING: E1 1
 .iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifDescr.10 = STRING: E1 2
 .iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifDescr.11 = STRING: E1 3
 .iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifDescr.12 = STRING: E1 4
 .iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifDescr.13 = STRING: E1 5
 .iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifDescr.14 = STRING: E1 6
 .iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifDescr.15 = STRING: E1 7

# snmpwalk -Of -cpassword -v2c mod-rk-22.access .iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifAdminStatus.8
 .iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifAdminStatus.8 = INTEGER: down(2)

