*** check_ifoperstatus.orig 2005-08-19 17:45:13.000000000 -0400 --- check_ifoperstatus 2005-08-23 16:32:12.000000000 -0400 *************** my $community = "public"; *** 64,78 **** my $maxmsgsize = 1472 ; # Net::SNMP default is 1472 my ($seclevel, $authproto, $secname, $authpass, $privpass, $auth, $priv, $context); my $port = 161; - my @snmpoids; my $sysUptime = '1.3.6.1.2.1.1.3.0'; my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; my $snmpIfAdminStatus = '1.3.6.1.2.1.2.2.1.7'; my $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8'; my $snmpIfName = '1.3.6.1.2.1.31.1.1.1.1'; my $snmpIfLastChange = '1.3.6.1.2.1.2.2.1.9'; my $snmpIfAlias = '1.3.6.1.2.1.31.1.1.1.18'; my $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28'; my $hostname; my $ifName; my $session; --- 64,84 ---- my $maxmsgsize = 1472 ; # Net::SNMP default is 1472 my ($seclevel, $authproto, $secname, $authpass, $privpass, $auth, $priv, $context); my $port = 161; my $sysUptime = '1.3.6.1.2.1.1.3.0'; my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; + my $snmpIfDescrOid = $snmpIfDescr; my $snmpIfAdminStatus = '1.3.6.1.2.1.2.2.1.7'; + my $snmpIfAdminStatusOid = $snmpIfAdminStatus; my $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8'; + my $snmpIfOperStatusOid = $snmpIfOperStatus; my $snmpIfName = '1.3.6.1.2.1.31.1.1.1.1'; + my $snmpIfNameOid = $snmpIfName; my $snmpIfLastChange = '1.3.6.1.2.1.2.2.1.9'; + my $snmpIfLastChangeOid = $snmpIfLastChange; my $snmpIfAlias = '1.3.6.1.2.1.31.1.1.1.18'; + my $snmpIfAliasOid = $snmpIfAlias; my $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28'; + my $snmpLocIfDescrOid = $snmpLocIfDescr; my $hostname; my $ifName; my $session; *************** my $lastc; *** 88,93 **** --- 94,101 ---- my $dormantWarn; my $adminWarn; my $name; + my $cacheFileChecked = 0; + my $cacheFileName = '/tmp/interface_cache.db'; ### Validate Arguments *************** alarm($timeout); *** 106,114 **** ## map ifdescr to ifindex - should look at being able to cache this value if (defined $ifdescr) { - # escape "/" in ifdescr - very common in the Cisco world - $ifdescr =~ s/\//\\\//g; - $status=fetch_ifdescr(); # if using on device with large number of interfaces # recommend use of SNMP v2 (get-bulk) if ($status==0) { --- 114,119 ---- *************** if (defined $ifdescr) { *** 122,155 **** ## Main function ! $snmpIfAdminStatus = $snmpIfAdminStatus . "." . $snmpkey; ! $snmpIfOperStatus = $snmpIfOperStatus . "." . $snmpkey; ! $snmpIfDescr = $snmpIfDescr . "." . $snmpkey; ! $snmpIfName = $snmpIfName . "." . $snmpkey ; ! $snmpIfAlias = $snmpIfAlias . "." . $snmpkey ; ! ! push(@snmpoids,$snmpIfAdminStatus); ! push(@snmpoids,$snmpIfOperStatus); ! push(@snmpoids,$snmpIfDescr); ! push(@snmpoids,$snmpIfName) if (defined $ifXTable) ; ! push(@snmpoids,$snmpIfAlias) if (defined $ifXTable) ; ! if (!defined($response = $session->get_request(@snmpoids))) { ! $answer=$session->error; ! $session->close; ! $state = 'WARNING'; ! print ("$state: SNMP error: $answer\n"); ! exit $ERRORS{$state}; } - $answer = sprintf("host '%s', %s(%s) is %s\n", - $hostname, - $response->{$snmpIfDescr}, - $snmpkey, - $ifOperStatus{$response->{$snmpIfOperStatus}} - ); - - ## Check to see if ifName match is requested and it matches - exit if no match ## not the interface we want to monitor if ( defined $name && not ($response->{$snmpIfName} eq $name) ) { --- 127,145 ---- ## Main function ! # moved fetching of information to function to allow it to be recalled if ! # bad snmpkey in cache file ! fetch_data(); ! # If using ifDescr check to make sure database didn't return ! # stale snmpkey ! if (defined $ifdescr) { ! if ($response->{$snmpIfDescr} ne $ifdescr) { ! fetch_ifdescr(); ! fetch_data(); ! } } ## Check to see if ifName match is requested and it matches - exit if no match ## not the interface we want to monitor if ( defined $name && not ($response->{$snmpIfName} eq $name) ) { *************** exit $ERRORS{$state}; *** 225,232 **** ### subroutines sub fetch_ifdescr { ! if (!defined ($response = $session->get_table($snmpIfDescr))) { $answer=$session->error; $session->close; $state = 'CRITICAL'; --- 215,270 ---- ### subroutines + sub fetch_data { + my @snmpoids; + + $snmpIfAdminStatus = $snmpIfAdminStatusOid . "." . $snmpkey; + $snmpIfOperStatus = $snmpIfOperStatusOid . "." . $snmpkey; + $snmpIfDescr = $snmpIfDescrOid . "." . $snmpkey; + $snmpIfName = $snmpIfNameOid . "." . $snmpkey ; + $snmpIfAlias = $snmpIfAliasOid . "." . $snmpkey ; + + push(@snmpoids,$snmpIfAdminStatus); + push(@snmpoids,$snmpIfOperStatus); + push(@snmpoids,$snmpIfDescr); + push(@snmpoids,$snmpIfName) if (defined $ifXTable) ; + push(@snmpoids,$snmpIfAlias) if (defined $ifXTable) ; + + if (!defined($response = $session->get_request(@snmpoids))) { + $answer=$session->error; + $session->close; + $state = 'WARNING'; + print ("$state: SNMP error: $answer\n"); + exit $ERRORS{$state}; + } + + $answer = sprintf("host '%s', %s(%s) is %s\n", + $hostname, + $response->{$snmpIfDescr}, + $snmpkey, + $ifOperStatus{$response->{$snmpIfOperStatus}} + ); + } + sub fetch_ifdescr { ! my %intcache; ! dbmopen %intcache, $cacheFileName, 0600 or exit $ERRORS{'CRITICAL'}; ! ! # check if we already checked cache file ! if (!$cacheFileChecked) { ! # check cache file for interface information, if exists use ! # if not then update cache file for the entire host looking ! # for this interface ! ! $cacheFileChecked = 1; ! if (exists $intcache{$hostname.$ifdescr}) { ! $snmpkey = $intcache{$hostname.$ifdescr}; ! dbmclose %intcache; ! return $snmpkey; ! } ! } ! ! if (!defined ($response = $session->get_table($snmpIfDescrOid))) { $answer=$session->error; $session->close; $state = 'CRITICAL'; *************** sub fetch_ifdescr { *** 235,246 **** exit $ERRORS{$state}; } foreach $key ( keys %{$response}) { if ($response->{$key} =~ /^$ifdescr$/) { ! $key =~ /.*\.(\d+)$/; ! $snmpkey = $1; #print "$ifdescr = $key / $snmpkey \n"; #debug } } unless (defined $snmpkey) { $session->close; --- 273,297 ---- exit $ERRORS{$state}; } + # snmpwalk succesful, empty cache file for this host + # TODO: empty cache file for host + + # escape "/" in ifdescr - very common in the Cisco world + $ifdescr =~ s/\//\\\//g; + foreach $key ( keys %{$response}) { + $key =~ /.*\.(\d+)$/; + my $cursnmpkey = $1; + if ($response->{$key} =~ /^$ifdescr$/) { ! #$key =~ /.*\.(\d+)$/; ! #$snmpkey = $1; ! $snmpkey = $cursnmpkey; #print "$ifdescr = $key / $snmpkey \n"; #debug } + + # for each interface update cache file + $intcache{$hostname.$response->{$key}} = $cursnmpkey; } unless (defined $snmpkey) { $session->close; *************** sub fetch_ifdescr { *** 248,254 **** printf "$state: Could not match $ifdescr on $hostname\n"; exit $ERRORS{$state}; } ! return $snmpkey; } --- 299,306 ---- printf "$state: Could not match $ifdescr on $hostname\n"; exit $ERRORS{$state}; } ! ! dbmclose %intcache; return $snmpkey; }