hotsanic |
Subversion Repositories: |
Compare with Previous - Blame - Download
#
# $Id: HotSaNICsnmp.pm,v 1.26 2004/07/11 22:39:39 bernisys Exp $
#
package HotSaNICsnmp;
use Fcntl;
use HotSaNICparser;
($VERSION = '$Revision: 1.26 $') =~ s/.*(\d+\.\d+).*/$1/;
# Get modulename
my $MODNAME = HotSaNICparser::get_module_name();
# Get HotSaNIC global configuration
my %conf = HotSaNICparser::get_config("../..",$MODNAME);
# Hash to hold the probed/read versions of diffrerent agents.
my %agent_v;
#
# get_session($host, $community, $ver)
#
# returns a new Net::SNMP session and sets version
#
sub get_session {
my ($host, $comm, $ver) = @_;
undef my $result;
$result = Net::SNMP->session(
Hostname => $host,
Community => $comm,
Port => 161
);
if(defined($result)) {
$result->version($ver);
$result->timeout(2);
$result->retries(1);
}
return $result;
}
#
# probe_version($host, $community)
#
# Checks the given hosts ability to answer bulk requests and returns
# either '1' if no bulk request was possible and '2c' if it was.
#
sub probe_version {
my $sys = 0; # use Net::SNMP by default
eval { require Net::SNMP; };
$sys = 1 if($@); # use system commands
my ($host, $comm) = @_;
my $result = 1; # default return value is '1'
# Now send a probe request to check which version to use
if($sys == 1) {
if (HotSaNIClog::check_debuglevel("SNMP_VERBOSE")) { HotSaNIClog::info("SNMP - probe_version() syscmd"); }
return $result if !defined($conf{SNMPBULKWALK});
open RESULT,"$conf{SNMPBULKWALK} -c $comm -v 2c -r 1 -t 2 $host .1.3.6.1.2.1.1.1|";
$result = '2c' if $? == 0;
close RESULT;
} else {
if (HotSaNIClog::check_debuglevel("SNMP_VERBOSE")) { HotSaNIClog::info("SNMP - probe_version() Net::SNMP"); }
my $session = get_session($host, $comm, '2c');
return $result if !defined($session);
my @test = '.1.3.6.1.2.1.1.1';
$result = '2c' if defined($session->get_bulk_request(-varbindlist => \@test));
$session->close();
}
return $result;
}
#
# set_version($host, $comm)
#
# trys to determit the version to use with specified host. If not in the
# info file the probe function will be called to set a version.
#
sub set_version {
my ($host, $comm) = @_;
$lockfile=$conf{VARDIR}."modules/$host.lock";
$infofile=$conf{VARDIR}."modules/$host.info";
sleep 1 while !sysopen(LOCK, $lockfile, O_WRONLY|O_EXCL|O_CREAT, 0644); # grab lock or wait
# Read info either from filesystem or probe it.
if( -e $infofile ) {
open (INFO, "<$infofile");
$agent_v{$host} = <INFO>;
close INFO;
} else {
open (INFO, ">$infofile");
$agent_v{$host} = probe_version($host, $comm);
print INFO $agent_v{$host};
close INFO;
}
close LOCK; # close lockfile
unlink $lockfile; # release lock
if (HotSaNIClog::check_debuglevel("SNMP_VERBOSE")) { HotSaNIClog::info("SNMP - set_version() [$agent_v{$host}]"); }
}
#
# snmp_walk($host, $comm, @oid)
#
# This function is used by the modules to retrieve one or more subtables from
# the SNMP tree on $host. The root OIDs are given in the third argument.
# The returned value is a reference to a hash which holds the result,
# where the OIDs are used as keys and guess the values are values from
# the snmptree.
#
# Note: The module has not to care about anything like using CPAN module
# or system commands, since this is handled transparent in this lib
#
sub snmp_walk {
my ($host, $comm, @oid) = @_;
undef my %result;
if (HotSaNIClog::check_debuglevel("SNMP_VERBOSE")) { HotSaNIClog::info("SNMP - enter snmp_walk()"); }
set_version($host, $comm) if !defined($agent_v{$host});
for (@oid) {
my $res = snmp_mod_walk($host, $comm, $_);
next if !defined ($res);
foreach ( keys(%$res) ) {
$result{$_} = $$res{$_};
}
}
if (HotSaNIClog::check_debuglevel("SNMP_VERBOSE")) { HotSaNIClog::info("SNMP - leave snmp_walk()"); }
return \%result;
}
#
# snmp_get($host, $comm, @oid)
#
# Retrieves one value from the given $host. Works similar to snmp_walk
# and return also a hash reference. This way you can query more values
# with get @ once.
#
sub snmp_get {
my ($host, $comm, @oid) = @_;
undef my %result;
if (HotSaNIClog::check_debuglevel("SNMP_VERBOSE")) { HotSaNIClog::info("SNMP - enter snmp_get()"); }
set_version($host, $comm) if !defined($agent_v{$host});
$result{$_} = snmp_mod_get($host, $comm, $_) for (@oid);
if (HotSaNIClog::check_debuglevel("SNMP_VERBOSE")) { HotSaNIClog::info("SNMP - leave snmp_get()"); }
return \%result;
}
#
# snmp_mod_get($host, $community, $oid)
#
# This is the Net::SNMP based implementation of snmp_get, which will
# hand out control to the system command fallback, if module is not
# availible.
#
sub snmp_mod_get {
eval { require Net::SNMP; };
return snmp_sys_get(@_) if($@);
my ($hostname, $community, $oid) = @_;
undef my $response;
my $session = get_session($hostname, $community, $agent_v{$hostname});
return undef if !defined($session);
if(!defined($response = $session->get_request($oid))) {
$session->close;
return undef;
}
$session->close;
if (HotSaNIClog::check_debuglevel("SNMP_VERBOSE")) { HotSaNIClog::info("SNMP - snmp_mod_get() [$$response{$oid}]"); }
return $$response{$oid};
}
#
# snmp_mod_walk($host, $community, $oid)
#
# The Net::SNMP based implementation of snmp_walk, which will hand
# out control to system command based fallback, if module is
# not availible.
#
sub snmp_mod_walk {
eval { require Net::SNMP; };
return snmp_sys_walk(@_) if($@);
my ($hostname, $community, $oid) = @_;
undef my $response;
my $session = get_session($hostname, $community, $agent_v{$hostname});
return undef if(!defined($session));
if(!defined($response = $session->get_table($oid))) {
$session->close;
return undef;
}
$session->close;
if (HotSaNIClog::check_debuglevel("SNMP_VERBOSE")) { HotSaNIClog::info("SNMP - snmp_mod_walk() [$response]"); }
return $response;
}
#
# snmp_sys_walk($host, $community, $oid)
#
# THis is the system command based fallback to snmp_walk, which
# will be used if no CPAN module is availible on the system using
# snmp_walk.
#
sub snmp_sys_walk {
my ($host,$com,$oid)=@_;
undef my %result;
defined($conf{SNMPWALK}) || return undef;
my $command;
if($agent_v{$host} eq '2c') {
$command = "$conf{SNMPBULKWALK} -c $com -v 2c -r 1 -t 2 -On -Oq $host $oid";
} else {
$command = "$conf{SNMPWALK} -c $com -v 1 -r 1 -t 2 -On -Oq $host $oid";
}
open OUTPUT,"$command|" || return undef;
while (<OUTPUT>) {
chomp;
my ($key, $value) = split;
$result{$key} = $value;
}
close OUTPUT;
if (HotSaNIClog::check_debuglevel("SNMP_VERBOSE")) { HotSaNIClog::info("SNMP - snmp_sys_walk() [".\%result."]"); }
return \%result;
}
#
# snmp_sys_get($host, $community, $oid)
#
# Analog to all the others here is the fallback to system commands
# for the get function. Used if, how could it be, no CPAN module
# availible.
#
sub snmp_sys_get {
my ($host,$com,$oid)=@_;
defined($conf{SNMPGET}) || return undef;
open RESULT,"$conf{SNMPGET} -c $com -v $agent_v{$host} -r 1 -t 2 -Oq $host $oid|" || return undef;
my $result=<RESULT>;
close RESULT;
chomp $result;
(undef, $result) = split / /,$result;
if (HotSaNIClog::check_debuglevel("SNMP_VERBOSE")) { HotSaNIClog::info("SNMP - snmp_sys_get() [$result]"); }
return $result;
}
1;