#! /usr/bin/perl
############################## check_snmp_storage ##############
# Version : 1.0.1
# Date :  May 17 2018
# Author  : Rob Hassing (rob.hassing (at) deltics.nl
# Licence : GPL - http://www.gnu.org/licenses/gpl.txt
# TODO : Add snmpv3 support
#################################################################
#
# help : ./check_aruba.pl -h

use strict;
use warnings;
use Getopt::Long;
use Net::SNMP qw(:snmp);

# SNMP Data
my $ap_table= '1.3.6.1.4.1.14823.2.2.1.5.2.1.4.1';
my $ap_status_table= '1.3.6.1.4.1.14823.2.2.1.5.2.1.4.1.19';
my $ap_name_table = '1.3.6.1.4.1.14823.2.2.1.5.2.1.4.1.3';
my $ap_model = '1.3.6.1.4.1.14823.2.2.1.5.2.1.4.1.5';
my $ap_serial = '1.3.6.1.4.1.14823.2.2.1.5.2.1.4.1.6';


# Globals

my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4);

my $Name='check_aruba.pl';
my $Version='1.0.0';
my $status='';
my $oid='';
my $down='0';
my $up='0';

my $o_host =    undef;          # hostname
my $o_community = undef;        # community
my $o_port =    161;            # port
my $o_version2 =  2;            # version
my $o_help=     undef;          # wan't some help ?
my $o_verb=     undef;          # verbose mode
my $o_version=  undef;          # print version
my $o_timeout=  5;              # Default 5s Timeout


#Functions:

sub p_version { print "$Name version : $Version\n"; }

sub print_usage {
    print "Usage: $Name [-v] -H <host> -C <snmp_community> [-2] [-p <port>] [-t <timeout>]\n";
}

sub help {
   print "\nSNMP Aruba Monitor for Nagios version ",$Version,"\n";
   print "(c)2018 Rob Hassing\n\n";
   print_usage();
   print <<EOT;
By default, plugin will monitor access points on a controller:
-v, --verbose
   print extra debugging information (and lists all storages)
-h, --help
   print this help message
-H, --hostname=HOST
   name or IP address of host to check
-C, --community=COMMUNITY NAME
   community name for the host's SNMP agent (implies SNMP v1)
-p, --port=PORT
   SNMP port (Default 161)
-t, --timeout=INTEGER
   timeout for SNMP in seconds (Default: 5)
-V, --version
   prints version number
Note :

EOT
}


sub check_options {
    Getopt::Long::Configure ("bundling");
    GetOptions(
        'v'     => \$o_verb,            'verbose'       => \$o_verb,
        'h'     => \$o_help,            'help'          => \$o_help,
        'H:s'   => \$o_host,            'hostname:s'    => \$o_host,
        'p:i'   => \$o_port,            'port:i'        => \$o_port,
        'C:s'   => \$o_community,       'community:s'   => \$o_community,
        '2'     => \$o_version2,        'v2c'           => \$o_version2,
        't:i'   => \$o_timeout,         'timeout:i'     => \$o_timeout,
        'V'     => \$o_version,         'version'       => \$o_version,
    );

  if (defined($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}};
  if (defined($o_version) ) { p_version(); exit $ERRORS{"UNKNOWN"}};

}

### Main:

check_options();

my ($session, $error) = Net::SNMP->session(
   -hostname    => $o_host,
   -community   => $o_community,
   -nonblocking => 1,
   -translate   => [-octetstring => 0],
   -version     => 'snmpv2c',
);

if (!defined $session) {
   printf "ERROR: %s.\n", $error;
   exit 1;
}

my %table; # Hash to store the results

my $result = $session->get_bulk_request(
   -varbindlist    => [ $ap_status_table ],
   -callback       => [ \&table_callback, \%table ],
   -maxrepetitions => 10,
);

if (!defined $result) {
   printf "ERROR: %s\n", $session->error();
   $session->close();
   exit 1;
}

# Now initiate the SNMP message exchange.

snmp_dispatcher();

#$session->close();

# Print the results

for my $oid (oid_lex_sort(keys %table)) {
   if (!oid_base_match($ap_name_table, $oid)) {
      $status = $table{$oid};
      if($status == 2){
        $down++;
        get_name($oid);
      } elsif($status == 1){
        $up++; 
      }
   } else {
      printf "%s = %s\n", $oid, unpack 'H*', $table{$oid};
   }
}
printf "There are $up access point on this controller and $down are down\n";
if($down > 0){
  exit $ERRORS{"CRITICAL"}
} elsif($down == 0){
  exit $ERRORS{"OK"}
}

sub table_callback
{
   my ($session, $table) = @_;

   my $list = $session->var_bind_list();

   if (!defined $list) {
      printf "ERROR: %s\n", $session->error();
      return;
   }

# Loop through each of the OIDs in the response and assign
# the key/value pairs to the reference that was passed with
# the callback.  Make sure that we are still in the table
# before assigning the key/values.

my @names = $session->var_bind_names();
my $next  = undef;

while (@names) {
   $next = shift @names;
   if (!oid_base_match($ap_status_table, $next)) {
      return; # Table is done.
   }
   $table->{$next} = $list->{$next};
}

# Table is not done, send another request, starting at the last
# OBJECT IDENTIFIER in the response.  No need to include the
# calback argument, the same callback that was specified for the
# original request will be used.

my $result = $session->get_bulk_request(
   -varbindlist    => [ $next ],
   -maxrepetitions => 10,
);

if (!defined $result) {
   printf "ERROR: %s.\n", $session->error();
}

return;
}

sub get_name {
my ($oid) = @_;
my $name = $oid;
my $model = $oid;
my $serial = $oid;

substr($name, index($name, '19'), 2) = '3';
substr($model, index($model, '19'), 2) = '13';
substr($serial, index($serial, '19'), 2) = '6';

my $name1 = `snmpget -On -v2c -c $o_community $o_host $name`;
my @words = split(' ', $name1);
my $model1 = `snmpget -On -v2c -c $o_community $o_host $model`;
my @words1 = split(' ', $model1);
my $serial1 = `snmpget -On -v2c -c $o_community $o_host $serial`;
my @words2 = split(' ', $serial1);
print "Access point model $words1[3]: $words[3] with serial $words2[3] is down!\n";
}

