Skip Menu |

This queue is for tickets about the Net-SNMP CPAN distribution.

Report information
The Basics
Id: 22690
Status: resolved
Worked: 15 min
Priority: 0/
Queue: Net-SNMP

People
Owner: dtown [...] cpan.org
Requestors: siemsen [...] ucar.edu
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 5.2.0
Fixed in: 5.2.0



Subject: get_table returns some junk entries
The attached file named GetArpNew.pl contains a program that reliably demonstrates the problem. The comment at the top of the file describes the problem. The program contains some hard-coded device names and a community string that you'll have to change. I attached the output of a run. It shows that get_table basically works, and works without error when talking to some of my routers. When it fails, some of the values in the table it returns are junk. Most of the table is fine - it's just some entries that are junk. It produces the same output on multiple runs. Here's some details about my system: $ perl -V Summary of my perl5 (revision 5 version 8 subversion 4) configuration: Platform: osname=linux, osvers=2.6.15.6, archname=i386-linux-thread-multi uname='linux ernie 2.6.15.6 #1 thu mar 16 13:11:55 est 2006 i686 gnulinux ' config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i386-linux -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.4 -Dsitearch=/usr/local/lib/perl/5.8.4 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.4 -Dd_dosuid -des' hint=recommended, useposix=true, d_sigaction=define usethreads=define use5005threads=undef useithreads=define usemultiplicity=define useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2', cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -I/usr/local/include' ccversion='', gccversion='3.3.5 (Debian 1:3.3.5-13)', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt perllibs=-ldl -lm -lpthread -lc -lcrypt libc=/lib/libc-2.3.2.so, so=so, useshrplib=true, libperl=libperl.so.5.8.4 gnulibc_version='2.3.2' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib' Characteristics of this binary (from libperl): Compile-time options: MULTIPLICITY USE_ITHREADS USE_LARGE_FILES PERL_IMPLICIT_CONTEXT Built under linux Compiled at May 10 2006 03:55:26 @INC: /etc/perl /usr/local/lib/perl/5.8.4 /usr/local/share/perl/5.8.4 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.8 /usr/share/perl/5.8 /usr/local/lib/site_perl . The devices that I am accessing are Cisco routers. If I can get past this bug, I'd like to replace SNMP_Session with Net::SNMP throughout my program. It is faster than SNMP_Session. One interesting thing: when I change the first argument from 'snmpv2' to 'snmpv1', Net::SNMP is significantly slower than SNMP_Session. I would've assumed that they'd run with similar times.
Subject: GetArpNew.pl
#!/usr/bin/perl -w # # GetArpWithNetSnmp.pl # # This program demonstrates a bug in the Net::SNMP Perl module. # # The program is a simplified version of a production program called # GetArp.pl. The real GetArp program has been running successfully # for years. It uses SNMP to retrieve ARP information from routers. # It uses the SNMP_Session module to do the actual SNMP communication. # The SNMP_Session module works fine, but it doesn't directly support # GETBULK, or SNMPv3, and the API is cumbersome. The Net::SNMP module # seems to be more popular and more current, and it supports GETBULK # and SNMPv3, and it has a much more convenient API. I want to # convert GetArp to use Net::SNMP. I want the basic function of # GetArp to stay the same, except that it might run faster due to # GETBULK suppert. # # I'm a suspicious person, so I wrote this progrom to test that # Net::SNMP actually returns the same data as SNMP_Session. This # program does the same SNMP access using both modules. The results # should be the same. They aren't. Net::SNMP seems to have a bug. # # I've removed all the extraneous stuff that doesn't have to do with SNMP. use strict; use FindBin; use lib $FindBin::Bin; # find modules in the same dir as this file use lib "SNMP_Session-1.08/lib"; # find modules in SNMP lib directory use SNMP_Session; use BER; use Net::SNMP 5.2.0 qw(:snmp); use Data::Dumper; use Time::HiRes; sub GetRouterArpTableUsingSnmpSession ($$$) { my $session = shift; my $routername = shift; my $Oid = shift; print "Getting ARPs from $routername using SNMP_Session...\n"; my($nxt_oid, $bindings, $binding, $value); my $orig_oid = encode_oid(split /\./, $Oid); my $enoid = $orig_oid; my %table = (); my $counter = 0; while ($session->getnext_request_response(($enoid))) { $counter ++; my $response = $session->pdu_buffer; ($bindings) = $session->decode_get_response ($response); ($binding, $bindings) = decode_sequence ($bindings); ($nxt_oid, $value) = decode_by_template ($binding, "%O%@"); last unless BER::encoded_oid_prefix_p($orig_oid, $nxt_oid); my $p_oid = BER::pretty_oid $nxt_oid; my @snmpid = split /\./, $p_oid; my $mac=''; foreach (unpack "xxCCCCCC", $value) { $mac = $mac . sprintf "%02x", $_; } my $ip = "$snmpid[12].$snmpid[13].$snmpid[14].$snmpid[15]"; $table{$ip} = $mac; $enoid = $nxt_oid; } print "returning success, did $counter requests\n"; return (%table); } sub GetRouterArpTableUsingNetSnmp ($$$) { my $Session = shift; my $RouterName = shift; my $Oid = shift; print "Getting ARPs from $RouterName using Net::Snmp...\n"; my $Arps = $Session->get_table($Oid); if (!defined($Arps)) { my $tmp = $Session->error(); print "couldn't get SNMP values, $tmp\n"; } my %table = (); foreach my $RetOid (keys %{$Arps}) { my $newoid = $RetOid; $newoid =~ s/^\.1\.3\.6\.1\.2\.1\.3\.1\.1\.2\.\d+\.\d+\.//; # strip off the leading oid octets my $newmac = $$Arps{$RetOid}; $newmac =~ s/^0x//; # strip aff the leading "0x" $table{$newoid} = $newmac; } print "returning success\n"; return (%table); } # # Main. ====================================================================== # my @routers = (); push @routers, 'blura'; push @routers, 'cg-voipr'; push @routers, 'cgra'; push @routers, 'cgrb'; push @routers, 'fl-voipr'; push @routers, 'flra'; push @routers, 'flrb'; push @routers, 'jef-voipr'; push @routers, 'jeffcor'; push @routers, 'marshallr'; push @routers, 'mlra'; push @routers, 'voip1r'; foreach my $RouterName (@routers) { print "reading ARP table from $RouterName...\n"; my $Community = 'ncar-read'; my $Oid = '.1.3.6.1.2.1.3.1.1.2'; # the ARP table #============================================================================= # Try it using SNMP_Session my ($seconds, $microseconds) = Time::HiRes::gettimeofday; my $session = SNMP_Session->open($RouterName, $Community, 161); if (!$session) { die "couldn't open SNMP session to $RouterName, returning\n"; } my %Arp = GetRouterArpTableUsingSnmpSession($session, $RouterName, $Oid); $session->close(); my $elapsed = Time::HiRes::tv_interval([$seconds, $microseconds]); print "SNMP_Session took $elapsed seconds\n"; # print Dumper \%Arp; #============================================================================= # Try it using Net::SNMP ($seconds, $microseconds) = Time::HiRes::gettimeofday; my ($Session, $Error) = Net::SNMP->session( -version => 'snmpv2', -timeout => 2, -hostname => $RouterName, -community => $Community ); if (!defined($Session)) { die "couldn't open SNMP session to $RouterName: $Error"; } my %Arp2 = GetRouterArpTableUsingNetSnmp($Session, $RouterName, $Oid); $Session->close; my $elapsed = Time::HiRes::tv_interval([$seconds, $microseconds]); print "Net::SNMP took $elapsed seconds\n"; # print Dumper \%Arp2; #============================================================================= # compare the results foreach my $Ip (keys %Arp) { if ($Arp{$Ip} ne $Arp2{$Ip}) { my $tmp1 = $Arp{$Ip}; my $tmp2 = $Arp2{$Ip}; print "Arp{$Ip} = \"$tmp1\", NOT EQUAL TO Arp2{$Ip} = \"$tmp2\"\n"; } } }
Subject: out.txt
���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
What you are seeing is the expected behavior of the module. The Net::SNMP module has translation enabled by default. When an OCTET STRING is received, the contents of the string are checked to make sure that all octets are printable. If any octet is not printable, the string is translated into the hexadecimal representation. If all of the octets are considered printable by the module, then no translation takes place (which is what is happening in your case). See ticket #18699 (https://rt.cpan.org/Ticket/Display.html?id=18699) for a more detailed explanation. Without further examination of what is going on, I can only guess on why SNMPv2c is faster than SNMPv1. The underlying framework for both v1 and v2 is the same, however the get_table() method uses get-bulk-requests when the version is set to v2 instead of get-next-request. -David
Subject: Re: [rt.cpan.org #22690] get_table returns some junk entries
Date: Mon, 30 Oct 2006 13:16:47 -0700
To: bug-Net-SNMP [...] rt.cpan.org
From: Pete Siemsen <siemsen [...] ucar.edu>
That explains the problem, and the solution described in ticket #18699 fixes the problem. Thank you very much! -- Pete On Oct 30, 2006, at 7:29 AM, via RT wrote: Show quoted text
> > <URL: http://rt.cpan.org/Ticket/Display.html?id=22690 > > > What you are seeing is the expected behavior of the module. The > Net::SNMP module has translation enabled by default. When an OCTET > STRING is received, the contents of the string are checked to make > sure > that all octets are printable. If any octet is not printable, the > string > is translated into the hexadecimal representation. If all of the > octets > are considered printable by the module, then no translation takes > place > (which is what is happening in your case). See ticket #18699 > (https://rt.cpan.org/Ticket/Display.html?id=18699) for a more detailed > explanation. > > Without further examination of what is going on, I can only guess > on why > SNMPv2c is faster than SNMPv1. The underlying framework for both > v1 and > v2 is the same, however the get_table() method uses get-bulk-requests > when the version is set to v2 instead of get-next-request. > > -David
Subject: Re: [rt.cpan.org #22690] Resolved: get_table returns some junk entries
Date: Tue, 31 Oct 2006 20:32:19 -0700
To: bug-Net-SNMP [...] rt.cpan.org
From: Pete Siemsen <siemsen [...] ucar.edu>
My request has been resolved. Thanks! -- Pete On Oct 31, 2006, at 8:28 PM, via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=22690 > > > According to our records, your request has been resolved. If you > have any > further questions or concerns, please respond to this message.
Closing ticket which I thought was already closed.