From 44a321cb8a42d6c0ea2d96a1086a17f2134c89cc Mon Sep 17 00:00:00 2001 From: Ethan Galstad Date: Thu, 28 Feb 2002 06:42:51 +0000 Subject: Initial revision git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@2 f882894a-f735-0410-b71e-b25c423dba1c --- contrib/aix/check_crit_dsk | 66 ++ contrib/aix/check_dsk | 62 ++ contrib/aix/check_failed | 48 ++ contrib/aix/check_io | 69 ++ contrib/aix/check_kerberos | 49 ++ contrib/aix/check_ping | 117 +++ contrib/aix/check_queue | 67 ++ contrib/aix/pg_stat | 45 ++ contrib/check_apache.pl | 283 ++++++++ contrib/check_apc_ups.pl | 314 ++++++++ contrib/check_bgpstate.pl | 215 ++++++ contrib/check_dhcp.c | 992 ++++++++++++++++++++++++++ contrib/check_dlswcircuit.pl | 221 ++++++ contrib/check_dns_random.pl | 75 ++ contrib/check_email_loop.pl | 268 +++++++ contrib/check_fping_in.c | 430 +++++++++++ contrib/check_ftpget.pl | 48 ++ contrib/check_ifoperstatus.pl | 145 ++++ contrib/check_ifstatus.pl | 178 +++++ contrib/check_ipxping.c | 200 ++++++ contrib/check_joy.sh | 69 ++ contrib/check_maxchannels.pl | 231 ++++++ contrib/check_maxwanstate.pl | 201 ++++++ contrib/check_mem.pl | 146 ++++ contrib/check_memory.tgz | Bin 0 -> 5813 bytes contrib/check_mysql.c | 75 ++ contrib/check_mysql.pl | 73 ++ contrib/check_nagios.pl | 48 ++ contrib/check_netapp.pl | 178 +++++ contrib/check_nmap.py | 440 ++++++++++++ contrib/check_nwstat.pl | 188 +++++ contrib/check_ora_table_space.pl | 82 +++ contrib/check_pop3.pl | 144 ++++ contrib/check_qmailq.pl | 121 ++++ contrib/check_rrd_data.pl | 129 ++++ contrib/check_sap.sh | 70 ++ contrib/check_sockets.pl | 145 ++++ contrib/check_timeout.c | 55 ++ contrib/check_uptime.c | 99 +++ contrib/checkciscotemp.pl | 163 +++++ contrib/maser-oracle.pl | 13 + contrib/mrtgext.pl | 291 ++++++++ contrib/readme.txt | 147 ++++ contrib/restrict.pl | 26 + contrib/tarballs/berger-ping.tar.gz | Bin 0 -> 2411 bytes contrib/tarballs/bowen-langley_plugins.tar.gz | Bin 0 -> 28728 bytes contrib/tarballs/check_bgp-1.0.tar.gz | Bin 0 -> 1444 bytes contrib/tarballs/check_breeze.tar.gz | Bin 0 -> 358 bytes contrib/tarballs/check_flexlm.tar.gz | Bin 0 -> 1169 bytes contrib/tarballs/check_hltherm.tar.gz | Bin 0 -> 2087 bytes contrib/tarballs/check_hprsc.tar.gz | Bin 0 -> 1942 bytes contrib/tarballs/check_radius.tar.gz | Bin 0 -> 25173 bytes contrib/tarballs/check_wave.tar.gz | Bin 0 -> 591 bytes contrib/tarballs/hopcroft-plugins.tar.gz | Bin 0 -> 3657 bytes contrib/tarballs/radius.tar.gz | Bin 0 -> 1913 bytes contrib/urlize.pl | 16 + contrib/utils.py | 310 ++++++++ 57 files changed, 7352 insertions(+) create mode 100644 contrib/aix/check_crit_dsk create mode 100644 contrib/aix/check_dsk create mode 100644 contrib/aix/check_failed create mode 100644 contrib/aix/check_io create mode 100644 contrib/aix/check_kerberos create mode 100644 contrib/aix/check_ping create mode 100644 contrib/aix/check_queue create mode 100644 contrib/aix/pg_stat create mode 100644 contrib/check_apache.pl create mode 100644 contrib/check_apc_ups.pl create mode 100644 contrib/check_bgpstate.pl create mode 100644 contrib/check_dhcp.c create mode 100755 contrib/check_dlswcircuit.pl create mode 100644 contrib/check_dns_random.pl create mode 100644 contrib/check_email_loop.pl create mode 100644 contrib/check_fping_in.c create mode 100755 contrib/check_ftpget.pl create mode 100644 contrib/check_ifoperstatus.pl create mode 100644 contrib/check_ifstatus.pl create mode 100644 contrib/check_ipxping.c create mode 100755 contrib/check_joy.sh create mode 100644 contrib/check_maxchannels.pl create mode 100644 contrib/check_maxwanstate.pl create mode 100644 contrib/check_mem.pl create mode 100644 contrib/check_memory.tgz create mode 100644 contrib/check_mysql.c create mode 100644 contrib/check_mysql.pl create mode 100644 contrib/check_nagios.pl create mode 100755 contrib/check_netapp.pl create mode 100644 contrib/check_nmap.py create mode 100644 contrib/check_nwstat.pl create mode 100644 contrib/check_ora_table_space.pl create mode 100644 contrib/check_pop3.pl create mode 100755 contrib/check_qmailq.pl create mode 100644 contrib/check_rrd_data.pl create mode 100755 contrib/check_sap.sh create mode 100644 contrib/check_sockets.pl create mode 100644 contrib/check_timeout.c create mode 100644 contrib/check_uptime.c create mode 100644 contrib/checkciscotemp.pl create mode 100644 contrib/maser-oracle.pl create mode 100644 contrib/mrtgext.pl create mode 100644 contrib/readme.txt create mode 100755 contrib/restrict.pl create mode 100644 contrib/tarballs/berger-ping.tar.gz create mode 100644 contrib/tarballs/bowen-langley_plugins.tar.gz create mode 100644 contrib/tarballs/check_bgp-1.0.tar.gz create mode 100644 contrib/tarballs/check_breeze.tar.gz create mode 100644 contrib/tarballs/check_flexlm.tar.gz create mode 100644 contrib/tarballs/check_hltherm.tar.gz create mode 100644 contrib/tarballs/check_hprsc.tar.gz create mode 100644 contrib/tarballs/check_radius.tar.gz create mode 100644 contrib/tarballs/check_wave.tar.gz create mode 100644 contrib/tarballs/hopcroft-plugins.tar.gz create mode 100644 contrib/tarballs/radius.tar.gz create mode 100644 contrib/urlize.pl create mode 100644 contrib/utils.py (limited to 'contrib') diff --git a/contrib/aix/check_crit_dsk b/contrib/aix/check_crit_dsk new file mode 100644 index 00000000..566e07c1 --- /dev/null +++ b/contrib/aix/check_crit_dsk @@ -0,0 +1,66 @@ +#!/bin/sh + +#========================================================================= +# Critical Disk Checker utility +# +# This is the same as the disk checker utility but we use it as +# a seperate service in Nagios to report on partitions that +# have reached 100% capacity. +# +# We have excluded /dev/cd0 because the cdrom drive will always +# report 100% capacity if a CD is in the drive. +# +# Authors: TheRocker +# SpEnTBoY +# +# Email: therocker@pawprints.2y.net +# lonny@abyss.za.org +# +#======================================================================= + +NUMBER=`rsh $1 -l root df -kP | grep -vE ":|/dev/cd0" | grep -E "100%" | tr -s ' '| cut -d' ' -f5 | cut -c1-3 | line` +TMPFILE=/tmp/tmpcrit.hndl +TMPTOO=/tmp/twocrit.hndl + +if [ "$NUMBER" -eq 100 ] +then + + `rsh $1 -l root df -kP |grep -vE ":|/dev/cd0" | grep -E "100%" | tr -s ' '| cut -d' ' -f6,5 >> $TMPFILE` + + LINES=`wc -l /tmp/tmpcrit.hndl | cut -c8` + LINESCTL=`wc -l /tmp/tmpcrit.hndl | cut -c8 ` + echo "Filesystems over 99% --> \c" + +#=============================================================== +# Just a little bit to check for multiple occurances of the +# condition. +#=============================================================== + + while [ $LINESCTL != 0 ] + do + + cat $TMPFILE | tail -$LINESCTL > $TMPTOO + cat $TMPTOO > $TMPFILE + LINESCTL=$(( $LINESCTL -1 )) + LINES=$(( $LINES -1 )) + DATA=`head -1 /tmp/tmpcrit.hndl` + echo "( $DATA ) \c" + + + done + echo "\n" + +#=============================================================== +# File clean up. Always pick up after yourself. Disk space +# doesn't grow on trees you know. +#=============================================================== + + rm -f $TMPFILE + rm -f $TMPTOO + exit 2 + +else + + echo "No Filesystems over 99%... OK" + exit 0 +fi diff --git a/contrib/aix/check_dsk b/contrib/aix/check_dsk new file mode 100644 index 00000000..c8ddb3f8 --- /dev/null +++ b/contrib/aix/check_dsk @@ -0,0 +1,62 @@ +#! /bin/sh + +#====================================================================== +# Disk Checker utility +# +# Simple little script that checks the status of all partitions +# on a node's hard disks. It will produce a warning alert and list +# the offending filesystems in nagios. +# +# Authors: SpEnTBoY +# TheRocker +# +# Email: lonny@abyss.za.org +# therocker@pawprints.2y.net +#===================================================================== + +NUMBER=`rsh $1 -l root df -kP | grep -v ":" | grep -E "9[0-9]%" | tr -s ' '| cut -d' ' -f5 | cut -c1-2 | line` +TMPFILE=/tmp/tmp.hndl +TMPTOO=/tmp/two.hndl + +if [ "$NUMBER" -gt 90 ] +then + + `rsh $1 -l root df -kP |grep -v ":" | grep -E "9[0-9]%" | tr -s ' '| cut -d' ' -f6,5 >> $TMPFILE` + + LINES=`wc -l /tmp/tmp.hndl | cut -c8` + LINESCTL=`wc -l /tmp/tmp.hndl | cut -c8 ` + echo "Filesystems over 90% --> \c" + +#====================================================================== +# You'll see this one in a few our shell scripts. Just chcecking for +# multiple occurances of the warnign condition. We gotta list 'em all +#====================================================================== + + while [ $LINESCTL != 0 ] + do + + cat $TMPFILE | tail -$LINESCTL > $TMPTOO + cat $TMPTOO > $TMPFILE + LINESCTL=$(( $LINESCTL -1 )) + LINES=$(( $LINES -1 )) + DATA=`head -1 /tmp/tmp.hndl` + echo "( $DATA ) \c" + + + done + echo "\n" + +#=============================================================== +# Clean up all those nasty tmp files that suck up valuable +# disk realestate. +#=============================================================== + + rm -f $TMPFILE + rm -f $TMPTOO + exit 1 + +else + + echo "No Filesystems over 90%... OK" + exit 0 +fi diff --git a/contrib/aix/check_failed b/contrib/aix/check_failed new file mode 100644 index 00000000..50cdf7e1 --- /dev/null +++ b/contrib/aix/check_failed @@ -0,0 +1,48 @@ +#!/usr/bin/perl +#====================== +# Created May 25, 2000 +#====================== + +# This scripts is for checking for failed root login attempts on +# any machine running AIX which has a failedlogin file in /etc/security +# The purpose is to thwart (good word) any unauthorised people from +# even trying to log in as root. This plugin has been developed for Nagios +# running on AIX. +# Lonny Selinger SpEnTBoY lonny@abyss.za.org +# May + + +my $server = $ARGV[0]; + +if (!$ARGV[0]) { + print "You must specify a server to check\n"; + print "usage: ./check_failed \n"; + exit (-1); + } else { + open (DATE, "/bin/date '+%b %d' |"); + while () { + $dline = $_; + @dresults = $dline; + chop $dresults[0]; + } + open (SULOG, "rsh $server -l root who /etc/security/failedlogin | grep root |"); + while () { + $line = $_; + @results = split (/\s+/,$line); + if ($line =~ /^root/) { + if (join(' ', @results[2,3]) eq $dresults[0]) { + print "FAILED root login on $dresults[0], node: $ARGV[0] from $results[5]\n"; + exit(2); + } + } + } +} +if (join(' ', @results[2,3]) ne $dresults[0]) { + print "No Failed Root Logins on This Node\n"; + exit(0); +} +exit(0); +close(SULOG); +close(DATE); + + diff --git a/contrib/aix/check_io b/contrib/aix/check_io new file mode 100644 index 00000000..58b25f6d --- /dev/null +++ b/contrib/aix/check_io @@ -0,0 +1,69 @@ +#! /bin/sh + +#================================================================= +# +# I/O Checker (KBPS) +# This Script uses iostat to monitor disk io +# Useful for notifications of disk thrashing. +# +# Authors: TheRocker +# SpEnTBoY +# +# Email: therocker@pawprints.2y.net +# lonny@abyss.za.org +# +#================================================================ + +NUMBER1=`rsh $1 -l root iostat -d | grep -e "hdisk" | tr -s ' ' | cut -d' ' -f2 | sort -2 -r | cut -c1 | line` +NUMBER2=`rsh $1 -l root iostat -d | grep -e "hdisk" | tr -s ' ' | cut -d' ' -f2 | sort -2 -r | cut -c2 | line` +TMPFILE=/tmp/iotest.hndl +TMPTOO=/tmp/iotwo.hndl + +#=========================================================== +# +# We do an evaluation on $NUMBER1 and $NUMBER2 to see if +# disk io is exceeding 40%. +# +#=========================================================== + +if [ "$NUMBER1" -gt 4 ] && [ "$NUMBER2" -gt 0 ] +then + + `rsh $1 -l root iostat -d | grep -v cd0 | tr -s ' '| cut -d' ' -f1,2 | grep -e "4[0-9]." >> $TMPFILE` + +#==================================================================== +# +# Of course, there may be more than one hard disk on the node +# so we use this bit of code to report on more than one instance +# of excessive disk IO. +# +#==================================================================== + + LINES=`wc -l /tmp/iotest.hndl | cut -c8` + LINESCTL=`wc -l /tmp/iotest.hndl | cut -c8 ` + echo "WARNING!!! Disk I/O Exceeding 40% on --> \c" + + while [ $LINESCTL != 0 ] + do + + cat $TMPFILE | tail -$LINESCTL > $TMPTOO + cat $TMPTOO > $TMPFILE + LINESCTL=$(( $LINESCTL -1 )) + LINES=$(( $LINES -1 )) + DATA=`head -1 /tmp/iotest.hndl` + echo "( $DATA ) " + + + done + echo "\n" + + rm -f $TMPFILE + rm -f $TMPTOO + exit 1 + +else + + print "No Disk I/O Exceeding 40%...OK" + exit 0 + +fi diff --git a/contrib/aix/check_kerberos b/contrib/aix/check_kerberos new file mode 100644 index 00000000..443ab109 --- /dev/null +++ b/contrib/aix/check_kerberos @@ -0,0 +1,49 @@ +#! /bin/sh + +#========================================================================= +# Kerberos Ticket Checker +# +# This script is handy if you allow kerberos tickets to expire +# on your nodes. The script will simply warn you when a node has +# kerberos tickets expiring on the current date. This will allow to +# re-initialize the tickets if you wish to do so. +# +# Nothing fancy here, all Nagios will show is the number of tickets +# that are going to (or already have) expired. +# +# An item of note: +# +# We made no provisions for the weekend. If tickets expire on the +# weekend and nobody is around, you won't see a warning on the +# Nagios console because we look for expired on the current day +# only. It's a good idea to have this warning emailed to the +# appropriate admin and if there is something critical that relies +# on Kerberos, you might want to send a page. +# +# Authors: TheRocker +# SpEnTBoY +# +# Email: therocker@pawprints.2y.net +# lonny@abyss.za.org +#========================================================================= + +TMPFILE=/tmp/kerbtmp.hndl +DATE=`date +%b' '%d` + +rsh $1 -l root /usr/lpp/ssp/kerberos/bin/klist | tr -s ' ' | cut -d' ' -f4,5,6 | grep -e "$DATE" > $TMPFILE + + +if [ -s $TMPFILE ] +then + + LINES=`wc -l /tmp/kerbtmp.hndl | cut -c7-8` + echo "Kerberos Tickets set to expire --> \c" + echo "$LINES \c" + echo "\n" + + rm -f $TMPFILE + exit 1 + +fi + echo "Kerberos Tickets are valid" + exit 0 diff --git a/contrib/aix/check_ping b/contrib/aix/check_ping new file mode 100644 index 00000000..aaa8c84e --- /dev/null +++ b/contrib/aix/check_ping @@ -0,0 +1,117 @@ +#!/usr/bin/perl -w + +#================================================================ +# +# This perl script will accept an argument and simply pass it +# to ping. It works by sending 2 ping to the specified host +# and evaluating on the average delta time of those 2 pings. +# +# Author: SpEnTBoY +# Email: lonny@abyss.za.org +# April 5,2000 +# +#================================================================ + +#============================ +# State predefined stuff and +# requirements +#============================ + +require 5.004; +use POSIX; +use strict; + +sub usage; + +my $ipaddr = $ARGV[0]; + +my $TIMEOUT = 15; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + +my $remote = shift || &usage(%ERRORS); +my $warning = shift || 750; +my $critical = shift || 1000; + +my $state = "OK"; +my $answer = undef; +my $offset = undef; +my $line = undef; + +#============================================================ +# If theres no response we can exit the bloody thing cleanly +# last thing I want to do is hang an AIX system ;-) +#============================================================ + +$SIG{'ALRM'} = sub { + print ("ERROR: No response from PING! (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + +#================================================ +# Pass stddn from $ARGV to the command and parse +# the info we need (namely the value for "max" +#================================================ + + + +open(PING,"/usr/sbin/ping -c 2 '$ipaddr' >&1|"); +while () { + $line = $_; + if (/round-trip min\/avg\/max = (.+)\/(.+)\/(.+) ms/) { + $offset = $3; + last; + } +} + +#================================================== +# Do some error checking on the output of the file +# and implement values for and +# deffinitions if they were specified by the user +# or sub in the predefined ones +#================================================== + +if (defined $offset) { + if (abs($offset) > $warning) { + if (abs($offset) > $critical) { + $state = "CRITICAL"; + $answer = ": Ping Time $offset MS greater than +/- $critical MS\n"; + } else { + $state = "WARNING"; + $answer = ": Ping Time $offset MS greater than +/- $warning MS\n"; + } + } else { + $state = "OK"; + $answer = ": Ping Time $offset MS\n"; + } +} else { + $state = "UNKNOWN"; + $answer = ": $line\n"; +} +print ("$state$answer"); +exit $ERRORS{$state}; + +sub usage { + print "\n"; + print "#=========================================\n"; + print "Check_Ping 0.02 script by Lonny Selinger\n"; + print "Made with AIX in mind ;-)\n"; + print "#=========================================\n"; + print "\n"; + print "#================================================\n"; + print " I'm going to need a few more arguments from you\n"; + print "#================================================\n"; + print "\n"; + print "#================================================\n"; + print "Usage: check_ping [ []\n"; + print "#================================================\n"; + print "\n"; + print " = Ping in MS at which a warning message will be generated.\n Defaults to 750.\n"; + print " = Ping in MS at which a critical message will be generated.\n Defaults to 1000.\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + diff --git a/contrib/aix/check_queue b/contrib/aix/check_queue new file mode 100644 index 00000000..9f709c54 --- /dev/null +++ b/contrib/aix/check_queue @@ -0,0 +1,67 @@ +#! /bin/sh + +#=============================================================== +# Print Queue Checker +# +# The print queue checker simply looks for an occurance of a +# DOWN queue. A note of warning, if you use remote queues in +# AIX to redirect print jobs from the AIX queue to an NT print +# server that print through DLC rather than IP, it will be very +# s - l - o - w. But it will work. +# +# Author: TheRocker +# Email: therocker@pawprints.2y.net +#=============================================================== + +TMPFILE=/tmp/qtmp.hndl +TMPTOO=/tmp/qtwo.hndl + +#======================================================================= +# +# This script will also work on AIX 4.2.1 BUT you have to change +# the following line. AIX 4.2.1 does not support the -W option +# with lpstat. For AIX 4.2.1 just remove the -W option and it should +# work just fine. +# +#======================================================================= + +`rsh $1 -l root lpstat -W | grep -e "DOWN" | tr -s ' ' | cut -d' ' -f1,3 > /tmp/qtmp.hndl 2> /tmp/q_err` + +if [ -s $TMPFILE ] +then + +#======================================================= +# +# If you've seen the other AIX scripts I wrote you may +# notice that I use this bit of code a lot. Well it +# works and appears to be all purpose. +# +#======================================================= + + LINES=`wc -l /tmp/qtmp.hndl | cut -c8` + LINESCTL=`wc -l /tmp/qtmp.hndl | cut -c8` + + echo "Print Queue DOWN --> \c" + + while [ $LINESCTL != 0 ] + do + + cat $TMPFILE | tail -$LINESCTL > $TMPTOO + cat $TMPTOO > $TMPFILE + LINESCTL=$(( $LINESCTL -1 )) + LINES=$(( $LINES -1 )) + DATA=`head -1 /tmp/qtmp.hndl` + echo "( $DATA ) \c" + + + done + + echo "\n" + + rm -f $TMPFILE + rm -f $TMPTOO + exit 2 + +fi + echo "Print Queues Running... OK" + exit 0 diff --git a/contrib/aix/pg_stat b/contrib/aix/pg_stat new file mode 100644 index 00000000..e0603ec4 --- /dev/null +++ b/contrib/aix/pg_stat @@ -0,0 +1,45 @@ +#!/bin/ksh + +#============================================================================== +# Script was originally created to collect stats and dump then to a log file +# every five minutes. But we like this better (the log file thing is still +# good if you want to track availability). +# +# Authors: SpEnTBoY +# TheRocker +# +# Email: lonny@abyss.za.org +# therocker@pawprints.2y.net +#============================================================================== + +#========================================================================================= +# +# The best way to do this is to use Kerberos but we use rsh here because our monitoring +# workstation doesn't have Kerberos installed. In order for this to work, the remote +# host ($1) must have a .rhosts file that contains a line like: +# +# monitorhost nagiosuser +# +#========================================================================================= + +PAGING2=`rsh $1 -l root lsps -a -s | grep -v Paging | tr -s ' '| cut -d' ' -f3 | cut -d'%' -f1` + + +if [ "$PAGING2" -gt "35" ] && [ "$PAGING2" -lt "50" ] +then + echo "Paging Space is over 35% ("$PAGING2")%" +exit 1 +fi + +if [ "$PAGING2" -gt "49" ] +then + echo "WARNING! Paging Space is over 50% ("$PAGING2")%" +exit 2 +fi + +if [ "$PAGING2" -lt "34" ] +then + echo "Paging Space is less than 34% ("$PAGING2")%" +exit 0 +fi + diff --git a/contrib/check_apache.pl b/contrib/check_apache.pl new file mode 100644 index 00000000..b9e69a0c --- /dev/null +++ b/contrib/check_apache.pl @@ -0,0 +1,283 @@ +#!/usr/bin/perl +# +# (c)2001 Sebastian Hetze, Linux Information Systems AG +# send bug reports to +# +# This program 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. +# +# This program 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 this program (or with Nagios); if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA +# +# +# Check apache status information provided by mod_status to find +# out about the load (number of servers working) and the +# performance (average response time for recent requests). +# +# Usage: +# check_apache -H [-lhV] [-w ] [-c ] [-u ] +# +# check_apache (if you cannot avoid it) +# + +use LWP::UserAgent; +use URI::URL; +use Getopt::Long; +Getopt::Long::Configure('bundling'); + +$version=0.01; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + + +# +# some default values +# +$perf_w=500; +$perf_c=1000; +$load_w=20; +$load_c=30; +$TIMEOUT=15; + +# +# get command line options the regular way +# +GetOptions + ("V" => \$opt_V, "version" => \$opt_V, + "h" => \$opt_h, "help" => \$opt_h, + "l" => \$opt_l, "load" => \$opt_l, + "v" => \$verbose, "verbose" => \$verbose, + "w=s" => \$opt_w, "warning=s" => \$opt_w, + "c=s" => \$opt_c, "critical=s" => \$opt_c, + "H=s" => \$opt_H, "hostname=s" => \$opt_H, + "u=s" => \$opt_u, "url=s" => \$opt_u); + +# +# handle the verbose stuff first +# +if ($opt_V) { + print "\n"; + print "check_apache nagios plugin version $version\n"; + print "\n"; + print "The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n"; + print "copies of the plugins under the terms of the GNU General Public License.\n"; + print "For more information about these matters, see the file named COPYING.\n"; + print "\n"; + print "Copyright (c) 2001 Sebastian Hetze Linux Information Systems AG\n"; + print "\n"; + print "\n"; + exit $ERRORS{'UNKNOWN'}; +} + +if ($opt_h) { + print_help(); + exit $ERRORS{'UNKNOWN'}; +} + +# +# now get options the weired way and set the defaults +# if nothing else is provided +# +$opt_H = shift unless ($opt_H); +print_usage() unless ($opt_H); + +if($opt_l) { + $autostring="?auto"; + ($opt_w) || ($opt_w = shift) || ($opt_w = $load_w); + $warn = $1 if ($opt_w =~ /([0-9]+)/); + ($opt_c) || ($opt_c = shift) || ($opt_c = $load_c); + $alert = $1 if ($opt_c =~ /([0-9]+)/); +} else { + $autostring=""; + ($opt_w) || ($opt_w = shift) || ($opt_w = $perf_w); + $warn = $1 if ($opt_w =~ /([0-9]+)/); + ($opt_c) || ($opt_c = shift) || ($opt_c = $perf_c); + $alert = $1 if ($opt_c =~ /([0-9]+)/); +} + +($opt_u) || ($opt_u = shift) || ($opt_u = "/server-status"); + + +# +# dont let us wait forever... +# +$SIG{'ALRM'} = sub { + print ("ERROR: No response from HTTP server (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +# +# now we set things up for the real work +# and fire up the request +# +$ua = new LWP::UserAgent; +$ua->agent("Nagios/0.1 " . $ua->agent); + + +$urlstring = "http://" . $opt_H . $opt_u . $autostring; +$url = url($urlstring); + +my $req = new HTTP::Request 'GET', $url; +my $res = $ua->request($req); + +# +# hopefully we´ve got something usefull +# +if ($res->is_success) { + if($opt_l) { + foreach $_ (split /^/m, $res->content) { + next if /^\s*$/; +# +# this is the load checking section +# we parse the whole content, just in case someone +# wants to use this some day in the future +# + if (/^Total Accesses:\s+([0-9.]+)/) { $accesses = $1; next; } + if (/^Total kBytes:\s+([0-9.]+)/) { $kbytes = $1; next; } + if (/^CPULoad:\s+([0-9.]+)\s+/) { $load = $1; next; } + if (/^Uptime:\s+([0-9.]+)\s+/) { $uptime = $1; next; } + if (/^ReqPerSec:\s+([0-9.]+)\s+/) { $rps = $1; next; } + if (/^BytesPerSec:\s+([0-9.]+)\s+/) { $bps = $1; next; } + if (/^BytesPerReq:\s+([0-9.]+)\s+/) { $bpr = $1; next; } + if (/^BusyServers:\s+([0-9.]+)\s+/) { $busy = $1; next; } + if (/^IdleServers:\s+([0-9.]+)\s+/) { $idle = $1; next; } + if (/^Scoreboard:\s+([SRWKDLG_.]+)\s+/) { $score = $1; next; } + print "Unknown Status\n"; + exit $ERRORS{"UNKNOWN"}; + } +# +# now we even parse the whole scoreboard, just for fun +# + foreach $scorepoint (split //m, $score) { + if($scorepoint eq '.') { $scores{'.'}+=1; next; } # Unused + if($scorepoint eq '_') { $scores{'_'}+=1; next; } # Waiting + if($scorepoint eq 'S') { $scores{'S'}+=1; next; } # Starting + if($scorepoint eq 'R') { $scores{'R'}+=1; next; } # Reading + if($scorepoint eq 'W') { $scores{'W'}+=1; next; } # Writing + if($scorepoint eq 'K') { $scores{'K'}+=1; next; } # Keepalive + if($scorepoint eq 'D') { $scores{'D'}+=1; next; } # DNS Lookup + if($scorepoint eq 'L') { $scores{'L'}+=1; next; } # Logging + if($scorepoint eq 'G') { $scores{'G'}+=1; next; } # Going + } + + if($busy>$alert) { + printf "HTTPD CRITICAL: %.0f servers running\n", $busy; + exit $ERRORS{"CRITICAL"}; + } + if($busy>$warn) { + printf "HTTPD WARNING: %.0f servers running\n", $busy; + exit $ERRORS{"WARNING"}; + } + printf "HTTPD ok: %.0f servers running, %d idle\n", $busy, $idle; + exit $ERRORS{"OK"}; + + } else { +# +# this is the performance check section +# We are a bit lazy here, no parsing of the initial data +# block and the scoreboard. +# However, you have the whole set of per server +# information to play with ;-) +# The actual performance is measured by adding up the +# milliseconds required to process the most recent +# requests of all instances and then taking the average. +# + foreach $tablerow (split //m, $res->content) { + ($empty,$Srv,$PID,$Acc,$M,$CPU,$SS,$Req,$Conn,$Child,$Slot,$Client,$VHost,$Request) + = split //, $tablerow; + if($Req) { + $lines+=1; + $req_sum+=$Req; + } + undef $Req; + } + $average=$req_sum/$lines; + if($average>$alert) { + printf "HTTPD CRITICAL: average response time %.0f + milliseconds\n", $average; + exit $ERRORS{"CRITICAL"}; + } + if($average>$warn) { + printf "HTTPD WARNING: average response time %.0f + milliseconds\n", $average; + exit $ERRORS{"WARNING"}; + } + if($average>0) { + printf "HTTPD ok: average response time %.0f milliseconds\n", + $average; + exit $ERRORS{"OK"}; + } + print "Unknown Status\n"; + exit $ERRORS{"UNKNOWN"}; + } +} else { + print "HTTP request failed\n"; + exit $ERRORS{"CRITICAL"}; +} + + +# +# ok, now we are almost through +# These last subroutines do the things for those that do not +# read source code. +# +sub print_usage () { + print "Usage: $0 -H [-lhV] [-w ] [-c ] [-u ]\n"; } + +sub print_help () { + print "\n"; + print "\n"; + print "check_apache nagios plugin version $version\n"; + print "\n"; + print "The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n"; + print "copies of the plugins under the terms of the GNU General Public License.\n"; + print "For more information about these matters, see the file named COPYING.\n"; + print "\n"; + print "Copyright (c) 2001 Sebastian Hetze Linux Information Systems AG\n"; + print "\n"; + print "\n"; + print "This plugin checks the apache HTTP service on the specified host.\n"; + print "It uses the mod_status facilities provided by the apache server.\n"; + print "The monitoring server must be authorized in httpd.conf.\n"; + print "\n"; + print "\n"; + print_usage(); + print "\n"; + print "Options:\n"; + print " -H, --hostname=ADDRESS\n"; + print " host name argument for server.\n"; + print " -l, --load\n"; + print " check load instead of performance.\n"; + print " -h, --help\n"; + print " print detailed help screen.\n"; + print " -V, --version\n"; + print " print version information.\n"; + print " -w, --warning=INTEGER\n"; + print " load / performance level at which a warning message will be gererated.\n"; + print " -c, --critical=INTEGER\n"; + print " load / performance level at which a critical message will be gererated.\n"; + print " -u, --url=PATH\n"; + print " location to call mod_status.\n"; + print "\n"; + print " Defaults for performance checking are $perf_w/$perf_c msec.\n"; + print " Defaults for load checking are $load_w/$load_c servers running.\n"; + print "\n"; + print "\n"; +} +# +# the end +# diff --git a/contrib/check_apc_ups.pl b/contrib/check_apc_ups.pl new file mode 100644 index 00000000..dd979f52 --- /dev/null +++ b/contrib/check_apc_ups.pl @@ -0,0 +1,314 @@ +#! /usr/bin/perl -wT +# +# Check_apc_ups - Check APC UPS status via SNMP +# Shamelessly copied from check_breeze.pl +# +# To do: +# - Send SNMP queries directly, instead of forking `snmpget`. +# - Make the status less verbose. Maybe we can send an "onLine, time +# remaining: hh:mm:ss" if all is well, and a list of specific problems +# if something is broken. + +BEGIN { + if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) { + $runtimedir = $1; + $PROGNAME = $2; + } +} + +use strict; +use Getopt::Long; +use vars qw($opt_V $opt_h $opt_H $opt_T $opt_t $opt_R $opt_r + $opt_L $opt_l $PROGNAME); +use lib $main::runtimedir; +use utils qw(%ERRORS &print_revision &support &usage); + +sub print_help (); +sub print_usage (); +sub get_snmp_int_val ($); +sub escalate_exitval ($); + +$ENV{'PATH'}=''; +$ENV{'BASH_ENV'}=''; +$ENV{'ENV'}=''; + +Getopt::Long::Configure('bundling'); +GetOptions + ("V" => \$opt_V, "version" => \$opt_V, + "h" => \$opt_h, "help" => \$opt_h, + "T=s" => \$opt_T, "temp-critical" => \$opt_T, + "t=s" => \$opt_t, "temp-warning" => \$opt_t, + "R=s" => \$opt_R, "runtime-critical" => \$opt_R, + "r=s" => \$opt_r, "runtime-warning" => \$opt_r, + "L=s" => \$opt_L, "load-critical" => \$opt_L, + "l=s" => \$opt_l, "load-warning" => \$opt_l, + "H=s" => \$opt_H, "hostname=s" => \$opt_H); + +if ($opt_V) { + print_revision($PROGNAME,'$Revision$'); + exit $ERRORS{'OK'}; +} + +if ($opt_h) {print_help(); exit $ERRORS{'OK'};} + +($opt_H) || ($opt_H = shift) || usage("Host name/address not specified\n"); +my $host = $1 if ($opt_H =~ /([-.A-Za-z0-9]+)/); +($host) || usage("Invalid host: $opt_H\n"); + +# Defaults + +$opt_R *= 60 * 100 if (defined $opt_R); # Convert minutes to secs/100 +$opt_r *= 60 * 100 if (defined $opt_R); + +my $tempcrit = $opt_T || 60; +my $tempwarn = $opt_t || 40; +my $runtimecrit = $opt_R || 30 * 60 * 100; # Secs / 100 +my $runtimewarn = $opt_r || 60 * 60 * 100; +my $loadcrit = $opt_L || 85; +my $loadwarn = $opt_l || 50; + +if ($tempcrit !~ /\d+/) { usage ("Invalid critical temperature threshold.\n"); } +if ($tempwarn !~ /\d+/) { usage ("Invalid critical temperature threshold.\n"); } + +if ($runtimecrit !~ /\d+/) { + usage ("Invalid critical run time threshold.\n"); +} +if ($runtimewarn !~ /\d+/) { + usage ("Invalid warning run time threshold.\n"); +} + +if ($loadcrit !~ /\d+/ || $loadcrit < 0 || $loadcrit > 100) { + usage ("Invalid critical load threshold.\n"); +} +if ($loadwarn !~ /\d+/ || $loadwarn < 0 || $loadwarn > 100) { + usage ("Invalid warning load threshold.\n"); +} + + +# APC UPS OIDs +# APC MIBs are available at ftp://ftp.apcftp.com/software/pnetmib/mib +my $upsBasicOutputStatus = ".1.3.6.1.4.1.318.1.1.1.4.1.1.0"; +my $upsBasicBatteryStatus = ".1.3.6.1.4.1.318.1.1.1.2.1.1.0"; +my $upsAdvInputLineFailCause = ".1.3.6.1.4.1.318.1.1.1.3.2.5.0"; +my $upsAdvBatteryTemperature = ".1.3.6.1.4.1.318.1.1.1.2.2.2.0"; +my $upsAdvBatteryRunTimeRemaining = ".1.3.6.1.4.1.318.1.1.1.2.2.3.0"; +my $upsAdvBatteryReplaceIndicator = ".1.3.6.1.4.1.318.1.1.1.2.2.4.0"; +my $upsAdvOutputLoad = ".1.3.6.1.4.1.318.1.1.1.4.2.3.0"; +my $upsAdvTestDiagnosticsResults = ".1.3.6.1.4.1.318.1.1.1.7.2.3.0"; + +my @outputStatVals = ( + [ undef, undef ], # pad 0 + [ undef, undef ], # pad 1 + [ "onLine", $ERRORS{'OK'} ], # 2 + [ "onBattery", $ERRORS{'WARNING'} ], # 3 + [ "onSmartBoost", $ERRORS{'WARNING'} ], # 4 + [ "timedSleeping", $ERRORS{'WARNING'} ], # 5 + [ "softwareBypass", $ERRORS{'WARNING'} ], # 6 + [ "off", $ERRORS{'CRITICAL'} ], # 7 + [ "rebooting", $ERRORS{'WARNING'} ], # 8 + [ "switchedBypass", $ERRORS{'WARNING'} ], # 9 + [ "hardwareFailureBypass", $ERRORS{'CRITICAL'} ], # 10 + [ "sleepingUntilPowerReturn", $ERRORS{'CRITICAL'} ], # 11 + [ "onSmartTrim", $ERRORS{'WARNING'} ], # 12 +); + +my @failCauseVals = ( + undef, + "noTransfer", + "highLineVoltage", + "brownout", + "blackout", + "smallMomentarySag", + "deepMomentarySag", + "smallMomentarySpike", + "largeMomentarySpike", + "selfTest", + "rateOfVoltageChnage", +); + +my @battStatVals = ( + [ undef, undef ], # pad 0 + [ undef, undef ], # pad 1 + [ "batteryNormal", $ERRORS{'OK'} ], # 2 + [ "batteryLow", $ERRORS{'CRITICAL'} ], # 3 +); + +my @battReplVals = ( + [ undef, undef ], # pad 0 + [ "noBatteryNeedsReplacing", $ERRORS{'OK'} ], # 1 + [ "batteryNeedsReplacing", $ERRORS{'CRITICAL'} ], # 2 +); + +my @diagnosticsResultsVals = ( + [ undef, undef ], # pad 0 + [ "OK", $ERRORS{'OK'} ], # 1 + [ "failed", $ERRORS{'CRITICAL'} ], # 2 + [ "invalidTest", $ERRORS{'CRITICAL'} ], # 3 + [ "testInProgress", $ERRORS{'OK'} ], # 4 +); + +my $exitval = $ERRORS{'UNKNOWN'}; +my $data; +my $onbattery = 3; + +$data = get_snmp_int_val( $upsBasicOutputStatus ); + +print "Output status: "; +if (defined ($data) && defined ($outputStatVals[$data][0])) { + print "$outputStatVals[$data][0] | "; + escalate_exitval($outputStatVals[$data][1]); +} else { + print "unknown | "; +} + +$data = get_snmp_int_val( $upsAdvBatteryRunTimeRemaining ); + +print "Rem time: "; +if (defined ($data)) { + my $hrs = int($data / (60 * 60 * 100)); # Data is hundredths of a second + my $mins = int($data / (60 * 100)) % 60; + my $secs = ($data % 100) / 100; + printf "%d:%02d:%05.2f | ", $hrs, $mins, $secs; + if ($data <= $runtimecrit) { + escalate_exitval($ERRORS{'CRITICAL'}); + } elsif ($data <= $runtimewarn) { + escalate_exitval($ERRORS{'WARNING'}); + } else { + escalate_exitval($ERRORS{'OK'}); + } +} else { + print "unknown | "; +} + +$data = get_snmp_int_val( $upsBasicBatteryStatus ); + +print "Battery status: "; +if (defined ($data) && defined ($battStatVals[$data][0])) { + my $failcause = "unknown"; + my $fc = get_snmp_int_val( $upsAdvInputLineFailCause ); + if ($data == $onbattery) { + if (defined ($failCauseVals[$fc])) { $failcause = $failCauseVals[$fc]; } + print "$battStatVals[$data][0] ($failcause) | "; + } else { + print "$battStatVals[$data][0] | "; + } + escalate_exitval($battStatVals[$data][1]); +} else { + print "unknown | "; +} + +$data = get_snmp_int_val( $upsAdvBatteryTemperature ); + +print "Battery temp(C): "; +if (defined ($data)) { + print "$data | "; + if ($data >= $tempcrit) { + escalate_exitval($ERRORS{'CRITICAL'}); + } elsif ($data >= $tempwarn) { + escalate_exitval($ERRORS{'WARNING'}); + } else { + escalate_exitval($ERRORS{'OK'}); + } +} else { + print "unknown | "; +} + +$data = get_snmp_int_val( $upsAdvBatteryReplaceIndicator ); + +print "Battery repl: "; +if (defined ($data) && defined ($battReplVals[$data][0])) { + print "$battReplVals[$data][0] | "; + escalate_exitval($battReplVals[$data][1]); +} else { + print "unknown | "; +} + +$data = get_snmp_int_val( $upsAdvOutputLoad ); + +print "Output load (%): "; +if (defined ($data)) { + print "$data | "; + if ($data >= $loadcrit) { + escalate_exitval($ERRORS{'CRITICAL'}); + } elsif ($data >= $loadwarn) { + escalate_exitval($ERRORS{'WARNING'}); + } else { + escalate_exitval($ERRORS{'OK'}); + } +} else { + print "unknown | "; +} + +$data = get_snmp_int_val( $upsAdvTestDiagnosticsResults ); + +print "Diag result: "; +if (defined ($data) && defined ($diagnosticsResultsVals[$data][0])) { + print "$diagnosticsResultsVals[$data][0]\n"; + escalate_exitval($diagnosticsResultsVals[$data][1]); +} else { + print "unknown\n"; +} + + +exit $exitval; + + +sub print_usage () { + print "Usage: $PROGNAME -H -T temp -t temp -R minutes -r minutes\n"; + print " -L percent -l percent\n"; +} + +sub print_help () { + print_revision($PROGNAME,'$Revision$'); + print "Copyright (c) 2001 Gerald Combs/Jeffrey Blank/Karl DeBisschop + +This plugin reports the status of an APC UPS equipped with an SNMP management +module. + +"; + print_usage(); + print " +-H, --hostname=HOST + Name or IP address of host to check +-T --temp-critical + Battery degrees C above which a CRITICAL status will result (default: 60) +-t --temp-warning + Battery degrees C above which a WARNING status will result (default: 40) +-R --runtime-critical + Minutes remaining below which a CRITICAL status will result (default: 30) +-r --runtime-warning + Minutes remaining below which a WARNING status will result (default: 60) +-L --load-critical + Output load pct above which a CRITICAL status will result (default: 85 +-l --load-warning + Output load pct above which a WARNING status will result (default: 50 + +"; + support(); +} + +sub get_snmp_int_val ($) { + my $val=0; + my $oid = shift(@_); + + $val = `/usr/bin/snmpget $host public $oid 2> /dev/null`; + my @test = split(/ /,$val,3); + + return undef unless (defined ($test[2])); + + if ($test[2] =~ /\(\d+\)/) { # Later versions of UCD SNMP + ($val) = ($test[2] =~ /\((\d+)\)/); + } elsif ($test[2] =~ /: \d+/) { + ($val) = ($test[2] =~ /: (\d+)/); + } else { + $val = $test[2]; + } + + return $val; +} + +sub escalate_exitval ($) { + my $newval = shift(@_); + + if ($newval > $exitval) { $exitval = $newval; } +} diff --git a/contrib/check_bgpstate.pl b/contrib/check_bgpstate.pl new file mode 100644 index 00000000..6658a0b8 --- /dev/null +++ b/contrib/check_bgpstate.pl @@ -0,0 +1,215 @@ +#!/usr/bin/perl -w +# +# check_bgpstate.pl - nagios plugin +# +# Copyright (C) 2000 Christoph Kron +# +# This program 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# Report bugs to: ck@zet.net +# +# 11.01.2000 Version 1.0 + + + +use strict; + +use Net::SNMP; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + + +# whois programm for RIPE database queries +my $whois = '/usr/bin/whois'; +my $status; +my $TIMEOUT = 30; + +# critical bgp sessions +my %uplinks = ( 1273, 'Uplink ECRC', + 1755, 'Uplink EBONE', + 3300, 'Uplink AUCS' + ); + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + + +my %bgpPeerState = ( + '1',"idle", + '2',"connect", + '3',"active", + '4',"opensent", + '5',"openconfirm", + '6',"established" + ); +my $state = "UNKNOWN"; +my $answer = ""; +my $snmpkey; +my $snmpoid; +my $key; +my $community = "public"; +my $port = 161; +my @snmpoids; +my $snmpbgpPeerState = '1.3.6.1.2.1.15.3.1.2'; +my $snmpbgpPeerLocalAddr = '1.3.6.1.2.1.15.3.1.5'; +my $snmpbgpPeerRemoteAddr = '1.3.6.1.2.1.15.3.1.7'; +my $snmpbgpPeerRemoteAs = '1.3.6.1.2.1.15.3.1.9'; +my $hostname; +my $session; +my $error; +my $response; +my %bgpStatus; +my $bgpestablished =0 ; +my $bgpcritical =0; +my $bgpdown =0; +my $bgpidle =0; +my $bgpmessage; +my $asname; +my $remoteas; +my @output; + +sub usage { + printf "\nMissing arguments!\n"; + printf "\n"; + printf "Perl bgpstate plugin for Nagios\n"; + printf "monitors all BGP sessions\n"; + printf "usage: \n"; + printf "check_bgpstate.pl -c -p \n"; + printf "Copyright (C) 2000 Christoph Kron\n"; + printf "check_bgpstate.pl comes with ABSOLUTELY NO WARRANTY\n"; + printf "This programm is licensed under the terms of the "; + printf "GNU General Public License\n(check source code for details)\n"; + printf "\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: No snmp response from $hostname (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +$status = GetOptions("community=s",\$community, + "port=i",\$port); +if ($status == 0) +{ + &usage; +} + + #shift; + $hostname = shift || &usage; + + +push(@snmpoids, $snmpbgpPeerState); +push(@snmpoids, $snmpbgpPeerLocalAddr); +push(@snmpoids, $snmpbgpPeerRemoteAddr); +push(@snmpoids, $snmpbgpPeerRemoteAs); + +foreach $snmpoid (@snmpoids) { + + ($session, $error) = Net::SNMP->session( + -hostname => $hostname, + -community => $community, + -port => $port + ); + + if (!defined($session)) { + $state='UNKNOWN'; + $answer=$error; + print ("$state: $answer"); + exit $ERRORS{$state}; + } + + if (!defined($response = $session->get_table($snmpoid))) { + $answer=$session->error; + $session->close; + $state = 'CRITICAL'; + print ("$state: $answer,$community,$snmpkey"); + exit $ERRORS{$state}; + } + + foreach $snmpkey (keys %{$response}) { + $snmpkey =~ m/.*\.(\d+\.\d+\.\d+\.\d+$)/; + $key = $1; +# printf "debug: $snmpkey: $key -> $response->{$snmpkey}\n"; + $bgpStatus{$key}{$snmpoid} = $response->{$snmpkey}; + } + $session->close; +} + +foreach $key (keys %bgpStatus) { + if ($bgpStatus{$key}{$snmpbgpPeerState} == 6 ) { + $bgpestablished++; + } + elsif ($bgpStatus{$key}{$snmpbgpPeerState} == 1 ) { + $bgpidle++; + } + else { + $bgpdown++ ; + if (exists($uplinks{$bgpStatus{$key}{$snmpbgpPeerRemoteAs}}) ) { + $bgpcritical++; + } + @output = `$whois -T aut-num AS$bgpStatus{$key}{$snmpbgpPeerRemoteAs}`; + + $asname = ""; + foreach (@output) { + if (m/as-name/) { + $asname = $_; + $asname =~ s/as-name://; + last; + } + if ( $asname =~ "" && m/descr/ ) { + $asname = $_; + $asname =~ s/descr://; + } + } + $asname =~ s/^\s*//; + $asname =~ s/\s*$//; + $bgpmessage .= sprintf("Peering with AS%s not established -> %s
", + $bgpStatus{$key}{$snmpbgpPeerRemoteAs}, + $asname); + } +} + + + if ($bgpdown > 0) { + if ($bgpcritical > 0) { + $state = 'CRITICAL'; + } + else { + $state = 'WARNING'; + } + $answer = sprintf("host '%s', sessions up: %d, down: %d, shutdown: %d
", + $hostname, + $bgpestablished, + $bgpdown, $bgpidle); + $answer = $answer . $bgpmessage . "\n"; + } + else { + $state = 'OK'; + $answer = sprintf("host '%s', sessions up: %d, down: %d, shutdown: %d\n", + $hostname, + $bgpestablished, + $bgpdown,$bgpidle); + } + +print ("$state: $answer"); +exit $ERRORS{$state}; + diff --git a/contrib/check_dhcp.c b/contrib/check_dhcp.c new file mode 100644 index 00000000..8168b947 --- /dev/null +++ b/contrib/check_dhcp.c @@ -0,0 +1,992 @@ +/****************************************************************************** +* +* CHECK_DHCP.C +* +* Program: DHCP plugin for Nagios +* License: GPL +* Copyright (c) 2001 Ethan Galstad (nagios@nagios.org) +* +* License Information: +* +* This program 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. +* +* This program 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 this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PROGNAME "check_dhcp" + +/*#define DEBUG*/ +#define HAVE_GETOPT_H + + +/**** Common definitions ****/ + +#define STATE_OK 0 +#define STATE_WARNING 1 +#define STATE_CRITICAL 2 +#define STATE_UNKNOWN -1 + +#define OK 0 +#define ERROR -1 + +#define FALSE 0 +#define TRUE 1 + + +/**** DHCP definitions ****/ + +#define MAX_DHCP_CHADDR_LENGTH 16 +#define MAX_DHCP_SNAME_LENGTH 64 +#define MAX_DHCP_FILE_LENGTH 128 +#define MAX_DHCP_OPTIONS_LENGTH 312 + + +typedef struct dhcp_packet_struct{ + u_int8_t op; /* packet type */ + u_int8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ + u_int8_t hlen; /* length of hardware address (of this machine) */ + u_int8_t hops; /* hops */ + u_int32_t xid; /* random transaction id number - chosen by this machine */ + u_int16_t secs; /* seconds used in timing */ + u_int16_t flags; /* flags */ + struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ + struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ + struct in_addr siaddr; /* IP address of DHCP server */ + struct in_addr giaddr; /* IP address of DHCP relay */ + unsigned char chaddr [MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */ + char sname [MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */ + char file [MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */ + char options[MAX_DHCP_OPTIONS_LENGTH]; /* options */ + }dhcp_packet; + + +typedef struct dhcp_offer_struct{ + struct in_addr server_address; /* address of DHCP server that sent this offer */ + struct in_addr offered_address; /* the IP address that was offered to us */ + u_int32_t lease_time; /* lease time in seconds */ + u_int32_t renewal_time; /* renewal time in seconds */ + u_int32_t rebinding_time; /* rebinding time in seconds */ + struct dhcp_offer_struct *next; + }dhcp_offer; + + +typedef struct requested_server_struct{ + struct in_addr server_address; + struct requested_server_struct *next; + }requested_server; + + +#define BOOTREQUEST 1 +#define BOOTREPLY 2 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNACK 6 +#define DHCPRELEASE 7 + +#define DHCP_OPTION_MESSAGE_TYPE 53 +#define DHCP_OPTION_HOST_NAME 12 +#define DHCP_OPTION_BROADCAST_ADDRESS 28 +#define DHCP_OPTION_REQUESTED_ADDRESS 50 +#define DHCP_OPTION_LEASE_TIME 51 +#define DHCP_OPTION_RENEWAL_TIME 58 +#define DHCP_OPTION_REBINDING_TIME 59 + +#define DHCP_INFINITE_TIME 0xFFFFFFFF + +#define DHCP_BROADCAST_FLAG 32768 + +#define DHCP_SERVER_PORT 67 +#define DHCP_CLIENT_PORT 68 + +#define ETHERNET_HARDWARE_ADDRESS 1 /* used in htype field of dhcp packet */ +#define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */ + +unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH]=""; + +char network_interface_name[8]="eth0"; + +u_int32_t packet_xid=0; + +u_int32_t dhcp_lease_time=0; +u_int32_t dhcp_renewal_time=0; +u_int32_t dhcp_rebinding_time=0; + +int dhcpoffer_timeout=2; + +dhcp_offer *dhcp_offer_list=NULL; +requested_server *requested_server_list=NULL; + +int valid_responses=0; /* number of valid DHCPOFFERs we received */ +int requested_servers=0; +int requested_responses=0; + +int request_specific_address=FALSE; +int received_requested_address=FALSE; +struct in_addr requested_address; + + +int process_arguments(int, char **); +int call_getopt(int, char **); +int validate_arguments(void); +void print_usage(void); +void print_help(void); + +int get_hardware_address(int,char *); + +int send_dhcp_discover(int); +int get_dhcp_offer(int); + +int get_results(void); + +int add_dhcp_offer(struct in_addr,dhcp_packet *); +int free_dhcp_offer_list(void); +int free_requested_server_list(void); + +int create_dhcp_socket(void); +int close_dhcp_socket(int); +int send_dhcp_packet(void *,int,int,struct sockaddr_in *); +int receive_dhcp_packet(void *,int,int,int,struct sockaddr_in *); + + + +int main(int argc, char **argv){ + int dhcp_socket; + int result; + + if(process_arguments(argc,argv)!=OK){ + /*usage("Invalid command arguments supplied\n");*/ + printf("Invalid command arguments supplied\n"); + exit(STATE_UNKNOWN); + } + + + /* create socket for DHCP communications */ + dhcp_socket=create_dhcp_socket(); + + /* get hardware address of client machine */ + get_hardware_address(dhcp_socket,network_interface_name); + + /* send DHCPDISCOVER packet */ + send_dhcp_discover(dhcp_socket); + + /* wait for a DHCPOFFER packet */ + get_dhcp_offer(dhcp_socket); + + /* close socket we created */ + close_dhcp_socket(dhcp_socket); + + /* determine state/plugin output to return */ + result=get_results(); + + /* free allocated memory */ + free_dhcp_offer_list(); + free_requested_server_list(); + + return result; + } + + + +/* determines hardware address on client machine */ +int get_hardware_address(int sock,char *interface_name){ + struct ifreq ifr; + + strncpy((char *)&ifr.ifr_name,interface_name,sizeof(ifr.ifr_name)); + + /* try and grab hardware address of requested interface */ + if(ioctl(sock,SIOCGIFHWADDR,&ifr)<0){ + printf("Error: Could not get hardware address of interface '%s'\n",interface_name); + exit(STATE_UNKNOWN); + } + + memcpy(&client_hardware_address[0],&ifr.ifr_hwaddr.sa_data,6); + +#ifdef DEBUG + printf("Hardware address: %02x:%02x:%02x:",client_hardware_address[0],client_hardware_address[1],client_hardware_address[2]); + printf("%02x:",client_hardware_address[3]); + printf("%02x:%02x\n",client_hardware_address[4],client_hardware_address[5]); + printf("\n"); +#endif + + return OK; + } + + +/* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */ +int send_dhcp_discover(int sock){ + dhcp_packet discover_packet; + struct sockaddr_in sockaddr_broadcast; + + + /* clear the packet data structure */ + bzero(&discover_packet,sizeof(discover_packet)); + + + /* boot request flag (backward compatible with BOOTP servers) */ + discover_packet.op=BOOTREQUEST; + + /* hardware address type */ + discover_packet.htype=ETHERNET_HARDWARE_ADDRESS; + + /* length of our hardware address */ + discover_packet.hlen=ETHERNET_HARDWARE_ADDRESS_LENGTH; + + discover_packet.hops=0; + + /* transaction id is supposed to be random */ + srand(time(NULL)); + packet_xid=random(); + discover_packet.xid=htonl(packet_xid); + + /**** WHAT THE HECK IS UP WITH THIS?!? IF I DON'T MAKE THIS CALL, ONLY ONE SERVER RESPONSE IS PROCESSED!!!! ****/ + /* downright bizzarre... */ + ntohl(discover_packet.xid); + + /*discover_packet.secs=htons(65535);*/ + discover_packet.secs=0xFF; + + /* tell server it should broadcast its response */ + discover_packet.flags=htons(DHCP_BROADCAST_FLAG); + + /* our hardware address */ + memcpy(discover_packet.chaddr,client_hardware_address,ETHERNET_HARDWARE_ADDRESS_LENGTH); + + /* first four bytes of options field is magic cookie (as per RFC 2132) */ + discover_packet.options[0]='\x63'; + discover_packet.options[1]='\x82'; + discover_packet.options[2]='\x53'; + discover_packet.options[3]='\x63'; + + /* DHCP message type is embedded in options field */ + discover_packet.options[4]=DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ + discover_packet.options[5]='\x01'; /* DHCP message option length in bytes */ + discover_packet.options[6]=DHCPDISCOVER; + + /* the IP address we're requesting */ + if(request_specific_address==TRUE){ + discover_packet.options[7]=DHCP_OPTION_REQUESTED_ADDRESS; + discover_packet.options[8]='\x04'; + memcpy(&discover_packet.options[9],&requested_address,sizeof(requested_address)); + } + + /* send the DHCPDISCOVER packet to broadcast address */ + sockaddr_broadcast.sin_family=AF_INET; + sockaddr_broadcast.sin_port=htons(DHCP_SERVER_PORT); + sockaddr_broadcast.sin_addr.s_addr=INADDR_BROADCAST; + bzero(&sockaddr_broadcast.sin_zero,sizeof(sockaddr_broadcast.sin_zero)); + + +#ifdef DEBUG + printf("DHCPDISCOVER to %s port %d\n",inet_ntoa(sockaddr_broadcast.sin_addr),ntohs(sockaddr_broadcast.sin_port)); + printf("DHCPDISCOVER XID: %lu (0x%X)\n",ntohl(discover_packet.xid),ntohl(discover_packet.xid)); + printf("DHCDISCOVER ciaddr: %s\n",inet_ntoa(discover_packet.ciaddr)); + printf("DHCDISCOVER yiaddr: %s\n",inet_ntoa(discover_packet.yiaddr)); + printf("DHCDISCOVER siaddr: %s\n",inet_ntoa(discover_packet.siaddr)); + printf("DHCDISCOVER giaddr: %s\n",inet_ntoa(discover_packet.giaddr)); +#endif + + /* send the DHCPDISCOVER packet out */ + send_dhcp_packet(&discover_packet,sizeof(discover_packet),sock,&sockaddr_broadcast); + +#ifdef DEBUG + printf("\n\n"); +#endif + + return OK; + } + + + + +/* waits for a DHCPOFFER message from one or more DHCP servers */ +int get_dhcp_offer(int sock){ + dhcp_packet offer_packet; + struct sockaddr_in source; + int result=OK; + int timeout=1; + int responses=0; + int x; + time_t start_time; + time_t current_time; + + time(&start_time); + + /* receive as many responses as we can */ + for(responses=0,valid_responses=0;;){ + + time(¤t_time); + if((current_time-start_time)>=dhcpoffer_timeout) + break; + +#ifdef DEBUG + printf("\n\n"); +#endif + + bzero(&source,sizeof(source)); + bzero(&offer_packet,sizeof(offer_packet)); + + result=OK; + result=receive_dhcp_packet(&offer_packet,sizeof(offer_packet),sock,dhcpoffer_timeout,&source); + + if(result!=OK){ +#ifdef DEBUG + printf("Result=ERROR\n"); +#endif + continue; + } + else{ +#ifdef DEBUG + printf("Result=OK\n"); +#endif + responses++; + } + +#ifdef DEBUG + printf("DHCPOFFER from IP address %s\n",inet_ntoa(source.sin_addr)); + printf("DHCPOFFER XID: %lu (0x%X)\n",ntohl(offer_packet.xid),ntohl(offer_packet.xid)); +#endif + + /* check packet xid to see if its the same as the one we used in the discover packet */ + if(ntohl(offer_packet.xid)!=packet_xid){ +#ifdef DEBUG + printf("DHCPOFFER XID (%lu) did not match DHCPDISCOVER XID (%lu) - ignoring packet\n",ntohl(offer_packet.xid),packet_xid); +#endif + continue; + } + + /* check hardware address */ + result=OK; +#ifdef DEBUG + printf("DHCPOFFER chaddr: "); +#endif + for(x=0;x %s\n",errno,strerror(errno)); +#endif + return ERROR; + } + else{ +#ifdef DEBUG + printf("receive_dhcp_packet() result: %d\n",recv_result); + printf("receive_dhcp_packet() source: %s\n",inet_ntoa(source_address.sin_addr)); +#endif + + memcpy(address,&source_address,sizeof(source_address)); + return OK; + } + } + + return OK; + } + + + +/* creates a socket for DHCP communication */ +int create_dhcp_socket(void){ + struct sockaddr_in myname; + int sock; + int flag=1; + + /* Set up the address we're going to bind to. */ + bzero(&myname,sizeof(myname)); + myname.sin_family=AF_INET; + myname.sin_port=htons(DHCP_CLIENT_PORT); + myname.sin_addr.s_addr=INADDR_ANY; /* listen on any address */ + bzero(&myname.sin_zero,sizeof(myname.sin_zero)); + + /* create a socket for DHCP communications */ + sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); + if(sock<0){ + printf("Error: Could not create socket!\n"); + exit(STATE_UNKNOWN); + } + +#ifdef DEBUG + printf("DHCP socket: %d\n",sock); +#endif + + /* set the reuse address flag so we don't get errors when restarting */ + flag=1; + if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){ + printf("Error: Could not set reuse address option on DHCP socket!\n"); + exit(STATE_UNKNOWN); + } + + /* set the broadcast option - we need this to listen to DHCP broadcast messages */ + if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char *)&flag,sizeof flag)<0){ + printf("Error: Could not set broadcast option on DHCP socket!\n"); + exit(STATE_UNKNOWN); + } + + /* bind the socket */ + if(bind(sock,(struct sockaddr *)&myname,sizeof(myname))<0){ + printf("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n",DHCP_CLIENT_PORT); + exit(STATE_UNKNOWN); + } + + return sock; + } + + + + + +/* closes DHCP socket */ +int close_dhcp_socket(int sock){ + + close(sock); + + return OK; + } + + + + +/* adds a requested server address to list in memory */ +int add_requested_server(struct in_addr server_address){ + requested_server *new_server; + + new_server=(requested_server *)malloc(sizeof(requested_server)); + if(new_server==NULL) + return ERROR; + + new_server->server_address=server_address; + + new_server->next=requested_server_list; + requested_server_list=new_server; + + requested_servers++; + +#ifdef DEBUG + printf("Requested server address: %s\n",inet_ntoa(new_server->server_address)); +#endif + + return OK; + } + + + + +/* adds a DHCP OFFER to list in memory */ +int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){ + dhcp_offer *new_offer; + int x; + int y; + unsigned option_type; + unsigned option_length; + + if(offer_packet==NULL) + return ERROR; + + /* process all DHCP options present in the packet */ + for(x=4;xoptions[x]==-1 || (int)offer_packet->options[x]==0) + break; + + /* get option type */ + option_type=offer_packet->options[x++]; + + /* get option length */ + option_length=offer_packet->options[x++]; + +#ifdef DEBUG + printf("Option: %d (0x%02X)\n",option_type,option_length); +#endif + + /* get option data */ + if(option_type==DHCP_OPTION_LEASE_TIME) + dhcp_lease_time=ntohl(*((u_int32_t *)&offer_packet->options[x])); + if(option_type==DHCP_OPTION_RENEWAL_TIME) + dhcp_renewal_time=ntohl(*((u_int32_t *)&offer_packet->options[x])); + if(option_type==DHCP_OPTION_REBINDING_TIME) + dhcp_rebinding_time=ntohl(*((u_int32_t *)&offer_packet->options[x])); + + /* skip option data we're ignoring */ + else + for(y=0;yserver_address=source; + new_offer->offered_address=offer_packet->yiaddr; + new_offer->lease_time=dhcp_lease_time; + new_offer->renewal_time=dhcp_renewal_time; + new_offer->rebinding_time=dhcp_rebinding_time; + + +#ifdef DEBUG + printf("Added offer from server @ %s",inet_ntoa(new_offer->server_address)); + printf(" of IP address %s\n",inet_ntoa(new_offer->offered_address)); +#endif + + /* add new offer to head of list */ + new_offer->next=dhcp_offer_list; + dhcp_offer_list=new_offer; + + return OK; + } + + + + +/* frees memory allocated to DHCP OFFER list */ +int free_dhcp_offer_list(void){ + dhcp_offer *this_offer; + dhcp_offer *next_offer; + + for(this_offer=dhcp_offer_list;this_offer!=NULL;this_offer=next_offer){ + next_offer=this_offer->next; + free(this_offer); + } + + return OK; + } + + + + +/* frees memory allocated to requested server list */ +int free_requested_server_list(void){ + requested_server *this_server; + requested_server *next_server; + + for(this_server=requested_server_list;this_server!=NULL;this_server=next_server){ + next_server=this_server->next; + free(this_server); + } + + return OK; + } + + +/* gets state and plugin output to return */ +int get_results(void){ + dhcp_offer *temp_offer; + requested_server *temp_server; + int result; + u_int32_t max_lease_time=0; + + received_requested_address=FALSE; + + /* checks responses from requested servers */ + requested_responses=0; + if(requested_servers>0){ + + for(temp_server=requested_server_list;temp_server!=NULL;temp_server=temp_server->next){ + + for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next){ + + /* get max lease time we were offered */ + if(temp_offer->lease_time>max_lease_time || temp_offer->lease_time==DHCP_INFINITE_TIME) + max_lease_time=temp_offer->lease_time; + + /* see if we got the address we requested */ + if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) + received_requested_address=TRUE; + + /* see if the servers we wanted a response from talked to us or not */ + if(!memcmp(&temp_offer->server_address,&temp_server->server_address,sizeof(temp_server->server_address))){ +#ifdef DEBUG + printf("DHCP Server Match: Offerer=%s",inet_ntoa(temp_offer->server_address)); + printf(" Requested=%s\n",inet_ntoa(temp_server->server_address)); +#endif + requested_responses++; + } + } + } + + } + + /* else check and see if we got our requested address from any server */ + else{ + + for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next){ + + /* get max lease time we were offered */ + if(temp_offer->lease_time>max_lease_time || temp_offer->lease_time==DHCP_INFINITE_TIME) + max_lease_time=temp_offer->lease_time; + + /* see if we got the address we requested */ + if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) + received_requested_address=TRUE; + } + } + + result=STATE_OK; + if(valid_responses==0) + result=STATE_CRITICAL; + else if(requested_servers>0 && requested_responses==0) + result=STATE_CRITICAL; + else if(requested_responses0) + printf(", %s%d of %d requested servers responded",((requested_responses0)?"only ":"",requested_responses,requested_servers); + + if(request_specific_address==TRUE) + printf(", requested address (%s) was %soffered",inet_ntoa(requested_address),(received_requested_address==TRUE)?"":"not "); + + printf(", max lease time = "); + if(max_lease_time==DHCP_INFINITE_TIME) + printf("Infinity"); + else + printf("%lu sec",(unsigned long)max_lease_time); + + printf(".\n"); + + return result; + } + + + + + + +/* print usage help */ +void print_help(void){ + + /*print_revision(PROGNAME,"$Revision$");*/ + + printf("Copyright (c) 2001 Ethan Galstad (nagios@nagios.org)\n\n"); + printf("This plugin tests the availability of DHCP servers on a network.\n\n"); + + print_usage(); + + printf + ("\nOptions:\n" + " -s, --serverip=IPADDRESS\n" + " IP address of DHCP server that we must hear from\n" + " -r, --requestedip=IPADDRESS\n" + " IP address that should be offered by at least one DHCP server\n" + " -t, --timeout=INTEGER\n" + " Seconds to wait for DHCPOFFER before timeout occurs\n" + " -i, --interface=STRING\n" + " Interface to to use for listening (i.e. eth0)\n" + " -v, --verbose\n" + " Print extra information (command-line use only)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n" + ); + + /*support();*/ + + return; + } + + +/* prints usage information */ +void print_usage(void){ + + printf("Usage: %s [-s serverip] [-r requestedip] [-t timeout] [-i interface]\n",PROGNAME); + printf(" %s --help\n",PROGNAME); + printf(" %s --version\n",PROGNAME); + + return; + } + + + + +/* process command-line arguments */ +int process_arguments(int argc, char **argv){ + int c; + + if(argc<1) + return ERROR; + + c=0; + while((c+=(call_getopt(argc-c,&argv[c])))0) + dhcpoffer_timeout=atoi(optarg); + /* + else + usage("Time interval must be a nonnegative integer\n"); + */ + break; + + case 'i': /* interface name */ + + strncpy(network_interface_name,optarg,sizeof(network_interface_name)-1); + network_interface_name[sizeof(network_interface_name)-1]='\x0'; + + break; + + case 'V': /* version */ + + /*print_revision(PROGNAME,"$Revision$");*/ + exit(STATE_OK); + + case 'h': /* help */ + + print_help(); + exit(STATE_OK); + + case '?': /* help */ + + /*usage("Invalid argument\n");*/ + break; + + default: + break; + } + } + + return i; + } + + + +int validate_arguments(void){ + + return OK; + } + diff --git a/contrib/check_dlswcircuit.pl b/contrib/check_dlswcircuit.pl new file mode 100755 index 00000000..f6ef9311 --- /dev/null +++ b/contrib/check_dlswcircuit.pl @@ -0,0 +1,221 @@ +#!/usr/bin/perl -w +# +# check_dlswcircuit.pl - nagios plugin +# +# Checks if a Cisco Dlsw circuit is connected. +# +# +# Copyright (C) 2000 Carsten Foss & Christoph Kron +# +# Basically this is an adapted version of Christoph Kron's (ck@zet.net) check_ifoperstatus.pl plugin. +# most of the thanks should go to him. +# +# This program 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Arguments : -s -d -c -p +# - +# Source & Dest Mac/Sap arguments must be given in Hex as this example : 40.00.01.37.45.01.ss (Where ss is the sap) +# +# Sample command line : check_dlswcircuit.pl -s 40.00.01.37.45.01.04 -d 40.00.02.37.45.02.04 -c secret 1.2.3.4 +# +# Sample host.cfg entry : +#service[Dlsw-xx]=NCP1-NCP2;0;24x7;3;5;1;router-admins;240;24x7;1;1;0;;check_dlswcircuit!-s 40.00.01.37.45.01.04!-d 40.00..01.37.45.02.04!-c secret!1.2.3.4 +# remember to add the service to commands.cfg , something like this: +# command[check_dlswcircuit]=$USER1$/check_dlswcircuit.pl $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ +# +# Report bugs to: cfo@dmdata.dk +# +# 11.03.2000 Version 1.0 + +use strict; + +use Net::SNMP; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + + +my $status; +my $TIMEOUT = 15; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + +my %dlswCircuitStatus = ( + '1','disconnected', + '2','circuitStart', + '3','resolvePending', + '4','circuitPending', + '5','circuitEstablished', + '6','connectPending', + '7','contactPending', + '8','connected', + '9','disconnectPending', + '10','haltPending', + '11','haltPendingNoack', + '13','circuitRestart', + '14','restartPending'); + +my $state = "UNKNOWN"; +my $answer = ""; +my $smac = ""; +my $dmac = ""; +my $community = "public"; +my $port = 161; +#Dlsw Circuit Oid enterprises.9.10.9.1.5.2.1.17.6.0.96.148.47.230.166.4.6.64.0.1.55.69.2.4 = 8 +my $enterpriseOid = "1.3.6.1.4.1"; +my $ciscoDlswCircuitOid = ".9.10.9.1.5.2.1.17."; +my $unknownOid = "6."; +my $smacOid = ""; +my $dmacOid = ""; +my $tmpOid = ""; +my @tmparg; +my $snmpoid; +my @snmpoids; +my $hostname; +my $session; +my $error; +my $response; +my $p = ""; +my $q = ""; + +sub usage { + printf "\nMissing arguments!\n"; + printf "\n"; + printf "Perl Check Cisco Dlsw Circuit State plugin for Nagios\n"; + printf "checks operational status of specified DLSW Circuit\n"; + printf "usage: \n"; + printf "check_dlswcircuit.pl -s -d -c -p "; + printf "\nCopyright (C) 2000 Carsten Foss\n"; + printf "check_dlswcircuit.pl comes with ABSOLUTELY NO WARRANTY\n"; + printf "This programm is licensed under the terms of the "; + printf "GNU General Public License\n(check source code for details)\n"; + printf "\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: No snmp response from $hostname (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +$status = GetOptions("sourcemac=s",\$smac,"destmac=s",\$dmac, + "community=s",\$community, + "port=i",\$port); +if ($status == 0) +{ + &usage; +} + +# +#Convert Source Mac & Sap +# + @tmparg = split(/\./,$smac); + #print "-$smac-\n"; + #print "@tmparg\n"; + #print "$#tmparg\n"; + if($#tmparg != 6) + { + print "SourceMac/Sap format $smac not valid\n"; + &usage; + } + while($p = shift @tmparg) + { + $q = hex($p); + $smacOid = $smacOid.$q; + $smacOid = $smacOid.'.'; + } + + #print "@tmparg1\n"; + #print "$smacOid\n"; + +# +#Convert Dest Mac & Sap +# + @tmparg = split(/\./,$dmac); + #print "-$dmac-\n"; + #print "@tmparg\n"; + #print "$#tmparg\n"; + if($#tmparg != 6) + { + print "DestMac/Sap format $dmac not valid\n"; + &usage; + } + + while($p = shift @tmparg) + { + $q = hex($p); + $dmacOid = $dmacOid.$q; + $dmacOid = $dmacOid.'.'; + } +# Remove Trailing Dot + $dmacOid = substr($dmacOid,0,length($dmacOid)-1); + + + #print "@tmparg1\n"; + #print "$dmacOid\n"; +#Build the Dlsw Oic to use + $snmpoid = $enterpriseOid.$ciscoDlswCircuitOid.$unknownOid.$smacOid.$unknownOid.$dmacOid ; + #print "$snmpoid\n"; + + #shift; + $hostname = shift || &usage; + + ($session, $error) = Net::SNMP->session( + -hostname => $hostname, + -community => $community, + -port => $port + ); + + if (!defined($session)) { + $state='UNKNOWN'; + $answer=$error; + print ("$state: $answer"); + exit $ERRORS{$state}; + } + + push(@snmpoids,$snmpoid); + #push(@snmpoids,$snmpLocIfDescr); + + if (!defined($response = $session->get_request(@snmpoids))) { + $answer=$session->error; + $session->close; + $state = 'CRITICAL'; + print ("$state: $answer,$community,$smac - $dmac"); + exit $ERRORS{$state}; + } + + $answer = sprintf("dlsw circuit %s - %s at host '%s',is %s\n", + $smac, + $dmac, + $hostname, + $dlswCircuitStatus{$response->{$snmpoid}} + ); + + $session->close; + + if ( $response->{$snmpoid} == 8 ) { + $state = 'OK'; + } + else { + $state = 'CRITICAL'; + } + +print ("$state: $answer"); +exit $ERRORS{$state}; diff --git a/contrib/check_dns_random.pl b/contrib/check_dns_random.pl new file mode 100644 index 00000000..787d4644 --- /dev/null +++ b/contrib/check_dns_random.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl +# ------------------------------------------------------------------------------ +# File Name: check_dns_random.pl +# Author: Richard Mayhew - South Africa +# Date: 2000/01/26 +# Version: 1.0 +# Description: This script will check to see if dns resolves hosts +# randomly from a list using the check_dns plugin. +# Email: netsaint@splash.co.za +# ------------------------------------------------------------------------------ +# Copyright 1999 (c) Richard Mayhew +# Credits go to Ethan Galstad for coding Nagios +# If any changes are made to this script, please mail me a copy of the +# changes :) +# License GPL +# ------------------------------------------------------------------------------ +# Date Author Reason +# ---- ------ ------ +# 1999/09/26 RM Creation +# ------------------------------------------------------------------------------ + +# -----------------------------------------------------------------[ Require ]-- +require 5.004; + +# --------------------------------------------------------------------[ Uses ]-- +use Socket; +use strict; + +# --------------------------------------------------------------[ Enviroment ]-- +$ENV{PATH} = "/bin"; +$ENV{BASH_ENV} = ""; +$|=1; + +my $host = shift || &usage; + +my $domainfile = "/usr/local/nagios/etc/domains.list"; +my $wc = `/usr/bin/wc -l $domainfile`; +my $check = "/usr/local/nagios/libexec/check_dns"; +my $x = 0; +my $srv_file = ""; +my $z = ""; +my $y = ""; + +open(DOMAIN,"<$domainfile") or die "Error Opening $domainfile File!\n"; + while () { + $srv_file .= $_; +} + close(DOMAIN); + my @data = split(/\n/,$srv_file); + +chomp $wc; +$wc =~ s/ //g; +$wc =~ s/domains//g; + +$x = rand $wc; +($z,$y) = split(/\./,$x); + +print `$check $data[$z] $host`; + + + +sub usage +{ + print "Minimum arguments not supplied!\n"; + print "\n"; + print "Perl Check Random DNS plugin for Nagios\n"; + print "Copyright (c) 2000 Richard Mayhew\n"; + print "\n"; + print "Usage: check_dns_random.pl \n"; + print "\n"; + print " = DNS server you would like to query.\n"; + exit -1; + +} + diff --git a/contrib/check_email_loop.pl b/contrib/check_email_loop.pl new file mode 100644 index 00000000..733406da --- /dev/null +++ b/contrib/check_email_loop.pl @@ -0,0 +1,268 @@ +#!/usr/bin/perl +# +# (c)2000 Benjamin Schmid, blueshift@gmx.net (emergency use only ;-) +# Copyleft by GNU GPL +# +# +# check_email_loop Nagios Plugin +# +# This script sends a mail with a specific id in the subject via +# an given smtp-server to a given email-adress. When the script +# is run again, it checks for this Email (with its unique id) on +# a given pop3 account and send another mail. +# +# +# Example: check_email_loop.pl -poph=mypop -popu=user -pa=password +# -smtph=mailer -from=returnadress@yoursite.com +# -to=remaileradress@friend.com -pendc=2 -lostc=0 +# +# This example will send eacht time this check is executed a new +# mail to remaileradress@friend.com using the SMTP-Host mailer. +# Then it looks for any back-forwarded mails in the POP3 host +# mypop. In this Configuration CRITICAL state will be reached if +# more than 2 Mails are pending (meaning that they did not came +# back till now) or if a mails got lost (meaning a mail, that was +# send later came back prior to another mail). +# + +use Net::POP3; +use Net::SMTP; +use strict; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + +# ---------------------------------------- + +my $TIMEOUT = 120; +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + +my $state = "UNKNOWN"; +my ($sender,$receiver, $pophost, $popuser, $poppasswd, $smtphost); +my ($poptimeout,$smtptimeout,$pinginterval)=(60,60,5); +my ($lostwarn, $lostcrit,$pendwarn, $pendcrit); + +# Internal Vars +my ($pop,$msgcount,@msglines,$statinfo,@messageids,$newestid); +my ($matchcount,$statfile) = (0,"check_email_loop.stat"); + +# Subs declaration +sub usage; +sub messagematchs; +sub nsexit; + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: $0 Time-Out $TIMEOUT s \n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +# Evaluate Command Line Parameters +my $status = GetOptions( + "from=s",\$sender, + "to=s",\$receiver, + "pophost=s",\$pophost, + "popuser=s",\$popuser, + "passwd=s",\$poppasswd, + "poptimeout=i",\$poptimeout, + "smtphost=s",\$smtphost, + "smtptimeout=i",\$smtptimeout, + "statfile=s",\$statfile, + "interval=i",\$pinginterval, + "lostwarr=i",\$lostwarn, + "lostcrit=i",\$lostcrit, + "pendwarn=i",\$pendwarn, + "pendcrit=i",\$pendcrit, + ); +usage() if ($status == 0 || ! ($pophost && $popuser && $poppasswd && + $smtphost && $receiver && $sender )); + +# Try to read the ids of the last send emails out of statfile +if (open STATF, "$statfile") { + @messageids = ; + chomp @messageids; + close STATF; +} + +# Try to open statfile for writing +if (!open STATF, ">$statfile") { + nsexit("Failed to open mail-ID database $statfile for writing",'CRITICAL'); +} + +# Ok - check if it's time to release another mail + +# ... + +# creating new serial id +my $serial = time(); +$serial = "ID#" . $serial . "#$$"; + +# sending new ping email +my $smtp = Net::SMTP->new($smtphost,Timeout=>$smtptimeout) + || nsexit("SMTP connect timeout ($smtptimeout s)",'CRITICAL'); +($smtp->mail($sender) && + $smtp->to($receiver) && + $smtp->data() && + $smtp->datasend("To: $receiver\nSubject: E-Mail Ping [$serial]\n\n". + "This is a automatically sended E-Mail.\n". + "It ist not intended for human reader.\n\n". + "Serial No: $serial\n") && + $smtp->dataend() && + $smtp->quit + ) || nsexit("Error delivering message",'CRITICAL'); + +# no the interessting part: let's if they are receiving ;-) + +$pop = Net::POP3->new( $pophost, + Timeout=>$poptimeout) + || nsexit("POP3 connect timeout (>$poptimeout s, host: $pophost)",'CRITICAL'); + +$msgcount=$pop->login($popuser,$poppasswd); + +$statinfo="$msgcount mails on POP3"; + +nsexit("POP3 login failed (user:$popuser)",'CRITICAL') if (!defined($msgcount)); + +# Count messages, that we are looking 4: +while ($msgcount > 0) { + @msglines = @{$pop->get($msgcount)}; + + for (my $i=0; $i < scalar @messageids; $i++) { + if (messagematchsid(\@msglines,$messageids[$i])) { + $matchcount++; + # newest received mail than the others, ok remeber id. + $newestid = $messageids[$i] if ($messageids[$i] > $newestid || !defined $newestid); + $pop->delete($msgcount); # remove E-Mail from POP3 server + splice @messageids, $i, 1;# remove id from List + last; # stop looking in list + } + } + + $msgcount--; +} + +$pop->quit(); # necessary for pop3 deletion! + +# traverse through the message list and mark the lost mails +# that mean mails that are older than the last received mail. +if (defined $newestid) { + $newestid =~ /\#(\d+)\#/; + $newestid = $1; + for (my $i=0; $i < scalar @messageids; $i++) { + $messageids[$i] =~ /\#(\d+)\#/; + my $akid = $1; + if ($akid < $newestid) { + $messageids[$i] =~ s/^ID/LI/; # mark lost + } + } +} + +# Write list to id-Database +foreach my $id (@messageids) { + print STATF "$id\n"; +} +print STATF "$serial\n"; # remember send mail of this session +close STATF; + +# ok - count lost and pending mails; +my @tmp = grep /^ID/, @messageids; +my $pendingm = scalar @tmp; +@tmp = grep /^LI/, @messageids; +my $lostm = scalar @tmp; + +# Evaluate the Warnin/Crit-Levels +if (defined $pendwarn && $pendingm > $pendwarn) { $state = 'WARNING'; } +if (defined $lostwarn && $lostm > $lostwarn) { $state = 'WARNING'; } +if (defined $pendcrit && $pendingm > $pendcrit) { $state = 'CRITICAL'; } +if (defined $lostcrit && $lostm > $lostcrit) { $state = 'CRITICAL'; } + +if ((defined $pendwarn || defined $pendcrit || defined $lostwarn + || defined $lostcrit) && ($state eq 'UNKNOWN')) {$state='OK';} + + +# Append Status info +$statinfo = $statinfo . ", $matchcount mail(s) came back,". + " $pendingm pending, $lostm lost."; + +# Exit in a Nagios-compliant way +nsexit($statinfo); + +# ---------------------------------------------------------------------- + +sub usage { + print "check_email_loop 1.0 Nagios Plugin - Real check of a E-Mail system\n"; + print "=" x 75,"\nERROR: Missing or wrong arguments!\n","=" x 75,"\n"; + print "This script sends a mail with a specific id in the subject via an given\n"; + print "smtp-server to a given email-adress. When the script is run again, it checks\n"; + print "for this Email (with its unique id) on a given pop3 account and sends \n"; + print "another mail.\n"; + print "\nThe following options are available:\n"; + print " -from=text email adress of send (for mail returnr on errors)\n"; + print " -to=text email adress to which the mails should send to\n"; + print " -pophost=text IP or name of the POP3-host to be checked\n"; + print " -popuser=text Username of the POP3-account\n"; + print " -passwd=text Password for the POP3-user\n"; + print " -poptimeout=num Timeout in seconds for the POP3-server\n"; + print " -smtphost=text IP oder name of the SMTP host\n"; + print " -smtptimeout=num Timeout in seconds for the SMTP-server\n"; + print " -statfile=text File to save ids of messages ($statfile)\n"; +# print " -interval=num Time (in minutes) that must pass by before sending\n" +# print " another Ping-mail (gibe a new try);\n"; + print " -lostwarn=num WARNING-state if more than num lost emails\n"; + print " -lostcrit=num CRITICAL \n"; + print " -pendwarn=num WARNING-state if more than num pending emails\n"; + print " -pendcrit=num CRITICAL \n"; + print " Options may abbreviated!\n"; + print " LOST mails are mails, being sent before the last mail arrived back.\n"; + print " PENDING mails are those, which are not. (supposed to be on the way)\n"; + print "\nExample: \n"; + print " $0 -poph=host -pa=pw -popu=popts -smtph=host -from=root\@me.com\n "; + print " -to=remailer\@testxy.com -lostc=0 -pendc=2\n"; + print "\nCopyleft 19.10.2000, Benjamin Schmid\n"; + print "This script comes with ABSOLUTELY NO WARRANTY\n"; + print "This programm is licensed under the terms of the "; + print "GNU General Public License\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + +# --------------------------------------------------------------------- + +sub nsexit { + my ($msg,$code) = @_; + $code=$state if (!defined $code); + print "$code: $msg\n" if (defined $msg); + exit $ERRORS{$code}; +} + +# --------------------------------------------------------------------- + +sub messagematchsid { + my ($mailref,$id) = (@_); + my (@tmp); + my $match = 0; + + # ID + $id =~ s/^LI/ID/; # evtl. remove lost mail mark + @tmp = grep /Subject: E-Mail Ping \[/, @$mailref; + chomp @tmp; + if (($tmp[0] =~ /$id/)) + { $match = 1; } + + # Sender: +# @tmp = grep /^From:\s+/, @$mailref; +# if (@tmp && $sender ne "") +# { $match = $match && ($tmp[0]=~/$sender/); } + + # Receiver: +# @tmp = grep /^To: /, @$mailref; +# if (@tmp && $receiver ne "") +# { $match = $match && ($tmp[0]=~/$receiver/); } + + return $match; +} + +# --------------------------------------------------------------------- diff --git a/contrib/check_fping_in.c b/contrib/check_fping_in.c new file mode 100644 index 00000000..50fd5eea --- /dev/null +++ b/contrib/check_fping_in.c @@ -0,0 +1,430 @@ +/****************************************************************************** +* +* CHECK_INET_FPING.C +* +* Program: Fping plugin for Nagios +* License: GPL +* Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) +* $Id$ +* +* Modifications: +* +* 08-24-1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) +* Intial Coding +* 09-11-1999 Karl DeBisschop (kdebiss@alum.mit.edu) +* Change to spopen +* Fix so that state unknown is returned by default +* (formerly would give state ok if no fping specified) +* Add server_name to output +* Reformat to 80-character standard screen +* 11-18-1999 Karl DeBisschop (kdebiss@alum.mit.edu) +* set STATE_WARNING of stderr written or nonzero status returned +* 09-29-2000 Matthew Grant (matthewg@plain.co.nz) +* changes for monitoring multiple hosts for checking Internet +* reachibility +* +* Description: +* +* This plugin will use the /bin/fping command (from nagios) to ping +* the specified host for a fast check if the host is alive. Note that +* it is necessary to set the suid flag on fping. +******************************************************************************/ + +#include "config.h" +#include "common.h" +#include "popen.h" +#include "utils.h" + +#define PROGNAME "check_fping" +#define PACKET_COUNT 15 +#define PACKET_SIZE 56 +#define CRITICAL_COUNT 2 +#define WARNING_COUNT 1 +#define UNKNOWN_PACKET_LOSS 200 /* 200% */ +#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */ + +#define STRSZ 100 + +int textscan(char *buf); +int process_arguments(int, char **); +int get_threshold (char *arg, char *rv[2]); +void print_usage(void); +void print_help(void); + +char *server_names=NULL; +char *name="INTERNET"; +int cthresh=CRITICAL_COUNT; +int wthresh=WARNING_COUNT; +int nnames=0; +int tpl=UNKNOWN_PACKET_LOSS; +double trta=UNKNOWN_TRIP_TIME; +int packet_size=PACKET_SIZE; +int packet_count=PACKET_COUNT; +int verbose=FALSE; +int fail = 0; +int not_found = 0; +int rta_fail = 0; +int pl_fail = 0; +int unreachable = 0; + +int main(int argc, char **argv){ + int result; + int status=STATE_UNKNOWN; + char *servers=NULL; + char *command_line=NULL; + char *input_buffer=NULL; + char *pl_buffer=NULL; + char *rta_buffer=NULL; + input_buffer=malloc(MAX_INPUT_BUFFER); + rta_buffer = malloc(80); + pl_buffer = malloc(80); + memset(rta_buffer, 0, 80); + memset(pl_buffer, 0, 80); + + if(process_arguments(argc,argv)==ERROR) + usage("Could not parse arguments\n"); + + servers=strscpy(servers,server_names); + + /* compose the command */ + command_line=ssprintf + (command_line,"%s -b %d -c %d %s", + PATH_TO_FPING, + packet_size, + packet_count, + servers); + + if (verbose) printf("%s\n",command_line); + + /* run the command */ + child_process=spopen(command_line); + if(child_process==NULL){ + printf("Unable to open pipe: %s\n",command_line); + return STATE_UNKNOWN; + } + + child_stderr=fdopen(child_stderr_array[fileno(child_process)],"r"); + if(child_stderr==NULL){ + printf("Could not open stderr for %s\n",command_line); + } + + while (fgets(input_buffer,MAX_INPUT_BUFFER-1,child_process)) { + if (verbose) printf("%s",input_buffer); + result = textscan(input_buffer); + status = max(status,result); + } + + while(fgets(input_buffer,MAX_INPUT_BUFFER-1,child_stderr)) { + if (verbose) printf("%s",input_buffer); + result = textscan(input_buffer); + status = max(status,result); + } + + (void)fclose(child_stderr); + + /* close the pipe */ + if(spclose(child_process)) + status=max(status,STATE_WARNING); + + /* Analyse fail count and produce results */ + if (fail >= wthresh) { + status = max(status, STATE_WARNING); + } + + if (fail >= cthresh) { + status = max(status, STATE_CRITICAL); + } + + if( tpl != UNKNOWN_PACKET_LOSS ) { + snprintf(pl_buffer, 80, ", %d PL", pl_fail); + } + + if( trta != UNKNOWN_TRIP_TIME ) { + snprintf(rta_buffer, 80, ", %d RTA", rta_fail); + + } + + printf("FPING %s - %s, %d of %d fail, %d NF, %d UR%s%s\n", + state_text(status), + (name != NULL ? name : server_names), + fail, + nnames, + not_found, + unreachable, + pl_buffer, + rta_buffer); + + return status; +} + + + +/* analyse fping output - each event resulting in an increment of fail + * must be mutually exclusive. packet loss and round trip time analysed + * together, both at once just results in one increment of fail + */ +int textscan(char *buf) +{ + char *rtastr=NULL; + char *losstr=NULL; + double loss; + double rta; + int status=STATE_OK; + + if (strstr(buf,"not found")) { + fail++; + not_found++; + } else if(strstr(buf,"xmt/rcv/%loss") + && strstr(buf,"min/avg/max")) { + losstr = strstr(buf,"="); + losstr = 1+strstr(losstr,"/"); + losstr = 1+strstr(losstr,"/"); + rtastr = strstr(buf,"min/avg/max"); + rtastr = strstr(rtastr,"="); + rtastr = 1+index(rtastr,'/'); + loss = strtod(losstr,NULL); + rta = strtod(rtastr,NULL); + /* Increment fail counter + */ + if (tpl!=UNKNOWN_PACKET_LOSS && loss>tpl) { + fail++; + } + else if (trta!=UNKNOWN_TRIP_TIME && rta>trta) { + fail++; + } + else if (loss >= 100) { + fail++; + } + /* Increment other counters + */ + if (trta!=UNKNOWN_TRIP_TIME && rta>trta) + rta_fail++; + if (tpl!=UNKNOWN_PACKET_LOSS && loss>tpl) + pl_fail++; + if (loss >= 100) + unreachable++; + } else if(strstr(buf,"xmt/rcv/%loss") ) { + losstr = strstr(buf,"="); + losstr = 1+strstr(losstr,"/"); + losstr = 1+strstr(losstr,"/"); + loss = strtod(losstr,NULL); + /* Increment fail counter + */ + if (tpl!=UNKNOWN_PACKET_LOSS && loss>tpl) { + fail++; + } + else if (loss >= 100) { + fail++; + } + /* Increment other counters + */ + if (tpl!=UNKNOWN_PACKET_LOSS && loss>tpl) + pl_fail++; + if (loss >= 100) + unreachable++; + } + + return status; +} + + + + +/* process command-line arguments */ +int process_arguments(int argc, char **argv) +{ + int c; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = + { + {"hostname" ,required_argument,0,'H'}, + {"critical" ,required_argument,0,'c'}, + {"warning" ,required_argument,0,'w'}, + {"bytes" ,required_argument,0,'b'}, + {"number" ,required_argument,0,'n'}, + {"pl-threshold" ,required_argument,0,'p'}, + {"rta-threshold" ,required_argument,0,'r'}, + {"name" ,required_argument,0,'N'}, + {"verbose" ,no_argument, 0,'v'}, + {"version" ,no_argument, 0,'V'}, + {"help" ,no_argument, 0,'h'}, + {0,0,0,0} + }; +#else + + if(argc<2) return ERROR; + + if (!is_option(argv[1])){ + server_names=argv[1]; + argv[1]=argv[0]; + argv=&argv[1]; + argc--; + } +#endif + + while (1){ +#ifdef HAVE_GETOPT_H + c = getopt_long(argc,argv,"+hVvH:c:w:b:n:N:p:r:",long_options,&option_index); +#else + c = getopt(argc,argv,"+hVvH:c:w:b:n:N:p:r:"); +#endif + + if (c==-1||c==EOF||c==1) + break; + + switch (c) + { + case '?': /* print short usage statement if args not parsable */ + printf("%s: Unknown argument: %s\n\n",my_basename(argv[0]),optarg); + print_usage(); + exit(STATE_UNKNOWN); + case 'h': /* help */ + print_help(); + exit(STATE_OK); + case 'V': /* version */ + print_revision(my_basename(argv[0]),"$Revision$"); + exit(STATE_OK); + case 'v': /* verbose mode */ + verbose=TRUE; + break; + case 'H': /* hostname */ + if(is_host(optarg)==FALSE){ + printf("Invalid host name/address\n\n"); + print_usage(); + exit(STATE_UNKNOWN); + } + if (server_names != NULL) + server_names=strscat(server_names," "); + server_names=strscat(server_names,optarg); + nnames++; + break; + case 'c': + if (is_intpos(optarg)) + cthresh = atoi(optarg); + else + usage("Critical threshold must be a positive integer"); + break; + case 'w': + if (is_intpos(optarg)) + wthresh = atoi(optarg); + else + usage("Warning threshold must be a postive integer"); + break; + case 'r': + if (is_intpos(optarg)) { + trta=strtod(optarg,NULL); + } + else { + usage("RTA threshold must be a positive integer"); + } + break; + case 'p': + if (is_intpos(optarg)) { + tpl=strtod(optarg,NULL); + } + else { + usage("RTA threshold must be a positive integer"); + } + break; + case 'b': /* bytes per packet */ + if (is_intpos(optarg)) + packet_size=atoi(optarg); + else + usage("Packet size must be a positive integer"); + break; + case 'N': /* Name of service */ + name = optarg; + break; + case 'n': /* number of packets */ + if (is_intpos(optarg)) + packet_count=atoi(optarg); + else + usage("Packet count must be a positive integer"); + break; + } + } + + while (optind < argc) { + if(is_host(argv[optind])==FALSE) { + printf("Invalid host name/address\n\n"); + print_usage(); + exit(STATE_UNKNOWN); + } + if (server_names != NULL) + server_names=strscat(server_names," "); + server_names=strscat(server_names,argv[optind]); + nnames++; + optind++; + } + + if (server_names==NULL || nnames < 2) + usage("At least 2 hostnames must be supplied\n\n"); + + if (cthresh < 2) + usage("Critical threshold must be at least 2"); + if (cthresh > nnames) + usage("Critical threshold cannot be greater than number of hosts tested"); + if (wthresh < 1) + usage("Warning threshold must be at least 1"); + if (wthresh > nnames) + usage("Warning threshold cannot be greater than number of hosts tested"); + if(wthresh >= cthresh) + usage("Warning threshold must be less than the critical threshold"); + + return OK; +} + + +void print_usage(void) +{ + printf("Usage: %s [] ...\n",PROGNAME); +} + + + + + +void print_help(void) +{ + + print_revision(PROGNAME,"$Revision$"); + + printf + ("Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)\n" + " (c) 2000 Matthew Grant (matthewg@plain.co.nz)\n" + "This plugin will use the /bin/fping command (from saint) to ping the\n" + "specified hosts for a fast check to see if the Internet is still \n" + "reachable, and the results of the testing aggregated. Note that it\n" + "is necessary to set the suid flag on fping.\n\n"); + + print_usage(); + + printf + ("\nOptions:\n" + "-b, --bytes=INTEGER\n" + " Size of ICMP packet (default: %d)\n" + "-c, --critical=INTEGER (default: %d)\n" + " critical threshold failure count\n" + "-n, --number=INTEGER\n" + " Number of ICMP packets to send (default: %d)\n" + "-H, --hostname=HOST\n" + " Name or IP Address of host to ping (IP Address bypasses name lookup,\n" + " reducing system load)\n" + "-h, --help\n" + " Print this help screen\n" + "-N, --name\n" + " Service name to print in results, defaults to INTERNET\n" + "-p, --pl-threshold\n" + " Packet loss threshold - specify to turn on packet loss testing\n" + "-r, --rta-threshold\n" + " Round trip average threshold - specify to turn on RTA testing\n" + "-V, --version\n" + " Print version information\n" + "-v, --verbose\n" + " Show details for command-line debugging (do not use with nagios server)\n" + "-w, --warning=INTEGER (default: %d)\n" + " warning threshold failure count\n", + PACKET_SIZE, CRITICAL_COUNT, PACKET_COUNT, WARNING_COUNT); +} diff --git a/contrib/check_ftpget.pl b/contrib/check_ftpget.pl new file mode 100755 index 00000000..de7e8242 --- /dev/null +++ b/contrib/check_ftpget.pl @@ -0,0 +1,48 @@ +#!/usr/bin/perl -w +## Written 12/5/00 Jeremy Hanmer +# $Id$ + +use strict; +use Net::FTP; +use Getopt::Std; + +use vars qw($opt_H $opt_u $opt_p $opt_f); +getopts("H:u:p:f:"); + +my $host = $opt_H || + die "usage: check_ftp.pl -h host [<-u user> <-p pass> <-f file>]\n"; + +my $username = $opt_u || 'anonymous'; +my $pass = $opt_p || "$ENV{'LOGNAME'}\@$ENV{'HOSTNAME'}" ; + +my $file = $opt_f; + +my $status = 0; +my $problem; +my $output = "ftp ok"; + +my $ftp = Net::FTP->new("$host") || + &crit("connect"); + +$ftp->login("$username", "$pass") || + &crit("login"); + +$ftp->get($file) || + &crit("get") if $file; + +sub crit() +{ + $problem = $_[0]; + $status = 2; + if ( $problem eq 'connect' ) { + $output = "can't connect"; + } elsif ( $problem eq 'login' ) { + $output = "can't log in"; + } elsif ( $problem eq 'get' ) { + $output = "cant get $file"; + } +} + +print "$output\n"; +exit $status; + diff --git a/contrib/check_ifoperstatus.pl b/contrib/check_ifoperstatus.pl new file mode 100644 index 00000000..3f21cddd --- /dev/null +++ b/contrib/check_ifoperstatus.pl @@ -0,0 +1,145 @@ +#!/usr/bin/perl -w +# +# check_ifoperstatus.pl - nagios plugin +# +# +# +# +# Copyright (C) 2000 Christoph Kron +# +# This program 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# Report bugs to: ck@zet.net +# +# 11.01.2000 Version 1.0 + +use strict; + +use Net::SNMP; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + + +my $status; +my $TIMEOUT = 15; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + +my %ifOperStatus = ('1','up', + '2','down', + '3','testing', + '4','unknown', + '5','dormant', + '6','notPresent'); + +my $state = "UNKNOWN"; +my $answer = ""; +my $snmpkey = 1; +my $community = "public"; +my $port = 161; +my @snmpoids; +my $snmpIfOperStatus; +my $snmpLocIfDescr; +my $hostname; +my $session; +my $error; +my $response; + + +sub usage { + printf "\nMissing arguments!\n"; + printf "\n"; + printf "Perl Check IfOperStatus plugin for Nagios\n"; + printf "checks operational status of specified interface\n"; + printf "usage: \n"; + printf "ifoperstatus.pl -k -c -p "; + printf "\nCopyright (C) 2000 Christoph Kron\n"; + printf "check_ifoperstatus.pl comes with ABSOLUTELY NO WARRANTY\n"; + printf "This programm is licensed under the terms of the "; + printf "GNU General Public License\n(check source code for details)\n"; + printf "\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: No snmp response from $hostname (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +$status = GetOptions("key=i",\$snmpkey, + "community=s",\$community, + "port=i",\$port); +if ($status == 0) +{ + &usage; +} + + #shift; + $hostname = shift || &usage; + + ($session, $error) = Net::SNMP->session( + -hostname => $hostname, + -community => $community, + -port => $port + ); + + if (!defined($session)) { + $state='UNKNOWN'; + $answer=$error; + print ("$state: $answer"); + exit $ERRORS{$state}; + } + + $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8' . "." . $snmpkey; + $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28' . "." . $snmpkey; + + + push(@snmpoids,$snmpIfOperStatus); + push(@snmpoids,$snmpLocIfDescr); + + if (!defined($response = $session->get_request(@snmpoids))) { + $answer=$session->error; + $session->close; + $state = 'CRITICAL'; + print ("$state: $answer,$community,$snmpkey"); + exit $ERRORS{$state}; + } + + $answer = sprintf("host '%s',%s(%s) is %s\n", + $hostname, + $response->{$snmpLocIfDescr}, + $snmpkey, + $ifOperStatus{$response->{$snmpIfOperStatus}} + ); + + $session->close; + + if ( $response->{$snmpIfOperStatus} == 1 ) { + $state = 'OK'; + } + else { + $state = 'CRITICAL'; + } + +print ("$state: $answer"); +exit $ERRORS{$state}; + diff --git a/contrib/check_ifstatus.pl b/contrib/check_ifstatus.pl new file mode 100644 index 00000000..a7ab39ec --- /dev/null +++ b/contrib/check_ifstatus.pl @@ -0,0 +1,178 @@ +#!/usr/bin/perl -w +# +# check_ifstatus.pl - nagios plugin +# +# +# Copyright (C) 2000 Christoph Kron +# +# This program 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# Report bugs to: ck@zet.net +# +# 11.01.2000 Version 1.0 + +use strict; + +use Net::SNMP; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + + +my $status; +my $TIMEOUT = 1500; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + +my %ifOperStatus = ('1','up', + '2','down', + '3','testing', + '4','unknown', + '5','dormant', + '6','notPresent'); + +my $state = "UNKNOWN"; +my $answer = ""; +my $snmpkey; +my $snmpoid; +my $key; +my $community = "public"; +my $port = 161; +my @snmpoids; +my $snmpIfAdminStatus = '1.3.6.1.2.1.2.2.1.7'; +my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; +my $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8'; +my $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28'; +my $hostname; +my $session; +my $error; +my $response; +my %ifStatus; +my $ifup =0 ; +my $ifdown =0; +my $ifdormant = 0; +my $ifmessage; + +sub usage { + printf "\nMissing arguments!\n"; + printf "\n"; + printf "Perl Check IfStatus plugin for Nagios\n"; + printf "monitors operational status of each interface\n"; + printf "usage: \n"; + printf "check_ifstatus.pl -c -p \n"; + printf "Copyright (C) 2000 Christoph Kron\n"; + printf "check_ifstatus.pl comes with ABSOLUTELY NO WARRANTY\n"; + printf "This programm is licensed under the terms of the "; + printf "GNU General Public License\n(check source code for details)\n"; + printf "\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: No snmp response from $hostname (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +$status = GetOptions("community=s",\$community, + "port=i",\$port); +if ($status == 0) +{ + &usage; +} + + #shift; + $hostname = shift || &usage; + + + + push(@snmpoids,$snmpIfOperStatus); + push(@snmpoids,$snmpLocIfDescr); + push(@snmpoids,$snmpIfAdminStatus); + push(@snmpoids,$snmpIfDescr); + +foreach $snmpoid (@snmpoids) { + + ($session, $error) = Net::SNMP->session( + -hostname => $hostname, + -community => $community, + -port => $port + ); + + if (!defined($session)) { + $state='UNKNOWN'; + $answer=$error; + print ("$state: $answer"); + exit $ERRORS{$state}; + } + + if (!defined($response = $session->get_table($snmpoid))) { + $answer=$session->error; + $session->close; + $state = 'CRITICAL'; + print ("$state: $answer,$community,$snmpkey"); + exit $ERRORS{$state}; + } + + foreach $snmpkey (keys %{$response}) { + $snmpkey =~ /.*\.(\d+)$/; + $key = $1; + $ifStatus{$key}{$snmpoid} = $response->{$snmpkey}; + } + $session->close; +} + + foreach $key (keys %ifStatus) { + # check only if interface is administratively up + if ($ifStatus{$key}{$snmpIfAdminStatus} == 1 ) { + if ($ifStatus{$key}{$snmpIfOperStatus} == 1 ) { $ifup++ ;} + if ($ifStatus{$key}{$snmpIfOperStatus} == 2 ) { + $ifdown++ ; + $ifmessage .= sprintf("%s: down -> %s
", + $ifStatus{$key}{$snmpIfDescr}, + $ifStatus{$key}{$snmpLocIfDescr}); + + } + if ($ifStatus{$key}{$snmpIfOperStatus} == 5 ) { $ifdormant++ ;} + } + } + + + if ($ifdown > 0) { + $state = 'CRITICAL'; + $answer = sprintf("host '%s', interfaces up: %d, down: %d, dormant: %d
", + $hostname, + $ifup, + $ifdown, + $ifdormant); + $answer = $answer . $ifmessage . "\n"; + } + else { + $state = 'OK'; + $answer = sprintf("host '%s', interfaces up: %d, down: %d, dormant: %d\n", + $hostname, + $ifup, + $ifdown, + $ifdormant); + } + +print ("$state: $answer"); +exit $ERRORS{$state}; + diff --git a/contrib/check_ipxping.c b/contrib/check_ipxping.c new file mode 100644 index 00000000..1ba10fe6 --- /dev/null +++ b/contrib/check_ipxping.c @@ -0,0 +1,200 @@ +/****************************************************************************************** + * + * CHECK_IPXPING.C + * + * Program: IPX ping plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * Last Modified: 09-24-1999 + * + * Command line: CHECK_IPXPING + * + * Description: + * + * This plugin will use the /usr/bin/ipxping command to ping the specified host using the + * IPX protocol. Note: Linux users must have IPX support compiled into the kernerl and + * must have IPX configured correctly in order for this plugin to work. + * If the round trip time value is above the level, a STATE_WARNING is + * returned. If it exceeds the level, a STATE_CRITICAL is returned. + * + * + * + * IMPORTANT!! + * + * This plugin will only work with the ipxping command that has been ported to Linux. + * The version for Sun takes different command line arguments and differs in its output. + * + *****************************************************************************************/ + +#include "../common/config.h" +#include "../common/common.h" +#include "netutils.h" + +/* this should be moved out to the configure script! */ +#define IPXPING_COMMAND "/tmp/ipxping/ipxping" + +/* these should be moved to the common header file */ +#define MAX_IPXNET_ADDRESS_LENGTH 12 +#define MAX_IPXHOST_ADDRESS_LENGTH 18 + +int socket_timeout=DEFAULT_SOCKET_TIMEOUT; +char dest_network[MAX_IPXNET_ADDRESS_LENGTH]; +char dest_address[MAX_IPXHOST_ADDRESS_LENGTH]; +int wrtt; +int crtt; + +int process_arguments(int,char **); + +FILE * spopen(const char *); +int spclose(FILE *); + +int main(int argc, char **argv){ + char command_line[MAX_INPUT_BUFFER]; + int rtt; + int bytes_returned; + int result=STATE_OK; + FILE *fp; + char input_buffer[MAX_INPUT_BUFFER]; + char *substr; + int current_line; + + if(process_arguments(argc,argv)!=OK){ + printf("Incorrect arguments supplied\n"); + printf("\n"); + printf("IPX ping plugin for Nagios\n"); + printf("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n"); + printf("Last Modified: 09-24-1999\n"); + printf("License: GPL\n"); + printf("\n"); + printf("Usage: %s [-to to_sec]\n",argv[0]); + printf("\n"); + printf("Options:\n"); + printf(" = IPX network that the remote host lies on. (Hex Format - 00:00:00:00)\n"); + printf(" = MAC address of the remote host. (Hex Format - 00:00:00:00:00:00)\n"); + printf(" = Round trip time in milliseconds necessary to result in a WARNING state\n"); + printf(" = Round trip time in milliseconds necessary to result in a CRITICAL state\n"); + printf(" [to_sec] = Seconds before we should timeout waiting for ping result. Default = %d sec\n",DEFAULT_SOCKET_TIMEOUT); + printf("\n"); + printf("Notes:\n"); + printf("This plugin will use the /usr/bin/ipxping command to ping the specified host using\n"); + printf("the IPX protocol. IPX support must be compiled into the kernel and your host must\n"); + printf("be correctly configured to use IPX before this plugin will work! An RPM package of\n"); + printf("the ipxping binary can be found at...\n"); + printf("http://www.rpmfind.net/linux/RPM/contrib/libc5/i386/ipxping-0.0-2.i386.shtml\n"); + printf("\n"); + return STATE_UNKNOWN; + } + + /* create the command line to use... */ + sprintf(command_line,"%s %s %s",IPXPING_COMMAND,dest_network,dest_address); + + /* initialize alarm signal handling */ + signal(SIGALRM,socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm(socket_timeout); + + /* run the command */ + fp = spopen(command_line); + if(fp==NULL){ + printf("Unable to open pipe: %s",command_line); + return STATE_UNKNOWN; + } + + current_line=0; + while(fgets(input_buffer,MAX_INPUT_BUFFER-1,fp)){ + + current_line++; + + /* skip the first line of the output */ + if(current_line==1) + continue; + + /* we didn't get the "is alive" */ + if(current_line==2 && !strstr(input_buffer,"is alive")) + result=STATE_CRITICAL; + + /* get the round trip time */ + if(current_line==3){ + substr=strtok(input_buffer,":"); + substr=strtok(NULL,"\n"); + rtt=atoi(substr); + } + + /* get the number of bytes returned */ + if(current_line==4 && strstr(input_buffer,"bytes returned")){ + bytes_returned=atoi(input_buffer); + } + } + + /* close the pipe */ + spclose(fp); + + /* reset the alarm */ + alarm(0); + + if(current_line==1 || result==STATE_CRITICAL) + printf("IPX Ping problem - No response from host\n"); + else{ + + if(rtt>crtt) + result=STATE_CRITICAL; + else if(rtt>wrtt) + result=STATE_WARNING; + + printf("IPX Ping %s - RTT = %d ms, %d bytes returned from %s %s\n",(result==STATE_OK)?"ok":"problem",rtt,bytes_returned,dest_network,dest_address); + } + + + return result; + } + + + +/* process all arguments passed on the command line */ +int process_arguments(int argc, char **argv){ + int x; + + /* no options were supplied */ + if(argc<5) + return ERROR; + + /* get the destination network address */ + strncpy(dest_network,argv[1],sizeof(dest_network)-1); + dest_network[sizeof(dest_network)-1]='\x0'; + + /* get the destination host address */ + strncpy(dest_address,argv[2],sizeof(dest_address)-1); + dest_address[sizeof(dest_address)-1]='\x0'; + + /* get the round trip time variables */ + wrtt=atoi(argv[3]); + crtt=atoi(argv[4]); + + /* process remaining arguments */ + for(x=6;x<=argc;x++){ + + /* we got the timeout to use */ + if(!strcmp(argv[x-1],"-to")){ + if(x