#! /usr/bin/perl -w
# Ce script généère une alarme si un nombre insuffisant de routes
# sont apprises via un ou des peers BGP.

use strict;
use Carp;
use Net::SNMP;
use Getopt::Std;
use vars qw/$opt_h $opt_c $opt_n $opt_f $opt_s $opt_l $opt_u $opt_x/;
# use Data::Dumper;
my $debug = 0;

# Options
my ($host, $community, $neighbor, $afi, $safi, $min_routes, $max_routes);

sub usage {
    my ($arg) = @_;

    if (defined($arg)) {
        print "$arg\n",
    }

    print <<EOF;

Usage:
$0 -h host [-c community | -u user -x password] -n neighbor -f afi -s safi -l min_routes
 -h host : hôte cible
 -c community : communauté SNMP utilisée
 -n neighbor: BGP neighbor (utiliser 62.240.3 pour tous les peers sur 62.240.3.0/24)
 -f afi: address family identifier (IPv4, IPv6)
 -s safi: subsequent address family identifier (unicast, multicast, vpn)
 -l min_routes : nombre de routes minimal

 -u SNMPv3 user
 -x SNMPv3 password

EOF
   exit(3);
}

getopt("h:c:n:f:s:l:u:x:");
$host = $opt_h || usage();
$community = $opt_c;
$neighbor = $opt_n || usage();
$afi = $opt_f || usage();
$safi = $opt_s || usage();
$min_routes = $opt_l || usage();
my $snmp_user = $opt_u;
my $snmp_password = $opt_x;

my $snmp_version;
if ($snmp_user && $snmp_password) {
   $snmp_version = 3
} else {
   $snmp_version = 1;
   if (! $community) {
      usage();
   }
}


$min_routes =~ /\d+/ || usage("le nombre minimal de routes doit être numérique");

$afi =~ /ipv4|ipv6/ || usage("afi est ipv4 ou ipv6");
$safi =~ /multicast|unicast|vpn/ || usage("safi est multicast ou unicast ou vpn");

my %afi_id = ( ipv4 => 1, ipv6 => 2);
my %safi_id = ( unicast => 1, multicast => 2, vpn => 128);

my $accepted_prefixes_oid = ".1.3.6.1.4.1.9.9.187.1.2.4.1.1";

my ($session, $error);

if ($snmp_version == 3) {
   ($session, $error) =
    Net::SNMP->session(-hostname => $host, -version => "3", -username => $snmp_user,
                           -authpassword => $snmp_password, -authprotocol => "sha");
} else {
   ($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
}


my $result = $session->get_table(-baseoid => $accepted_prefixes_oid);

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

my $total_routes = 0;
for my $index ( keys(%{$result}) ) {
    print "Table OID is $index\n" if $debug;
    next unless $index =~
            /$accepted_prefixes_oid\.(\S+)\.$afi_id{$afi}\.$safi_id{$safi}/;
    my $peer = $1;
    print "Peer $peer\n" if $debug;
    if ( $peer =~ $neighbor ) {
        my $routes = $result->{$index};
        print "$routes routes\n" if $debug;
        $total_routes += $result->{$index};
    }
}

if ( $total_routes < $min_routes ) {
    print "CRITICAL: only $total_routes routes\n";
    exit(2); # CRITICAL
}

else {
    print "OK: $total_routes routes\n";
    exit(0); # OK
}

__END__


# snmpwalk -Of -v2c -cpassword bossk .1.3.6.1.4.1.9.9.187.1.2.4.1.1.212.43.193.49.1.1
.iso.org.dod.internet.private.enterprises.cisco.ciscoMgmt.ciscoBgp4MIB.ciscoBgp4MIBObjects.cbgpPeer.cbgpPeerAddrFamilyPrefixTable.cbgpPeerAddrFamilyPrefixEntry.cbgpPeerAcceptedPrefixes.212.43.193.49.ipv4.unicast = Counter32: 141569
