#!/usr/bin/perl # # # AUTHORS: # Copyright (C) 2003-2008 Opsera Limited. All rights reserved # # This file is part of Opsview # # Opsview is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Opsview is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Opsview; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # use lib qw ( /usr/local/nagios/perl/lib ); use Net::SNMP; use Getopt::Std; $script = "check_uptime"; $script_version = "3.0"; $script_description = "Returns uptime of SNMP agent (usually equal to system uptime). Warning state if less than 1 hour."; $metric = 1; $oid_sysDescr = ".1.3.6.1.2.1.1.1.0"; # Used to check whether SNMP is actually responding $oid_sysUpTime = ".1.3.6.1.2.1.1.3.0"; # $ipaddress = "192.168.10.30"; $version = "2c"; # Default SNMP version to use $timeout = 2; $warning = 730; # warning threshold $critical = 3650; # critical threshold $status = 0; $returnstring = ""; $snmpv3_username = "initial"; # SNMPv3 username $snmpv3_password = ""; # SNMPv3 password $snmpv3_authprotocol = "md5"; # SNMPv3 hash algorithm (md5 / sha) $snmpv3_privpassword = ""; # SNMPv3 hash algorithm (md5 / sha) $snmpv3_privprotocol = "des"; # SNMPv3 encryption protocol (des / aes / aes128) $community = "public"; # Default community string (for SNMP v1 / v2c) # Do we have enough information? if (@ARGV < 1) { print "Too few arguments\n"; usage(); } getopts("h:H:C:U:P:v:a:e:w:c:x:"); if ($opt_h){ usage(); exit(0); } if ($opt_H){ $hostname = $opt_H; } else { print "No hostname specified\n"; usage(); } if ($opt_C){ $community = $opt_C; } if ($opt_U){ $snmpv3_username = $opt_U; } if ($opt_P){ $snmpv3_password = $opt_P; } if ($opt_a){ $snmpv3_authprotocol = $opt_a; } if ($opt_e){ $snmpv3_privprotocol = $opt_e; } if ($opt_v){ $version = $opt_v; } if ($opt_w){ $warning = $opt_w; } if ($opt_c){ $critical = $opt_c; } if ($opt_x){ $snmpv3_privpassword = $opt_x; } # Checks whether requested SNMP version is supported if ($version !~/^[13]|[2c]$/){ print "SNMP v$version not supported by this plugin\n"; exit(1); } # Cache file name $statusfile = "/usr/local/nagios/var/uptime_$hostname.db"; # Create the SNMP session if ($version == "3"){ ($s, $e) = Net::SNMP->session( -username => $snmpv3_username, -authpassword => $snmpv3_password, -authprotocol => $snmpv3_authprotocol, -privpassword => $snmpv3_privpassword, -privprotocol => $snmpv3_privprotocol, -hostname => $hostname, -version => $version, -timeout => $timeout, ); if ($s){ } else { print "Agent not responding, tried SNMP v3 ($e)\n"; exit(1); } } my $triedv2c = 0; # Track whether we've attempted SNMPv2c connection if ($version == "2c"){ ($s, $e) = Net::SNMP->session( -community => $community, -hostname => $hostname, -version => $version, -timeout => $timeout, ); if (!defined($s->get_request($oid_sysDescr))) { # try SNMP v1 if v2c doesn't work $triedv2c = 1; $version = 1; } } if ($version == "1"){ ($s, $e) = Net::SNMP->session( -community => $community, -hostname => $hostname, -version => $version, -timeout => $timeout, ); if (!defined($s->get_request($oid_sysDescr))) { if ($triedv2c == 1){ print "Agent not responding, tried SNMP v1 and v2c\n"; } else { print "Agent not responding, tried SNMP v1\n"; } exit(1); } } main(); # Close the session $s->close(); if ($returnstring eq ""){ $status = 3; } if ($status == 0){ print "Status is OK - $returnstring\n"; } elsif ($status == 1){ print "Status is a WARNING level - $returnstring\n"; } elsif ($status == 2){ print "Status is CRITICAL - $returnstring\n"; } else{ print "Plugin error! SNMP status unknown\n"; } exit $status; sub main { if (!defined($s->get_request($oid_sysUpTime))) { if (!defined($s->get_request($oid_sysDescr))) { $returnstring = "SNMP agent not responding"; $status = 1; return 1; } else { $returnstring = "SNMP OID does not exist"; $status = 1; return 1; } } foreach ($s->var_bind_names()) { $uptime = $s->var_bind_list()->{$_}; } # Call again to get uptime in timeticks $s->translate([ '-timeticks' => 0 ]); if (!defined($s->get_request($oid_sysUpTime))) { if (!defined($s->get_request($oid_sysDescr))) { $returnstring = "SNMP agent not responding"; $status = 1; return 1; } else { $returnstring = "SNMP OID does not exist"; $status = 1; return 1; } } foreach ($s->var_bind_names()) { $timeticks = $s->var_bind_list()->{$_}; } $days = 0; ($days,$null) = split(/days/, $uptime); $days =~ s/ //g; $temp = "Uptime: $uptime|days=$days"; append($temp); if (lc($uptime) =~ /seconds/){ $status = 1; } if (lc($uptime) =~ /minute/){ $status = 1; } # Check previous uptime value if status is warning $just_rolled_over = 0; if($status != 0) { # Get previous uptime value readstatus(); # If just_rolled_over flag set AND last uptime is less than current uptime if($just_rolled_over == 1 && $prev_uptime < $timeticks) { $status = 0; } else { # If last uptime was close to the 32-bit limit (within 8 minutes) # 4294967296 - 48000 = 4294919296 if($prev_uptime >= 4294919296) { $status = 0; $just_rolled_over = 1; } else { $just_rolled_over = 0; } } } # cache uptime writestatus($timeticks, $just_rolled_over); } sub usage { print << "USAGE"; $script v$script_version $script_description Usage: $script -H -c [...] Options: -H Hostname or IP address -C Community (default is public) -U SNMPv3 auth username -P SNMPv3 auth password -x SNMPv3 priv passphrase -a SNMPv3 hashing algorithm (default is MD5) -e SNMPv3 encryption protocol (default is DES) -v SNMP version (1, 2c or 3 supported) -------------------------------------------------------------------- Copyright (C) 2003-2008 Opsera Limited. All rights reserved This program is free software; you can redistribute it or modify it under the terms of the GNU General Public License -------------------------------------------------------------------- USAGE exit 1; } sub append { my $appendstring = @_[0]; $returnstring = "$returnstring$appendstring"; } sub errorhandler { my $returnstring = @_[0]; print "$returnstring\n"; } #################################################################### # Returns the SNMP community string for a given hostname / IP # #################################################################### sub return_snmpcommunity { my $requiredhostname = @_[0]; my $returncommunity = "public"; my $tempcommunity = ""; my $temphostname = ""; my $row = 0; my $nullval = 0; if (-e "$configfilepath/livehosttable.db"){ open INFILE, "<$configfilepath/livehosttable.db" or die "Can't open file $configfilepath/livehosttable.db $1"; foreach $line () { ($temphostname,$nullval,$nullval,$nullval,$nullval,$nullval,$nullval,$tempcommunity) = split(/:/, $line); if ($temphostname eq $requiredhostname) { if ($tempcommunity eq ""){ $returncommunity = $defaultcommunity; } else { $returncommunity = $tempcommunity; # print "lookup for $temphostname successful: $tempcommunity\n"; } last; } } } else { } close INFILE; return($returncommunity); } sub readstatus { $prev_uptime = 0; $just_rolled_over = 0; if(-e "$statusfile") { open STATUSFILE, "<$statusfile" or die "Can't open $statusfile: $!"; $line = ; ($prev_uptime, $just_rolled_over) = split(/,/, $line); } } sub writestatus { my($cur_uptime) = shift; my($rolled_over_flag) = shift; open STATUSFILE, ">$statusfile" or die "Can't open $statusfile: $!"; print STATUSFILE "$cur_uptime,$rolled_over_flag\n"; close STATUSFILE; }