#! /usr/bin/perl

use strict;
use warnings;
use Getopt::Std;
use List::Util "max";

sub _usage() {
    print << "USAGE";
check_snmp_generic v1.0
Usage: check_snmp_generic [options] <hostname> <OID>
Options: 
   -w|c <threshold>     Sets warning/critical on returned state greater than
                        threshold.  Takes precedence over regex search if set.
   -C <name>            Sets SNMP community name
   -r <regex>           Perl Regular expression to use as "OK" state.
                        Default is "ok"

NOTE: Warning/Critical are unset by default. You MUST set both if you want
      distinct warning/critical thresholds.
      Setting -c does not set -w, and vice versa.

USAGE
    exit 3;
}

my %opts;
getopt('wcCrm', \%opts);
if (@ARGV < 2) {
   _usage();
}

my $errorState = "SNMP";
my $perfData = "";
my $returnCode = 0;
my $hostname = shift;
my $oid = shift;
my $community = exists($opts{C}) ? $opts{C} : "nagios";
my $regex = exists($opts{r}) ? $opts{r} : "ok";

open(SNMP, "/usr/bin/snmpbulkwalk -v2c -c $community $hostname $oid|") or die "Can't open snmpbulkwalk $!";

my (@input) = <SNMP>;
close(SNMP);
$? and exit 3;

foreach (@input)
{
    chomp;
    s/.*-MIB\:\://;
    s/INTEGER\:\s//;
    $perfData .= $_ . " -- ";
    s/.*\s=\s(.*)$/$1/;
    if (exists($opts{c}) || exists($opts{w})) {
        /.*?(\d+).*/;
        if ( exists($opts{c}) && $1 > $opts{c} ) {
           $errorState .= " CRITICAL " . $_;
           $returnCode = 2;
        }
        elsif (exists($opts{w}) && $1 > $opts{w}) {
           $errorState .= " WARNING " . $_;
           $returnCode = max $returnCode, 1;
        }
    }
    elsif (! (/$regex/)) {
        $errorState .= " CRITICAL " . $_;
        $returnCode = 2;
    }
}
if ($errorState !~ m/(WARNING|CRITICAL)/ ) {
    $errorState .= " OK"
}

print $errorState . ' | ' . $perfData . "\n";
exit $returnCode;
