Reading SNMP values from a device with multiple view-based ACM contexts, using Net::SNMP

StackOverflow https://stackoverflow.com/questions/20060223

  •  31-07-2022
  •  | 
  •  

Question

I am trying to use Perl and Net::SNMP to query a device that has multiple configured views/contexts (a Cisco ACE 4710, for example). The equivalent snmpwalk command is:

snmpwalk -c public@CONTEXT_NAME -v 2c 1.2.3.4 '.1.3.6.1.4.1.9.9.480.1.1.2'

I can enumerate the various contexts/views with SNMP-VIEW-BASED-ACM-MIB, e.g.:

my $vacmContextName = '.1.3.6.1.6.3.16.1.1.1.1';
my ($session, $error) = Net::SNMP->session(-hostname => '1.2.3.4', -community => 'public');
my %contexts = %{ $snmp->get_entries(-columns => [ $vacmContextName ]) };

...but am having trouble now reading any further OIDs from each specific context, e.g.:

my $ciscoL4L7ResourceLimitTable = '.1.3.6.1.4.1.9.9.480.1.1.2';
my ($session, $error) = Net::SNMP->session(-hostname => '1.2.3.4', -community => 'public@CONTEXT_NAME');
my %stats = %{ $snmp->get_entries(-columns => [ $ciscoL4L7ResourceLimitTable ]) }

If I run with -debug => DEBUG_ALL, I see the data being returned in the packet inspection (with recognisable data from that context), but then I get a lot of the following errors:

error: [131] Net::SNMP::Security::Community::process_incoming_msg(): The community name "public@CONTEXT_NAME" was expected, but "public" was found
error: [218] Net::SNMP::MessageProcessing::prepare_data_elements(): The community name "public@CONTEXT_NAME" was expected, but "public" was found
error: [398] Net::SNMP::Dispatcher::_transport_response_received(): The community name "public@CONTEXT_NAME" was expected, but "public" was found
error: [1234] Net::SNMP::__ANON__(): The community name "public@CONTEXT_NAME" was expected, but "public" was found
error: [2363] Net::SNMP::__ANON__(): The community name "public@CONTEXT_NAME" was expected, but "public" was found

...and the resulting contents of %stats is undef.

If I try with -community => 'public', it works, but I only get values from the default context (which doesn't contain everything I need).

If I try with -contextname => 'CONTEXT_NAME', I just get:

error: [2423] Net::SNMP::_context_name(): The contextName argument is only supported in SNMPv3

Is it not possible to do what I need with Net::SNMP?

This is perl, v5.10.1 (*) built for i386-linux-thread-multi
CPAN_FILE    D/DT/DTOWN/Net-SNMP-v6.0.1.tar.gz
INST_VERSION v6.0.1
Was it helpful?

Solution

From an email conversation I just had with the package author, Word-of-$DEITY is:

Cisco's "context implementation" is vendor specific and is not standards based. The use of "contexts" is officially defined in the SNMPv3 RFCs (specifications). The Net::SNMP modules tries to follow the RFCs in its implementation. I would have to go back to the RFCs determine if it is legal to respond to an SNMP v1/2c message with a "community" string that is not the same as the one with which the request was made. This is the problem that you are seeing.

You are most likely not going to get Cisco to change their implementation even if it is violating an RFC, so your only recourse is to comment out the code in the Net/SNMP/Security/Community.pm module that is returning an error on the send/receive of differing community strings. I typically do not add modification to the module to work around vendor specific problems.

Rather than comment out the relevant section of the Community.pm (which is used by far more on my server than just this script), I have instead elected to shim/monkey-patch the method in question in my own code, for example:

no warnings 'redefine';
use Net::SNMP::Security::Community;
*Net::SNMP::Security::Community::process_incoming_msg = sub { return 1; };

This way, the failing method is bypassed in favour of just accepting any returned community string.

Filthy dirty on all counts, but acceptable within my controlled environment. Anyone coming across this in the future should make sure that version != 6.0.1 hasn't changed the way this module works, or what the existing subroutine does before attempting the same.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top