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

Greetings, Here is my code:
#!/usr/bin/perl -w use strict; use Net::SNMP; # this script gets passed a machine name ($machine_name) # and then an unknown number of commands if(!defined($ARGV[0])) { print "this scripts takes arguments example: test.pl machine.name comm +and1 command2 command3"; exit(1); } my $machine_name = $ARGV[0]; my $community = 'public'; my $snmp_port = 161; my @Commands; my $i; for ($i=1; $i < $#ARGV; $i++) { push @Commands, $ARGV[$i]; } #test to make sure variables have values. print "/nMachine:$machine_name"; foreach my $command_test (@Commands) { print "command: $command_test\n"; } print "Building Session..."; my ($session, $error) = Net::SNMP->session( -hostname => $machine_name, -community => $community, -port => $snmp_port ); ################################# ### This code above used to be... ### my ($session, $error) = Net::SNMP->session( ### -hostname => shift || 'localhost', ### -community => shift || 'public', ### -port => shift || 161 ### ); ################################# if (!defined($session)) { printf("ERROR in session: %s.\n",$error); exit 1; } ### general OID for system up time my $sysUpTime = '1.3.6.1.2.1.1.3.0'; ### These are Cisco OID's which i use for the AS5400 bank my $ModemsAvailable = '1.3.6.1.4.1.9.9.47.1.1.7.0'; my $ModemsUnavailable = '1.3.6.1.4.1.9.9.47.1.1.8.0'; my $result = $session->get_request( -varbindlist => [$sysUpTime] ); if(!defined($result)) { print "error in result: %s, status:%s.\n",$session->error,$session->er +ror_status); $session->close; exit 1; } my $result2 = $session->get_request( -varbindlist => [$ModemsAvailable] ); if(!defined($result2)) { print "error in result2: %s, status:%s.\n",$session->error,$session->e +rror_status); $session->close; exit 1; } my $result3 = $session->get_request( -varbindlist => [$ModemsUnavailable] }; if(!defined($result3)) { print "error in result3: %s, status:%s.\n",$session->error,$session->e +rror_status); $session->close; exit 1; } print "\nSystem uptime for host: '%s' is %s\n",$session->hostname, $re +sult->{$sysUpTime} ); print "\nModems Available for host: '%s' is %s\n",$session->hostname, +$result->{$sysUpTime} ); print "\nModems Unavailable for host: '%s' is %s\n",$session->hostname +, $result->{$sysUpTime} ); exit 0;

Does anyone know of a way to loop through multiple requests without needing to make a new variable everytime?
I am planning on having hundreds of commands available, where you just pass a number as argument like 1 3, and that would mean return the system uptime, and the modems unavailable. I was thinking somthing like this:

%cmd_table = ( 1 => 'sysUpTime', 2 => 'ModemsAvailable', 3 => 'ModemsUnavailable' ) my @results; foreach my $command (@Commands) { if(!defined(my $result_temp = $session->get_request( -varbindlist => ['$'.%cmd_table{$command}] ))) { print "error with command #:%s, %s", $command, %cmd_table{$command}); push @results, $result_temp; } }
Do you think this would work better, excuse any
obvious syntax problems.
If you have any idea's on how to make this whole
thing better your input would be appriciated.
I Typed this code from reading off my xterm so
I havn't actually ran this and tested this code,
it might have little typo's in it that I missed
in the trasfer
Thanks,
Enigmae

Replies are listed 'Best First'.
Re: Making a scalable Net::SNMP script?
by dingus (Friar) on Nov 21, 2002 at 18:44 UTC
    You could use either an array or (probably better) a hash something like this:
    my %cmdtable=( ### general OID for system up time sysUpTime => '1.3.6.1.2.1.1.3.0', ### These are Cisco OID's which i use for the AS5400 bank ModemsAvailable = '1.3.6.1.4.1.9.9.47.1.1.7.0', ModemsUnavailable = 1.3.6.1.4.1.9.9.47.1.1.8.0')
    and then indeed you can do a
    my @results; for (keys %cmdtable) { ...
    If you need them ordered you can EITHER have the order in a separate array or have 2 arrays one for command and one for the OID.

    Assuming you need to do this sort of thing for many devices and you wish to do it in a reasonable timeframe you may want to look at POE as that should nicely cope with multiple parallel SNMP requests an responses. I seem to recall from days querying SNMP devices that responses are often in the seconds (or worse if you have to retry), which means that if you need to do 100 queries on 100 differnt devices in a strict sequence you get a script that runs for 3 hours instead of under two minutes! POE should let you parallelise nicely - indeed the POE cookbook may actually have sample code for this thing.

    Dingus


    Enter any 47-digit prime number to continue.