aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/aix/check_crit_dsk66
-rw-r--r--contrib/aix/check_dsk62
-rw-r--r--contrib/aix/check_failed48
-rw-r--r--contrib/aix/check_io69
-rw-r--r--contrib/aix/check_kerberos49
-rw-r--r--contrib/aix/check_ping117
-rw-r--r--contrib/aix/check_queue67
-rw-r--r--contrib/aix/pg_stat45
-rw-r--r--contrib/check_apache.pl283
-rw-r--r--contrib/check_apc_ups.pl314
-rw-r--r--contrib/check_bgpstate.pl215
-rw-r--r--contrib/check_dhcp.c992
-rwxr-xr-xcontrib/check_dlswcircuit.pl221
-rw-r--r--contrib/check_dns_random.pl75
-rw-r--r--contrib/check_email_loop.pl268
-rw-r--r--contrib/check_fping_in.c430
-rwxr-xr-xcontrib/check_ftpget.pl48
-rw-r--r--contrib/check_ifoperstatus.pl145
-rw-r--r--contrib/check_ifstatus.pl178
-rw-r--r--contrib/check_ipxping.c200
-rwxr-xr-xcontrib/check_joy.sh69
-rw-r--r--contrib/check_maxchannels.pl231
-rw-r--r--contrib/check_maxwanstate.pl201
-rw-r--r--contrib/check_mem.pl146
-rw-r--r--contrib/check_memory.tgzbin0 -> 5813 bytes
-rw-r--r--contrib/check_mysql.c75
-rw-r--r--contrib/check_mysql.pl73
-rw-r--r--contrib/check_nagios.pl48
-rwxr-xr-xcontrib/check_netapp.pl178
-rw-r--r--contrib/check_nmap.py440
-rw-r--r--contrib/check_nwstat.pl188
-rw-r--r--contrib/check_ora_table_space.pl82
-rw-r--r--contrib/check_pop3.pl144
-rwxr-xr-xcontrib/check_qmailq.pl121
-rw-r--r--contrib/check_rrd_data.pl129
-rwxr-xr-xcontrib/check_sap.sh70
-rw-r--r--contrib/check_sockets.pl145
-rw-r--r--contrib/check_timeout.c55
-rw-r--r--contrib/check_uptime.c99
-rw-r--r--contrib/checkciscotemp.pl163
-rw-r--r--contrib/maser-oracle.pl13
-rw-r--r--contrib/mrtgext.pl291
-rw-r--r--contrib/readme.txt147
-rwxr-xr-xcontrib/restrict.pl26
-rw-r--r--contrib/tarballs/berger-ping.tar.gzbin0 -> 2411 bytes
-rw-r--r--contrib/tarballs/bowen-langley_plugins.tar.gzbin0 -> 28728 bytes
-rw-r--r--contrib/tarballs/check_bgp-1.0.tar.gzbin0 -> 1444 bytes
-rw-r--r--contrib/tarballs/check_breeze.tar.gzbin0 -> 358 bytes
-rw-r--r--contrib/tarballs/check_flexlm.tar.gzbin0 -> 1169 bytes
-rw-r--r--contrib/tarballs/check_hltherm.tar.gzbin0 -> 2087 bytes
-rw-r--r--contrib/tarballs/check_hprsc.tar.gzbin0 -> 1942 bytes
-rw-r--r--contrib/tarballs/check_radius.tar.gzbin0 -> 25173 bytes
-rw-r--r--contrib/tarballs/check_wave.tar.gzbin0 -> 591 bytes
-rw-r--r--contrib/tarballs/hopcroft-plugins.tar.gzbin0 -> 3657 bytes
-rw-r--r--contrib/tarballs/radius.tar.gzbin0 -> 1913 bytes
-rw-r--r--contrib/urlize.pl16
-rw-r--r--contrib/utils.py310
57 files changed, 7352 insertions, 0 deletions
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 <Server Name>\n";
+ exit (-1);
+ } else {
+ open (DATE, "/bin/date '+%b %d' |");
+ while (<DATE>) {
+ $dline = $_;
+ @dresults = $dline;
+ chop $dresults[0];
+ }
+ open (SULOG, "rsh $server -l root who /etc/security/failedlogin | grep root |");
+ while (<SULOG>) {
+ $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 (<PING>) {
+ $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 <crit> and <warn>
+# 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 <host> [<warn> [<crit>]\n";
+ print "#================================================\n";
+ print "\n";
+ print "<warn> = Ping in MS at which a warning message will be generated.\n Defaults to 750.\n";
+ print "<crit> = 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 <S.Hetze@Linux-AG.com>
+#
+# 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 <host> [-lhV] [-w <warn>] [-c <crit>] [-u <url>]
+#
+# check_apache <host> <warn> <crit> <url> (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 /<tr>/m, $res->content) {
+ ($empty,$Srv,$PID,$Acc,$M,$CPU,$SS,$Req,$Conn,$Child,$Slot,$Client,$VHost,$Request)
+ = split /<td>/, $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 <host> [-lhV] [-w <warn>] [-c <crit>] [-u <url>]\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 <host> -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 <READCOMMUNITY> -p <PORT> <HOSTNAME>\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<BR>",
+ $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<BR>",
+ $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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <features.h>
+#include <linux/if_ether.h>
+#include <getopt.h>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#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(&current_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<ETHERNET_HARDWARE_ADDRESS_LENGTH;x++){
+#ifdef DEBUG
+ printf("%02X",(unsigned char)offer_packet.chaddr[x]);
+#endif
+ if(offer_packet.chaddr[x]!=client_hardware_address[x]){
+ result=ERROR;
+ }
+ }
+#ifdef DEBUG
+ printf("\n");
+#endif
+ if(result==ERROR){
+#ifdef DEBUG
+ printf("DHCPOFFER hardware address did not match our own - ignoring packet\n");
+#endif
+ continue;
+ }
+
+#ifdef DEBUG
+ printf("DHCPOFFER ciaddr: %s\n",inet_ntoa(offer_packet.ciaddr));
+ printf("DHCPOFFER yiaddr: %s\n",inet_ntoa(offer_packet.yiaddr));
+ printf("DHCPOFFER siaddr: %s\n",inet_ntoa(offer_packet.siaddr));
+ printf("DHCPOFFER giaddr: %s\n",inet_ntoa(offer_packet.giaddr));
+#endif
+
+ add_dhcp_offer(source.sin_addr,&offer_packet);
+
+ valid_responses++;
+ }
+
+#ifdef DEBUG
+ printf("Total responses seen on the wire: %d\n",responses);
+ printf("Valid responses for this machine: %d\n",valid_responses);
+#endif
+
+ return OK;
+ }
+
+
+
+/* sends a DHCP packet */
+int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in *dest){
+ struct sockaddr_in myname;
+ int result;
+
+ result=sendto(sock,(char *)buffer,buffer_size,0,(struct sockaddr_in *)dest,sizeof(*dest));
+
+#ifdef DEBUG
+ printf("send_dhcp_packet result: %d\n",result);
+#endif
+
+ if(result<0)
+ return ERROR;
+
+ return OK;
+ }
+
+
+
+/* receives a DHCP packet */
+int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, struct sockaddr_in *address){
+ struct timeval tv;
+ fd_set readfds;
+ int recv_result;
+ socklen_t address_size;
+ struct sockaddr_in source_address;
+
+
+ /* wait for data to arrive (up time timeout) */
+ tv.tv_sec=timeout;
+ tv.tv_usec=0;
+ FD_ZERO(&readfds);
+ FD_SET(sock,&readfds);
+ select(sock+1,&readfds,NULL,NULL,&tv);
+
+ /* make sure some data has arrived */
+ if(!FD_ISSET(sock,&readfds)){
+#ifdef DEBUG
+ printf("No (more) data recieved\n");
+#endif
+ return ERROR;
+ }
+
+ else{
+
+ /* why do we need to peek first? i don't know, its a hack. without it, the source address of the first packet received was
+ not being interpreted correctly. sigh... */
+ bzero(&source_address,sizeof(source_address));
+ recv_result=recvfrom(sock,(char *)buffer,buffer_size,MSG_PEEK,(struct sockaddr_in *)&source_address,&address_size);
+#ifdef DEBUG
+ printf("recv_result_1: %d\n",recv_result);
+#endif
+ recv_result=recvfrom(sock,(char *)buffer,buffer_size,0,(struct sockaddr_in *)&source_address,&address_size);
+#ifdef DEBUG
+ printf("recv_result_2: %d\n",recv_result);
+#endif
+
+ if(recv_result==-1){
+#ifdef DEBUG
+ printf("recvfrom() failed, ");
+ printf("errno: (%d) -> %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;x<MAX_DHCP_OPTIONS_LENGTH;){
+
+ /* end of options (0 is really just a pad, but bail out anyway) */
+ if((int)offer_packet->options[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;y<option_length;y++,x++);
+ }
+
+#ifdef DEBUG
+ if(dhcp_lease_time==DHCP_INFINITE_TIME)
+ printf("Lease Time: Infinite\n");
+ else
+ printf("Lease Time: %lu seconds\n",(unsigned long)dhcp_lease_time);
+ if(dhcp_renewal_time==DHCP_INFINITE_TIME)
+ printf("Renewal Time: Infinite\n");
+ else
+ printf("Renewal Time: %lu seconds\n",(unsigned long)dhcp_renewal_time);
+ if(dhcp_rebinding_time==DHCP_INFINITE_TIME)
+ printf("Rebinding Time: Infinite\n");
+ printf("Rebinding Time: %lu seconds\n",(unsigned long)dhcp_rebinding_time);
+#endif
+
+ new_offer=(dhcp_offer *)malloc(sizeof(dhcp_offer));
+
+ if(new_offer==NULL)
+ return ERROR;
+
+
+ new_offer->server_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_responses<requested_servers)
+ result=STATE_WARNING;
+ else if(request_specific_address==TRUE && received_requested_address==FALSE)
+ result=STATE_WARNING;
+
+
+ printf("DHCP %s: ",(result==STATE_OK)?"ok":"problem");
+
+ /* we didn't receive any DHCPOFFERs */
+ if(dhcp_offer_list==NULL){
+ printf("No DHCPOFFERs were received.\n");
+ return result;
+ }
+
+ printf("Received %d DHCPOFFER(s)",valid_responses);
+
+ if(requested_servers>0)
+ printf(", %s%d of %d requested servers responded",((requested_responses<requested_servers) && requested_responses>0)?"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])))<argc){
+
+ /*
+ if(is_option(argv[c]))
+ continue;
+ */
+ }
+
+ return validate_arguments();
+ }
+
+
+
+int call_getopt(int argc, char **argv){
+ int c=0;
+ int i=0;
+ struct in_addr ipaddress;
+
+#ifdef HAVE_GETOPT_H
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ {"serverip", required_argument,0,'s'},
+ {"requestedip", required_argument,0,'r'},
+ {"timeout", required_argument,0,'t'},
+ {"interface", required_argument,0,'i'},
+ {"verbose", no_argument, 0,'v'},
+ {"version", no_argument, 0,'V'},
+ {"help", no_argument, 0,'h'},
+ {0,0,0,0}
+ };
+#endif
+
+ while(1){
+#ifdef HAVE_GETOPT_H
+ c=getopt_long(argc,argv,"+hVvt:s:r:t:i:",long_options,&option_index);
+#else
+ c=getopt(argc,argv,"+?hVvt:s:r:t:i:");
+#endif
+
+ i++;
+
+ if(c==-1||c==EOF||c==1)
+ break;
+
+ switch(c){
+ case 'w':
+ case 'r':
+ case 't':
+ case 'i':
+ i++;
+ break;
+ default:
+ break;
+ }
+
+ switch(c){
+
+ case 's': /* DHCP server address */
+ if(inet_aton(optarg,&ipaddress))
+ add_requested_server(ipaddress);
+ /*
+ else
+ usage("Invalid server IP address\n");
+ */
+ break;
+
+ case 'r': /* address we are requested from DHCP servers */
+ if(inet_aton(optarg,&ipaddress)){
+ requested_address=ipaddress;
+ request_specific_address=TRUE;
+ }
+ /*
+ else
+ usage("Invalid requested IP address\n");
+ */
+ break;
+
+ case 't': /* timeout */
+
+ /*
+ if(is_intnonneg(optarg))
+ */
+ if(atoi(optarg)>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 <SourceMac> -d <DestMac> -c <READCOMMUNITY> -p <PORT> <HOSTNAME or IP-Addr>
+# -
+# 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 <SourceMac> -d <DestMac> -c <READCOMMUNITY> -p <PORT> <HOSTNAME>";
+ 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 (<DOMAIN>) {
+ $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 <host>\n";
+ print "\n";
+ print "<host> = 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 = <STATF>;
+ 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 <host_address> <host_address> [<host_address>] ...\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 <IF_KEY> -c <READCOMMUNITY> -p <PORT> <HOSTNAME>";
+ 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 <READCOMMUNITY> -p <PORT> <HOSTNAME>\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<BR>",
+ $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<BR>",
+ $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 <dest_network> <dest_address> <wrtt> <crtt>
+ *
+ * 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 <wrtt> level, a STATE_WARNING is
+ * returned. If it exceeds the <crtt> 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 <dest_network> <dest_address> <wrtt> <crtt> [-to to_sec]\n",argv[0]);
+ printf("\n");
+ printf("Options:\n");
+ printf(" <dest_network> = IPX network that the remote host lies on. (Hex Format - 00:00:00:00)\n");
+ printf(" <dest_address> = MAC address of the remote host. (Hex Format - 00:00:00:00:00:00)\n");
+ printf(" <wrtt> = Round trip time in milliseconds necessary to result in a WARNING state\n");
+ printf(" <crtt> = 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<argc){
+ socket_timeout=atoi(argv[x]);
+ if(socket_timeout<=0)
+ return ERROR;
+ x++;
+ }
+ else
+ return ERROR;
+ }
+
+ /* else we got something else... */
+ else
+ return ERROR;
+ }
+
+ return OK;
+ }
+
+
+
+
diff --git a/contrib/check_joy.sh b/contrib/check_joy.sh
new file mode 100755
index 00000000..cd076db9
--- /dev/null
+++ b/contrib/check_joy.sh
@@ -0,0 +1,69 @@
+#! /bin/sh
+
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
+
+PROGNAME=`basename $0`
+PROGPATH=`echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,'`
+REVISION=`echo '$Revision$' | sed -e 's/[^0-9.]//g'`
+STATUS=""
+
+. $PROGPATH/utils.sh
+
+
+print_usage() {
+ echo "Usage: $PROGNAME /dev/js<#> <button #>"
+}
+
+print_help() {
+ print_revision $PROGNAME $REVISION
+ echo ""
+ print_usage
+ echo ""
+ echo "This plugin checks a joystick button status using the "
+ echo "joyreadbutton utility from the joyd package."
+ echo ""
+ support
+ exit 0
+}
+
+if [ $# -ne 2 ]; then
+ print_usage
+ exit 0
+fi
+
+case "$1" in
+ --help)
+ print_help
+ exit 0
+ ;;
+ -h)
+ print_help
+ exit 0
+ ;;
+ --version)
+ print_revision $PROGNAME $REVISION
+ exit 0
+ ;;
+ -V)
+ print_revision $PROGNAME $REVISION
+ exit 0
+ ;;
+ /dev/js*)
+ joyreadbutton $1 $2 1>&1 1>/dev/null
+ STATUS=$?
+ if [ "$STATUS" -eq 0 ]; then
+ echo OK
+ exit 0
+ elif [ "$STATUS" -eq 1 ];then
+ echo CRITICAL
+ exit 2
+ else
+ echo UNKNOWN
+ exit -1
+ fi
+ ;;
+ *)
+ print_usage
+ exit 0
+ ;;
+esac
diff --git a/contrib/check_maxchannels.pl b/contrib/check_maxchannels.pl
new file mode 100644
index 00000000..a3ce525b
--- /dev/null
+++ b/contrib/check_maxchannels.pl
@@ -0,0 +1,231 @@
+#!/usr/bin/perl -w
+#
+# check_maxchannels.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 $state = "UNKNOWN";
+my $answer = "";
+my $snmpkey;
+my $snmpoid;
+my $key;
+my $community = "public";
+my $port = 161;
+my @snmpoids;
+# free channels
+my $snmpWanAvailableChannels = '1.3.6.1.4.1.529.4.23.0';
+# maximum channels
+my $snmpWanSwitchedChannels = '1.3.6.1.4.1.529.4.24.0';
+my $snmpWanDisabledChannels = '1.3.6.1.4.1.529.4.25.0';
+my $snmpWanActiveChannels = '1.3.6.1.4.1.529.4.26.0';
+my $snmpWanNailedChannels = '1.3.6.1.4.1.529.4.27.0';
+my $snmpWanOutOfServiceChannels = '1.3.6.1.4.1.529.4.28.0';
+my $snmpEventCurrentActiveSessions = '1.3.6.1.4.1.529.10.6.0';
+# since startup
+my $snmpEventTotalNoModems = '1.3.6.1.4.1.529.10.15.0';
+# lan modem
+my $snmpDeadLanModem = '1.3.6.1.4.1.529.15.7.0';
+my $snmpDisabledLanModem = '1.3.6.1.4.1.529.15.5.0';
+my $snmpSuspectLanModem = '1.3.6.1.4.1.529.15.3.0';
+my $snmpAvailLanModem = '1.3.6.1.4.1.529.15.1.0';
+my $snmpBusyLanModem = '1.3.6.1.4.1.529.15.9.0';
+# max modems
+my $snmpMdmNumber = '1.3.6.1.2.1.38.1.1.0';
+my $hostname;
+my $session;
+my $error;
+my $response;
+my %wanStatus;
+
+
+my $WanAvailableChannels;
+my $WanSwitchedChannels;
+my $WanDisabledChannels;
+my $WanActiveChannels;
+my $WanNailedChannels;
+my $WanOutOfServiceChannels;
+my $EventCurrentActiveSessions;
+my $EventTotalNoModems;
+my $DeadLanModem;
+my $DisabledLanModem;
+my $SuspectLanModem;
+my $AvailLanModem;
+my $BusyLanModem;
+my $MdmNumber;
+
+
+sub usage {
+ printf "\nMissing arguments!\n";
+ printf "\n";
+ printf "Perl Check maxchannels plugin for Nagios\n";
+ printf "monitors ISDN lines and modems on Ascend MAX 2000/4000/6000/TNT\n";
+ printf "usage: \n";
+ printf "check_maxchannel.pl -c <READCOMMUNITY> -p <PORT> <HOSTNAME>\n";
+ printf "Copyright (C) 2000 Christoph Kron\n";
+ printf "check_maxchannels.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,$snmpWanAvailableChannels);
+push(@snmpoids,$snmpWanSwitchedChannels);
+push(@snmpoids,$snmpWanDisabledChannels);
+push(@snmpoids,$snmpWanActiveChannels);
+push(@snmpoids,$snmpWanNailedChannels);
+push(@snmpoids,$snmpWanOutOfServiceChannels);
+
+push(@snmpoids,$snmpEventCurrentActiveSessions);
+
+push(@snmpoids,$snmpEventTotalNoModems);
+push(@snmpoids,$snmpDeadLanModem);
+push(@snmpoids,$snmpDisabledLanModem);
+push(@snmpoids,$snmpSuspectLanModem);
+push(@snmpoids,$snmpAvailLanModem);
+push(@snmpoids,$snmpBusyLanModem);
+push(@snmpoids,$snmpMdmNumber);
+
+ ($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_request(@snmpoids))) {
+ $answer=$session->error;
+ $session->close;
+ $state = 'CRITICAL';
+ print ("$state: $answer,$community");
+ exit $ERRORS{$state};
+ }
+
+
+$WanAvailableChannels = $response->{$snmpWanAvailableChannels};
+$WanSwitchedChannels = $response->{$snmpWanSwitchedChannels};
+$WanDisabledChannels = $response->{$snmpWanDisabledChannels};
+$WanActiveChannels = $response->{$snmpWanActiveChannels};
+$WanNailedChannels = $response->{$snmpWanNailedChannels};
+$WanOutOfServiceChannels = $response->{$snmpWanOutOfServiceChannels};
+$EventCurrentActiveSessions = $response->{$snmpEventCurrentActiveSessions};
+$EventTotalNoModems = $response->{$snmpEventTotalNoModems};
+$DeadLanModem = $response->{$snmpDeadLanModem};
+$DisabledLanModem = $response->{$snmpDisabledLanModem};
+$SuspectLanModem = $response->{$snmpSuspectLanModem};
+$AvailLanModem = $response->{$snmpAvailLanModem};
+$BusyLanModem = $response->{$snmpBusyLanModem};
+$MdmNumber = $response->{$snmpMdmNumber};
+
+# less than 50% -> WARNING
+if ( 0 < $WanOutOfServiceChannels
+ && $WanOutOfServiceChannels < ($snmpWanSwitchedChannels * 0.5) ) {
+ $state = 'WARNING';
+}
+elsif ($WanOutOfServiceChannels > 0) {
+ $state = 'CRITICAL';
+}
+elsif ($DeadLanModem > 0) {
+ $state = 'CRITICAL';
+}
+elsif ($SuspectLanModem > 0) {
+ $state = 'WARNING';
+}
+elsif ($AvailLanModem == 0) {
+ $state = 'WARNING';
+}
+else {
+ $state = 'OK';
+}
+
+
+$answer = sprintf("active sessions: %d (%d), active modems: %d (%d)<BR>",
+ $EventCurrentActiveSessions,
+ $WanSwitchedChannels,
+ $BusyLanModem,
+ $MdmNumber);
+
+$answer .= sprintf("channels available: %d, disabled: %d",
+ $WanAvailableChannels,
+ $WanDisabledChannels);
+
+$answer .= sprintf(", out of service: %d, nailed: %d<BR>",
+ $WanOutOfServiceChannels,
+ $WanNailedChannels);
+
+$answer .= sprintf("modems avail.: %d, disabled: %d, suspect: %d, dead: %d<BR>",
+ $AvailLanModem,
+ $DisabledLanModem,
+ $SuspectLanModem,
+ $DeadLanModem);
+
+$answer .= sprintf("unserviced modem calls: %d (since startup)\n",
+ $EventTotalNoModems);
+
+$session->close;
+
+print ("$state: $answer");
+exit $ERRORS{$state};
+
diff --git a/contrib/check_maxwanstate.pl b/contrib/check_maxwanstate.pl
new file mode 100644
index 00000000..4fbb9da2
--- /dev/null
+++ b/contrib/check_maxwanstate.pl
@@ -0,0 +1,201 @@
+#!/usr/bin/perl -w
+#
+# check_maxwanstate.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 %wanLineState = (
+ 1,'ls-unknown',
+ 2,'ls-does-not-exist',
+ 3,'ls-disabled',
+ 4,'ls-no-physical',
+ 5,'ls-no-logical',
+ 6,'ls-point-to-point',
+ 7,'ls-multipoint-1',
+ 8,'ls-multipoint-2',
+ 9,'ls-loss-of-sync',
+ 10,'ls-yellow-alarm',
+ 11,'ls-ais-receive',
+ 12,'ls-no-d-channel',
+ 13,'ls-active',
+ 14,'ls-maintenance');
+
+my %wanLineType = (
+ '1.3.6.1.4.1.529.4.1','Any',
+ '1.3.6.1.4.1.529.4.2','T1',
+ '1.3.6.1.4.1.529.4.3','E1',
+ '1.3.6.1.4.1.529.4.4','Dpnss',
+ '1.3.6.1.4.1.529.4.5','Bri',
+ '1.3.6.1.4.1.529.4.6','S562',
+ '1.3.6.1.4.1.529.4.7','S564',
+ '1.3.6.1.4.1.529.4.8','Sdsl',
+ '1.3.6.1.4.1.529.4.9','AdslCap');
+
+my $state = "UNKNOWN";
+my $answer = "";
+my $snmpkey;
+my $snmpoid;
+my $key;
+my $community = "public";
+my $port = 161;
+my @snmpoids;
+my $snmpWanLineName = '1.3.6.1.4.1.529.4.21.1.2';
+my $snmpWanLineType = '1.3.6.1.4.1.529.4.21.1.3';
+my $snmpWanLineState = '1.3.6.1.4.1.529.4.21.1.5';
+my $snmpWanLineUsage = '1.3.6.1.4.1.529.4.21.1.8';
+
+my $hostname;
+my $session;
+my $error;
+my $response;
+my %wanStatus;
+my $ifup =0 ;
+my $ifdown =0;
+my $ifdormant = 0;
+my $ifmessage;
+
+sub usage {
+ printf "\nMissing arguments!\n";
+ printf "\n";
+ printf "Perl Check maxwanstate plugin for Nagios\n";
+ printf "monitors E1/T1 interface status\n";
+ printf "usage: \n";
+ printf "check_maxwanstate.pl -c <READCOMMUNITY> -p <PORT> <HOSTNAME>";
+ printf "Copyright (C) 2000 Christoph Kron\n";
+ printf "check_maxwanstate.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,$snmpWanLineUsage);
+push(@snmpoids,$snmpWanLineState);
+push(@snmpoids,$snmpWanLineName);
+push(@snmpoids,$snmpWanLineType);
+
+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;
+ $wanStatus{$key}{$snmpoid} = $response->{$snmpkey};
+ }
+ $session->close;
+}
+
+ foreach $key (keys %wanStatus) {
+ # look only at active Interfaces lu-trunk(5)
+ if ($wanStatus{$key}{$snmpWanLineUsage} == 5 ) {
+
+ # 13 -> active
+ if ($wanStatus{$key}{$snmpWanLineState} == 13 ) {
+ $ifup++;
+ }
+ else {
+ $ifdown++ ;
+ $ifmessage .= sprintf("%s interface status : %s (%s)<BR>",
+ $wanLineType{$wanStatus{$key}{$snmpWanLineType}},
+ $wanLineState{$wanStatus{$key}{$snmpWanLineState}},
+ $wanStatus{$key}{$snmpWanLineName});
+
+ }
+ }
+ }
+
+
+ if ($ifdown > 0) {
+ $state = 'CRITICAL';
+ $answer = sprintf("host '%s', interfaces up: %d, down: %d<BR>",
+ $hostname,
+ $ifup,
+ $ifdown);
+ $answer = $answer . $ifmessage . "\n";
+ }
+ else {
+ $state = 'OK';
+ $answer = sprintf("host '%s', interfaces up: %d, down: %d\n",
+ $hostname,
+ $ifup,
+ $ifdown);
+ }
+
+print ("$state: $answer");
+exit $ERRORS{$state};
+
diff --git a/contrib/check_mem.pl b/contrib/check_mem.pl
new file mode 100644
index 00000000..f0c82129
--- /dev/null
+++ b/contrib/check_mem.pl
@@ -0,0 +1,146 @@
+#!/usr/bin/perl -w
+# $Id$
+
+# check_mem.pl Copyright (C) 2000 Dan Larsson <dl@tyfon.net>
+#
+# 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
+
+# Tell Perl what we need to use
+use strict;
+use Getopt::Std;
+
+use vars qw($opt_c $opt_f $opt_u $opt_w
+ $free_memory $used_memory $total_memory
+ $crit_level $warn_level
+ %exit_codes @memlist
+ $percent $fmt_pct
+ $verb_err $command_line);
+
+# Predefined exit codes for Nagios
+%exit_codes = ('UNKNOWN' ,-1,
+ 'OK' , 0,
+ 'WARNING' , 1,
+ 'CRITICAL', 2,);
+
+# Turn this to 1 to see reason for parameter errors (if any)
+$verb_err = 0;
+
+# This the unix command string that brings Perl the data
+$command_line = `vmstat | tail -1 | awk '{print \$4,\$5}'`;
+
+chomp $command_line;
+@memlist = split(/ /, $command_line);
+
+# Define the calculating scalars
+$used_memory = $memlist[0];
+$free_memory = $memlist[1];
+$total_memory = $used_memory + $free_memory;
+
+# Get the options
+if ($#ARGV le 0)
+{
+ &usage;
+}
+else
+{
+ getopts('c:fuw:');
+}
+
+# Shortcircuit the switches
+if (!$opt_w or $opt_w == 0 or !$opt_c or $opt_c == 0)
+{
+ print "*** You must define WARN and CRITICAL levels!" if ($verb_err);
+ &usage;
+}
+elsif (!$opt_f and !$opt_u)
+{
+ print "*** You must select to monitor either USED or FREE memory!" if ($verb_err);
+ &usage;
+}
+
+# Check if levels are sane
+if ($opt_w <= $opt_c and $opt_f)
+{
+ print "*** WARN level must not be less than CRITICAL when checking FREE memory!" if ($verb_err);
+ &usage;
+}
+elsif ($opt_w >= $opt_c and $opt_u)
+{
+ print "*** WARN level must not be greater than CRITICAL when checking USED memory!" if ($verb_err);
+ &usage;
+}
+
+$warn_level = $opt_w;
+$crit_level = $opt_c;
+
+if ($opt_f)
+{
+ $percent = $free_memory / $total_memory * 100;
+ $fmt_pct = sprintf "%.1f", $percent;
+ if ($percent <= $crit_level)
+ {
+ print "Memory CRITICAL - $fmt_pct% ($free_memory kB) free\n";
+ exit $exit_codes{'CRITICAL'};
+ }
+ elsif ($percent <= $warn_level)
+ {
+ print "Memory WARNING - $fmt_pct% ($free_memory kB) free\n";
+ exit $exit_codes{'WARNING'};
+ }
+ else
+ {
+ print "Memory OK - $fmt_pct% ($free_memory kB) free\n";
+ exit $exit_codes{'OK'};
+ }
+}
+elsif ($opt_u)
+{
+ $percent = $used_memory / $total_memory * 100;
+ $fmt_pct = sprintf "%.1f", $percent;
+ if ($percent >= $crit_level)
+ {
+ print "Memory CRITICAL - $fmt_pct% ($used_memory kB) used\n";
+ exit $exit_codes{'CRITICAL'};
+ }
+ elsif ($percent >= $warn_level)
+ {
+ print "Memory WARNING - $fmt_pct% ($used_memory kB) used\n";
+ exit $exit_codes{'WARNING'};
+ }
+ else
+ {
+ print "Memory OK - $fmt_pct% ($used_memory kB) used\n";
+ exit $exit_codes{'OK'};
+ }
+}
+
+# Show usage
+sub usage()
+{
+ print "\ncheck_mem.pl v1.0 - Nagios Plugin\n\n";
+ print "usage:\n";
+ print " check_mem.pl -<f|u> -w <warnlevel> -c <critlevel>\n\n";
+ print "options:\n";
+ print " -f Check FREE memory\n";
+ print " -u Check USED memory\n";
+ print " -w PERCENT Percent free/used when to warn\n";
+ print " -c PERCENT Percent free/used when critical\n";
+ print "\nCopyright (C) 2000 Dan Larsson <dl\@tyfon.net>\n";
+ print "check_mem.pl comes with absolutely NO WARRANTY either implied or explicit\n";
+ print "This program is licensed under the terms of the\n";
+ print "GNU General Public License (check source code for details)\n";
+ exit $exit_codes{'UNKNOWN'};
+}
diff --git a/contrib/check_memory.tgz b/contrib/check_memory.tgz
new file mode 100644
index 00000000..b0f80160
--- /dev/null
+++ b/contrib/check_memory.tgz
Binary files differ
diff --git a/contrib/check_mysql.c b/contrib/check_mysql.c
new file mode 100644
index 00000000..9abacf87
--- /dev/null
+++ b/contrib/check_mysql.c
@@ -0,0 +1,75 @@
+/*****************************************************************
+ *
+ * Program: check_mysql.c
+ * License: GPL
+ *
+ * Written by Tim Weippert
+ * (based on plugins by Ethan Galstad and MySQL example code)
+ *
+ * Command line: check_mysql <host> [user] [passwd]
+ * <host> can be the FQDN or the IP-Adress
+ * [user] and [passwd] are optional
+ *
+ * Description:
+ *
+ * This plugin attempts to connect to an MySQL Server
+ * with the optional specified parameters user and passwd.
+ * Normaly the host and a user HAVE to assigned.
+ *
+ * The plugin returns
+ * STATE_OK and the Version Number of the Server when all is fine
+ * STATE_CRITICAL if the Connection can't be esablished
+ * STATE_WARNING if the connection was established but the
+ * program can't get the Versoin Number
+ * STATE_UNKNOWN if to many parameters are given
+ *
+ * Copyright (c) 1999 by Tim Weippert
+ *
+ * Changes:
+ * 16.12.1999: Changed the return codes from numbers to statements
+ *
+ *******************************************************************/
+
+#include "../common/config.h"
+#include "../common/common.h"
+#include "mysql.h"
+
+MYSQL mysql;
+
+int main(int argc, char **argv)
+{
+ uint i = 0;
+ char *host;
+ char *user;
+ char *passwd;
+
+ char *status;
+ char *version;
+
+ if ( argc > 4 ) {
+ printf("Too many Arguments supplied - %i .\n", argc);
+ printf("Usage: %s <host> [user] [passwd]\n", argv[0]);
+ return STATE_UNKNOWN;
+ }
+
+ (host = argv[1]) || (host = NULL);
+ (user = argv[2]) || (user = NULL);
+ (passwd = argv[3]) || (passwd = NULL);
+
+ if (!(mysql_connect(&mysql,host,user,passwd))) {
+ printf("Can't connect to Mysql on Host: %s\n", host);
+ return STATE_CRITICAL;
+ }
+
+ if ( !(version = mysql_get_server_info(&mysql)) ) {
+ printf("Connect OK, but can't get Serverinfo ... something wrong !\n");
+ return STATE_WARNING;
+ }
+
+ printf("Mysql ok - Running Version: %s\n", version);
+
+ mysql_close(&mysql);
+ return STATE_OK;
+}
+
+
diff --git a/contrib/check_mysql.pl b/contrib/check_mysql.pl
new file mode 100644
index 00000000..143d5a5a
--- /dev/null
+++ b/contrib/check_mysql.pl
@@ -0,0 +1,73 @@
+#!/nyet/bin/perl
+#
+# (c)1999 Mitch Wright, NetLine Corporation
+# Read the GNU copyright stuff for all the legalese
+#
+# Check to see that our MySQL server(s) are up and running.
+# This plugin requires that mysqladmin(1) is installed on the system.
+# Since it is part of the MySQL distribution, that should be a problem.
+#
+# If no parameters are giving, a usage statement is output.
+#
+# Exit 0 on success, providing some informational output
+# Exit 2 on failure, provide what we can...
+#
+
+require 5.004;
+
+sub usage;
+
+my $TIMEOUT = 15;
+my $MYSQLADMIN = "/usr/local/bin/mysqladmin";
+
+my %ERRORS = ('UNKNOWN' , '-1',
+ 'OK' , '0',
+ 'WARNING', '1',
+ 'CRITICAL', '2');
+
+my $host = shift || &usage(%ERRORS);
+my $user = shift || &usage(%ERRORS);
+my $pass = shift || "";
+my $warn = shift || 60;
+my $crit = shift || 100;
+
+my $state = "OK";
+
+# Just in case of problems, let's not hang Nagios
+$SIG{'ALRM'} = sub {
+ print ("ERROR: No response from MySQL server (alarm)\n");
+ exit $ERRORS{"UNKNOWN"};
+};
+alarm($TIMEOUT);
+
+open (OUTPUT,
+ "$MYSQLADMIN -h $host -u $user --password=\"$pass\" version 2>&1
+ |");
+
+while (<OUTPUT>) {
+ if (/failed/) { $state="CRITICAL"; s/.*://; $status=$_; last; }
+ next if /^\s*$/;
+ if (/^Server version\s+(\d+.*)/) { $version = $1; next; }
+ if (/^Uptime:\s+(\d.*)/) { $uptime = $1; next; }
+ if (/^Threads:\s+(\d+)\s+/) { $threads = $1; next; }
+}
+
+$status = "Version $version -- $threads Threads <br>Uptime $uptime" if
+$state ne "CRITICAL";
+
+if ($threads >= $warn) { $state = "WARNING"; }
+if ($threads >= $crit) { $state = "CRITICAL"; }
+
+print $status;
+exit $ERRORS{$state};
+
+sub usage {
+ print "Required arguments not given!\n\n";
+ print "MySQL status checker plugin for Nagios, V1.01\n";
+ print "Copyright (c) 1999-2000 Mitch Wright \n\n";
+ print "Usage: check_mysql.pl <host> <user> [<pass> [<warn>
+ [<crit>]]]\n\n"; print " <pass> = password to use for <user> at
+ <host>\n"; print " <warn> = number of threads to warn us
+ about\n"; print " <crit> = number of threads to scream at us
+ about\n"; exit $ERRORS{"UNKNOWN"};
+}
diff --git a/contrib/check_nagios.pl b/contrib/check_nagios.pl
new file mode 100644
index 00000000..7d15d4db
--- /dev/null
+++ b/contrib/check_nagios.pl
@@ -0,0 +1,48 @@
+#!/usr/bin/perl
+# denao - denao@uol.com.br - Systems Engineering
+# Universo Online - http://www.uol.com.br
+use DBI;
+use Time::Local;
+
+my $t_lambuja = 5; # (expire_minutes)
+my $databasename = ""; # The name of nagios database (i.e.: nagios)
+my $table = "programstatus";
+my $where = "localhost"; # The machine where the database
+my $port = "3306";
+my $base = "DBI:mysql:$databasename:$where:$port";
+my $user = ""; # the user to connect to the database
+ # (needs permission to "select at programstatus table only"
+my $password = ""; # the password (if any)
+my %results;
+my @fields = qw( last_update );
+my $dbh = DBI->connect($base,$user,$password);
+my $fields = join(', ', @fields);
+my $query = "SELECT $fields FROM $table";
+
+my $sth = $dbh->prepare($query);
+$sth->execute();
+
+@results{@fields} = ();
+$sth->bind_columns(map { \$results{$_} } @fields);
+
+$sth->fetch();
+$sth->finish();
+$dbh->disconnect();
+
+check_update();
+
+sub check_update {
+($yea,$mon,$day,$hou,$min,$sec)=($results{last_update}=~/(\d+)\-(\d+)\-(\d+)\s(\d+)\:(\d+)\:(\d+)/);
+($sec_now, $min_now, $hou_now, $day_now, $mon_now, $yea_now) = (localtime(time))[0,1,2,3,4,5];
+$mon_now+=1; $yea_now+=1900;
+$unixdate=timelocal($sec,$min,$hou,$day,$mon,$yea);
+$unixdate_now=timelocal($sec_now,$min_now,$hou_now,$day_now,$mon_now,$yea_now);
+ if (scalar($unixdate_now - $unixdate) > scalar($t_lambuja * 60)) {
+ print "Nagios problem: nagios is down, for at least " . scalar($t_lambuja) . " minutes.\n";
+ exit(1);
+ } else {
+ print "Nagios ok: status data updated " . scalar($unixdate_now - $unixdate) . " seconds ago\n";
+ exit(0);
+ }
+}
+
diff --git a/contrib/check_netapp.pl b/contrib/check_netapp.pl
new file mode 100755
index 00000000..d556e9da
--- /dev/null
+++ b/contrib/check_netapp.pl
@@ -0,0 +1,178 @@
+#!/usr/bin/perl -wT
+# check_netapp
+#
+# Copyright (C) 2000 Leland E. Vandervort <leland@mmania.com>
+#
+# 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
+####################################
+# checks for overtemperature, fans, psu, and nfs operations/second on
+# Network Appliance Filers.
+# Returns:
+# OK if temp, fans, psu OK and Ops/Sec below warning and critical
+# Thresholds (default is warning=3500, critical=5000)
+# ** Note: See the specifications for your Filer model for
+# the thresholds !
+# Returns Warning if NFS Ops/Sec is above warning threshold
+# (default 3500, or specified by -o command line option)
+# Returns Critical if NFS Ops/Sec is above critical threshold
+# ( -m option, or default 5000), or if overtem, psufault, or
+# fanfault detected.
+#
+####################################
+# Notes on operational limits for NetApp Filers:
+# Platform Maximum Ops/Second (recommended)
+# -------------------------------------------------------------
+# F230 1000
+# F740 5500
+# F760 9000
+####################################
+
+use Net::SNMP;
+use Getopt::Long;
+&Getopt::Long::config('auto_abbrev');
+
+my $status;
+my $response = "";
+my $TIMEOUT = 10;
+my $community = "public";
+my $port = 161;
+my $opsthresh = "3500";
+my $critical = "5000";
+
+my $status_string = "";
+
+my %OIDLIST = (
+ overtemp => '1.3.6.1.4.1.789.1.2.4.1.0',
+ failedfan => '1.3.6.1.4.1.789.1.2.4.2.0',
+ failedpsu => '1.3.6.1.4.1.789.1.2.4.4.0',
+ nfsops => '1.3.6.1.4.1.789.1.2.2.1.0'
+ );
+
+
+
+my %STATUSCODE = ( 'UNKNOWN' => '-1',
+ 'OK' => '0',
+ 'WARNING' => '1',
+ 'CRITICAL' => '2');
+
+my $state = "UNKNOWN";
+
+
+$SIG{'ALRM'} = sub {
+ print "ERROR: No snmp response from $hostname (sigALRM)\n";
+ exit($STATUSCODE{"UNKNOWN"});
+};
+
+alarm($TIMEOUT);
+
+sub get_nfsops {
+ my $nfsops_start = &SNMPGET($OIDLIST{nfsops});
+ sleep(1);
+ my $nfsops_end = &SNMPGET($OIDLIST{nfsops});
+ my $nfsopspersec = $nfsops_end - $nfsops_start;
+ return($nfsopspersec);
+}
+
+
+sub show_help {
+ printf("\nPerl NetApp filer plugin for Nagios\n");
+ printf("Usage:\n");
+ printf("
+ check_netapp [options] <hostname>
+ Options:
+ -c snmp-community
+ -p snmp-port
+ -o Operations per second warning threshold
+ -m Operations per second critical threshold
+
+");
+ printf("Copyright (C)2000 Leland E. Vandervort\n");
+ printf("check_netapp comes with absolutely NO WARRANTY either implied or explicit\n");
+ printf("This program is licensed under the terms of the\n");
+ printf("GNU General Public License\n(check source code for details)\n\n\n");
+ exit($STATUSCODE{"UNKNOWN"});
+}
+
+
+$status = GetOptions( "community=s", \$community,
+ "port=i", \$port,
+ "opsthresh=i", \$opsthresh,
+ "maxops=i", \$critical );
+
+if($status == 0) {
+ &show_help;
+}
+
+sub SNMPGET {
+ $OID = shift;
+ ($session,$error) = Net::SNMP->session(
+ Hostname => $hostname,
+ Community => $community,
+ Port => $port
+ );
+ if(!defined($session)) {
+ printf("$state %s\n", $error);
+ exit($STATUSCODE{$state});
+ }
+ if(!defined($response = $session->get_request($OID))) {
+ printf("$state %s\n", $session->error());
+ $session->close();
+ exit($STATUSCODE{$state});
+ }
+ $session->close();
+ return($response->{$OID});
+}
+
+$hostname = shift || &show_help;
+
+my $tempcheck = &SNMPGET($OIDLIST{overtemp});
+if($tempcheck == 1) {
+ $state = "OK";
+ $status_string .= "Temp OK ";
+}
+else {
+ $state = "CRITICAL";
+ $status_string .= "Temp CRIT";
+}
+
+foreach $element ('failedfan','failedpsu') {
+ my $my_return = &SNMPGET($OIDLIST{$element});
+ if(($my_return =~ /no/) || ($my_return == 0)) {
+ $status_string .= "$element = $my_return ";
+ $state = "OK";
+ }
+ else {
+ $status_string .= "$element = $my_return ";
+ $state = "CRITICAL";
+ }
+}
+
+my $tmp_opssec = &get_nfsops();
+
+if ($tmp_opssec >= $critical) {
+ $state = "CRITICAL";
+}
+elsif ($tmp_opssec >= $opsthresh) {
+ $state = "WARNING";
+}
+else {
+ $state = "OK";
+}
+
+$status_string .= "Ops\/Sec = $tmp_opssec ";
+
+print "$state $status_string\n";
+exit($STATUSCODE{$state});
diff --git a/contrib/check_nmap.py b/contrib/check_nmap.py
new file mode 100644
index 00000000..4f53406d
--- /dev/null
+++ b/contrib/check_nmap.py
@@ -0,0 +1,440 @@
+#!/usr/bin/python
+# Change the above line if python is somewhere else
+
+#
+# check_nmap
+#
+# Program: nmap plugin for Nagios
+# License: GPL
+# Copyright (c) 2000 Jacob Lundqvist (jaclu@galdrion.com)
+#
+_version_ = '1.20'
+#
+#
+# Description:
+#
+# Does a nmap scan, compares open ports to those given on command-line
+# Reports warning for closed that should be open and error for
+# open that should be closed.
+# If optional ports are given, no warning is given if they are closed
+# and they are included in the list of valid ports.
+#
+# Requirements:
+# python
+# nmap
+#
+# History
+# -------
+# 1.20 2000-07-15 jaclu Updated params to correctly comply to plugin-standard
+# moved support classes to utils.py
+# 1.16 2000-07-14 jaclu made options and return codes more compatible with
+# the plugin developer-guidelines
+# 1.15 2000-07-14 jaclu added random string to temp-file name
+# 1.14 2000-07-14 jaclu added check for error from subproc
+# 1.10 2000-07-14 jaclu converted main part to class
+# 1.08 2000-07-13 jaclu better param parsing
+# 1.07 2000-07-13 jaclu changed nmap param to -P0
+# 1.06 2000-07-13 jaclu make sure tmp file is deleted on errors
+# 1.05 2000-07-12 jaclu in debug mode, show exit code
+# 1.03 2000-07-12 jaclu error handling on nmap output
+# 1.01 2000-07-12 jaclu added license
+# 1.00 2000-07-12 jaclu implemented timeout handling
+# 0.20 2000-07-10 jaclu Initial release
+
+
+import sys, os, string, whrandom
+
+import tempfile
+from getopt import getopt
+
+#
+# import generic Nagios-plugin stuff
+#
+import utils
+
+# Where temp files should be placed
+tempfile.tempdir='/usr/local/nagios/var'
+
+# Base name for tempfile
+tempfile.template='check_nmap_tmp.'
+
+# location and possibly params for nmap
+nmap_cmd='/usr/bin/nmap -P0'
+
+
+
+
+
+
+#
+# the class that does all the real work in this plugin...
+#
+#
+class CheckNmap:
+
+ # Retcodes, so we are compatible with nagios
+ #ERROR= -1
+ UNKNOWN= -1
+ OK= 0
+ WARNING= 1
+ CRITICAL= 2
+
+
+ def __init__(self,cmd_line=[]):
+ """Constructor.
+ arguments:
+ cmd_line: normaly sys.argv[1:] if called as standalone program
+ """
+ self.tmp_file=''
+ self.host='' # host to check
+ self.timeout=10
+ self.debug=0 # 1= show debug info
+ self.ports=[] # list of mandatory ports
+ self.opt_ports=[] # list of optional ports
+ self.ranges='' # port ranges for nmap
+ self.exit_code=0 # numerical exit-code
+ self.exit_msg='' # message to caller
+
+ self.ParseCmdLine(cmd_line)
+
+ def Run(self):
+ """Actually run the process.
+ This method should be called exactly once.
+ """
+
+ #
+ # Only call check_host if cmd line was accepted earlier
+ #
+ if self.exit_code==0:
+ self.CheckHost()
+
+ self.CleanUp()
+ return self.exit_code,self.exit_msg
+
+ def Version(self):
+ return 'check_nmap %s' % _version_
+
+ #-----------------------------------------
+ #
+ # class internal stuff below...
+ #
+ #-----------------------------------------
+
+ #
+ # Param checks
+ #
+ def param2int_list(self,s):
+ lst=string.split(string.replace(s,',',' '))
+ try:
+ for i in range(len(lst)):
+ lst[i]=int(lst[i])
+ except:
+ lst=[]
+ return lst
+
+ def ParseCmdLine(self,cmd_line):
+ try:
+ opt_list=getopt(cmd_line,'vH:ho:p:r:t:V',['debug','host=','help',
+ 'optional=','port=','range=','timeout','version'])
+ for opt in opt_list[0]:
+ if opt[0]=='-v' or opt[0]=='--debug':
+ self.debug=1
+ elif opt[0]=='-H' or opt[0]=='--host':
+ self.host=opt[1]
+ elif opt[0]=='-h' or opt[0]=='--help':
+ doc_help()
+ self.exit_code=1 # request termination
+ break
+ elif opt[0]=='-o' or opt[0]=='--optional':
+ self.opt_ports=self.param2int_list(opt[1])
+ elif opt[0]=='-p' or opt[0]=='--port':
+ self.ports=self.param2int_list(opt[1])
+ elif opt[0]=='-r' or opt[0]=='--range':
+ r=string.replace(opt[1],':','-')
+ self.ranges=r
+ elif opt[0]=='-t' or opt[0]=='--timeout':
+ self.timeout=opt[1]
+ elif opt[0]=='-V' or opt[0]=='--version':
+ print self.Version()
+ self.exit_code=1 # request termination
+ break
+ else:
+ self.host=''
+ break
+
+ except:
+ # unknown param
+ self.host=''
+
+ if self.debug:
+ print 'Params:'
+ print '-------'
+ print 'host = %s' % self.host
+ print 'timeout = %s' % self.timeout
+ print 'ports = %s' % self.ports
+ print 'optional ports = %s' % self.opt_ports
+ print 'ranges = %s' % self.ranges
+ print
+
+ #
+ # a option that wishes us to terminate now has been given...
+ #
+ # This way, you can test params in debug mode and see what this
+ # program recognised by suplying a version param at the end of
+ # the cmd-line
+ #
+ if self.exit_code<>0:
+ sys.exit(self.UNKNOWN)
+
+ if self.host=='':
+ doc_syntax()
+ self.exit_code=self.UNKNOWN
+ self.exit_msg='UNKNOWN: bad params, try running without any params for syntax'
+
+
+ def CheckHost(self):
+ 'Check one host using nmap.'
+ #
+ # Create a tmp file for storing nmap output
+ #
+ # The tempfile module from python 1.5.2 is stupid
+ # two processes runing at aprox the same time gets
+ # the same tempfile...
+ # For this reason I use a random suffix for the tmp-file
+ # Still not 100% safe, but reduces the risk significally
+ # I also inserted checks at various places, so that
+ # _if_ two processes in deed get the same tmp-file
+ # the only result is a normal error message to nagios
+ #
+ r=whrandom.whrandom()
+ self.tmp_file=tempfile.mktemp('.%s')%r.randint(0,100000)
+ if self.debug:
+ print 'Tmpfile is: %s'%self.tmp_file
+ #
+ # If a range is given, only run nmap on this range
+ #
+ if self.ranges<>'':
+ global nmap_cmd # needed, to avoid error on next line
+ # since we assigns to nmap_cmd :)
+ nmap_cmd='%s -p %s' %(nmap_cmd,self.ranges)
+ #
+ # Prepare a task
+ #
+ t=utils.Task('%s %s' %(nmap_cmd,self.host))
+ #
+ # Configure a time-out handler
+ #
+ th=utils.TimeoutHandler(t.Kill, time_to_live=self.timeout,
+ debug=self.debug)
+ #
+ # Fork of nmap cmd
+ #
+ t.Run(detach=0, stdout=self.tmp_file,stderr='/dev/null')
+ #
+ # Wait for completition, error or timeout
+ #
+ nmap_exit_code=t.Wait(idlefunc=th.Check, interval=1)
+ #
+ # Check for timeout
+ #
+ if th.WasTimeOut():
+ self.exit_code=self.CRITICAL
+ self.exit_msg='CRITICAL - Plugin timed out after %s seconds' % self.timeout
+ return
+ #
+ # Check for exit status of subprocess
+ # Must do this after check for timeout, since the subprocess
+ # also returns error if aborted.
+ #
+ if nmap_exit_code <> 0:
+ self.exit_code=self.UNKNOWN
+ self.exit_msg='nmap program failed with code %s' % nmap_exit_code
+ return
+ #
+ # Read output
+ #
+ try:
+ f = open(self.tmp_file, 'r')
+ output=f.readlines()
+ f.close()
+ except:
+ self.exit_code=self.UNKNOWN
+ self.exit_msg='Unable to get output from nmap'
+ return
+
+ #
+ # Store open ports in list
+ # scans for lines where first word contains '/'
+ # and stores part before '/'
+ #
+ self.active_ports=[]
+ try:
+ for l in output:
+ if len(l)<2:
+ continue
+ s=string.split(l)[0]
+ if string.find(s,'/')<1:
+ continue
+ p=string.split(s,'/')[0]
+ self.active_ports.append(int(p))
+ except:
+ # failure due to strange output...
+ pass
+
+ if self.debug:
+ print 'Ports found by nmap: ',self.active_ports
+ #
+ # Filter out optional ports, we don't check status for them...
+ #
+ try:
+ for p in self.opt_ports:
+ self.active_ports.remove(p)
+
+ if self.debug and len(self.opt_ports)>0:
+ print 'optional ports removed:',self.active_ports
+ except:
+ # under extreame loads the remove(p) above failed for me
+ # a few times, this exception hanlder handles
+ # this bug-alike situation...
+ pass
+
+ opened=self.CheckOpen()
+ closed=self.CheckClosed()
+
+ if opened <>'':
+ self.exit_code=self.CRITICAL
+ self.exit_msg='PORTS CRITICAL - Open:%s Closed:%s'%(opened,closed)
+ elif closed <>'':
+ self.exit_code=self.WARNING
+ self.exit_msg='PORTS WARNING - Closed:%s'%closed
+ else:
+ self.exit_code=self.OK
+ self.exit_msg='PORTS ok - Only defined ports open'
+
+
+ #
+ # Compares requested ports on with actually open ports
+ # returns all open that should be closed
+ #
+ def CheckOpen(self):
+ opened=''
+ for p in self.active_ports:
+ if p not in self.ports:
+ opened='%s %s' %(opened,p)
+ return opened
+
+ #
+ # Compares requested ports with actually open ports
+ # returns all ports that are should be open
+ #
+ def CheckClosed(self):
+ closed=''
+ for p in self.ports:
+ if p not in self.active_ports:
+ closed='%s %s' % (closed,p)
+ return closed
+
+
+ def CleanUp(self):
+ #
+ # If temp file exists, get rid of it
+ #
+ if self.tmp_file<>'' and os.path.isfile(self.tmp_file):
+ try:
+ os.remove(self.tmp_file)
+ except:
+ # temp-file colition, some other process already
+ # removed the same file...
+ pass
+
+ #
+ # Show numerical exits as string in debug mode
+ #
+ if self.debug:
+ print 'Exitcode:',self.exit_code,
+ if self.exit_code==self.UNKNOWN:
+ print 'UNKNOWN'
+ elif self.exit_code==self.OK:
+ print 'OK'
+ elif self.exit_code==self.WARNING:
+ print 'WARNING'
+ elif self.exit_code==self.CRITICAL:
+ print 'CRITICAL'
+ else:
+ print 'undefined'
+ #
+ # Check if invalid exit code
+ #
+ if self.exit_code<-1 or self.exit_code>2:
+ self.exit_msg=self.exit_msg+' - undefined exit code (%s)' % self.exit_code
+ self.exit_code=self.UNKNOWN
+
+
+
+
+
+#
+# Help texts
+#
+def doc_head():
+ print """
+check_nmap plugin for Nagios
+Copyright (c) 2000 Jacob Lundqvist (jaclu@galdrion.com)
+License: GPL
+Version: %s""" % _version_
+
+
+def doc_syntax():
+ print """
+Usage: check_ports [-v|--debug] [-H|--host host] [-V|--version] [-h|--help]
+ [-o|--optional port1,port2,port3 ...] [-r|--range range]
+ [-p|--port port1,port2,port3 ...] [-t|--timeout timeout]"""
+
+
+def doc_help():
+ 'Help is displayed if run without params.'
+ doc_head()
+ doc_syntax()
+ print """
+Options:
+ -h = help (this screen ;-)
+ -v = debug mode, show some extra output
+ -H host = host to check (name or IP#)
+ -o ports = optional ports that can be open (one or more),
+ no warning is given if optional port is closed
+ -p ports = ports that should be open (one or more)
+ -r range = port range to feed to nmap. Example: :1024,2049,3000:7000
+ -t timeout = timeout in seconds, default 10
+ -V = Version info
+
+This plugin attempts to verify open ports on the specified host.
+
+If all specified ports are open, OK is returned.
+If any of them are closed, WARNING is returned (except for optional ports)
+If other ports are open, CRITICAL is returned
+
+If possible, supply an IP address for the host address,
+as this will bypass the DNS lookup.
+"""
+
+
+#
+# Main
+#
+if __name__ == '__main__':
+
+ if len (sys.argv) < 2:
+ #
+ # No params given, show syntax and exit
+ #
+ doc_syntax()
+ sys.exit(-1)
+
+ nmap=CheckNmap(sys.argv[1:])
+ exit_code,exit_msg=nmap.Run()
+
+ #
+ # Give Nagios a msg and a code
+ #
+ print exit_msg
+ sys.exit(exit_code)
diff --git a/contrib/check_nwstat.pl b/contrib/check_nwstat.pl
new file mode 100644
index 00000000..2194640e
--- /dev/null
+++ b/contrib/check_nwstat.pl
@@ -0,0 +1,188 @@
+#!/usr/bin/perl
+#
+# check_nwstat.pl: Nagios plugin that uses Jim Drews' nwstat.pl for
+# MRTG instead of emulating it. For use particularly with Cliff
+# Woolley's mrtgext.pl Unix companion to Drews' MRTGEXT.NLM, where
+# mrtgext.pl can contain custom commands that check_nwstat won't recognize,
+# though this also does its best to perfectly emulate the C version
+# of check_nwstat.
+#
+
+
+######################################################################
+# Configuration
+######################################################################
+
+$nwstatcmd = "/apps/mrtg/helpers/nwstat.pl";
+
+use Getopt::Long;
+
+$::host = shift || &usage(%ERROR);
+$::opt_v = undef;
+$::opt_wv = undef;
+$::opt_cv = undef;
+$::opt_to = 10;
+$::opt_url = undef;
+
+GetOptions (qw(v=s wv=i cv=i to=i url=s)) || &usage(%ERROR);
+
+my $cmd1 = "";
+my $cmd2 = "ZERO";
+my $backward = 0;
+my $desc = "";
+my $okstr = "OK";
+my $probstr = "Problem";
+my $result = "";
+my @CMD;
+my %ERROR = ("UNKNOWN" => -1,
+ "OK" => 0,
+ "WARNING" => 1,
+ "CRITICAL" => 2);
+my $status = $ERROR{"OK"};
+
+
+######################################################################
+# Main program
+######################################################################
+
+$SIG{'ALRM'} = sub {
+ print "Connection timed out\n";
+ exit $ERROR{"CRITICAL"};
+};
+
+# translate table for compatability with
+# check_nwstat (C version)
+SWITCH: for ($::opt_v) {
+ /^LOAD(1|5|15)$/
+ && do { $desc = "Load <status> - Up <cmd2>, ".
+ "$1-min load average = <cmd0>%";
+ $cmd1 = "UTIL$1"; last; };
+ /^CONNS$/ && do { $desc = "Conns <status>: ".
+ "<cmd0> current connections";
+ $cmd1 = "CONNECT"; last; };
+ /^CDBUFF$/ && do { $desc = "Dirty cache buffers = <cmd0>";
+ $cmd1 = "S3"; last; };
+ /^LTCH$/ && do { $desc = "Long term cache hits = <cmd0>%";
+ $cmd1 = "S1";
+ $backward = 1; last; };
+ /^CBUFF$/ && do { $desc = "Total cache buffers = <cmd0>";
+ $cmd1 = "S2";
+ $backward = 1; last; };
+ /^LRUM$/ && do { $desc = "LRU sitting time = <cmd0> minutes";
+ $cmd1 = "S5";
+ $backward = 1; last; };
+ /^VPF(.*)$/ && do { $desc = "<status><int(cmd0/1024)> MB ".
+ "(<result>%) free on volume $1";
+ $okstr = ""; $probstr = "Only ";
+ $cmd1 = "VKF$1";
+ $cmd2 = "VKS$1";
+ $backward = 1; last; };
+ /^VKF/ && do { $desc = "<status><cmd0> KB free on volume $1";
+ $okstr = ""; $probstr = "Only ";
+ $cmd1 = "$::opt_v";
+ $backward = 1; last; };
+ /^$/ && die "Nothing to check!";
+ $desc = "<status>: <cmd0>";
+ $cmd1 = "$::opt_v";
+ }
+
+
+# begin timeout period, run the check
+alarm($::opt_to);
+open ( CMD, "$nwstatcmd $host $cmd1 $cmd2|" ) || die "Couldn't execute nwstat";
+@CMD = <CMD>;
+close ( CMD );
+alarm(0);
+
+for (@CMD) { chomp; }
+
+# for any variables that manipulate the results instead of
+# just using <cmd0> directly, do that manipulation here into <result>
+SWITCH: for ($::opt_v) {
+ /^VPF/ && do { $result=int(("$CMD[0]"/"$CMD[1]")*100); last; };
+ $result = "$CMD[0]";
+ }
+
+if ("$result" == -1) {
+ $status = $ERROR{"UNKNOWN"};
+ $desc = "Server returned \"variable unknown\"";
+} elsif ("$result" == -2) {
+ $status = $ERROR{"CRITICAL"};
+ $desc = "Connection failed";
+}
+
+if (defined($::opt_cv) && $status == $ERROR{"OK"}) {
+ if ($backward) {
+ ("$result" <= "$::opt_cv") && ( $status = $ERROR{"CRITICAL"} );
+ } else {
+ ("$result" >= "$::opt_cv") && ( $status = $ERROR{"CRITICAL"} );
+ }
+}
+if (defined($::opt_wv) && $status == $ERROR{"OK"}) {
+ if ($backward) {
+ ("$result" <= "$::opt_wv") && ( $status = $ERROR{"WARNING"} );
+ } else {
+ ("$result" >= "$::opt_wv") && ( $status = $ERROR{"WARNING"} );
+ }
+}
+
+$desc =~ s/<status>/($status == $ERROR{"OK"})?"$okstr":"$probstr"/eg;
+$desc =~ s/<([^>]*)cmd([0-3])([^>]*)>/eval("$1\"$CMD[$2]\"$3")/eg;
+$desc =~ s/<result>/"$result"/eg;
+
+if (defined($::opt_url)) {
+ print "<A HREF=\"$::opt_url\">$desc</A>\n";
+} else {
+ print "$desc\n";
+}
+exit $status;
+
+
+######################################################################
+# Subroutines
+######################################################################
+
+sub usage {
+
+ %ERROR = shift;
+
+ print <<EOF
+check_nwstat.pl plugin for Nagios
+by Cliff Woolley, (c) 2000
+
+Usage: ./check_nwstat.pl <host_address> [-v variable] [-wv warn_value] [-cv crit_value] [-to to_sec] [-url url_value]
+
+Options:
+ [variable] = Variable to check. Valid variables include:
+ LOAD1 = 1 minute average CPU load
+ LOAD5 = 5 minute average CPU load
+ LOAD15 = 15 minute average CPU load
+ CONNS = number of currently licensed connections
+ VPF<vol> = percent free space on volume <vol>
+ VKF<vol> = KB of free space on volume <vol>
+ LTCH = percent long term cache hits
+ CBUFF = current number of cache buffers
+ CDBUFF = current number of dirty cache buffers
+ LRUM = LRU sitting time in minutes
+ [warn_value] = Threshold for value necessary to result in a warning status
+ [crit_value] = Threshold for value necessary to result in a critical status
+ [to_sec] = Number of secs before connection times out - default is 10 sec
+ [url_value] = URL to use in output as a hyperlink. Useful to link to a page
+ with more details or history for this variable (ie an MRTG page)
+
+This plugin attempts to contact the MRTGEXT NLM running on a Novell server
+to gather the requested system information.
+
+Notes:
+ - This plugin requres that the MRTGEXT.NLM file distributed with
+ James Drews' MRTG extension for NetWare (available from
+ http://www.engr.wisc.edu/~drews/mrtg/) be loaded on the Novell
+ servers you wish to check.
+ - Critical thresholds should be lower than warning thresholds when
+ the following variables are checked: VPF, VKF, LTCH, CBUFF, and LRUM.
+EOF
+;
+
+ exit $ERROR{"UNKNOWN"};
+}
+
diff --git a/contrib/check_ora_table_space.pl b/contrib/check_ora_table_space.pl
new file mode 100644
index 00000000..24497b24
--- /dev/null
+++ b/contrib/check_ora_table_space.pl
@@ -0,0 +1,82 @@
+#!/usr/bin/perl
+#
+# Program check_ora_table_space
+# Written by: Erwan Arzur (erwan@netvalue.com)
+# License: GPL
+#
+# Last Modified: $Date$
+# Revisiin: $Revision$
+#
+# "check_ora_table_space.pl" plugin to check the state of Oracle
+# table spaces. Scarce documentation.
+#
+# you need DBD-Oracle-1.03.tar.gz and DBI-1.13.tar.gz from CPAN.org as
+# well as some Oracle client stuff to use it.
+#
+# The SQL request comes from www.dbasupport.com
+#
+
+use DBI;
+$ENV{"ORACLE_HOME"}="/intranet/apps/oracle";
+
+my $host = shift || &usage ("no host specified");
+my $sid = shift || &usage ("no sid specified");
+my $port = shift || &usage ("no port specified");
+my $dbuser = shift || &usage ("no user specified");
+my $dbpass = shift || &usage ("no password specified");
+my $tablespace = shift || &usage ("no table space specified");
+
+my $alertpct = int(shift) || &usage ("no warning state percentage specified");
+my $critpct = int(shift) || &usage ("no critical state percentage specified");
+
+my $dbh = DBI->connect( "dbi:Oracle:host=$host;port=$port;sid=$sid", $dbuser, $dbpass, { PrintError => 0, AutoCommit => 1, RaiseError => 0 } )
+ || &error ("cannot connect to $dbname: $DBI::errstr\n");
+
+#$sth = $dbh->prepare(q{SELECT tablespace_name, SUM(BYTES)/1024/1024 FreeSpace FROM dba_free_space group by tablespace_name})
+my $exit_code = -1;
+$sth = $dbh->prepare(<<EOF
+select a.TABLESPACE_NAME, a.total,nvl(b.used,0) USED,
+nvl((b.used/a.total)*100,0) PCT_USED
+from (select TABLESPACE_NAME, sum(bytes)/(1024*1024) total
+from sys.dba_data_files group by TABLESPACE_NAME) a,
+(select TABLESPACE_NAME,bytes/(1024*1024) used from sys.SM\$TS_USED) b
+where a.TABLESPACE_NAME='$tablespace' and
+ a.TABLESPACE_NAME=b.TABLESPACE_NAME(+)
+EOF
+)
+ || &error("Cannot prepare request : $DBI::errstr\n");
+$sth->execute
+ || &error("Cannot execute request : $DBI::errstr\n");
+
+while (($tbname, $total, $used, $pct_used) = $sth->fetchrow)
+{
+ $pct_used=int($pct_used);
+ print STDOUT "size: " . $total . " MB Used:" . int($used) . " MB (" . int($pct_used) . "%)\n";
+ #print "table space $answer\n";
+ if ($pct_used > $alertpct) {
+ if ($pct_used > $critpct) {
+ $exit_code = 2
+ } else {
+ $exit_code = 1;
+ }
+ } else {
+ $exit_code = 0;
+ }
+}
+
+$rc = $dbh->disconnect
+ || &error ("Cannot disconnect from database : $dbh->errstr\n");
+
+exit ($exit_code);
+
+sub usage {
+ print "@_\n" if @_;
+ print "usage : check_ora_table_space.pl <host> <sid> <port> <user> <passwd> <tablespace> <pctwarn> <pctcrit>\n";
+ exit (-1);
+}
+
+sub error {
+ print "@_\n" if @_;
+ exit (2);
+}
+
diff --git a/contrib/check_pop3.pl b/contrib/check_pop3.pl
new file mode 100644
index 00000000..c0c2712c
--- /dev/null
+++ b/contrib/check_pop3.pl
@@ -0,0 +1,144 @@
+#!/usr/bin/perl
+# ------------------------------------------------------------------------------
+# File Name: check_pop3.pl
+# Author: Richard Mayhew - South Africa
+# Date: 2000/01/21
+# Version: 1.0
+# Description: This script will check to see if an POP3 is running
+# and whether authentication can take place.
+# 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/20 RM Creation
+# 1999/09/20 TP Changed script to use strict, more secure by
+# specifying $ENV variables. The bind command is
+# still insecure through. Did most of my work
+# with perl -wT and 'use strict'
+# 2000/01/20 RM Corrected POP3 Exit State.
+# 2000/01/21 RM Fix Exit Codes Again!!
+# ------------------------------------------------------------------------------
+
+# -----------------------------------------------------------------[ Require ]--
+require 5.004;
+
+# --------------------------------------------------------------------[ Uses ]--
+use Socket;
+use strict;
+
+# --------------------------------------------------------------[ Enviroment ]--
+$ENV{PATH} = "/bin";
+$ENV{BASH_ENV} = "";
+$|=1;
+# ------------------------------------------------------------------[ Global ]--
+my $TIMEOUT = 60;
+
+# -------------------------------------------------------------------[ usage ]--
+sub usage
+{
+ print "Minimum arguments not supplied!\n";
+ print "\n";
+ print "Perl Check POP3 plugin for Nagios\n";
+ print "Copyright (c) 2000 Richard Mayhew\n";
+ print "\n";
+ print "Usage: check_pop3.pl <host> <username> <password> [port]\n";
+ print "\n";
+ print "<port> = Port that the pop3 daemon is running on <host>. Defaults to 110.\n";
+ exit -1;
+
+}
+
+# --------------------------------------------------------------[ bindRemote ]--
+sub bindRemote
+{
+ my ($in_remotehost, $in_remoteport, $in_hostname) = @_;
+ my $proto;
+ my $sockaddr;
+ my $this;
+ my $thisaddr;
+ my $that;
+ my ($name, $aliases,$type,$len,$thataddr) = gethostbyname($in_remotehost);
+
+ if (!socket(ClientSocket,AF_INET, SOCK_STREAM, $proto)) { die $!; }
+ $sockaddr = 'S n a4 x8';
+ $this = pack($sockaddr, AF_INET, 0, $thisaddr);
+ $that = pack($sockaddr, AF_INET, $in_remoteport, $thataddr);
+ if (!bind(ClientSocket, $this)) { print "Connection Refused"; exit 2; }
+ if (!connect(ClientSocket, $that)) { print "Connection Refused"; exit 2; }
+ select(ClientSocket); $| = 1; select(STDOUT);
+ return \*ClientSocket;
+}
+
+# ====================================================================[ MAIN ]==
+MAIN:
+{
+ my $hostname;
+ my $remotehost = shift || &usage;
+ my $username = shift || &usage;
+ my $password = shift || &usage;
+ my $remoteport = shift || 110;
+
+ # Just in case of problems, let's not hang Nagios
+ $SIG{'ALRM'} = sub {
+ print "Something is Taking a Long Time, Increase Your TIMEOUT (Currently Set At $TIMEOUT Seconds)\n";
+ exit -1;
+ };
+
+ alarm($TIMEOUT);
+
+ chop($hostname = `hostname`);
+ my ($name, $alias, $proto) = getprotobyname('tcp');
+ my $ClientSocket = &bindRemote($remotehost,$remoteport,$hostname);
+
+
+print ClientSocket "user $username\n";
+
+#Debug Server
+#print "user $username\n";
+
+#Sleep or 3 secs, incase server is slow.
+sleep 3;
+
+print ClientSocket "pass $password\n";
+
+#Debug Server
+#print "pass $password\n";
+
+while (<ClientSocket>) {
+
+print ClientSocket "pass $password\n";
+
+#Debug Server
+#print $_;
+
+err($_) if (m/\-ERR\s+(.*)\s+.*/);
+message($_) if (m/\+OK Mailbox open,\s+(.*\d)\s+messages.*/);
+}
+}
+
+sub message
+{
+ my $answer = "UNKNOWN";
+ $answer = "Pop3 OK - Total Messages On Server :- $1";
+ alarm(0);
+ print ClientSocket "quit\n";
+ print "$answer";
+ exit 0;
+}
+
+sub err
+{
+ my $answer = "UNKNOWN";
+ $answer = "Pop3 Error :- $1";
+ alarm(0);
+ print ClientSocket "quit\n";
+ print "$answer";
+ exit 2;
+}
+
diff --git a/contrib/check_qmailq.pl b/contrib/check_qmailq.pl
new file mode 100755
index 00000000..4c3f68ff
--- /dev/null
+++ b/contrib/check_qmailq.pl
@@ -0,0 +1,121 @@
+#!/usr/bin/perl
+#
+# check_qmailq.pl - nagios plugin
+# This plugin allows you to check the number of Mails in a qmail-
+# queue. PLUGIN NEEDS CONFIGURATION ! (see below)
+#
+# Copyright 2000 Benjamin Schmid
+#
+# 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.
+#
+#
+# Emergency E-Mail :) blueshift@gmx.net
+#
+
+### CONFIGURATION SECTION ####################
+
+my $statcommand = "/var/qmail/bin/qmail-qstat";
+my $queuewarn = 5; # Warning, if more than x mail in Queue
+my $queuecrit = 10; # Critical if "--"
+my $prewarn = 1; # Warning, if more than x unhandled mails
+ # (not in Queue
+my $precrit = 5; # Critical, if "--"
+
+### CONFIURATION SECTION END ################
+
+use strict;
+use Carp;
+
+#use Getopt::Long;
+#&Getopt::Long::config('auto_abbrev');
+
+
+
+my $TIMEOUT = 15;
+
+my %ERRORS = ('UNKNOWN' , '-1',
+ 'OK' , '0',
+ 'WARNING', '1',
+ 'CRITICAL', '2');
+
+my $state = "UNKNOWN";
+my $answer = "";
+
+#sub usage {
+# printf "\nMissing arguments!\n";
+# printf "\n";
+# printf "Printer Server Queue Nagios Plugin\n";
+# printf "monitors jobs in lpr queues\n";
+# printf "usage: \n";
+# printf "check_lpq.pl \n";
+# printf "Copyright (C) 2000 Benjamin Schmid\n";
+# printf "check_lpq.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: check_lpq.pl Time-Out $TIMEOUT s \n");
+ exit $ERRORS{"UNKNOWN"};
+};
+alarm($TIMEOUT);
+
+
+#$status = GetOptions("community=s",\$community,
+# "port=i",\$port);
+#if ($status == 0)
+#{
+# &usage;
+#}
+
+# $hostname = shift || &usage;
+
+if (! open STAT, "$statcommand|") {
+ print ("$state: $statcommand returns no result!");
+ exit $ERRORS{$state};
+}
+my @lines = <STAT>;
+close STAT;
+
+# Mails in Queues
+if ($lines[0]=~/^messages in queue: (\d+)/) {
+ my $anzq = $1;
+ $answer = $answer . "$anzq";
+ $state='WARNING' if ($anzq >= $queuewarn);
+ $state='CRITICAL' if ($anzq >= $queuecrit);
+} else {
+ $state='CRITICAL';
+ $answer="Keine gueltigte Antwort (Zeile #1) von $statcommand\n";
+}
+
+# Unverarbeite Mails
+if ($lines[1]=~/^messages in queue but not yet preprocessed: (\d+)/) {
+ my $anzp = $1;
+ $answer = $answer . " E-Mail(s) nicht ausgeliefert, $anzp unverarbeitet.";
+ $state='WARNING' if ($anzp >= $prewarn && $state eq 'UNKNOWN');
+ $state='CRITICAL' if ($anzp >= $precrit);
+} else {
+ $state='CRITICAL';
+ $answer=$answer . "Keine gueltigte Antwort (Zeile #2) von $statcommand\n";
+}
+
+$state = 'OK' if ($state eq 'UNKNOWN');
+
+print ("$state: $answer\n");
+exit $ERRORS{$state};
+
diff --git a/contrib/check_rrd_data.pl b/contrib/check_rrd_data.pl
new file mode 100644
index 00000000..0ff8750b
--- /dev/null
+++ b/contrib/check_rrd_data.pl
@@ -0,0 +1,129 @@
+#!/usr/bin/perl -wT
+
+# check_rrd_data plugin for nagios
+#
+# usage:
+# check_rrd machine_id perlexp_warn perlexp_crit perlexp_default [ds]
+#
+# Checks data from a RRD file. machine_id is normally an IP address, that has
+# to be mapped to a RRD file, by means of the config file (by default
+# /var/spool/nagios/rrd-files, a file with pairs of (machine_id,rrd_file),
+# separated by whitespace). It can be a RRD file, too.
+#
+# The Perl expressions are expressions to be evaluated in the following cases:
+#
+# - perlexp_crit. The first one, to check if there is a critical situation. If
+# it returns other than "", it will be a critical message.
+# - perlexp_warn. The second one to be evaluated. If returns other than "", a
+# warning will be issued to Nagios.
+# - perlexp_default. If both of the above return "", it will be evaluated, and
+# wathever returns this expression will be returned by the script. NOTE that
+# this is different from the other two cases, to allow the user issue a
+# warning or critical failure even if the other two don't return it.
+#
+# Use these hosts.cfg entries as examples
+#
+# command[check_ping]=$USER1$/check_rrd_data.pl $HOSTADDRESS$ \
+# 'return "CHECK_CRICKET_PING: Warning\n" if ($value > 10);' 'return \
+# "CHECK_CRICKET_PING: Critical\n" if ($value > 100);' 'printf \
+# "PING OK - RTA = %.2fms\n", $value; return 0;' 1
+# service[machine]=PING;0;24x7;3;5;1;router-admins;240;24x7;1;1;1;;check_ping
+#
+# initial version: 28 Nov 2000 by Esteban Manchado Velázquez
+# current status: 0.1
+#
+# Copyright Notice: GPL
+#
+
+# Doesn't work! Why?
+# BEGIN {
+ # my $runtimedir = substr($0,0,rindex($0,'/'));
+ # require "$runtimedir/utils.pm";
+# }
+
+require '/usr/libexec/nagios/plugins/utils.pm';
+use RRD::File;
+# use strict; # RRD:File and utils.pm don't like this
+
+my $configfilepath = "/var/spool/nagios/rrd-files"; # Change if needed
+my %hostfile; # For storing config
+my $rrdfile; # RRD file to open
+
+$ENV{'PATH'} = "/bin:/usr/bin";
+$ENV{'ENV'} = "";
+
+if (scalar @ARGV != 4 && scalar @ARGV != 5) {
+ print STDERR join "' '", @ARGV, "\n";
+ my $foo = 'check_rrd_data';
+ print STDERR $foo, " <file.rrd> <perl_exp_warn> <perl_exp_crit> <perl_exp_default> [<ds>]\n\n";
+ print STDERR "<perl_exp_*> is an expression that gets evaluated with \$_ at the current\n";
+ print STDERR "value of the data source. If it returns something other than \"\", there\n";
+ print STDERR "will be a warning or a critical failure. Else, the expression\n";
+ print STDERR "<perl_exp_default> will be evaluated\n";
+ exit;
+}
+
+# Check configuration file
+open F, $configfilepath or do {
+ print "Can't open config file $configfilepath\n";
+ return $ERRORS{'UNKNOWN'};
+};
+while (<F>) {
+ next unless /(.+)\s+(.+)/;
+ $hostfile{$1} = $2;
+}
+close F;
+
+# Default
+my $ds = defined $ARGV[4]?$ARGV[4]:0;
+ # print "\$ds = " . $ds . ":";
+ # print "\$ARGV[4] = " . $ARGV[4] . ":";
+$ds =~ s/\$//g; # Sometimes Nagios gives 1$ as the last parameter
+
+# Guess which RRD file have to be opened
+$rrdfile = $ARGV[0] if (-r $ARGV[0]); # First the parameter
+$rrdfile = $hostfile{$ARGV[0]} unless $rrdfile; # Second, the config file
+ # print "$ARGV[0]:";
+
+if (! $rrdfile) {
+ print "Can't open data file for $ARGV[0]\n"; # Aaaargh!
+ return $ERRORS{'UNKNOWN'}; # Unknown
+}
+
+ # print "Opening file $rrdfile:";
+my $rrd = new RRD::File ( -file => $rrdfile );
+$rrd->open();
+if (! $rrd->loadHeader()) {
+ print "Couldn't read header from $rrdfile\n";
+ exit $ERRORS{'UNKNOWN'}; # Unknown
+}
+my $value = $rrd->getDSCurrentValue($ds);
+$rrd->close();
+
+# Perl expressions to evaluate
+my ($perl_exp_warn, $perl_exp_crit, $perl_exp_default) =
+ ($ARGV[1], $ARGV[2], $ARGV[3]);
+my $result; # Result of the expressions (will be printed)
+my @data; # Special data reserved for the expressions, to pass data
+
+# First check for critical errors
+$perl_exp_crit =~ /(.*)/;
+$perl_exp_crit = $1;
+$result = eval $perl_exp_crit;
+if ($result) {
+ print $result;
+ exit 2; # Critical
+}
+
+# Check for warnings
+$perl_exp_warn =~ /(.*)/;
+$perl_exp_warn = $1;
+$result = eval $perl_exp_warn;
+if ($result) {
+ print $result;
+ exit 1; # Warning
+}
+
+$perl_exp_default =~ /(.*)/;
+$perl_exp_default = $1;
+eval $perl_exp_default; # Normally returns 0 (OK)
diff --git a/contrib/check_sap.sh b/contrib/check_sap.sh
new file mode 100755
index 00000000..eadf977e
--- /dev/null
+++ b/contrib/check_sap.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+################################################################################
+#
+# CHECK_SAP plugin for Nagios
+#
+# Written by Karel Salavec (karel.salavec@ct.cz)
+# Last Modified: 20Apr2000
+#
+# Command line: CHECK_SAP <typ_of_check> <param1> <param2> [<param3>]
+#
+# Description:
+# This plugin will attempt to open an SAP connection with the message
+# server or application server.
+# It need the sapinfo program installed on your server (see Notes).
+#
+# Notes:
+# - This plugin requires that the saprfc-devel-45A-1.i386.rpm (or higher)
+# package be installed on your machine. Sapinfo program
+# is a part of this package.
+# - You can find this package at SAP ftp server in
+# /general/misc/unsupported/linux
+#
+#
+# Parameters:
+# $1 - type of checking - valid values: "ms" = message server
+# "as" = application server
+# $2 - SAP server identification - can be IP address, DNS name or SAP
+# connect string (for example: /H/saprouter/S/sapdp01/H/sapserv3)
+# $3 - for $1="ms" - SAP system name (for example: DEV, TST, ... )
+# for $1="as" - SAP system number - note: central instance have sysnr=00
+# $4 - valid only for $1="ms" - logon group name - default: PUBLIC
+#
+# Example of command definitions for nagios:
+#
+# command[check_sap_ms]=/usr/local/nagios/libexec/check_sap ms $HOSTADDRESS$ $ARG1$ $ARG2$
+# command[check_sap_as]=/usr/local/nagios/libexec/check_sap as $HOSTADDRESS$ $ARG1$
+# command[check_sap_ex]=/usr/local/nagios/libexec/check_sap as $ARG1$ $ARG2$
+# (for ARG1 see SAP OOS1 transaction)
+#
+##############################################################################
+
+if [ $# -lt 3 ]; then
+echo "Need min. 3 parameters"
+exit 2
+fi
+
+case "$1"
+ in
+ ms)
+ if [ $4 ]
+ then
+ params="r3name=$3 mshost=$2 group=$4"
+ else
+ params="r3name=$3 mshost=$2"
+ fi
+ ;;
+ as)
+ params="ashost=$2 sysnr=$3"
+ ;;
+ *)
+ echo "The first parametr must be ms (message server) or as (application server)!"
+ exit 2
+ ;;
+esac
+
+if /usr/sap/rfcsdk/bin/sapinfo $params | grep -i ERROR ; then
+exit 2
+else
+exit 0
+fi
diff --git a/contrib/check_sockets.pl b/contrib/check_sockets.pl
new file mode 100644
index 00000000..b8ae24a2
--- /dev/null
+++ b/contrib/check_sockets.pl
@@ -0,0 +1,145 @@
+#! /usr/bin/perl
+# ------------------------------------------------------------------------------
+# File Name: check_sockets.pl
+# Author: Richard Mayhew - South Africa
+# Date: 2000/07/11
+# Version: 1.0
+# Description: This script will check to see how may open sockets
+# a server has and waron respectivly
+# 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 :)
+# Some code taken from Charlie Cook (check_disk.pl)
+# License GPL
+#
+# ------------------------------------------------------------------------------
+# Date Author Reason
+# ---- ------ ------
+# 1999/09/20 RM Creation
+# 1999/09/20 TP Changed script to use strict, more secure by
+# specifying $ENV variables. The bind command is
+# still insecure through. Did most of my work
+# with perl -wT and 'use strict'
+#
+# ------------------------------------------------------------------------------
+
+# -----------------------------------------------------------------[ Require ]--
+require 5.004;
+# --------------------------------------------------------------------[ Uses ]--
+use Socket;
+use strict;
+# --------------------------------------------------------------[ Enviroment ]--
+$ENV{'PATH'}='/bin:/sbin:/usr/bin:/usr/sbin';
+$ENV{BASH_ENV} = "";
+# ------------------------------------------------------------------[ Global ]--
+my $TIMEOUT = 20;
+my %ERRORS = (
+ 'UNKNOWN', '-1',
+ 'OK', '0',
+ 'WARNING', '1',
+ 'CRITICAL', '2');
+# --------------------------------------------------------------[ connection ]--
+sub connection
+{
+ my ($in_total,$in_warn,$in_crit,$in_high) = @_;
+ my $state;
+ my $answer;
+
+ $in_total =~ s/\ //g;
+ if ($in_total >= 0) {
+
+ if ($in_total > $in_crit) {
+ $state = "CRITICAL";
+ $answer = "Critical Number Of Sockets Connected : $in_total (Limit = $in_crit)\n";
+
+ } elsif ($in_total > $in_warn) {
+ $state = "WARNING";
+ $answer = "Warning Number Of Sockets Connected : $in_total (Limit = $in_warn)\n";
+
+ } else {
+ if ($in_high ne "") {
+ $answer = "Sockets OK - Current Sockets: $in_total : $in_high\n";
+ }
+ if ($in_high eq "") {
+ $answer = "Sockets OK - Current Sockets: $in_total\n";
+ }
+ $state = "OK";
+ }
+
+ } else {
+ $state = "UNKNOWN";
+ $answer = "Something is Really WRONG! Sockets Is A Negative Figure!\n";
+ }
+
+ print $answer;
+ exit $ERRORS{$state};
+}
+
+# -------------------------------------------------------------------[ usage ]--
+sub usage
+{
+ print "Minimum arguments not supplied!\n";
+ print "\n";
+ print "Perl Check Sockets plugin for Nagios\n";
+ print "Copyright (c) 2000 Richard Mayhew\n";
+ print "\n";
+ print "Usage: check_sockets.pl <type> <warn> <crit>\n";
+ print "\n";
+ print "<type> = TOTAL, TCP, UDP, RAW.\n";
+ print "<warn> = Number of sockets connected at which a warning message will be generated.[Default = 256]\n";
+ print "<crit> = Number of sockets connected at which a critical message will be generated.[Default = 512]\n";
+ exit $ERRORS{"UNKNOWN"};
+
+}
+
+# ====================================================================[ MAIN ]==
+MAIN:
+{
+ my $type = shift || &usage;
+ my $warn = shift || 256;
+ my $crit = shift || 512;
+ my $data;
+ my @data;
+ my $line;
+ my $data1;
+ my $data2;
+ my $data3;
+ my $junk;
+ my $total1;
+ my $total2;
+ $type = uc $type;
+ if ($type eq "TOTAL") {
+ $type = "sockets";
+ }
+
+ # Just in case of problems, let's not hang Nagios
+ $SIG{'ALRM'} = sub {
+ print "Somthing is Taking a Long Time, Increase Your TIMEOUT (Currently Set At $TIMEOUT Seconds)\n";
+ exit $ERRORS{"UNKNOWN"};
+ };
+
+ $data = `/bin/cat /proc/net/sockstat`;
+ @data = split("\n",$data);
+ alarm($TIMEOUT);
+ my $output = "";
+ my $high;
+
+
+ foreach $line (@data) {
+ if ($line =~ /$type/) {
+ ($data1,$data2,$data3) = split(" ",$line,3);
+
+ if ($data3 =~ /highest/){
+ ($total1,$junk,$total2) = split(" ",$data3,3);
+ $output = $total1;
+ $high = $total2;
+ }
+ else {$output = $data3;}
+ alarm(0);
+ connection($output,$warn,$crit,$high);
+ }
+ }
+}
diff --git a/contrib/check_timeout.c b/contrib/check_timeout.c
new file mode 100644
index 00000000..858bdfe9
--- /dev/null
+++ b/contrib/check_timeout.c
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ *
+ * CHECK_TIMEOUT.C
+ *
+ * Program: Plugin timeout tester for Nagios
+ * License: GPL
+ * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)
+ *
+ * Last Modified: 01-10-2000
+ *
+ * Command line: CHECK_TIMEOUT <something..>
+ *
+ * Description:
+ * This 'plugin' - if you want to call it that - doesn't do anything. It
+ * just stays in a loop forever and never exits, and is therefore useful for
+ * testing service and host check timeouts in Nagios. You must supply at
+ * least one argument on the command line in order to activate the loop.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <unistd.h>
+
+
+int main(int argc, char **argv){
+
+ if(argc==1){
+ printf("Incorrect arguments supplied\n");
+ printf("\n");
+ printf("Plugin timeout tester for Nagios\n");
+ printf("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n");
+ printf("Last Modified: 01-10-2000\n");
+ printf("License: GPL\n");
+ printf("\n");
+ printf("Usage: %s <something>\n",argv[0]);
+ printf("\n");
+ printf("Options:\n");
+ printf(" <something> = Anything at all...\n");
+ printf("\n");
+ printf("Notes:\n");
+ printf("This 'plugin' doesn't do anything. It is designed to never exit and therefore\n");
+ printf("provides an easy way of testing service and host check timeouts in Nagios.\n");
+ printf("\n");
+ return 0;
+ }
+
+ /* let's never leave here, okay? */
+ while(1)
+ sleep(1);
+
+ return 0;
+ }
+
+
+
diff --git a/contrib/check_uptime.c b/contrib/check_uptime.c
new file mode 100644
index 00000000..46a1b826
--- /dev/null
+++ b/contrib/check_uptime.c
@@ -0,0 +1,99 @@
+/******************************************************************************
+ *
+ * CHECK_UPTIME.C
+ *
+ * Program: Uptime plugin for Nagios
+ * License: GPL
+ * Copyright (c) 2000 Teresa Ramanan (teresa@redowl.org)
+ *
+ * Based on CHECK_LOAD.C
+ * Copyright (c) 1999 Felipe Gustavo de Almeida <galmeida@linux.ime.usp.br>
+ *
+ * Last Modified: $Date$
+ *
+ * Command line: CHECK_UPTIME <host_address>
+ *
+ * Description:
+ *
+ * This plugin parses the output from "uptime", tokenizing it with ',' as the
+ * delimiter. Returning only the number of days and/or the hours and minutes
+ * a machine has been up and running.
+ *
+ *****************************************************************************/
+
+#include "common/config.h"
+#include "common/common.h"
+#include "common/utils.h"
+#include "common/popen.h"
+
+int main(int argc, char **argv)
+{
+
+ int result;
+ char input_buffer[MAX_INPUT_BUFFER];
+ int ct;
+ int i;
+ char *tok1 = NULL;
+ char *daytok = NULL;
+ char *hrmintok = NULL;
+ char *runstr = NULL;
+ char tempp;
+ char ch;
+ char delim[] = ",";
+
+ if(argc != 2){
+ printf("Incorrect number of arguments supplied\n");
+ printf("\n");
+ print_revision(argv[0],"$Revision$");
+ printf("Copyright (c) 2000 Teresa Ramanan (tlr@redowl.org)\n");
+ printf("\n");
+ printf("Usage: %s <host_address>\n",argv[0]);
+ printf("\n");
+ return STATE_UNKNOWN;
+ }
+
+ child_process = spopen(PATH_TO_UPTIME);
+ if(child_process==NULL){
+ printf("Error opening %s\n",PATH_TO_UPTIME);
+ 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",PATH_TO_UPTIME);
+ }
+ fgets(input_buffer,MAX_INPUT_BUFFER-1,child_process);
+ i = 0;
+ ct = 0;
+
+ /* Let's mark the end of this string for parsing purposes */
+ input_buffer[strlen(input_buffer)-1]='\0';
+
+ tempp = input_buffer[0];
+ while(ch != '\0'){
+ ch = (&tempp)[i];
+ if (ch == ',') { ct++; }
+ i++;
+ }
+ runstr = input_buffer;
+ tok1 = strsep(&runstr, delim);
+ if (ct > 4) {
+ hrmintok = strsep(&runstr, delim);
+ hrmintok++;
+ daytok = strstr(tok1,"up");
+ }
+ else {
+ hrmintok = strstr(tok1, "up");
+ }
+
+ result = spclose(child_process);
+ if(result){
+ printf("Error code %d returned in %s\n",result,PATH_TO_UPTIME);
+ return STATE_UNKNOWN;
+ }
+ if (hrmintok == NULL) {
+ printf("Problem - unexpected data returned\n");
+ return STATE_UNKNOWN;
+ }
+ printf("%s%s%s\n",(daytok == NULL)?"":daytok,(daytok == NULL)?"":",",hrmintok);
+ return STATE_OK;
+}
diff --git a/contrib/checkciscotemp.pl b/contrib/checkciscotemp.pl
new file mode 100644
index 00000000..a702a89e
--- /dev/null
+++ b/contrib/checkciscotemp.pl
@@ -0,0 +1,163 @@
+#!/usr/bin/perl -wT
+# check_ciscotemp.pl
+#
+# Copyright (C) 2000 Leland E. Vandervort <leland@mmania.com>
+#
+# 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
+####################################
+# Nagios pluging to check inlet and outlet temperatures on
+# Cisco router platforms which support environmental monitoring
+# (7200, 7500, GSR12000...)
+####################################
+# default temperature thresholds are 30C for inlet, 40C outlet.
+# if input or output is less than thresholds, returns OK
+# if equal to (the temps don't change that rapidly) returns WARNING
+# if greater than threshold, returns CRITICAL
+# if undetermined, or cannot access environmental, returns UNKNOWN
+# (in accordance with the plugin coding guidelines)
+####################################
+
+use Net::SNMP;
+use Getopt::Long;
+&Getopt::Long::config('auto_abbrev');
+
+my $status;
+my $response = "";
+my $timeout = 10;
+my $community = "public";
+my $port = 161;
+my $INTAKE_TEMP = "1.3.6.1.4.1.9.9.13.1.3.1.3.1";
+my $OUTLET_TEMP = "1.3.6.1.4.1.9.9.13.1.3.1.3.3";
+my $in_temp;
+my $out_temp;
+my $inlet_thresh = 30;
+my $outlet_thresh = 40;
+
+my %STATUSCODE = ( 'UNKNOWN' => '-1',
+ 'OK' => '0',
+ 'WARNING' => '1',
+ 'CRITICAL' => '2');
+
+my $state = "UNKNOWN";
+
+
+$SIG{'ALRM'} = sub {
+ print "ERROR: No snmp response from $hostname (sigALRM)\n";
+ exit($STATUSCODE{"UNKNOWN"});
+};
+
+Getopt::Long::Configure('bundling');
+$status = GetOptions
+ ("community=s", \$community,
+ "C=s", \$community,
+ "H=s", \$hostname,
+ "hostname=s", \$hostname,
+ "port=i", \$port,
+ "timeout=i", \$timeout,
+ "c=s", \$critical_vals,
+ "w=s", \$warning_vals,
+ "ithresh=i", \$inlet_thresh,
+ "othresh=i", \$outlet_thresh);
+
+if($status == 0) {
+ &show_help;
+}
+
+unless (defined($hostname)) {
+ $hostname = shift || &show_help;
+}
+
+if (defined($critical_vals)) {
+ die "Cannot Parse Critical Thresholds\n"
+ unless (split(/:/,$critical_vals)>=2);
+ ($inlet_thresh,$outlet_thresh) = @_
+}
+die unless(defined($inlet_thresh) && defined($outlet_thresh));
+
+if (defined($warning_vals)) {
+ die "Cannot Parse Critical Thresholds\n"
+ unless (split(/:/,$warning_vals)>=2);
+ ($inlet_warn,$outlet_warn) = @_;
+}else{
+ $inlet_warn=$inlet_thresh;
+ $outlet_warn=$outlet_thresh;
+}
+
+alarm($timeout);
+
+$in_temp = &SNMPGET($INTAKE_TEMP);
+$out_temp = &SNMPGET($OUTLET_TEMP);
+
+if (($in_temp < $inlet_thresh) && ($out_temp < $outlet_thresh)) {
+ $state = "OK";
+}
+elsif (($in_temp == $inlet_thresh) || ($out_temp == $outlet_thresh)) {
+ if(($in_temp > $inlet_thresh) || ($out_temp > $outlet_thresh)) {
+ $state = "CRITICAL";
+ }
+ else {
+ $state = "WARNING";
+ }
+}
+elsif (($in_temp > $inlet_thresh) || ($out_temp > $outlet_thresh)) {
+ $state = "CRITICAL";
+}
+else {
+ $state = "WARNING";
+}
+
+print "$state Inlet Temp: $in_temp Outlet Temp: $out_temp\n";
+exit($STATUSCODE{$state});
+
+sub show_help {
+ printf("\nPerl envmon temperature plugin for Nagios\n");
+ printf("Usage:\n");
+ printf("
+ check_ciscotemp [options] <hostname>
+ Options:
+ -C snmp-community
+ -p snmp-port
+ -i input temperature threshold
+ -o output temperature threshold
+
+");
+ printf("Copyright (C)2000 Leland E. Vandervort\n");
+ printf("check_ciscotemp comes with absolutely NO WARRANTY either implied or explicit\n");
+ printf("This program is licensed under the terms of the\n");
+ printf("GNU General Public License\n(check source code for details)\n\n\n");
+ exit($STATUSCODE{"UNKNOWN"});
+}
+
+sub SNMPGET {
+ $OID = shift;
+ ($session,$error) = Net::SNMP->session(
+ Hostname => $hostname,
+ Community => $community,
+ Port => $port
+ );
+ if(!defined($session)) {
+ printf("$state %s\n", $error);
+ exit($STATUSCODE{$state});
+ }
+ if(!defined($response = $session->get_request($OID))) {
+ printf("$state %s\n", $session->error());
+ $session->close();
+ exit($STATUSCODE{$state});
+ }
+ $session->close();
+ return($response->{$OID});
+}
+
diff --git a/contrib/maser-oracle.pl b/contrib/maser-oracle.pl
new file mode 100644
index 00000000..aa2741f1
--- /dev/null
+++ b/contrib/maser-oracle.pl
@@ -0,0 +1,13 @@
+#!/usr/bin/perl
+
+# Oracle plugin submitted by Christopher Maser (maser@onvista.de)
+# 12/31/1999
+
+my $host=$ARGV[0];
+my @test=`tnsping $host`;
+my $arg=$test[6];
+chomp $arg;
+if ($arg =~ /^OK (.*)/)
+{print "$arg"; exit 0}
+else {exit 2;}
+
diff --git a/contrib/mrtgext.pl b/contrib/mrtgext.pl
new file mode 100644
index 00000000..b9e9f6b9
--- /dev/null
+++ b/contrib/mrtgext.pl
@@ -0,0 +1,291 @@
+#!/usr/bin/perl -w
+#
+# mrtgext.pl v0.3
+# (c)2000 Cliff Woolley, Washington and Lee University
+# jwoolley@wlu.edu
+#
+# A UNIX counterpart to Jim Drews' MRTG Extension for netware servers
+# Mimics output of mrtgext.nlm using output of various standard UNIX
+# programs (df, uptime, and uname)
+#
+# Dependencies: I make some assumptions about the output format of
+# your df and uptime commands. If you have nonstandard outputs for
+# any of these, either pick a different command that gives more
+# standard output or modify the script below. Example: use /usr/bin/bdf
+# on HP-UX instead of /usr/bin/df, because bdf follows the output format
+# I expect while df does not. This was written on Linux and tested on
+# HP-UX 10.20 (with changes to the subroutines at the bottom of the
+# program to reflect HP's command parameters); similar tweaking could
+# well be required to port this to other platforms. If you get it
+# working on your platform, please send me any changes you had to
+# make so I can try to incorporate them.
+#
+#
+# Following is what I expect the programs' outputs to look like:
+#
+# ======= df ========
+# Filesystem 1k-blocks Used Available Use% Mounted on
+# /dev/sda1 1014696 352708 609612 37% /
+# /dev/sda2 2262544 586712 1559048 27% /apps
+# /dev/sda3 4062912 566544 3286604 15% /share
+# /dev/sr0 651758 651758 0 100% /cdrom
+# ===================
+#
+# ===== uptime ======
+# 3:17pm up 15 days, 4:40, 5 users, load average: 0.12, 0.26, 0.33
+# ===================
+#
+
+###############################################################
+# Configuration section
+###############################################################
+
+$dfcmd = "/bin/df 2>/dev/null";
+$uptimecmd = "/usr/bin/uptime";
+%customcmds = ( "PROCS" => "numprocesses",
+ "ZOMBIES" => "numzombies",
+ "MEMFREE" => "memfree",
+ "SWAPUSED" => "swapused",
+ "TCPCONNS" => "tcpconns",
+ "CLIENTS" => "ipclients" );
+ # These are functions that you can
+ # define and customize for your system.
+ # You probably need to change the provided
+ # subroutines to work on your system (if
+ # not Linux).
+
+$rootfsnickname = "root"; # this is necessary as a kludge to
+ # better match the netware behavior.
+ # if you already have a _filesystem_
+ # mounted as /root, then you'll need
+ # to change this to something else
+$DEBUG = 0;
+$recvtimeout = 30;
+
+
+###############################################################
+# Program section
+###############################################################
+
+require 5.004;
+
+use Sys::Hostname;
+
+
+$DEBUG = $ARGV[0] unless ($DEBUG);
+$SIG{'ALRM'} = sub { exit 1; };
+
+# some things never change
+$hostname = hostname;
+
+
+if ( $DEBUG ) {
+ $| = 1;
+ print scalar localtime,": mrtgext.pl started\n";
+}
+
+# timeout period
+alarm($recvtimeout);
+my $items = <STDIN>;
+alarm(0);
+
+$items =~ s/[\r\n]//g;
+( $DEBUG ) && print scalar localtime,": request: \"$items\"\n";
+my @items = split (/\s+/,"$items");
+( $DEBUG ) && print scalar localtime,": ",scalar @items," item(s) to process\n";
+
+my $uptime = `$uptimecmd`;
+my @df = grep {/^\//} `$dfcmd`;
+
+my $processed = 1;
+
+foreach $_ (@items) {
+ ( $DEBUG ) && print scalar localtime,": processing item #$processed: \"$_\"\n";
+ $_ = uc; #convert $_ to upper case
+ if ( /^UTIL1$/ ) {
+ $uptime =~ /load average: ([^,]+),/;
+ print $1 * 100,"\n";
+ }
+ elsif ( /^UTIL5$/ ) {
+ $uptime =~ /load average: [^,]+, ([^,]+)/;
+ print $1 * 100,"\n";
+ }
+ elsif ( /^UTIL15$/ ) {
+ $uptime =~ /load average: [^,]+, [^,]+, ([^,]+)/;
+ print $1 * 100,"\n";
+ }
+ elsif ( /^CONNECT$/ ) {
+ $uptime =~ /(\d+) users?,/;
+ print "$1\n";
+ }
+ elsif ( /^NAME$/ ) {
+ print "$hostname\n";
+ }
+ elsif ( /^UPTIME$/ ) {
+ $uptime =~ /up (.*),\s+\d+\s+users?,/;
+ print "$1\n";
+ }
+ elsif ( /^VOLUMES$/ ) {
+ foreach $dfline (@df) {
+ my $volname = (split(/\s+/, "$dfline"))[5];
+ $volname =~ s/^\/$/$rootfsnickname/;
+ $volname =~ s/^\///;
+ $volname =~ s/\//_/g;
+ print "$volname\n";
+ }
+ }
+ elsif ( /^VF(\w*)$/ ) {
+ my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1";
+ foreach $dfline (@df) {
+ my @dfline = split(/\s+/, "$dfline");
+ if ($dfline[5] =~ /^\/?$volname$/i ) {
+ print (($dfline[1]-$dfline[2]) * 1024,"\n");
+ goto done;
+ }
+ }
+ ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n";
+ print "-1\n";
+ }
+ elsif ( /^VU(\w*)$/ ) {
+ my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1";
+ foreach $dfline (@df) {
+ my @dfline = split(/\s+/, "$dfline");
+ if ($dfline[5] =~ /^\/?$volname$/i ) {
+ print ($dfline[2] * 1024,"\n");
+ goto done;
+ }
+ }
+ ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n";
+ print "-1\n";
+ }
+ elsif ( /^VS(\w*)$/ ) {
+ my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1";
+ foreach $dfline (@df) {
+ my @dfline = split(/\s+/, "$dfline");
+ if ($dfline[5] =~ /^\/?$volname$/i ) {
+ print ($dfline[1] * 1024,"\n");
+ goto done;
+ }
+ }
+ ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n";
+ print "-1\n";
+ }
+ elsif ( /^VKF(\w*)$/ ) {
+ my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1";
+ foreach $dfline (@df) {
+ my @dfline = split(/\s+/, "$dfline");
+ if ($dfline[5] =~ /^\/?$volname$/i ) {
+ print (($dfline[1]-$dfline[2]),"\n");
+ goto done;
+ }
+ }
+ ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n";
+ print "-1\n";
+ }
+ elsif ( /^VKU(\w*)$/ ) {
+ my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1";
+ foreach $dfline (@df) {
+ my @dfline = split(/\s+/, "$dfline");
+ if ($dfline[5] =~ /^\/?$volname$/i ) {
+ print ($dfline[2],"\n");
+ goto done;
+ }
+ }
+ ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n";
+ print "-1\n";
+ }
+ elsif ( /^VKS(\w*)$/ ) {
+ my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1";
+ foreach $dfline (@df) {
+ my @dfline = split(/\s+/, "$dfline");
+ if ($dfline[5] =~ /^\/?$volname$/i ) {
+ print ($dfline[1],"\n");
+ goto done;
+ }
+ }
+ ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n";
+ print "-1\n";
+ }
+ elsif ( /^ZERO$/ ) {
+ print "0\n";
+ }
+ elsif (exists( $customcmds{"$_"} )) {
+ my $cmdsub = "$customcmds{$_}";
+ print &$cmdsub."\n";
+ }
+ else {
+ print "-1\n";
+ }
+ done: $processed++;
+}
+( $DEBUG ) && print scalar localtime,": done.\n";
+
+
+###############################################################
+# CUSTOMIZED PROCEDURES
+###############################################################
+
+sub numprocesses {
+
+ my $num = `/bin/ps -eaf | /usr/bin/tail -n +2 | /usr/bin/wc -l`;
+ chomp ($num);
+ $num =~ s/\s+//g;
+
+ $num;
+}
+
+sub numzombies {
+
+ my $num = `/bin/ps -afx | /usr/bin/awk '{print \$3}' | /usr/bin/grep Z | /usr/bin/tail -n +2 | /usr/bin/wc -l`;
+ chomp ($num);
+ $num =~ s/\s+//g;
+
+ $num;
+}
+
+sub tcpconns {
+
+ my $num = `/bin/netstat -nt | /usr/bin/tail -n +3 | /usr/bin/wc -l`;
+ chomp ($num);
+ $num =~ s/\s+//g;
+
+ $num;
+}
+
+sub ipclients {
+
+ my $num = `/bin/netstat -nt | /usr/bin/tail -n +3 | /usr/bin/awk '{print \$5}' | /bin/cut -d : -f 1 | /usr/bin/sort -nu | /usr/bin/wc -l`;
+ chomp ($num);
+ $num =~ s/\s+//g;
+
+ $num;
+}
+
+sub memfree {
+
+ open( FP, "/proc/meminfo" );
+ my @meminfo = <FP>;
+ close(FP);
+
+ # total: used: free: shared: buffers: cached:
+ # Mem: 994615296 592801792 401813504 91193344 423313408 93118464
+ # Swap: 204791808 0 204791808
+ my ($total,$free,$buffers,$cache) = (split(/ +/,$meminfo[1]))[1,3,5,6];
+
+ int(($free+$buffers+$cache)/$total*100);
+}
+
+sub swapused {
+
+ open( FP, "/proc/meminfo" );
+ my @meminfo = <FP>;
+ close(FP);
+
+ # total: used: free: shared: buffers: cached:
+ # Mem: 994615296 592424960 402190336 89821184 423313408 93077504
+ # Swap: 204791808 0 204791808
+
+ my ($total,$used) = (split(/ +/,$meminfo[2]))[1,2];
+
+ int($used/$total*100);
+}
diff --git a/contrib/readme.txt b/contrib/readme.txt
new file mode 100644
index 00000000..d9ae0250
--- /dev/null
+++ b/contrib/readme.txt
@@ -0,0 +1,147 @@
+Contrib Plugins README
+----------------------
+
+This directory contains plugins which have been contributed by various people, but that
+have not yet been incorporated into the core plugins distribution.
+
+If you have questions regarding the use of these plugins, try contacting the author(s)
+or post a message to the nagios-users mailing list (nagios-users@onelist.com)
+requesting assistance.
+
+
+Plugin Overview
+---------------
+
+berger-ping.tar.gz - Perl script version of the check_ping plugin and a corresponding
+ CGI (mtr.cgi) that uses mtr to traceroute a path to a host.
+ (Gary Berger)
+
+bowen-langley_plugins.tar.gz
+ - Several C plugins including check_inode, check_boot, etc.
+ (Adam Bown & Thomas Langley)
+
+
+check_bgpstate.tar.gz - Perl script intended for monitoring BGP sessions on Cisco routers.
+ Only useful if you are using BGP4 as a routing protocol. For
+ critical alert the AS (autonomous system) number has to be in the
+ uplinks hash (see the source code). Requires SNMP read community.
+ (Christoph Kron)
+
+check_breeze.tar.gz - Perl script to test signal strength on Breezecom wireless
+ equipment (Jeffrey Blank)
+
+check_dns_random.tar.gz - Perl script to see if dns resolves hosts randomly from a list
+ using the check_dns plugin (Richard Mayhew)
+
+check_flexlm.tar.gz - Perl script to check a flexlm licensing manager using lmtest
+ (Ernst-Dieter Martin)
+
+check_hltherm.tar.gz - C program to check the temperature on a Hot Little Therm temperature
+ probe. The HLT device, along with temperature probes, can be obtained
+ from Spiderplant at http://www.spiderplant.com
+ (Ethan Galstad)
+
+check_ifoperstatus.tar.gz
+ - Perl script that checks the operational interface status (up/down) for
+ one interface on cisco/ascend routers. Especially useful for monitoring
+ leased lines. Requires SNMP read community and SNMP interface key.
+ (Christoph Kron)
+
+check_ifstatus.tar.gz - Perl script that checks operational interface status for every interface
+ on cisco routers. Requires SNMP read community.
+ (Christoph Kron)
+
+check_ipxping.tar.gz - C program that it similiar to the check_ping plugin, except that it
+ send IPX ping packets to Novell servers or other IPX devices. This
+ requires the ipxping binary for Linux systems. It does NOT by work
+ without modification with the ipxping binary for SunOS/Solaris.
+ (Ethan Galstad)
+
+check_maxchannels.tar.gz
+ - Perl script that can only be used for monitoring Ascend/Lucent Max/TNT
+ access server. Checks ISDN channels and modem cards. Also shows ISDN and
+ modem usage. Requires SNMP read community.
+ (Christoph Kron)
+
+check_maxwanstate.tar.gz
+ - Perl script that can only be used for monitoring Ascend/Lucent Max/TNT
+ access server. Checks if every enabled E1/T1 interface is operational
+ (link active). Requires SNMP read community.
+ (Christoph Kron)
+
+check_memory.tgz - C program to check available system memory - RAM, swap, buffers,
+ and cache (Joshua Jackson)
+
+check_nfs.tar.gz - Perl script to test and NFS server using rpcinfo
+ (Ernst-Dieter Martin)
+ <NOW PART OF check_rpc IN CORE>
+
+check_ntp.tar.gz - Perl script to check an NTP time source (Bo Kernsey)
+ <MOVED TO CORE>
+
+check_ora.tar.gz - Shell script that will check an Oracle database and the TNS listener.
+ Unlike the check_oracle plugin, this plugin detects when a database is
+ down and does not create temp files (Jason Hedden)
+ <MOVED TO CORE>
+
+check_pop3.tar.gz - Perl script that checks to see if POP3 is running and whether or not
+ authentication can take place (Richard Mayhew)
+
+check_radius.tar.gz - C program to check RADIUS authentication. This is a hacked version of
+ the Cistron Radiusd program radtest that acts as a plugin for Nagios.
+ The vast majority of the code was written by someone at Livingston
+ Enterprises and Cistron. NOTE: Due to the copyright restrictions in
+ this code, it cannot be distributed under the GPL license, and thus
+ will not appear in the core plugin distribution!
+ (Adam Jacob)
+
+check_real.tar.gz - C program to check the status of a REAL media server
+ (Pedro Leite)
+ <MOVED TO CORE>
+
+check_rpc.pl.gz - Perl script to check rpc services. Will check to see if the a specified
+ program is running on the specified server (Chris Kolquist)
+
+check_sap.tar.gz - Shell script to check an SAP message or application server. Requires
+ that you install the saprfc-devel-45A-1.i386.rpm (or higher) package
+ on your system. The package can be obtained from the SAP FTP site in
+ the /general/misc/unsupported/linux directory. (Kavel Salavec)
+
+check_uptime.tar.gz - C program to check system uptime. Must be compiled with the release
+ 1.2.8 or later of the plugins. (Teresa Ramanan)
+
+check_wave.tar.gz - Perl script to test signal strength on Speedlan wireless
+ equipment (Jeffrey Blank)
+
+hopcroft-plugins.tar.gz - Various example plugin scripts contributed by Stanley Hopcroft.
+ Includes a plugin to check Internet connectivity by checking various
+ popular search engines, a plugin to check the availability of login
+ to a TN/3270 mainframe database using Expect to search for "usual"
+ screens, and another plugin to test the availability of a database
+ search via the web.
+ (Stanley Hopcroft)
+
+maser-oracle.tar.gz - This is a modification to the check_oracle plugin script that returns
+ the response time in milliseconds. Requires the Oracle tnsping utility.
+ (Christoph Maser)
+
+radius.tar.gz - Code modifications necessary to make the radexample app
+ supplied with the radiusclient code work as a RADIUS plugin
+ for Nagios (Nick Shore)
+
+vincent-check_radius.tar.gz
+ - C program to check RADIUS authentication. Requires the radiusclient
+ library available from ftp://ftp.cityline.net/pub/radiusclient/
+ (Robert August Vincent II)
+ <MOVED TO CORE>
+
+weipert-mysql.tar.gz - C program to check a connection to a MySQL database server, with an
+ optional username and password. Requires mysql.h and libmysqlclient
+ to compile (Time Weipert)
+
+wright-mysql.tar.gz - Perl script to check MySQL database servers. Requires that mysqladmin(1)
+ be installed on the system (included in the MySQL distribution). This
+ plugin can accept warning and critical thresholds for the number of threads
+ in use by the server (Mitch Wright)
+
+
diff --git a/contrib/restrict.pl b/contrib/restrict.pl
new file mode 100755
index 00000000..75ea5698
--- /dev/null
+++ b/contrib/restrict.pl
@@ -0,0 +1,26 @@
+#!/usr/bin/perl
+
+eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
+ if 0;
+
+# Set this to your local Nagios plugin path
+my $pluginpath = "/usr/libexec/nagios/plugins/";
+
+# Put all the legal commands (i.e. the commands that are
+# not Nagios checks but are allowed to be executed anyway)
+# in the following associative array.
+my %legal_cmds = ("nc" => "/usr/sbin/nc");
+
+# This will not work on OpenSSH
+# It does work on ssh-1.2.27-1i
+@arg = split ' ',$ENV{'SSH_ORIGINAL_COMMAND'};
+
+$arg[0] =~ s/.*\///; # strip leading path
+$arg[0] =~ tr/-_.a-zA-Z0-9/X/c; # change atypical chars to X
+
+if (!defined ($cmd = $legal_cmds{$arg[0]}))
+{
+ $cmd = $pluginpath . $arg[0];
+}
+
+exec { $cmd } @arg or die "Can't exec $cmd: $!";
diff --git a/contrib/tarballs/berger-ping.tar.gz b/contrib/tarballs/berger-ping.tar.gz
new file mode 100644
index 00000000..cc58750d
--- /dev/null
+++ b/contrib/tarballs/berger-ping.tar.gz
Binary files differ
diff --git a/contrib/tarballs/bowen-langley_plugins.tar.gz b/contrib/tarballs/bowen-langley_plugins.tar.gz
new file mode 100644
index 00000000..6195109f
--- /dev/null
+++ b/contrib/tarballs/bowen-langley_plugins.tar.gz
Binary files differ
diff --git a/contrib/tarballs/check_bgp-1.0.tar.gz b/contrib/tarballs/check_bgp-1.0.tar.gz
new file mode 100644
index 00000000..9d45c195
--- /dev/null
+++ b/contrib/tarballs/check_bgp-1.0.tar.gz
Binary files differ
diff --git a/contrib/tarballs/check_breeze.tar.gz b/contrib/tarballs/check_breeze.tar.gz
new file mode 100644
index 00000000..fb5186ef
--- /dev/null
+++ b/contrib/tarballs/check_breeze.tar.gz
Binary files differ
diff --git a/contrib/tarballs/check_flexlm.tar.gz b/contrib/tarballs/check_flexlm.tar.gz
new file mode 100644
index 00000000..4ab71441
--- /dev/null
+++ b/contrib/tarballs/check_flexlm.tar.gz
Binary files differ
diff --git a/contrib/tarballs/check_hltherm.tar.gz b/contrib/tarballs/check_hltherm.tar.gz
new file mode 100644
index 00000000..7c45cc87
--- /dev/null
+++ b/contrib/tarballs/check_hltherm.tar.gz
Binary files differ
diff --git a/contrib/tarballs/check_hprsc.tar.gz b/contrib/tarballs/check_hprsc.tar.gz
new file mode 100644
index 00000000..8998ff83
--- /dev/null
+++ b/contrib/tarballs/check_hprsc.tar.gz
Binary files differ
diff --git a/contrib/tarballs/check_radius.tar.gz b/contrib/tarballs/check_radius.tar.gz
new file mode 100644
index 00000000..70bb08a2
--- /dev/null
+++ b/contrib/tarballs/check_radius.tar.gz
Binary files differ
diff --git a/contrib/tarballs/check_wave.tar.gz b/contrib/tarballs/check_wave.tar.gz
new file mode 100644
index 00000000..755be5a9
--- /dev/null
+++ b/contrib/tarballs/check_wave.tar.gz
Binary files differ
diff --git a/contrib/tarballs/hopcroft-plugins.tar.gz b/contrib/tarballs/hopcroft-plugins.tar.gz
new file mode 100644
index 00000000..0406a743
--- /dev/null
+++ b/contrib/tarballs/hopcroft-plugins.tar.gz
Binary files differ
diff --git a/contrib/tarballs/radius.tar.gz b/contrib/tarballs/radius.tar.gz
new file mode 100644
index 00000000..022dc3be
--- /dev/null
+++ b/contrib/tarballs/radius.tar.gz
Binary files differ
diff --git a/contrib/urlize.pl b/contrib/urlize.pl
new file mode 100644
index 00000000..8bb591f2
--- /dev/null
+++ b/contrib/urlize.pl
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+#
+# urlize.pl
+# jcw, 5/12/00
+#
+# A wrapper around Nagios plugins that provides a URL link in the output
+#
+
+($#ARGV < 1) && die "Incorrect arguments";
+my $url = shift;
+
+chomp ($result = `@ARGV`);
+print "<A HREF=\"$url\">$result</A>\n";
+
+# exit with same exit value as the child produced
+exit ($? >> 8);
diff --git a/contrib/utils.py b/contrib/utils.py
new file mode 100644
index 00000000..73d795c9
--- /dev/null
+++ b/contrib/utils.py
@@ -0,0 +1,310 @@
+#
+#
+# Util classes for Nagios plugins
+#
+#
+
+
+
+#==========================================================================
+#
+# Version: = '$Id$'
+#
+# (C) Rob W.W. Hooft, Nonius BV, 1998
+#
+# Contact r.hooft@euromail.net for questions/suggestions.
+# See: <http://starship.python.net/crew/hooft/>
+# Distribute freely.
+#
+# jaclu@galdrion.com 2000-07-14
+# Some changes in error handling of Run() to avoid error garbage
+# when used from Nagios plugins
+# I also removed the following functions: AbortableWait() and _buttonkill()
+# since they are only usable with Tkinter
+
+import sys,os,signal,time,string
+
+class error(Exception):
+ pass
+
+class _ready(Exception):
+ pass
+
+def which(filename):
+ """Find the file 'filename' in the execution path. If no executable
+ file is found, return None"""
+ for dir in string.split(os.environ['PATH'],os.pathsep):
+ fn=os.path.join(dir,filename)
+ if os.path.exists(fn):
+ if os.stat(fn)[0]&0111:
+ return fn
+ else:
+ return None
+
+class Task:
+ """Manage asynchronous subprocess tasks.
+ This differs from the 'subproc' package!
+ - 'subproc' connects to the subprocess via pipes
+ - 'task' lets the subprocess run autonomously.
+ After starting the task, we can just:
+ - ask whether it is finished yet
+ - wait until it is finished
+ - perform an 'idle' task (e.g. Tkinter's mainloop) while waiting for
+ subprocess termination
+ - kill the subprocess with a specific signal
+ - ask for the exit code.
+ Summarizing:
+ - 'subproc' is a sophisticated os.popen()
+ - 'task' is a sophisticated os.system()
+ Another difference of task with 'subproc':
+ - If the Task() object is deleted, before the subprocess status
+ was retrieved, the child process will stay.
+ It will never be waited for (i.e., the process will turn into
+ a zombie. Not a good idea in general).
+
+ Public data:
+ None.
+
+ Public methods:
+ __init__, __str__, Run, Wait, Kill, Done, Status.
+ """
+ def __init__(self,command):
+ """Constructor.
+ arguments:
+ command: the command to run, in the form of a string,
+ or a tuple or list of words.
+ """
+ if type(command)==type(''):
+ self.cmd=command
+ self.words=string.split(command)
+ elif type(command)==type([]) or type(command)==type(()):
+ # Surround each word by ' '. Limitation: words cannot contain ' chars
+ self.cmd="'"+string.join(command,"' '")+"'"
+ self.words=tuple(command)
+ else:
+ raise error("command must be tuple, list, or string")
+ self.pid=None
+ self.status=None
+
+ def Run(self,usesh=0,detach=0,stdout=None,stdin=None,stderr=None):
+ """Actually run the process.
+ This method should be called exactly once.
+ optional arguments:
+ usesh=0: if 1, run 'sh -c command', if 0, split the
+ command into words, and run it by ourselves.
+ If usesh=1, the 'Kill' method might not do what
+ you want (it will kill the 'sh' process, not the
+ command).
+ detach=0: if 1, run 'sh -c 'command&' (regardless of
+ 'usesh'). Since the 'sh' process will immediately
+ terminate, the task created will be inherited by
+ 'init', so you can safely forget it. Remember that if
+ detach=1, Kill(), Done() and Status() will manipulate
+ the 'sh' process; there is no way to find out about the
+ detached process.
+ stdout=None: filename to use as stdout for the child process.
+ If None, the stdout of the parent will be used.
+ stdin= None: filename to use as stdin for the child process.
+ If None, the stdin of the parent will be used.
+ stderr=None: filename to use as stderr for the child process.
+ If None, the stderr of the parent will be used.
+ return value:
+ None
+ """
+ if self.pid!=None:
+ raise error("Second run on task forbidden")
+ self.pid=os.fork()
+ if not self.pid:
+ for fn in range(3,256): # Close all non-standard files in a safe way
+ try:
+ os.close(fn)
+ except os.error:
+ pass
+ #
+ # jaclu@galdrion.com 2000-07-14
+ #
+ # I changed this bit somewhat, since Nagios plugins
+ # should send only limited errors to the caller
+ # The original setup here corupted output when there was an error.
+ # Instead the caller should check result of Wait() and anything
+ # not zero should be reported as a failure.
+ #
+ try:
+ if stdout: # Replace stdout by file
+ os.close(1)
+ i=os.open(stdout,os.O_CREAT|os.O_WRONLY|os.O_TRUNC,0666)
+ if i!=1:
+ sys.stderr.write("stdout not opened on 1!\n")
+ if stdin: # Replace stdin by file
+ os.close(0)
+ i=os.open(stdin,os.O_RDONLY)
+ if i!=0:
+ sys.stderr.write("stdin not opened on 0!\n")
+ if stderr: # Replace stderr by file
+ os.close(2)
+ i=os.open(stderr,os.O_CREAT|os.O_WRONLY|os.O_TRUNC,0666)
+ if i!=2:
+ sys.stdout.write("stderr not opened on 2!\n")
+ #try:
+ if detach:
+ os.execv('/bin/sh',('sh','-c',self.cmd+'&'))
+ elif usesh:
+ os.execv('/bin/sh',('sh','-c',self.cmd))
+ else:
+ os.execvp(self.words[0],self.words)
+ except:
+ #print self.words
+ #sys.stderr.write("Subprocess '%s' execution failed!\n"%self.cmd)
+ sys.exit(1)
+ else:
+ # Mother process
+ if detach:
+ # Should complete "immediately"
+ self.Wait()
+
+ def Wait(self,idlefunc=None,interval=0.1):
+ """Wait for the subprocess to terminate.
+ If the process has already terminated, this function will return
+ immediately without raising an error.
+ optional arguments:
+ idlefunc=None: a callable object (function, class, bound method)
+ that will be called every 0.1 second (or see
+ the 'interval' variable) while waiting for
+ the subprocess to terminate. This can be the
+ Tkinter 'update' procedure, such that the GUI
+ doesn't die during the run. If this is set to
+ 'None', the process will really wait. idlefunc
+ should ideally not take a very long time to
+ complete...
+ interval=0.1: The interval (in seconds) with which the 'idlefunc'
+ (if any) will be called.
+ return value:
+ the exit status of the subprocess (0 if successful).
+ """
+ if self.status!=None:
+ # Already finished
+ return self.status
+ if callable(idlefunc):
+ while 1:
+ try:
+ pid,status=os.waitpid(self.pid,os.WNOHANG)
+ if pid==self.pid:
+ self.status=status
+ return status
+ else:
+ idlefunc()
+ time.sleep(interval)
+ except KeyboardInterrupt:
+ # Send the interrupt to the inferior process.
+ self.Kill(signal=signal.SIGINT)
+ elif idlefunc:
+ raise error("Non-callable idle function")
+ else:
+ while 1:
+ try:
+ pid,status=os.waitpid(self.pid,0)
+ self.status=status
+ return status
+ except KeyboardInterrupt:
+ # Send the interrupt to the inferior process.
+ self.Kill(signal=signal.SIGINT)
+
+ def Kill(self,signal=signal.SIGTERM):
+ """Send a signal to the running subprocess.
+ optional arguments:
+ signal=SIGTERM: number of the signal to send.
+ (see os.kill)
+ return value:
+ see os.kill()
+ """
+ if self.status==None:
+ # Only if it is not already finished
+ return os.kill(self.pid,signal)
+
+ def Done(self):
+ """Ask whether the process has already finished.
+ return value:
+ 1: yes, the process has finished.
+ 0: no, the process has not finished yet.
+ """
+ if self.status!=None:
+ return 1
+ else:
+ pid,status=os.waitpid(self.pid,os.WNOHANG)
+ if pid==self.pid:
+ #print "OK:",pid,status
+ self.status=status
+ return 1
+ else:
+ #print "NOK:",pid,status
+ return 0
+
+ def Status(self):
+ """Ask for the status of the task.
+ return value:
+ None: process has not finished yet (maybe not even started).
+ any integer: process exit status.
+ """
+ self.Done()
+ return self.status
+
+ def __str__(self):
+ if self.pid!=None:
+ if self.status!=None:
+ s2="done, exit status=%d"%self.status
+ else:
+ s2="running"
+ else:
+ s2="prepared"
+ return "<%s: '%s', %s>"%(self.__class__.__name__,self.cmd,s2)
+
+
+#==========================================================================
+#
+#
+# Class: TimeoutHandler
+# License: GPL
+# Copyright (c) 2000 Jacob Lundqvist (jaclu@galdrion.com)
+#
+# Version: 1.0 2000-07-14
+#
+# Description:
+# On init, suply a call-back kill_func that should be called on timeout
+#
+# Make sure that what ever you are doing is calling Check periodically
+#
+# To check if timeout was triggered call WasTimeOut returns (true/false)
+#
+
+import time,sys
+
+class TimeoutHandler:
+ def __init__(self,kill_func,time_to_live=10,debug=0):
+ 'Generic time-out handler.'
+ self.kill_func=kill_func
+ self.start_time=time.time()
+ self.stop_time=+self.start_time+int(time_to_live)
+ self.debug=debug
+ self.aborted=0
+
+ def Check(self):
+ 'Call this periodically to check for time-out.'
+ if self.debug:
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ if time.time()>=self.stop_time:
+ self.TimeOut()
+
+ def TimeOut(self):
+ 'Trigger the time-out callback.'
+ self.aborted=1
+ if self.debug:
+ print 'Timeout, aborting'
+ self.kill_func()
+
+ def WasTimeOut(self):
+ 'Indicates if timeout was triggered 1=yes, 0=no.'
+ if self.debug:
+ print ''
+ print 'call duration: %.2f seconds' % (time.time()-self.start_time)
+ return self.aborted