#! /usr/bin/perl -w

# Ce script génère une alarme quand des le nombre d'utilisateurs
# sur une liste de tunnels est inférieur à une valeur donnée.

use strict;
use Carp;
use Net::SNMP;
use Getopt::Std;
# use Data::Dumper;

my %options;
my $debug = 0;

sub usage {
    my $arg = shift;    
    print <<EOF;

$arg

Usage:
 -h host : hôte cible
 -C community : communauté SNMP utilisée
 -t ip_list : liste d'addresses IP correspondant aux tunnels
 -w users : génère un warning si nombre d'utilisateurs inférieur
 -c users : génère une alarme critical si nombre d'utilisateurs inférieur

EOF
   exit(3);
}

getopt("h:C:t:w:c:", \%options);
my $host = $options{h} || usage("pas d'hôte");
my $community = $options{C} || usage("pas de communauté");
my $ip_list = $options{t} || usage("pas de liste de tunnels");
my $warning_user_count= $options{w} || usage("pas de niveau warning");
my $critical_user_count = $options{c} || usage("pas de niveau critical");

my @ips = split ',', $ip_list;

my %tunnel_id;
my %tunnel_users;

# On veut générer une alarme si le nombre d'utilisateurs
# sur un ensemble de tunnels L2TP est inférieur à un niveau donné.
#
# ON utilise la MIB CISCO-VPDN-MGMT-MIB.
# On procéde en deux temps :
# 1) On récupère l'ID du tunnel :
#       cvpdnTunnelAttrRemoteIpAddress.l2tp.$tunnel_id = $ip_address
# 2) On récupère le status administratif :
#       cvpdnTunnelAttrActiveSessions.l2tp.$tunnel_id = $user_count


my $tunnel_address_table_oid = ".1.3.6.1.4.1.9.10.24.1.2.2.1.15.2";
my $tunnel_active_sessions_table_oid = ".1.3.6.1.4.1.9.10.24.1.2.2.1.9.2";

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 les ID des tunnels.

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

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

for my $index ( keys(%{$result}) ) {
    my $ip = $result->{$index};
    my ($tunnel_index) = reverse split /\./, $index;
    $tunnel_id{$ip} = $tunnel_index;
}

# 2) On récupère le nombre de sessions sur les tunnels.

$result = $session->get_table(-baseoid => $tunnel_active_sessions_table_oid);

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

for my $index ( keys(%{$result}) ) {
    my $user_count = $result->{$index};
    my ($tunnel_index) = reverse split /\./, $index;
    $tunnel_users{$tunnel_index} = $user_count;
}

# On compte le nombre d'utilisateurs sur tous les tunnels
my $total_user_count = 0;
for my $ip (@ips) {
    if ( my $id = $tunnel_id{$ip} ) {
        my $user_count = $tunnel_users{$id};
        $total_user_count += $user_count;
        if ($debug) {
            print "added $user_count users for IP $ip, total $total_user_count\n";
        }
    }
}

if ( $total_user_count < $critical_user_count ) {
   print "CRITICAL: only $total_user_count users\n";
   exit(2); # CRITICAL
}
elsif ( $total_user_count < $warning_user_count ) {
   print "WARNING: only $total_user_count users\n";
   exit(1); # WARNING
}
else {
   print "OK: $total_user_count users\n";
   exit(0); # OK
}

__END__
    
# snmpwalk -cpassword -v2c boussh 1.3.6.1.4.1.9.10.24.1.2.2.1.15.2
CISCO-VPDN-MGMT-MIB::cvpdnTunnelAttrRemoteIpAddress.l2tp.11281 = IpAddress: 212.30.117.16
CISCO-VPDN-MGMT-MIB::cvpdnTunnelAttrRemoteIpAddress.l2tp.49887 = IpAddress: 213.203.79.8
CISCO-VPDN-MGMT-MIB::cvpdnTunnelAttrRemoteIpAddress.l2tp.63352 = IpAddress: 212.43.192.200
# snmpwalk -cpassword -v2c boussh 1.3.6.1.4.1.9.10.24.1.2.2.1.9.2
CISCO-VPDN-MGMT-MIB::cvpdnTunnelAttrActiveSessions.l2tp.11281 = Gauge32: 161
CISCO-VPDN-MGMT-MIB::cvpdnTunnelAttrActiveSessions.l2tp.49887 = Gauge32: 206
CISCO-VPDN-MGMT-MIB::cvpdnTunnelAttrActiveSessions.l2tp.63352 = Gauge32: 4

