2

I'm trying to do a snmpwalk to the AP status on a wlc. I'm really new to perl so bear with me but I was working with this guide. I was able to get the CPU Utilization just fine, but that was just a get request where as this is a walk.

My input: perl test.pl -H 10.192.54.30 -C public -O .1.3.6.1.4.1.14179.2.2.1.1.6.0 -w 20 -c 30

The code:

#!/bin/perl
use strict;
use warnings;
use Net::SNMP;
use Getopt::Long qw(:config no_ignore_case);


my $hostaddr = '';
my $community = '';
my $crit = '';
my $warn = '';
my $oid = '';

GetOptions(
        "host|H=s" => \$hostaddr,
        "community|C=s" => \$community,
        "crit|c:s" => \$crit,
        "warn|w:s" => \$warn,
        "oid|O=s" => \$oid);

print "$hostaddr $community $crit $warn $oid\n";

my ($session, $error) = Net::SNMP->session(
                        -hostname => "$hostaddr",
                        -community => "$community",
                        -timeout => "30",
                        -port => "161");

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

my $response = $session->get_table( -baseoid => $oid );

if (! defined $response) {
    die "Failed to get OID '$oid': " . $session->error;
}

foreach my $key (keys %$response) {
    print "$key: $response->{$key}\n";
}

my $err = $session->error;
if ($err){
        return 1;
}
print "\n";
exit 0;

The output:

10.192.54.30 public 30 20  .1.3.6.1.4.1.14179.2.2.1.1.6.0
Can't use an undefined value as a HASH reference at test.pl line 26.
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
cflinspach
  • 290
  • 1
  • 4
  • 16
  • get_request() fails in your code. The $response object is therefore undefined. You try to access an undefined value. Print $err to get more information. – user3606329 Feb 14 '17 at 21:08
  • I added print $err on line 29 and get the same output. – cflinspach Feb 14 '17 at 21:15
  • Are you sure? $session->error() should print you the error from get_request(). See: http://search.cpan.org/~dtown/Net-SNMP-v6.0.1/lib/Net/SNMP.pm#error()_-_get_the_current_error_message_from_the_object – user3606329 Feb 14 '17 at 21:24
  • 4
    Your code has `strict` and `warnings`! And your tutorial does not. That is so great! Even if you claim to be very new at Perl, you are doing the most crucial things right. Good job :) – simbabque Feb 14 '17 at 21:25
  • You can peek into `$session` directly with Data::Dumper. `use Data::Dumper; print Dumper $session;`. That's an object, but it will only show you the data associated with it. Most of the time that's the best place to start debugging. Note that `use` statements go at the top, but if it's just for debugging and you'll take it out later just put it where you need it. That way you'll remember to remove it later. – simbabque Feb 14 '17 at 21:30
  • This is unrelated to your issue, but your program would be much easier to understand if you used [Getopt::Long](https://metacpan.org/pod/Getopt::Long). Instead of the confusing `$opts{c}` and `$opts{C}`, you could have `$opts{critical}` and `$opts{community}`. Also, it looks like you might be writing a Nagios plugin...if so, have you seen [Monitoring::Plugin](https://metacpan.org/pod/Monitoring::Plugin)? – ThisSuitIsBlackNot Feb 14 '17 at 22:20
  • @ThisSuitIsBlackNot I haven't seen that, thanks for the info! – cflinspach Feb 15 '17 at 14:59

1 Answers1

2

Several problems:

  • You're calling $session->get_request wrong. At a minimum, you have to pass the -varbindlist option and an arrayref of OIDs. See the documentation.

  • get_request returns undef on error, and since undef is not a hash reference, you can't dereference it. You have to check for errors before you try to do something with $response.

  • You shouldn't copy the contents of $response into a separate hash just to print them.

Fixed version:

my $response = $session->get_request( -varbindlist => [$desc] );

if (! defined $response) {
    die "Failed to get OID '$desc': " . $session->error;
}

foreach my $key (keys %$response) {
    print "$key: $response->{$key}\n";
}

# Alternatively,
# use Data::Dumper; print Dumper $response;
ThisSuitIsBlackNot
  • 23,492
  • 9
  • 63
  • 110
  • That seemed to fix one problem, but now I get "Received noSuchName(2) error-status at error-index 1", but I can walk the OID just fine with snmpwalk. – cflinspach Feb 15 '17 at 14:53
  • snmpwalk -c public 10.192.54.30 -v 1 .1.3.6.1.4.1.14179.2.2.1.1.6 iso.3.6.1.4.1.14179.2.2.1.1.6.176.170.119.98.152.208 = INTEGER: 1 iso.3.6.1.4.1.14179.2.2.1.1.6.176.170.119.204.244.0 = INTEGER: 1 iso.3.6.1.4.1.14179.2.2.1.1.6.244.207.226.84.120.224 = INTEGER: 1 iso.3.6.1.4.1.14179.2.2.1.1.6.244.207.226.133.180.16 = INTEGER: 1 iso.3.6.1.4.1.14179.2.2.1.1.6.244.207.226.137.75.224 = INTEGER: 1 iso.3.6.1.4.1.14179.2.2.1.1.6.244.207.226.137.116.80 = INTEGER: 1 iso.3.6.1.4.1.14179.2.2.1.1.6.244.207.226.137.117.144 = INTEGER: 1 – cflinspach Feb 15 '17 at 15:53
  • perl test.pl -H 10.192.54.30 -C public -O .1.3.6.1.4.1.14179.2.2.1.1.6 -w 20 -c 30 10.76.64.12 r350urc31 30 20 .1.3.6.1.4.1.14179.2.2.1.1.6 Failed to get OID '.1.3.6.1.4.1.14179.2.2.1.1.6': Received noSuchName(2) error-status at error-index 1 at test.pl line 28. – cflinspach Feb 15 '17 at 15:55
  • @red_eagle To do an apples-to-apples comparison, you should use `snmpget` instead of `snmpwalk`. I don't see OID `.1.3.6.1.4.1.14179.2.2.1.1.6` in your `snmpwalk` output, so I don't think your SNMP agent provides it. – ThisSuitIsBlackNot Feb 15 '17 at 17:43
  • That oid is the first part. I understand what your saying though so I'm trying to setup a while loop with get_next_request so as long as $response is defined it works. Really if you want to see what the real goal is I wrote it in [bash](http://stackoverflow.com/questions/42208795/new-nagios-bash-plugin-output-error-such-instance-currently-exists-at-this-oid) but Nagios/icinga seems to like perl better. – cflinspach Feb 15 '17 at 18:05
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/135798/discussion-between-red-eagle-and-thissuitisblacknot). – cflinspach Feb 15 '17 at 18:10