# -*- perl -*-
#
# $Revision: 1.7 $

# This nagios module does Cisco switch checks via SNMP
#
# useage: check_csl_service -Scisco -H<hostname> -o <os>
#
# Written by Adam J. Kunen <ajkunen@cs.wisc.edu>
#
# Changes:
#		* Thu Oct 16 14:49:59 CDT 2003
#			Started work on this project
#
#		* Fri Oct 17 15:05:49 CDT 2003
#			Looks like it works.. Just looks at interface error/packet counters
#
#		* Sat Jan 7 18:50:23 CDT 2005
#			Grabbing all ifindex from table instead of getting total count and using 1..total
#				ifindex are not guaranteed to be continuous, 3750 start @ 10000
#			Detected duplex, adjusting error percentages 
#

package cisco;



# Do the export stuff
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(&print_usage &print_version &service_test);

# Include the netsaint stuff
use lib $main::runtimedir;
use csl_utils qw($TIMEOUT %ERRORS);


# and of course
use strict;

# Some stuff to do it all good
use Socket;
#use SNMP_util;
use Net::SNMP;
use FileHandle;
use File::stat;
use Data::Dumper;


# Global defines
my $CACHE_DIR = "/tmp/nagios_cisco";	# what directory to cache switch counters
my $SNMP_COMMUNITY = "CSL";
my $SNMP_PORT = "161";

# OID Numbers
my $OID_SYS_DESCR = '1.3.6.1.2.1.1.1.0';
my $OID_NUM_IF = '1.3.6.1.2.1.2.1.0';	# This will grab the number of interfaces on the switch
my $OID_INDEX_NUMBERS = '1.3.6.1.2.1.2.2.1.1'; #This will grab all the ifindex numbers
my $OID_STACK_LOC = '1.3.6.1.4.1.9.5.1.4.1.1.11';
my $OID_DUPLEX = '1.3.6.1.4.1.9.5.1.4.1.1.10';
my $OID_SYSNAME = '1.3.6.1.2.1.1.5.0';


my %OID_CPUTEMP_STAT =
	(
		cpu1min				=>	'1.3.6.1.4.1.9.2.1.57.0',
		cpu5min				=>	'1.3.6.1.4.1.9.2.1.58.0',
		tempInlet			=>	'1.3.6.1.4.1.9.9.13.1.3.1.3.1',
		tempOutlet			=>	'1.3.6.1.4.1.9.9.13.1.3.1.3.2',
		tempState			=>	'1.3.6.1.4.1.9.9.13.1.3.1.6.1',
	);

my %OID_BLOCKS = 
	(
		name				=>	'1.3.6.1.2.1.2.2.1.2',	# Internal interface name
		type				=> 	'1.3.6.1.2.1.2.2.1.3',	# Numeric interface type
		adminStatus			=>	'1.3.6.1.2.1.2.2.1.7',	# Administrative Status
		operStatus			=> 	'1.3.6.1.2.1.2.2.1.8',	# Operational Status (link state)
		lastChange			=>	'1.3.6.1.2.1.2.2.1.9',	# Last change
		packetsIn			=>	'1.3.6.1.2.1.2.2.1.11',	# unicast packets in
		errorsIn			=>	'1.3.6.1.2.1.2.2.1.14', # Input errors
		packetsOut			=>	'1.3.6.1.2.1.2.2.1.17',	# unicast packets out
		errorsOut			=>	'1.3.6.1.2.1.2.2.1.20', # Output errors
		description			=>	'1.3.6.1.2.1.31.1.1.1.18', # decription line for if
		HCpacketsIn			=>	'1.3.6.1.2.1.31.1.1.1.7', # 64 bit counters,
		HCpacketsOut			=>	'1.3.6.1.2.1.31.1.1.1.11'
	);

my %OID_MEM_BLOCKS = 
	(
		mem_pools_name			=>	'1.3.6.1.4.1.9.9.48.1.1.1.2', # Memory pools
		mem_pools_used			=>	'1.3.6.1.4.1.9.9.48.1.1.1.5', # Used Memory
		mem_pools_free			=>	'1.3.6.1.4.1.9.9.48.1.1.1.6', # Free memory
		mem_pools_maxfrag		=>	'1.3.6.1.4.1.9.9.48.1.1.1.7'  # Largest Fragment
	);

my %OID_NX_MEM_BLOCKS = 
	(
		mem_pools_used			=>	'1.3.6.1.4.1.9.9.109.1.1.1.1.12', # Used Memory
		mem_pools_free			=>	'1.3.6.1.4.1.9.9.109.1.1.1.1.13', # Free memory
	);

my %IF_STATUS =
	(
		1	=>	'up',
		2	=>	'down',
		3	=>	'testing',
		4	=>	'unknown',
		5	=>	'dormant',
		6	=>	'notPresent',
		7	=>	'lowerLayerDown'
	);

my %DUPLEX_STATUS = 
	(
		1	=>	'half',
		2	=>	'full',
		3	=>	'disagree',
		4	=>	'auto'
	);


my  %MEM_PER_THRESH = (
	'C3750' => {
		'I/O' => {
                                WARN      => 85,
                                CRIT      => 90,
	        },
	},
        'C2950' => {
                'Processor' => {
                                WARN      => 85,
                                CRIT      => 90,
                },
        },
        'default' => {
                'I/O' => {
                                WARN      => 80,
                                CRIT      => 90,
                },
                'Processor'     => {
                                WARN      => 75,
                                CRIT      => 80,
                },
                default     => {
                                WARN      => 30,
                                CRIT      => 50,
                },
        },
 );



# Configuration
my $TIMEOUT =    5;		# Ping timeout 
my $FD_THRESH_WARN = 5;		# Warning packet count threshold
my $FD_THRESH_CRIT = 10;	# Critical packet count threshold
my $FD_PER_WARN = 0.01;		# Warning percent error limit
my $FD_PER_CRIT = 0.05;		# Critical percent error limit
my $HD_PER_WARN = 0.25;         # Warning percent error limit
my $HD_PER_CRIT = 0.50;         # Critical percent error limit
my $CPU_PER_WARN = 50;	# Warning percent CPU usage
my $CPU_PER_CRIT = 75;	# Critical percent CPU usage
my $FILE_PERMS = 0666;          # File permisions for the cache files
my $DIR_PERMS = 0777;           # Dir permisions for the chache directory


# Globald vars
my $DEBUG; 
my $VERBOSE;

# prototypes
sub print_usage ();
sub print_version ();
sub service_test (%);



##############################################################################
# Usage sub
##############################################################################
sub print_usage () {

    print "
Usage:  Check cisco values
Options:
    -H <hostname> 
    -o <os>
	--debug
    --help
    --version
    --usage
	-C <snmp_community>
";
    return $ERRORS{'OK'};
}


##############################################################################
# Version sub
##############################################################################
sub print_version () {
    my $version = '$Revision: 1.7 $';
    $version =~ s/^\$Revision: //;
    $version =~ s/ \$\s*$//;

    print "cisco.pm - $version\n";
    return $ERRORS{'OK'};
}


##############################################################################
# Service check (this is the main routine)
##############################################################################
sub service_test (%) 
{
	# Parse the options
    my %options = @_;
    if ($options{"version"})
    {
        print_version();
    }
    if ($options{"usage"})
    {
        print_usage();
    }
    if ($options{"debug"})
    {
        # Turn verbose on
        $options{"verbose"} = 1;

        # Turn debuggin on
        $DEBUG = 1;
        print "Debuggin output enabled\n";
    }
    if ($options{"verbose"}) 
    {
        foreach my $opt (sort keys(%options)) 
        {
            if ($options{$opt}) 
            {
                print "$opt - $options{$opt}\n";               
            }
        }
        $VERBOSE = 1;
	$DEBUG = 1;
    }

    # Check what network we are on
    my $thishost = `uname -n`;
    chomp $thishost;
    my $ip = gethostbyname($thishost); 
    $ip = inet_ntoa($ip);
    if(! ($ip =~ /^128\.105\.123\.\d+$/))
    {
        die "You must run this from the 123 network for SNMP to work!\n";
    }

    
	
    my $host = $options{"opt_H"};
	$SNMP_COMMUNITY = $options{"opt_C"} if $options{"opt_C"};

    if(!$host || $host eq "") {
        print "\nERROR Switch name not specified.\n";
        &print_usage();
        return $ERRORS{'OK'};
    }

	# Debug output
	if($DEBUG)
	{
		print "Switch name:    $host\n";
		print "SNMP Community: $SNMP_COMMUNITY\n";

	}

	# get the model via sysdescr
	my $arch = SNMP_GetArch($host);
	if($DEBUG){print "Detected Arch: $arch\n";}

	my $cpu_temp_stats;
	if (!($arch =~ /n5000/) && !($arch =~ /Cisco Controller/)) {
	    # not present on Nexus switches
	    # might be able to get temperatures from 1.3.6.1.4.1.9.9.91 somewhere
	    # for Nexus switches
	    #
	    # Get switch stats CPU/Temp
	    $cpu_temp_stats = SNMP_GetSwitchCpuTemp($host);
	}

	my $mem_info;
	if (!($arch =~ /n5000/) && !($arch =~ /Cisco Controller/)) {
	    # not present on Nexus switches
	    $mem_info = SNMP_GetMemPoolInfo($host,$arch);
	    if($DEBUG){print Dumper $mem_info;}	
	}

	# Get the new switch information
	my $if;
	if (! ($arch =~ /Cisco Controller/)){
	    $if = SNMP_GetInterfaces($host);
	}

	# Read the cached data from the last check
	my ($if_last, $t); 
	if (! ($arch =~ /Cisco Controller/)){
	    ($if_last, $t) = CacheRead($host);
	}

	if ($arch =~ /Cisco Controller/) {
	    return $ERRORS{'OK'};
	}

	# Write the new info to the cache
	CacheWrite($host, $if);

	# if there wasn't previous data, just say so
	if(!$if_last)
	{
		print "No previous information about switch in cache, next time this runs will produce meaniful results\n";
		return $ERRORS{UNKNOWN};
	}
	
        # Okay analyze the data
        my $warnings = 0; 
        my $criticals = 0;
        my $unknowns = 0;
        my @list;

	foreach my $pool (keys %$mem_info){
	
	  my $MEM_PER_WARN;       # Warning percernt memory usage
	  my $MEM_PER_CRIT;        # Critical percent memory usage
	
	#if $defined arch and pool use those
	#else check for default arch pool
	#else check use default arch, default pool


	  if(defined $MEM_PER_THRESH{$arch}->{$mem_info->{$pool}->{name}} ){
		 $MEM_PER_WARN = $MEM_PER_THRESH{$arch}->{$mem_info->{$pool}->{name}}->{WARN};
		 $MEM_PER_CRIT = $MEM_PER_THRESH{$arch}->{$mem_info->{$pool}->{name}}->{CRIT};
		 if($DEBUG){printf("Using architecture %s pool memory thresholds WARN %s CRIT %s\n",$mem_info->{$pool}->{name},$MEM_PER_WARN,$MEM_PER_CRIT);}
	  }else{
		if(defined $MEM_PER_THRESH{default}->{$mem_info->{$pool}->{name}}){
			$MEM_PER_WARN = $MEM_PER_THRESH{default}->{$mem_info->{$pool}->{name}}->{WARN};
                        $MEM_PER_CRIT = $MEM_PER_THRESH{default}->{$mem_info->{$pool}->{name}}->{CRIT};
                        if($DEBUG){printf("Using default architecture and %s pool memory thresholds WARN %s CRIT %s\n",$mem_info->{$pool}->{name},$MEM_PER_WARN,$MEM_PER_CRIT);}
		}else{
			$MEM_PER_WARN = $MEM_PER_THRESH{default}->{default}->{WARN};
                	$MEM_PER_CRIT = $MEM_PER_THRESH{default}->{default}->{CRIT};
        	        if($DEBUG){printf("Using default architecture and default pool memory thresholds WARN %s CRIT %s\n",$MEM_PER_WARN,$MEM_PER_CRIT);}
		}
	  }

	  my $per_memusage = ($mem_info->{$pool}->{used} / $mem_info->{$pool}->{total}) * 100;	
	  if($DEBUG){printf("Pool %s usage at %.2f\n",$mem_info->{$pool}->{name},$per_memusage);}

          if($per_memusage >= $MEM_PER_CRIT )
          {
                $criticals++;
                my $msg = sprintf("%s MEM %0.2f > %s ",$mem_info->{$pool}->{name},$per_memusage,$MEM_PER_CRIT);
                push @list,$msg;
         
          }
          elsif($per_memusage >= $MEM_PER_WARN )
          {
               $warnings++;
               my $msg = sprintf("%s MEM %0.2f > %s ",,$mem_info->{$pool}->{name},$per_memusage,$MEM_PER_WARN);
               push @list,$msg;
          }
	}

	if($cpu_temp_stats->{$OID_CPUTEMP_STAT{cpu1min}} >= $CPU_PER_CRIT )
	{
                $criticals++;
                my $msg = sprintf("CPU %0.2s > %s ",$cpu_temp_stats->{$OID_CPUTEMP_STAT{cpu1min}},$CPU_PER_CRIT);
                push @list,$msg;
        }
	elsif($cpu_temp_stats->{$OID_CPUTEMP_STAT{cpu1min}} >= $CPU_PER_WARN )
	{
                $warnings++;
                my $msg = sprintf("CPU %0.2s > %s ",$cpu_temp_stats->{$OID_CPUTEMP_STAT{cpu1min}},$CPU_PER_WARN);
                push @list,$msg;
	}

	foreach my $ifname (sort keys %$if)
	{
		my $i = $if->{$ifname};
		my $i2 = $if_last->{$ifname};

		# check to make sure its an ethernet interface
		next unless $i->{type} == 6;
			
		# Make the shortname name for the interface
		my $shortname = $ifname;
		$shortname =~ s/GigabitEthernet/Gi/i;
		$shortname =~ s/FastEthernet/Fa/i;

		# Check to see if the port is administratively up
		next unless $IF_STATUS{$i->{adminStatus}} eq 'up';

		# Check to see if the link state is up
#		if($i->{adminStatus} ne $i->{operStatus})
#		{
#			$msg .= "LINK DOWN. ";
#		}

		# Check for overflow
		if($i->{HCpacketsIn} < $i2->{HCpacketsIn}){
		    $i2->{HCpacketsIn} = 0;
		}
		
		if($i->{HCpacketsOut} < $i2->{HCpacketsOut}){
		    $i2->{HCpacketsOut} = 0;
		}
	
		# Check the error counters
		my $dInPackets = $i->{HCpacketsIn} - $i2->{HCpacketsIn}; 
		my $dInErrors = $i->{errorsIn} - $i2->{errorsIn};
		my $PerIn = 0;
		$PerIn = $dInErrors / $dInPackets if $dInPackets;

		my $dOutPackets = $i->{HCpacketsOut} - $i2->{HCpacketsOut}; 
		my $dOutErrors = $i->{errorsOut} - $i2->{errorsOut};
		my $PerOut = 0;
		$PerOut = $dOutErrors / $dOutPackets if $dOutPackets;

		# Chop them to 0.001 accuracy
		$PerIn = sprintf "%.3f", $PerIn;
		$PerOut = sprintf "%.3f", $PerOut;

		#
		# If duplex == undef, assume it is full
		if(!defined $i->{duplex}){
			$i->{duplex} = 2;
		}

		# Check for problems with counters
		my $error;
		if($DUPLEX_STATUS{$i->{duplex}} eq 'full'){
			if($PerIn >= $FD_PER_CRIT || $dInErrors >= $FD_THRESH_CRIT
				|| $PerOut >= $FD_PER_CRIT || $dOutErrors >= $FD_THRESH_CRIT)
			{	
				$error = 1;
				$criticals ++;
			}
			elsif($PerIn >= $FD_PER_WARN || $dInErrors >= $FD_THRESH_WARN
				|| $PerOut >= $FD_PER_WARN || $dOutErrors >= $FD_THRESH_WARN)
			{
				$error = 1;
				$warnings ++;
			}
		}elsif($DUPLEX_STATUS{$i->{duplex}} eq 'half'){
                        if($PerIn >= $HD_PER_CRIT || $PerOut >= $HD_PER_CRIT )
                        {
                                $error = 1;
                                $criticals ++;
                        }
                        elsif($PerIn >= $HD_PER_WARN || $PerOut >= $HD_PER_WARN )
                        {
                                $error = 1;
                                $warnings ++;
                        }
		}elsif($DUPLEX_STATUS{$i->{duplex}} eq 'disagree'){
				$error = 1;
				$criticals ++;
		}elsif($DUPLEX_STATUS{$i->{duplex}} eq 'auto'){
			# port link status is probably down
		}else{
			#printf("Unknown duplex value %s\n",$DUPLEX_STATUS{$i->{duplex}});
			# unknown duplex value
		}
		# If we created a message, add it to the list
		# along with the if name
		if($error)
		{
			my $msg = "$shortname: ";
			$msg .= "[$i->{description}] " if $i->{description} =~ /\w/;
			$msg .= "Duplex=" . $DUPLEX_STATUS{$i->{duplex}} . " ";
			$msg .= "InErr=" . $dInErrors . "pks($PerIn\%) ";
			$msg .= "OutErr=" . $dOutErrors . "pks($PerOut\%) ";
			
			push @list, $msg;
		}
	}

	if(@list)
	{
		my $stat = 'OK';
		$stat = 'UNKNOWN' if $unknowns;
		$stat = 'WARNING' if $warnings;
		$stat = 'CRITICAL' if $criticals;
		
		print "$stat: " . (join " # ", @list);
		print "\n";
		
		exit $ERRORS{$stat};
	}
	else
	{
		print "OK: Switch reports no problems\n";
		exit $ERRORS{OK};
	}
	
}

sub CacheWrite
{
	my ($host, $h) = @_;

        my $fname = "$CACHE_DIR/$host";

	# Make sure the dir exists
	mkdir "$CACHE_DIR" if ! -d $CACHE_DIR;
        chmod $DIR_PERMS, $CACHE_DIR;

	# Open the file and dump
	open my $fh, ">$fname" or die "Couldn't open file '$fname': $!\n";
	print $fh Dumper($h);
	close $fh;

        # Chmod it
        chmod $FILE_PERMS, $fname;
}

sub CacheRead
{
	my ($host) = @_;

	# create filename
	my $fname = "$CACHE_DIR/$host";
	
	# make sure the file exists
	return if ! -e $fname;

	# grab the last modification time (epoch time)
	my $tstamp = (stat($fname))[9];

	# Read the file
	my $str = `/bin/cat $fname`;
	return if !$str;

	# Eval the data into a hash
	my $VAR1;
	eval $str;

	# return!
	return ($VAR1, $tstamp);
}

sub SNMP_GetArch
{
        my ($host) = @_;
	my $model;

        # Connect to the host
        my ($snmp, $error) = Net::SNMP->session
            (
                -hostname   => $host,
                -community  => $SNMP_COMMUNITY,
                -port       => $SNMP_PORT,
                -version    => 2
            );

        # Make sure we connected
        if(!defined $snmp)
        {
            print "Couldn't connect to host via SNMP\n";
            exit $ERRORS{CRITICAL};
        }

	# Grab the sysdecr
        my $result = $snmp->get_request(-varbindlist => [$OID_SYS_DESCR]);
        if(!defined $result)
        {
            print "Failed SNMP Query: " . $snmp->error() . "\n";
            exit $ERRORS{CRITICAL};
        }
        my $sysDescr = $result->{$OID_SYS_DESCR};

        # stolen from genRtrConfig
	if ($DEBUG) { print "sysDescr: $sysDescr\n"; }
        if ($sysDescr =~ /IOS \(tm\)/) {
           ($model) = $sysDescr =~ /IOS\s+\(tm\)\s+(\S+)/;
        } elsif ($sysDescr =~ /IOS Software/) {
           ($model) = $sysDescr =~ /IOS\s+Software\,\s+(\S+)/;
        } elsif ($sysDescr =~ /C\d\d\d\d Software \(/ ) {
           ($model) = $sysDescr =~ /(\S+) Software \(/;
        } elsif ($sysDescr =~ /Cisco.NX-OS.*Software \(/ ) {
	   print "Found NX-OS!\n" if $DEBUG;
           #($model) = $sysDescr =~ /(\S+), Software\(/;
           $model = $sysDescr;
	   $model =~ s/, Software.*$//;
	   $model =~ s/Cisco NX-OS.tm. //;
        } elsif ($sysDescr =~ /Cisco Controller/) {
	   ($model) = $sysDescr;
	}
        #print "Type of arch: $model\n" if $DEBUG;
	if ($DEBUG) { print "model: $model\n"; }

	return $model;
}

sub SNMP_GetInterfaces
{
	my ($host) = @_;
	my %duplex;
	my @ifindex;

        # Connect to the host
        my ($snmp, $error) = Net::SNMP->session
            (
                -hostname   => $host,
                -community  => $SNMP_COMMUNITY,
                -port       => $SNMP_PORT,
                -version    => 2
            );

        # Make sure we connected
        if(!defined $snmp)
        {
            print "Couldn't connect to host via SNMP\n";
            exit $ERRORS{CRITICAL};
        }

        # Grab the number of interfaces
        my $result = $snmp->get_request(-varbindlist => [$OID_NUM_IF]);
        if(!defined $result)
        {
            print "Failed SNMP Query: " . $snmp->error() . "\n";
            exit $ERRORS{CRITICAL};
        }
        my $numIf = $result->{$OID_NUM_IF};

	print "Number of interfaces: $numIf\n" if $DEBUG;

	my $result = $snmp->get_table(-baseoid => $OID_INDEX_NUMBERS);
        if(!defined $result)
        {
            print "Failed SNMP Query: " . $snmp->error() . "\n";
            exit $ERRORS{CRITICAL};
        }
	#print Dumper $result;
	foreach my $key (keys %$result){
	    #print "Adding key $result->{$key}\n";
	    push @ifindex,$result->{$key};
	}

	# mblodget duplex code

	my $result = $snmp->get_table(-baseoid => $OID_STACK_LOC);
        if(!defined $result)
        {
		#ahmm nothing,  aironets and 2950 don't have this table
        }else{

        	my %result2 = map {
                	my $newkey = $_;
                	$newkey =~ s/.*\.(\d+\.\d+)$/$1/;
                	$newkey = $OID_DUPLEX.'.'.$newkey;
                	$newkey => $result->{$_};
        	} keys %$result;
        	my %result3 = reverse %result2;

        	my $result = $snmp->get_table(-baseoid => $OID_DUPLEX);
        	if(!defined $result)
     			{
            		print "Failed SNMP Query: " . $snmp->error() . "\n";
            		exit $ERRORS{CRITICAL};
        		}
        	
		foreach my $key (keys %result3){
         	       $duplex{$key} = $result->{$result3{$key}};
        	}
	
	}
	# Grab all the interface data
        my %blocks;
	foreach my $key (keys %OID_BLOCKS)
	{
                my $h = $snmp->get_table(-baseoid => $OID_BLOCKS{$key});
                if(!$h)
                {   
                    print "Error accessing oid $key: " .$snmp->error() . "\n";
                    exit $ERRORS{CRITICAL};
                }
		#print Dumper $h;
                # eliminate all the oid paths from the hash keys
                my %h2 = map {
                    my $newkey = $_;
                    $newkey =~ s/.*\.(\d+)$/$1/;
                    $newkey => $h->{$_};
                } keys %$h;

                $blocks{$key} = \%h2;
	}
	
	# Build a more meaninful hash
	my $h;
	foreach my $if (@ifindex)
	{
		# get the name
		my $ifname = $blocks{name}->{$if};
		
		# create the hash for that interface
		my %ih = map { $_ => $blocks{$_}->{$if} } keys %OID_BLOCKS;
		$ih{duplex} = $duplex{$if};		

		# add that to our hash
		$h->{$ifname} = \%ih;

		# debug output
		if($DEBUG && $ih{duplex} ==1 )
		{
			print "Interface $ifname:\n";
			print "   Duplex: $ih{duplex}\n";
			print "   Input:\n";
			print "      Packets: $ih{HCpacketsIn}\n";
			print "      Errors: $ih{errorsIn}\n";
			print "   Output:\n";
			print "      Packets: $ih{HCpacketsOut}\n";
			print "      Errors: $ih{errorsOut}\n";
		}
	}

	# Return the newfound data
	#print Dumper $h;
	return $h;
}


sub SNMP_GetSwitchCpuTemp{                
        my ($host) = @_;
                 
        # Connect to the host   
        my ($snmp, $error) = Net::SNMP->session
            (
                -hostname   => $host,
                -community  => $SNMP_COMMUNITY,
                -port       => $SNMP_PORT,
                -version    => 2  
            );
         
        # Make sure we connected
        if(!defined $snmp)
        {
            print "Couldn't connect to host via SNMP\n";
            exit $ERRORS{CRITICAL};
        }

	my @temparray = values %OID_CPUTEMP_STAT;

        # Grab the number of interfaces
        my $result = $snmp->get_request(-varbindlist => \@temparray );
        if(!defined $result)
        {
            print "Failed SNMP Query: " . $snmp->error() . "\n";
            exit $ERRORS{CRITICAL};
        }
        
	if($DEBUG){
	  foreach my $key (keys %OID_CPUTEMP_STAT){
	    print "$key: $result->{$OID_CPUTEMP_STAT{$key}}\n";
	  }
	}	
	return $result;
}


sub SNMP_GetMemPoolInfo{
        my ($host,$arch) = @_;
	my %blocks;
	my %pools;
	                        
        # Connect to the host
        my ($snmp, $error) = Net::SNMP->session
            (           
                -hostname   => $host,
                -community  => $SNMP_COMMUNITY,
                -port       => $SNMP_PORT,
                -version    => 2
            );
                        
        # Make sure we connected
        if(!defined $snmp)
        {
            print "Couldn't connect to host via SNMP\n";
            exit $ERRORS{CRITICAL};
        }

	foreach my $key (keys %OID_MEM_BLOCKS){

          my $h = $snmp->get_table(-baseoid => $OID_MEM_BLOCKS{$key});
          if(!defined $h)
          {
              print "Failed SNMP Query: " . $snmp->error() . "\n";
              exit $ERRORS{CRITICAL};
          }
          my %h2 = map {
            my $newkey = $_;
            $newkey =~ s/.*\.(\d+)$/$1/;
            $newkey => $h->{$_};
          } keys %$h;
 
          $blocks{$key} = \%h2;
	}
	foreach my $key (keys %{$blocks{mem_pools_name}}){
		$pools{$key}->{name} = $blocks{mem_pools_name}->{$key};
                $pools{$key}->{free} = $blocks{mem_pools_free}->{$key};
                $pools{$key}->{used} = $blocks{mem_pools_used}->{$key};
                $pools{$key}->{total} = $blocks{mem_pools_free}->{$key} + $blocks{mem_pools_used}->{$key};

	}
	#print Dumper \%pools;
	return \%pools;
}

#DONE
1;

