# This is a simple wrapper for SNMP_utils. People who want to # use other SNMP libraries can hook the calls here by replacing this # copy of snmpUtils.pm with their own, which redirects the calls # to their own library. package snmpUtils; use Common::Log; use BER; use SNMP_Session; use SNMP_util; use Sys::Hostname; # snmp_utils 0.55 has a reference to main::DEBUG, so we instantiate # it here, if necessary if (! defined($main::DEBUG)) { $main::DEBUG = 0; } # this keeps BER from formatting timeticks, so that if someone # want to put them into an RRD, it would work. $BER::pretty_print_timeticks = 0; my($err) = ''; # Max number of times a device can fail to respond before we skip further # requests. Adjust as needed. (This should probably be made a target # attribute in the config tree so it can be set on a per device basis.) my $MAXTRIES = 2; my %skipcnt; sub init { %skipcnt = (); } # this funky wrapper is because SNMP_Session throws exceptions with # warn(), which we need to catch, instead of letting them run # roughshod over Cricket's output. sub _do { my($subref, @args) = @_; my(@res); return (-1) if (defined $skipcnt{$args[0]} && $skipcnt{$args[0]} >= $MAXTRIES); $err = ''; eval { local($SIG{'__WARN__'}) = sub { $err = $_[0]; die($err); }; @res = &{$subref}(@args); }; # do a little post processing on the overly wordy errors # that SNMP_Session gives us... if (defined($err) && $err ne '') { my(@err) = split(/\n\s*/, $err); if ($err[1] eq "no response received") { $skipcnt{$args[0]}++; my $host = (split(/: /,$err[2]))[1]; $host =~ s/\)$//; $err = "No response from $host"; $err .= " - Skipping." if ($skipcnt{$args[0]} >= $MAXTRIES); } elsif ($#err+1 > 2) { my($code) = (split(/: /, $err[2]))[1]; $code = ": undefined error code" if (!$code); $err = "$err[1] $code."; if ($code eq "noSuchName") { my($oid) = $err[3]; $oid =~ s/.*\((.*)\).*/$1/; $err .= " $oid"; } } else { $err =~ s/\n//g; } Warn($err); } return @res; } sub get { _do(\&snmpget, @_); } sub getnext { _do(\&snmpgetnext, @_); } sub walk { _do(\&snmpwalk, @_); } sub trap2 { my($to, $spec, @data) = @_; # this is the OID for enterprises.webtv.wtvOps.wtvOpsTraps my($ent) = ".1.3.6.1.4.1.2595.1.1"; _do(\&snmptrap, $to, $ent, hostname(), 6, $spec, @data); } sub trap { my($to, $spec, @data) = @_; # this is the OID for enterprises.webtv.wtvOps.wtvOpsTraps my($ent) = ".1.3.6.1.4.1.2595.1.1"; # this makes a oid->value map for the trap. Note that # we just fake up simple one-level OID's... it suits our needs. my($item, @vars); my($ct) = 1; foreach $item (@data) { my($type) = "string"; $type = "integer" if ($item =~ /^(\d+)$/); push @vars, $ct, $type, $item; $ct++; } _do(\&snmptrap, $to, $ent, hostname(), 6, $spec, @vars); } 1; # Local Variables: # mode: perl # indent-tabs-mode: nil # tab-width: 4 # perl-indent-level: 4 # End: