Skip to content

Instantly share code, notes, and snippets.

@pmorch
Created October 17, 2011 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pmorch/1293702 to your computer and use it in GitHub Desktop.
Save pmorch/1293702 to your computer and use it in GitHub Desktop.
Net-SNMP perl interface problem when retry after initial noSuchName

This is supporting formation for this sourceforget bug report:

SNMP Version 1: If I try to SNMP get two OIDs:

  • one of which doesn't exist
  • the other being in numerical .1.3.6.1.4.1.123456.1 format

like this:

my $vars = new SNMP::VarList(
    [ 
        # enterprises.123456.1.0 - Some bogus OID
        '.1.3.6.1.4.1.123456.1', 0
    ], [ 
        # This ifIndex doesn't actually exist
        'ifIndex', 10000
    ],
);
$sess->get($vars)

Then Net-SNMP returns this in $sess:

ErrorStr: (noSuchName) There is no such variable name in this MIB.
ErrorInd: 2

and replaces the numerical OID with a symbolic one (enterprises.123456.1.0 in the example).

When I remove the 2nd OID like so:

splice @$vars, $sess->{ErrorInd} - 1, 1;

And try again. Then I get this:

ErrorStr: Unknown Object Identifier (Sub-id not found: (top) -> enterprises)

So Net-SNMP replaced my numerical OID with one it doesn't understand itself? I therefore file a bug...

Here is a some reproducing code along with some sample output.

About the inital OID set

We start out with tese two OIDs:

  • .1.3.6.1.4.1.123456.1.0 - An OID for which there is no MIB file
  • ifIndex.10000

The ifIndex.10000 is last, because testing shows that the Net-SNMP agent (localhost) will give a noSuchName error with ErrorInd pointing that least OID.

I started out with the first OID being a real valid OID in numerical form. So it doesn't matter whether there is a mib for the first OID or not.

Workaround

Use UseLongNames => 1 in the $sess object.

or

When the OIDs come back with an noSuchName error, replace the OIDs with the ones from the original set. I.e. replace the enterprises... with .1.3.6... And then splice and try again. Then it works.

System info

Linux with libsnmp-perl 5.4.1~dfsg-12

ErrorStr (noSuchName): (noSuchName) There is no such variable name in this MIB. Ind: 2
$VAR1 = 'after get';
$VAR2 = bless( [
bless( [
'enterprises.123456.1.0',
'',
'',
'NULL'
], 'SNMP::Varbind' ),
bless( [
'ifIndex',
'10000',
'',
'INTEGER32'
], 'SNMP::Varbind' )
], 'SNMP::VarList' );
$VAR1 = 'after removal of first (0th) element';
$VAR2 = bless( [
bless( [
'enterprises.123456.1.0',
'',
'',
'NULL'
], 'SNMP::Varbind' )
], 'SNMP::VarList' );
ErrorStr (Sub-id not found): Unknown Object Identifier (Sub-id not found: (top) -> enterprises)
ErrorStr (Sub-id not found): Unknown Object Identifier (Sub-id not found: (top) -> enterprises)
In the following two lines, 'noSuchName' errors are expected
ErrorStr (fine): (noSuchName) There is no such variable name in this MIB.
ErrorStr (fine): (noSuchName) There is no such variable name in this MIB.
#!/usr/bin/perl -w
use strict;
use SNMP;
=head Description
See ./README.md for a description
=cut
use Data::Dumper;
# A windows host running http://www.snmp-informant.com/
my $sess = new SNMP::Session(
DestHost => 'localhost',
Community => 'public',
Version => '1',
# Enabling this makes the problem go away...
# UseLongNames => 1,
);
my $vars = new SNMP::VarList(
[
# enterprises.123456.1.0 - Some bogus OID
# This OID doesn't actually exist, and that creates problems later, but
# do see ./README.md for more details
'.1.3.6.1.4.1.123456.1', 0
], [
# This ifIndex doesn't actually exist
'ifIndex', 10000
],
);
$sess->get($vars);
printf "ErrorStr (noSuchName): %s Ind: %s\n", @{$sess}{qw(ErrorStr ErrorInd)};
# Note how the numerical enterprises OID has been translated
print Dumper('after get', $vars);
# The errorStr
splice @$vars, $sess->{ErrorInd} - 1, 1;
print Dumper('after removal of first (0th) element', $vars);
$sess->get($vars);
printf "ErrorStr (Sub-id not found): %s\n", $sess->{ErrorStr};
# So to recap, this doesn't work:
$vars = new SNMP::VarList( [ 'enterprises.123456.1.0' ] );
$sess->get($vars);
printf "ErrorStr (Sub-id not found): %s\n", $sess->{ErrorStr};
# In the following, "fine" means that it doesn't bomb out with a (Sub-id not
# found) error. As expected, they do yield a noSuchName error because the agent
# doesn't have a enterprises.123456.1.0 OID.
print "In the following two lines, 'noSuchName' errors are expected\n";
# Contrary to above, this does work:
$vars = new SNMP::VarList( [ 'enterprises.123456.1', 0 ] );
$sess->get($vars);
printf "ErrorStr (fine): %s\n", $sess->{ErrorStr};
# And so does this
$vars = new SNMP::VarList( [ 'RFC1155-SMI::enterprises.123456.1', 0 ] );
$sess->get($vars);
printf "ErrorStr (fine): %s\n", $sess->{ErrorStr};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment