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

What I'm trying to do:

I have to get the SNMP value from several Object Identifiers (OIDs) that mean the same thing, but aren't present on all devices. IE: A Cisco 6509 may support the .chassisId OID, but the next device doesn't. I don't want to have to write 18 different subs for all the different devices I have.

What I want to happen is have the getSnmpInfo sub recognize that it was passed a list variable then run itself against each list entry. And if it was passed a scalar, just run against that one value.

I suppose one kludge is to collapse the list with a delimiter, search for it in the sub and expand the list if found.

I seems like there must be a better way though. It feels like I'm missing something fundamental here. And it doesn't help that my previous XP is all in PHP, bash, and .bat files *shudder*

Please excuse my coding if you find it hideous... I'm a newbie to Perl.

Here's the sub:

# main section my ( $sysChassisID, #and other stuff ); # define OID of system Chassis ID attribute (serial number) my @sysChassisIDOID = ( "1.3.6.1.4.1.9.3.6.3", # .chassisId "1.3.6.1.2.1.47.1.1.1.1.11.0", # .entPhysicalSerialNumber.0 "1.3.6.1.2.1.47.1.1.1.1.11.1", # .entPhysicalSerialNumber.1 "1.3.6.1.4.1.9.5.1.2.19.0", # .CiscoStackMIB.chassisSerialNumbe +rString ); # calling the sub: (this takes place inside a while loop as # the script goes through a list of IP addresses. # I borrowed heavily from cdppoll.pl. $sysChassisID = getSnmpInfo (@sysChassisIDOID) sub getSnmpInfo { my($crap , $value , $result); my $varType = ref($_[0]); # Get the variable type from ref() if ($varType eq "ARRAY") { my @tmp = $_[0]; print "\n DEBUG::GET_SNMP_INFO: OID is an array" if $debugg +ing; # march through the array until a valid value is collected the +n # return that value. while (@tmp) { my $tOID = shift @tmp; $value = getSnmpInfo($tOID); return $value if ((ref($value) eq "SCALAR") and ($value =~ m/[ +A-Za-z0-9]{1,}/)); next; } } elsif ($varType eq "SCALAR") { print "\n DEBUG::GET_SNMP_INFO: OID is a scalar" if $de +bugging; } else { print "\n DEBUG:GET_SNMP_INFO:: OID is an illegal varia +ble type ($varType)" if $debugging; return 0; } my($oid) = $_[0]; $session = (defined $_[1]) ? ($_[1]) : ($session); unless ($session) { print "\n DEBUG::GET_SNMP_INFO: session not established in +getSnmpInfo sub-routine, check scopes and pass as option 2 to getSnmp +Info" if $debugging; print "\n WARN::GET_SNMP_INFO: getSnmpInfo returning null, +session unavailable."; return 0; } print "\n DEBUG::GET_SNMP_INFO: fetching OID: $oid" if $debuggi +ng; $result = $session->get_request("$oid"); return unless (defined $result); ($crap , $value) = %$result; print "\n DEBUG::GET_SNMP_INFO: OID value: $value" if $debuggin +g; return $value; }
Thanks for taking your time. - Rowshi

Replies are listed 'Best First'.
Re: data type discovery inside sub: how?
by Corion (Patriarch) on Jul 20, 2007 at 09:21 UTC

    You are close. When you determine that you were passed an array reference, you need to copy the array, not the reference. Instead of:

    if ($varType eq "ARRAY") { my @tmp = $_[0];

    you need to dereference the reference:

    if ($varType eq "ARRAY") { my @tmp = @{ $_[0] };

    Also see tye's References Quick Reference for a quick overview of references in Perl

Re: data type discovery inside sub: how?
by shmem (Chancellor) on Jul 20, 2007 at 09:58 UTC
    Missing semicolon on that line:
    $sysChassisID = getSnmpInfo (@sysChassisIDOID)

    which isn't quite right in your context anyways. You are passing a list consiting of the array elements into the sub, but you seem to want to pass a reference:

    $sysChassisID = getSnmpInfo (\@sysChassisIDOID);

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: data type discovery inside sub: how?
by rowshi (Initiate) on Jul 20, 2007 at 10:25 UTC
    Thanks gentlemen (gentlemonks?) You made my code work... well sort of. I still have some problems but you made my big one disappear, and for that I am extremely grateful. Domo!