bowei_99 has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,

I have a script that gathers information about shares on a Windows server (printer name, comment). It uses the MS LanMgr MIB II, and gets parameters like number of print jobs and queue name OK, but the comment it reads as null. Yet, when I do an snmpwalk for that OID (.1.3.6.1.4.1.77.1.2.27.1.3), I get the comments I expect, i.e. that I see when accessing the share. I checked in a couple places, like here and here, and made sure it was in fact the same OID as I'm querying in the script.

Have any of you ran into this?

This is the code I wrote. I modified it from p. 355 of "Perl for System Administration" (by David Blank-Edelman). I figured on using SNMP instead of Net::SNMP or SNMP_Session.pm, since it can parse MIBs and make my code more maintainable and readable. Plus, I figure it should be easier for the code to match a printer queue name with a comment that way. I set the debug variable to maximum (2), but it just shows that it read the MIB OK, and read in a null value for the comment.

sub QuerySNMP { use SNMP; #$SNMP::debugging = 2; my ($hostname) = shift @_; #my (@params) = qw(1.3.6.1.77.1.2.27.1.1 1.3.6.1.4.1.77.1.2.27.1.3 +); $ENV{'MIBFILES'} = "LanMgr-Mib-II-MIB.my"; my ($session) = new SNMP::Session( DestHost => $hostname, Community => "public", UseSprintValue => 1, ); if (!(defined($session))) { die "Session creation error: $SNMP::Session::ErrorStr - $!\n +" ; } my ($vars) = new SNMP::VarList(['svPrintQName'], ['svPrintQNumJobs'], ['svShareComment'], ); my ($q, $num_jobs, $share_comment) = $session->getnext($vars); if ($session->{ErrorStr}) {; die "Getnext failed - error: " . $session->{ErrorStr} . " - $! +\n" } while (!$session->{ErrorStr} ) { print "q - $q, num jobs - $num_jobs, comment - $share_comment, + tag - " . $$vars[0]->tag . "\n"; ($q, $num_jobs) = $session->getnext($vars); } }

Replies are listed 'Best First'.
Re: SNMP from script conflicts with snmpwalk
by monarch (Priest) on Nov 14, 2005 at 22:44 UTC
    The simplest answer I can think of is the while loop..
    while (!$session->{ErrorStr} ) { print( "q - $q, num jobs - $num_jobs, " . "comment - $share_comment, " . "tag - " . $$vars[0]->tag . "\n" ); ------> ($q, $num_jobs) = $session->getnext($vars); }
    ..why isn't the marked line assigning $share_comment? Also, because of the while loop, it appears that you're attempting to read in a table (or a series of columnar objects), in which case you don't want to start with object .0 (although there's no harm in doing this because the SNMP RFCs state that columnar objects must never commence with a .0 suffix - unfortunately Nortel struggles to comply with this in their SNMP agents).
      ------> ($q, $num_jobs) = $session->getnext($vars);
      Duh, I knew it was something trivial. Yeah, I updated the line with

      ($q, $num_jobs, $share_comment) = $session->getnext($vars);

      and it works,i.e. it shows the values I expect. I think I had changed it earlier in the code, but forgot to change this line, too.

        If your IP addresses are getting jumbled up you now have to ask yourself: "are all my values that are returned on the same row?"

        If it is at all possible that particular rows have a field missing then your individual column getnexts are going to get out of sync.. you may be retrieving share name for row 12 while retrieving comment for row 15.

        To guard against this you are going to have to harvest the last integer from the OID of each column and ensure they are all the same. (The last OID of each column is the row number, or more accurately, the index of the row.. actually the index might be an IP address and consist of many integers.. The only right way to obtain the row number is to strip off the leading digits that match the OID of the variable you are getting - confused yet?).

        Whilst SNMP is a simple protocol to implement, it's not so simple to use.. you have my empathy.

        Actually, the comments show up as IP addresses expected, but they are jumbled up, i.e. different values from what I see in Windows.... Hmm... the values from snmpwalk match with what's seen through the Windows share - perhaps something with this module?

        This is what the code looks like now. Only made a couple changes - since I only need the queue name and comments, I only collect that ...

        sub QuerySNMP { use SNMP; #$SNMP::debugging = 2; $ENV{'MIBFILES'} = "LanMgr-Mib-II-MIB.my"; my ($hostname) = shift @_; my ($session) = new SNMP::Session( DestHost => $hostname, Community => "public", UseSprintValue => 1, ); if (!(defined($session))) { die "Session creation error: $SNMP::Session::ErrorStr + - $!\n" ; } my ($vars) = new SNMP::VarList(['svPrintQName'], ['s +vShareComment '], ); my ($q, $num_jobs, $share_comment) = $session->getnext($vars) +; if ($session->{ErrorStr}) {; die "Getnext failed - error: " . $session->{ErrorStr} +. " - $!\n" } while (!$session->{ErrorStr} ) { print "q - $q, comment - $share_comment\n"; my ($q, $share_comment) = $session->getnext($vars); } }
Re: SNMP from script conflicts with snmpwalk
by idsfa (Vicar) on Nov 14, 2005 at 20:58 UTC

    The docs suggest that you want:

    my $vars = new SNMP::VarList(['svPrintQName',0], ['svPrintQNumJobs',0], ['svShareComment',0]);

    Specifically, the line that says "for scalar MIB objects use '0' "


    The intelligent reader will judge for himself. Without examining the facts fully and fairly, there is no way of knowing whether vox populi is really vox dei, or merely vox asinorum. — Cyrus H. Gordon
      When taking the time to read the author's post, and browsing the MIB provided, it can be seen that the objects being requested are columnar, not scalar objects.

      Thus the author's code is correct, there should not be a .0 suffix when getnexting these columnar objects.

      > Specifically, the line that says "for scalar MIB objects use '0' "

      I tried that, still the same thing. I tried putting in 0 (as idsfa suggested), as well as '0', and 1, and same results.