diff options
| author | Ethan Galstad <egalstad@users.sourceforge.net> | 2002-02-28 06:42:51 +0000 |
|---|---|---|
| committer | Ethan Galstad <egalstad@users.sourceforge.net> | 2002-02-28 06:42:51 +0000 |
| commit | 44a321cb8a42d6c0ea2d96a1086a17f2134c89cc (patch) | |
| tree | a1a4d9f7b92412a17ab08f34f04eec45433048b7 /contrib | |
| parent | 54fd5d7022ff2d6a59bc52b8869182f3fc77a058 (diff) | |
| download | monitoring-plugins-44a321cb8a42d6c0ea2d96a1086a17f2134c89cc.tar.gz | |
Initial revision
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@2 f882894a-f735-0410-b71e-b25c423dba1c
Diffstat (limited to 'contrib')
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 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | |||
| 3 | #========================================================================= | ||
| 4 | # Critical Disk Checker utility | ||
| 5 | # | ||
| 6 | # This is the same as the disk checker utility but we use it as | ||
| 7 | # a seperate service in Nagios to report on partitions that | ||
| 8 | # have reached 100% capacity. | ||
| 9 | # | ||
| 10 | # We have excluded /dev/cd0 because the cdrom drive will always | ||
| 11 | # report 100% capacity if a CD is in the drive. | ||
| 12 | # | ||
| 13 | # Authors: TheRocker | ||
| 14 | # SpEnTBoY | ||
| 15 | # | ||
| 16 | # Email: therocker@pawprints.2y.net | ||
| 17 | # lonny@abyss.za.org | ||
| 18 | # | ||
| 19 | #======================================================================= | ||
| 20 | |||
| 21 | NUMBER=`rsh $1 -l root df -kP | grep -vE ":|/dev/cd0" | grep -E "100%" | tr -s ' '| cut -d' ' -f5 | cut -c1-3 | line` | ||
| 22 | TMPFILE=/tmp/tmpcrit.hndl | ||
| 23 | TMPTOO=/tmp/twocrit.hndl | ||
| 24 | |||
| 25 | if [ "$NUMBER" -eq 100 ] | ||
| 26 | then | ||
| 27 | |||
| 28 | `rsh $1 -l root df -kP |grep -vE ":|/dev/cd0" | grep -E "100%" | tr -s ' '| cut -d' ' -f6,5 >> $TMPFILE` | ||
| 29 | |||
| 30 | LINES=`wc -l /tmp/tmpcrit.hndl | cut -c8` | ||
| 31 | LINESCTL=`wc -l /tmp/tmpcrit.hndl | cut -c8 ` | ||
| 32 | echo "Filesystems over 99% --> \c" | ||
| 33 | |||
| 34 | #=============================================================== | ||
| 35 | # Just a little bit to check for multiple occurances of the | ||
| 36 | # condition. | ||
| 37 | #=============================================================== | ||
| 38 | |||
| 39 | while [ $LINESCTL != 0 ] | ||
| 40 | do | ||
| 41 | |||
| 42 | cat $TMPFILE | tail -$LINESCTL > $TMPTOO | ||
| 43 | cat $TMPTOO > $TMPFILE | ||
| 44 | LINESCTL=$(( $LINESCTL -1 )) | ||
| 45 | LINES=$(( $LINES -1 )) | ||
| 46 | DATA=`head -1 /tmp/tmpcrit.hndl` | ||
| 47 | echo "( $DATA ) \c" | ||
| 48 | |||
| 49 | |||
| 50 | done | ||
| 51 | echo "\n" | ||
| 52 | |||
| 53 | #=============================================================== | ||
| 54 | # File clean up. Always pick up after yourself. Disk space | ||
| 55 | # doesn't grow on trees you know. | ||
| 56 | #=============================================================== | ||
| 57 | |||
| 58 | rm -f $TMPFILE | ||
| 59 | rm -f $TMPTOO | ||
| 60 | exit 2 | ||
| 61 | |||
| 62 | else | ||
| 63 | |||
| 64 | echo "No Filesystems over 99%... OK" | ||
| 65 | exit 0 | ||
| 66 | 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 @@ | |||
| 1 | #! /bin/sh | ||
| 2 | |||
| 3 | #====================================================================== | ||
| 4 | # Disk Checker utility | ||
| 5 | # | ||
| 6 | # Simple little script that checks the status of all partitions | ||
| 7 | # on a node's hard disks. It will produce a warning alert and list | ||
| 8 | # the offending filesystems in nagios. | ||
| 9 | # | ||
| 10 | # Authors: SpEnTBoY | ||
| 11 | # TheRocker | ||
| 12 | # | ||
| 13 | # Email: lonny@abyss.za.org | ||
| 14 | # therocker@pawprints.2y.net | ||
| 15 | #===================================================================== | ||
| 16 | |||
| 17 | NUMBER=`rsh $1 -l root df -kP | grep -v ":" | grep -E "9[0-9]%" | tr -s ' '| cut -d' ' -f5 | cut -c1-2 | line` | ||
| 18 | TMPFILE=/tmp/tmp.hndl | ||
| 19 | TMPTOO=/tmp/two.hndl | ||
| 20 | |||
| 21 | if [ "$NUMBER" -gt 90 ] | ||
| 22 | then | ||
| 23 | |||
| 24 | `rsh $1 -l root df -kP |grep -v ":" | grep -E "9[0-9]%" | tr -s ' '| cut -d' ' -f6,5 >> $TMPFILE` | ||
| 25 | |||
| 26 | LINES=`wc -l /tmp/tmp.hndl | cut -c8` | ||
| 27 | LINESCTL=`wc -l /tmp/tmp.hndl | cut -c8 ` | ||
| 28 | echo "Filesystems over 90% --> \c" | ||
| 29 | |||
| 30 | #====================================================================== | ||
| 31 | # You'll see this one in a few our shell scripts. Just chcecking for | ||
| 32 | # multiple occurances of the warnign condition. We gotta list 'em all | ||
| 33 | #====================================================================== | ||
| 34 | |||
| 35 | while [ $LINESCTL != 0 ] | ||
| 36 | do | ||
| 37 | |||
| 38 | cat $TMPFILE | tail -$LINESCTL > $TMPTOO | ||
| 39 | cat $TMPTOO > $TMPFILE | ||
| 40 | LINESCTL=$(( $LINESCTL -1 )) | ||
| 41 | LINES=$(( $LINES -1 )) | ||
| 42 | DATA=`head -1 /tmp/tmp.hndl` | ||
| 43 | echo "( $DATA ) \c" | ||
| 44 | |||
| 45 | |||
| 46 | done | ||
| 47 | echo "\n" | ||
| 48 | |||
| 49 | #=============================================================== | ||
| 50 | # Clean up all those nasty tmp files that suck up valuable | ||
| 51 | # disk realestate. | ||
| 52 | #=============================================================== | ||
| 53 | |||
| 54 | rm -f $TMPFILE | ||
| 55 | rm -f $TMPTOO | ||
| 56 | exit 1 | ||
| 57 | |||
| 58 | else | ||
| 59 | |||
| 60 | echo "No Filesystems over 90%... OK" | ||
| 61 | exit 0 | ||
| 62 | 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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | #====================== | ||
| 3 | # Created May 25, 2000 | ||
| 4 | #====================== | ||
| 5 | |||
| 6 | # This scripts is for checking for failed root login attempts on | ||
| 7 | # any machine running AIX which has a failedlogin file in /etc/security | ||
| 8 | # The purpose is to thwart (good word) any unauthorised people from | ||
| 9 | # even trying to log in as root. This plugin has been developed for Nagios | ||
| 10 | # running on AIX. | ||
| 11 | # Lonny Selinger SpEnTBoY lonny@abyss.za.org | ||
| 12 | # May | ||
| 13 | |||
| 14 | |||
| 15 | my $server = $ARGV[0]; | ||
| 16 | |||
| 17 | if (!$ARGV[0]) { | ||
| 18 | print "You must specify a server to check\n"; | ||
| 19 | print "usage: ./check_failed <Server Name>\n"; | ||
| 20 | exit (-1); | ||
| 21 | } else { | ||
| 22 | open (DATE, "/bin/date '+%b %d' |"); | ||
| 23 | while (<DATE>) { | ||
| 24 | $dline = $_; | ||
| 25 | @dresults = $dline; | ||
| 26 | chop $dresults[0]; | ||
| 27 | } | ||
| 28 | open (SULOG, "rsh $server -l root who /etc/security/failedlogin | grep root |"); | ||
| 29 | while (<SULOG>) { | ||
| 30 | $line = $_; | ||
| 31 | @results = split (/\s+/,$line); | ||
| 32 | if ($line =~ /^root/) { | ||
| 33 | if (join(' ', @results[2,3]) eq $dresults[0]) { | ||
| 34 | print "FAILED root login on $dresults[0], node: $ARGV[0] from $results[5]\n"; | ||
| 35 | exit(2); | ||
| 36 | } | ||
| 37 | } | ||
| 38 | } | ||
| 39 | } | ||
| 40 | if (join(' ', @results[2,3]) ne $dresults[0]) { | ||
| 41 | print "No Failed Root Logins on This Node\n"; | ||
| 42 | exit(0); | ||
| 43 | } | ||
| 44 | exit(0); | ||
| 45 | close(SULOG); | ||
| 46 | close(DATE); | ||
| 47 | |||
| 48 | |||
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 @@ | |||
| 1 | #! /bin/sh | ||
| 2 | |||
| 3 | #================================================================= | ||
| 4 | # | ||
| 5 | # I/O Checker (KBPS) | ||
| 6 | # This Script uses iostat to monitor disk io | ||
| 7 | # Useful for notifications of disk thrashing. | ||
| 8 | # | ||
| 9 | # Authors: TheRocker | ||
| 10 | # SpEnTBoY | ||
| 11 | # | ||
| 12 | # Email: therocker@pawprints.2y.net | ||
| 13 | # lonny@abyss.za.org | ||
| 14 | # | ||
| 15 | #================================================================ | ||
| 16 | |||
| 17 | NUMBER1=`rsh $1 -l root iostat -d | grep -e "hdisk" | tr -s ' ' | cut -d' ' -f2 | sort -2 -r | cut -c1 | line` | ||
| 18 | NUMBER2=`rsh $1 -l root iostat -d | grep -e "hdisk" | tr -s ' ' | cut -d' ' -f2 | sort -2 -r | cut -c2 | line` | ||
| 19 | TMPFILE=/tmp/iotest.hndl | ||
| 20 | TMPTOO=/tmp/iotwo.hndl | ||
| 21 | |||
| 22 | #=========================================================== | ||
| 23 | # | ||
| 24 | # We do an evaluation on $NUMBER1 and $NUMBER2 to see if | ||
| 25 | # disk io is exceeding 40%. | ||
| 26 | # | ||
| 27 | #=========================================================== | ||
| 28 | |||
| 29 | if [ "$NUMBER1" -gt 4 ] && [ "$NUMBER2" -gt 0 ] | ||
| 30 | then | ||
| 31 | |||
| 32 | `rsh $1 -l root iostat -d | grep -v cd0 | tr -s ' '| cut -d' ' -f1,2 | grep -e "4[0-9]." >> $TMPFILE` | ||
| 33 | |||
| 34 | #==================================================================== | ||
| 35 | # | ||
| 36 | # Of course, there may be more than one hard disk on the node | ||
| 37 | # so we use this bit of code to report on more than one instance | ||
| 38 | # of excessive disk IO. | ||
| 39 | # | ||
| 40 | #==================================================================== | ||
| 41 | |||
| 42 | LINES=`wc -l /tmp/iotest.hndl | cut -c8` | ||
| 43 | LINESCTL=`wc -l /tmp/iotest.hndl | cut -c8 ` | ||
| 44 | echo "WARNING!!! Disk I/O Exceeding 40% on --> \c" | ||
| 45 | |||
| 46 | while [ $LINESCTL != 0 ] | ||
| 47 | do | ||
| 48 | |||
| 49 | cat $TMPFILE | tail -$LINESCTL > $TMPTOO | ||
| 50 | cat $TMPTOO > $TMPFILE | ||
| 51 | LINESCTL=$(( $LINESCTL -1 )) | ||
| 52 | LINES=$(( $LINES -1 )) | ||
| 53 | DATA=`head -1 /tmp/iotest.hndl` | ||
| 54 | echo "( $DATA ) " | ||
| 55 | |||
| 56 | |||
| 57 | done | ||
| 58 | echo "\n" | ||
| 59 | |||
| 60 | rm -f $TMPFILE | ||
| 61 | rm -f $TMPTOO | ||
| 62 | exit 1 | ||
| 63 | |||
| 64 | else | ||
| 65 | |||
| 66 | print "No Disk I/O Exceeding 40%...OK" | ||
| 67 | exit 0 | ||
| 68 | |||
| 69 | 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 @@ | |||
| 1 | #! /bin/sh | ||
| 2 | |||
| 3 | #========================================================================= | ||
| 4 | # Kerberos Ticket Checker | ||
| 5 | # | ||
| 6 | # This script is handy if you allow kerberos tickets to expire | ||
| 7 | # on your nodes. The script will simply warn you when a node has | ||
| 8 | # kerberos tickets expiring on the current date. This will allow to | ||
| 9 | # re-initialize the tickets if you wish to do so. | ||
| 10 | # | ||
| 11 | # Nothing fancy here, all Nagios will show is the number of tickets | ||
| 12 | # that are going to (or already have) expired. | ||
| 13 | # | ||
| 14 | # An item of note: | ||
| 15 | # | ||
| 16 | # We made no provisions for the weekend. If tickets expire on the | ||
| 17 | # weekend and nobody is around, you won't see a warning on the | ||
| 18 | # Nagios console because we look for expired on the current day | ||
| 19 | # only. It's a good idea to have this warning emailed to the | ||
| 20 | # appropriate admin and if there is something critical that relies | ||
| 21 | # on Kerberos, you might want to send a page. | ||
| 22 | # | ||
| 23 | # Authors: TheRocker | ||
| 24 | # SpEnTBoY | ||
| 25 | # | ||
| 26 | # Email: therocker@pawprints.2y.net | ||
| 27 | # lonny@abyss.za.org | ||
| 28 | #========================================================================= | ||
| 29 | |||
| 30 | TMPFILE=/tmp/kerbtmp.hndl | ||
| 31 | DATE=`date +%b' '%d` | ||
| 32 | |||
| 33 | rsh $1 -l root /usr/lpp/ssp/kerberos/bin/klist | tr -s ' ' | cut -d' ' -f4,5,6 | grep -e "$DATE" > $TMPFILE | ||
| 34 | |||
| 35 | |||
| 36 | if [ -s $TMPFILE ] | ||
| 37 | then | ||
| 38 | |||
| 39 | LINES=`wc -l /tmp/kerbtmp.hndl | cut -c7-8` | ||
| 40 | echo "Kerberos Tickets set to expire --> \c" | ||
| 41 | echo "$LINES \c" | ||
| 42 | echo "\n" | ||
| 43 | |||
| 44 | rm -f $TMPFILE | ||
| 45 | exit 1 | ||
| 46 | |||
| 47 | fi | ||
| 48 | echo "Kerberos Tickets are valid" | ||
| 49 | 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 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | |||
| 3 | #================================================================ | ||
| 4 | # | ||
| 5 | # This perl script will accept an argument and simply pass it | ||
| 6 | # to ping. It works by sending 2 ping to the specified host | ||
| 7 | # and evaluating on the average delta time of those 2 pings. | ||
| 8 | # | ||
| 9 | # Author: SpEnTBoY | ||
| 10 | # Email: lonny@abyss.za.org | ||
| 11 | # April 5,2000 | ||
| 12 | # | ||
| 13 | #================================================================ | ||
| 14 | |||
| 15 | #============================ | ||
| 16 | # State predefined stuff and | ||
| 17 | # requirements | ||
| 18 | #============================ | ||
| 19 | |||
| 20 | require 5.004; | ||
| 21 | use POSIX; | ||
| 22 | use strict; | ||
| 23 | |||
| 24 | sub usage; | ||
| 25 | |||
| 26 | my $ipaddr = $ARGV[0]; | ||
| 27 | |||
| 28 | my $TIMEOUT = 15; | ||
| 29 | |||
| 30 | my %ERRORS = ('UNKNOWN' , '-1', | ||
| 31 | 'OK' , '0', | ||
| 32 | 'WARNING', '1', | ||
| 33 | 'CRITICAL', '2'); | ||
| 34 | |||
| 35 | my $remote = shift || &usage(%ERRORS); | ||
| 36 | my $warning = shift || 750; | ||
| 37 | my $critical = shift || 1000; | ||
| 38 | |||
| 39 | my $state = "OK"; | ||
| 40 | my $answer = undef; | ||
| 41 | my $offset = undef; | ||
| 42 | my $line = undef; | ||
| 43 | |||
| 44 | #============================================================ | ||
| 45 | # If theres no response we can exit the bloody thing cleanly | ||
| 46 | # last thing I want to do is hang an AIX system ;-) | ||
| 47 | #============================================================ | ||
| 48 | |||
| 49 | $SIG{'ALRM'} = sub { | ||
| 50 | print ("ERROR: No response from PING! (alarm)\n"); | ||
| 51 | exit $ERRORS{"UNKNOWN"}; | ||
| 52 | }; | ||
| 53 | alarm($TIMEOUT); | ||
| 54 | |||
| 55 | #================================================ | ||
| 56 | # Pass stddn from $ARGV to the command and parse | ||
| 57 | # the info we need (namely the value for "max" | ||
| 58 | #================================================ | ||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | open(PING,"/usr/sbin/ping -c 2 '$ipaddr' >&1|"); | ||
| 63 | while (<PING>) { | ||
| 64 | $line = $_; | ||
| 65 | if (/round-trip min\/avg\/max = (.+)\/(.+)\/(.+) ms/) { | ||
| 66 | $offset = $3; | ||
| 67 | last; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | #================================================== | ||
| 72 | # Do some error checking on the output of the file | ||
| 73 | # and implement values for <crit> and <warn> | ||
| 74 | # deffinitions if they were specified by the user | ||
| 75 | # or sub in the predefined ones | ||
| 76 | #================================================== | ||
| 77 | |||
| 78 | if (defined $offset) { | ||
| 79 | if (abs($offset) > $warning) { | ||
| 80 | if (abs($offset) > $critical) { | ||
| 81 | $state = "CRITICAL"; | ||
| 82 | $answer = ": Ping Time $offset MS greater than +/- $critical MS\n"; | ||
| 83 | } else { | ||
| 84 | $state = "WARNING"; | ||
| 85 | $answer = ": Ping Time $offset MS greater than +/- $warning MS\n"; | ||
| 86 | } | ||
| 87 | } else { | ||
| 88 | $state = "OK"; | ||
| 89 | $answer = ": Ping Time $offset MS\n"; | ||
| 90 | } | ||
| 91 | } else { | ||
| 92 | $state = "UNKNOWN"; | ||
| 93 | $answer = ": $line\n"; | ||
| 94 | } | ||
| 95 | print ("$state$answer"); | ||
| 96 | exit $ERRORS{$state}; | ||
| 97 | |||
| 98 | sub usage { | ||
| 99 | print "\n"; | ||
| 100 | print "#=========================================\n"; | ||
| 101 | print "Check_Ping 0.02 script by Lonny Selinger\n"; | ||
| 102 | print "Made with AIX in mind ;-)\n"; | ||
| 103 | print "#=========================================\n"; | ||
| 104 | print "\n"; | ||
| 105 | print "#================================================\n"; | ||
| 106 | print " I'm going to need a few more arguments from you\n"; | ||
| 107 | print "#================================================\n"; | ||
| 108 | print "\n"; | ||
| 109 | print "#================================================\n"; | ||
| 110 | print "Usage: check_ping <host> [<warn> [<crit>]\n"; | ||
| 111 | print "#================================================\n"; | ||
| 112 | print "\n"; | ||
| 113 | print "<warn> = Ping in MS at which a warning message will be generated.\n Defaults to 750.\n"; | ||
| 114 | print "<crit> = Ping in MS at which a critical message will be generated.\n Defaults to 1000.\n\n"; | ||
| 115 | exit $ERRORS{"UNKNOWN"}; | ||
| 116 | } | ||
| 117 | |||
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 @@ | |||
| 1 | #! /bin/sh | ||
| 2 | |||
| 3 | #=============================================================== | ||
| 4 | # Print Queue Checker | ||
| 5 | # | ||
| 6 | # The print queue checker simply looks for an occurance of a | ||
| 7 | # DOWN queue. A note of warning, if you use remote queues in | ||
| 8 | # AIX to redirect print jobs from the AIX queue to an NT print | ||
| 9 | # server that print through DLC rather than IP, it will be very | ||
| 10 | # s - l - o - w. But it will work. | ||
| 11 | # | ||
| 12 | # Author: TheRocker | ||
| 13 | # Email: therocker@pawprints.2y.net | ||
| 14 | #=============================================================== | ||
| 15 | |||
| 16 | TMPFILE=/tmp/qtmp.hndl | ||
| 17 | TMPTOO=/tmp/qtwo.hndl | ||
| 18 | |||
| 19 | #======================================================================= | ||
| 20 | # | ||
| 21 | # This script will also work on AIX 4.2.1 BUT you have to change | ||
| 22 | # the following line. AIX 4.2.1 does not support the -W option | ||
| 23 | # with lpstat. For AIX 4.2.1 just remove the -W option and it should | ||
| 24 | # work just fine. | ||
| 25 | # | ||
| 26 | #======================================================================= | ||
| 27 | |||
| 28 | `rsh $1 -l root lpstat -W | grep -e "DOWN" | tr -s ' ' | cut -d' ' -f1,3 > /tmp/qtmp.hndl 2> /tmp/q_err` | ||
| 29 | |||
| 30 | if [ -s $TMPFILE ] | ||
| 31 | then | ||
| 32 | |||
| 33 | #======================================================= | ||
| 34 | # | ||
| 35 | # If you've seen the other AIX scripts I wrote you may | ||
| 36 | # notice that I use this bit of code a lot. Well it | ||
| 37 | # works and appears to be all purpose. | ||
| 38 | # | ||
| 39 | #======================================================= | ||
| 40 | |||
| 41 | LINES=`wc -l /tmp/qtmp.hndl | cut -c8` | ||
| 42 | LINESCTL=`wc -l /tmp/qtmp.hndl | cut -c8` | ||
| 43 | |||
| 44 | echo "Print Queue DOWN --> \c" | ||
| 45 | |||
| 46 | while [ $LINESCTL != 0 ] | ||
| 47 | do | ||
| 48 | |||
| 49 | cat $TMPFILE | tail -$LINESCTL > $TMPTOO | ||
| 50 | cat $TMPTOO > $TMPFILE | ||
| 51 | LINESCTL=$(( $LINESCTL -1 )) | ||
| 52 | LINES=$(( $LINES -1 )) | ||
| 53 | DATA=`head -1 /tmp/qtmp.hndl` | ||
| 54 | echo "( $DATA ) \c" | ||
| 55 | |||
| 56 | |||
| 57 | done | ||
| 58 | |||
| 59 | echo "\n" | ||
| 60 | |||
| 61 | rm -f $TMPFILE | ||
| 62 | rm -f $TMPTOO | ||
| 63 | exit 2 | ||
| 64 | |||
| 65 | fi | ||
| 66 | echo "Print Queues Running... OK" | ||
| 67 | 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 @@ | |||
| 1 | #!/bin/ksh | ||
| 2 | |||
| 3 | #============================================================================== | ||
| 4 | # Script was originally created to collect stats and dump then to a log file | ||
| 5 | # every five minutes. But we like this better (the log file thing is still | ||
| 6 | # good if you want to track availability). | ||
| 7 | # | ||
| 8 | # Authors: SpEnTBoY | ||
| 9 | # TheRocker | ||
| 10 | # | ||
| 11 | # Email: lonny@abyss.za.org | ||
| 12 | # therocker@pawprints.2y.net | ||
| 13 | #============================================================================== | ||
| 14 | |||
| 15 | #========================================================================================= | ||
| 16 | # | ||
| 17 | # The best way to do this is to use Kerberos but we use rsh here because our monitoring | ||
| 18 | # workstation doesn't have Kerberos installed. In order for this to work, the remote | ||
| 19 | # host ($1) must have a .rhosts file that contains a line like: | ||
| 20 | # | ||
| 21 | # monitorhost nagiosuser | ||
| 22 | # | ||
| 23 | #========================================================================================= | ||
| 24 | |||
| 25 | PAGING2=`rsh $1 -l root lsps -a -s | grep -v Paging | tr -s ' '| cut -d' ' -f3 | cut -d'%' -f1` | ||
| 26 | |||
| 27 | |||
| 28 | if [ "$PAGING2" -gt "35" ] && [ "$PAGING2" -lt "50" ] | ||
| 29 | then | ||
| 30 | echo "Paging Space is over 35% ("$PAGING2")%" | ||
| 31 | exit 1 | ||
| 32 | fi | ||
| 33 | |||
| 34 | if [ "$PAGING2" -gt "49" ] | ||
| 35 | then | ||
| 36 | echo "WARNING! Paging Space is over 50% ("$PAGING2")%" | ||
| 37 | exit 2 | ||
| 38 | fi | ||
| 39 | |||
| 40 | if [ "$PAGING2" -lt "34" ] | ||
| 41 | then | ||
| 42 | echo "Paging Space is less than 34% ("$PAGING2")%" | ||
| 43 | exit 0 | ||
| 44 | fi | ||
| 45 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | # | ||
| 3 | # (c)2001 Sebastian Hetze, Linux Information Systems AG | ||
| 4 | # send bug reports to <S.Hetze@Linux-AG.com> | ||
| 5 | # | ||
| 6 | # This program is free software; you can redistribute it and/or | ||
| 7 | # modify it under the terms of the GNU General Public License | ||
| 8 | # as published by the Free Software Foundation; either version 2 | ||
| 9 | # of the License, or (at your option) any later version. | ||
| 10 | # | ||
| 11 | # This program is distributed in the hope that it will be useful, | ||
| 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty | ||
| 13 | # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | # GNU General Public License for more details. | ||
| 15 | # | ||
| 16 | # you should have received a copy of the GNU General Public License | ||
| 17 | # along with this program (or with Nagios); if not, write to the | ||
| 18 | # Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 19 | # Boston, MA 02111-1307, USA | ||
| 20 | # | ||
| 21 | # | ||
| 22 | # Check apache status information provided by mod_status to find | ||
| 23 | # out about the load (number of servers working) and the | ||
| 24 | # performance (average response time for recent requests). | ||
| 25 | # | ||
| 26 | # Usage: | ||
| 27 | # check_apache -H <host> [-lhV] [-w <warn>] [-c <crit>] [-u <url>] | ||
| 28 | # | ||
| 29 | # check_apache <host> <warn> <crit> <url> (if you cannot avoid it) | ||
| 30 | # | ||
| 31 | |||
| 32 | use LWP::UserAgent; | ||
| 33 | use URI::URL; | ||
| 34 | use Getopt::Long; | ||
| 35 | Getopt::Long::Configure('bundling'); | ||
| 36 | |||
| 37 | $version=0.01; | ||
| 38 | |||
| 39 | my %ERRORS = ('UNKNOWN' , '-1', | ||
| 40 | 'OK' , '0', | ||
| 41 | 'WARNING', '1', | ||
| 42 | 'CRITICAL', '2'); | ||
| 43 | |||
| 44 | |||
| 45 | # | ||
| 46 | # some default values | ||
| 47 | # | ||
| 48 | $perf_w=500; | ||
| 49 | $perf_c=1000; | ||
| 50 | $load_w=20; | ||
| 51 | $load_c=30; | ||
| 52 | $TIMEOUT=15; | ||
| 53 | |||
| 54 | # | ||
| 55 | # get command line options the regular way | ||
| 56 | # | ||
| 57 | GetOptions | ||
| 58 | ("V" => \$opt_V, "version" => \$opt_V, | ||
| 59 | "h" => \$opt_h, "help" => \$opt_h, | ||
| 60 | "l" => \$opt_l, "load" => \$opt_l, | ||
| 61 | "v" => \$verbose, "verbose" => \$verbose, | ||
| 62 | "w=s" => \$opt_w, "warning=s" => \$opt_w, | ||
| 63 | "c=s" => \$opt_c, "critical=s" => \$opt_c, | ||
| 64 | "H=s" => \$opt_H, "hostname=s" => \$opt_H, | ||
| 65 | "u=s" => \$opt_u, "url=s" => \$opt_u); | ||
| 66 | |||
| 67 | # | ||
| 68 | # handle the verbose stuff first | ||
| 69 | # | ||
| 70 | if ($opt_V) { | ||
| 71 | print "\n"; | ||
| 72 | print "check_apache nagios plugin version $version\n"; | ||
| 73 | print "\n"; | ||
| 74 | print "The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n"; | ||
| 75 | print "copies of the plugins under the terms of the GNU General Public License.\n"; | ||
| 76 | print "For more information about these matters, see the file named COPYING.\n"; | ||
| 77 | print "\n"; | ||
| 78 | print "Copyright (c) 2001 Sebastian Hetze Linux Information Systems AG\n"; | ||
| 79 | print "\n"; | ||
| 80 | print "\n"; | ||
| 81 | exit $ERRORS{'UNKNOWN'}; | ||
| 82 | } | ||
| 83 | |||
| 84 | if ($opt_h) { | ||
| 85 | print_help(); | ||
| 86 | exit $ERRORS{'UNKNOWN'}; | ||
| 87 | } | ||
| 88 | |||
| 89 | # | ||
| 90 | # now get options the weired way and set the defaults | ||
| 91 | # if nothing else is provided | ||
| 92 | # | ||
| 93 | $opt_H = shift unless ($opt_H); | ||
| 94 | print_usage() unless ($opt_H); | ||
| 95 | |||
| 96 | if($opt_l) { | ||
| 97 | $autostring="?auto"; | ||
| 98 | ($opt_w) || ($opt_w = shift) || ($opt_w = $load_w); | ||
| 99 | $warn = $1 if ($opt_w =~ /([0-9]+)/); | ||
| 100 | ($opt_c) || ($opt_c = shift) || ($opt_c = $load_c); | ||
| 101 | $alert = $1 if ($opt_c =~ /([0-9]+)/); | ||
| 102 | } else { | ||
| 103 | $autostring=""; | ||
| 104 | ($opt_w) || ($opt_w = shift) || ($opt_w = $perf_w); | ||
| 105 | $warn = $1 if ($opt_w =~ /([0-9]+)/); | ||
| 106 | ($opt_c) || ($opt_c = shift) || ($opt_c = $perf_c); | ||
| 107 | $alert = $1 if ($opt_c =~ /([0-9]+)/); | ||
| 108 | } | ||
| 109 | |||
| 110 | ($opt_u) || ($opt_u = shift) || ($opt_u = "/server-status"); | ||
| 111 | |||
| 112 | |||
| 113 | # | ||
| 114 | # dont let us wait forever... | ||
| 115 | # | ||
| 116 | $SIG{'ALRM'} = sub { | ||
| 117 | print ("ERROR: No response from HTTP server (alarm)\n"); | ||
| 118 | exit $ERRORS{"UNKNOWN"}; | ||
| 119 | }; | ||
| 120 | alarm($TIMEOUT); | ||
| 121 | |||
| 122 | |||
| 123 | # | ||
| 124 | # now we set things up for the real work | ||
| 125 | # and fire up the request | ||
| 126 | # | ||
| 127 | $ua = new LWP::UserAgent; | ||
| 128 | $ua->agent("Nagios/0.1 " . $ua->agent); | ||
| 129 | |||
| 130 | |||
| 131 | $urlstring = "http://" . $opt_H . $opt_u . $autostring; | ||
| 132 | $url = url($urlstring); | ||
| 133 | |||
| 134 | my $req = new HTTP::Request 'GET', $url; | ||
| 135 | my $res = $ua->request($req); | ||
| 136 | |||
| 137 | # | ||
| 138 | # hopefully we´ve got something usefull | ||
| 139 | # | ||
| 140 | if ($res->is_success) { | ||
| 141 | if($opt_l) { | ||
| 142 | foreach $_ (split /^/m, $res->content) { | ||
| 143 | next if /^\s*$/; | ||
| 144 | # | ||
| 145 | # this is the load checking section | ||
| 146 | # we parse the whole content, just in case someone | ||
| 147 | # wants to use this some day in the future | ||
| 148 | # | ||
| 149 | if (/^Total Accesses:\s+([0-9.]+)/) { $accesses = $1; next; } | ||
| 150 | if (/^Total kBytes:\s+([0-9.]+)/) { $kbytes = $1; next; } | ||
| 151 | if (/^CPULoad:\s+([0-9.]+)\s+/) { $load = $1; next; } | ||
| 152 | if (/^Uptime:\s+([0-9.]+)\s+/) { $uptime = $1; next; } | ||
| 153 | if (/^ReqPerSec:\s+([0-9.]+)\s+/) { $rps = $1; next; } | ||
| 154 | if (/^BytesPerSec:\s+([0-9.]+)\s+/) { $bps = $1; next; } | ||
| 155 | if (/^BytesPerReq:\s+([0-9.]+)\s+/) { $bpr = $1; next; } | ||
| 156 | if (/^BusyServers:\s+([0-9.]+)\s+/) { $busy = $1; next; } | ||
| 157 | if (/^IdleServers:\s+([0-9.]+)\s+/) { $idle = $1; next; } | ||
| 158 | if (/^Scoreboard:\s+([SRWKDLG_.]+)\s+/) { $score = $1; next; } | ||
| 159 | print "Unknown Status\n"; | ||
| 160 | exit $ERRORS{"UNKNOWN"}; | ||
| 161 | } | ||
| 162 | # | ||
| 163 | # now we even parse the whole scoreboard, just for fun | ||
| 164 | # | ||
| 165 | foreach $scorepoint (split //m, $score) { | ||
| 166 | if($scorepoint eq '.') { $scores{'.'}+=1; next; } # Unused | ||
| 167 | if($scorepoint eq '_') { $scores{'_'}+=1; next; } # Waiting | ||
| 168 | if($scorepoint eq 'S') { $scores{'S'}+=1; next; } # Starting | ||
| 169 | if($scorepoint eq 'R') { $scores{'R'}+=1; next; } # Reading | ||
| 170 | if($scorepoint eq 'W') { $scores{'W'}+=1; next; } # Writing | ||
| 171 | if($scorepoint eq 'K') { $scores{'K'}+=1; next; } # Keepalive | ||
| 172 | if($scorepoint eq 'D') { $scores{'D'}+=1; next; } # DNS Lookup | ||
| 173 | if($scorepoint eq 'L') { $scores{'L'}+=1; next; } # Logging | ||
| 174 | if($scorepoint eq 'G') { $scores{'G'}+=1; next; } # Going | ||
| 175 | } | ||
| 176 | |||
| 177 | if($busy>$alert) { | ||
| 178 | printf "HTTPD CRITICAL: %.0f servers running\n", $busy; | ||
| 179 | exit $ERRORS{"CRITICAL"}; | ||
| 180 | } | ||
| 181 | if($busy>$warn) { | ||
| 182 | printf "HTTPD WARNING: %.0f servers running\n", $busy; | ||
| 183 | exit $ERRORS{"WARNING"}; | ||
| 184 | } | ||
| 185 | printf "HTTPD ok: %.0f servers running, %d idle\n", $busy, $idle; | ||
| 186 | exit $ERRORS{"OK"}; | ||
| 187 | |||
| 188 | } else { | ||
| 189 | # | ||
| 190 | # this is the performance check section | ||
| 191 | # We are a bit lazy here, no parsing of the initial data | ||
| 192 | # block and the scoreboard. | ||
| 193 | # However, you have the whole set of per server | ||
| 194 | # information to play with ;-) | ||
| 195 | # The actual performance is measured by adding up the | ||
| 196 | # milliseconds required to process the most recent | ||
| 197 | # requests of all instances and then taking the average. | ||
| 198 | # | ||
| 199 | foreach $tablerow (split /<tr>/m, $res->content) { | ||
| 200 | ($empty,$Srv,$PID,$Acc,$M,$CPU,$SS,$Req,$Conn,$Child,$Slot,$Client,$VHost,$Request) | ||
| 201 | = split /<td>/, $tablerow; | ||
| 202 | if($Req) { | ||
| 203 | $lines+=1; | ||
| 204 | $req_sum+=$Req; | ||
| 205 | } | ||
| 206 | undef $Req; | ||
| 207 | } | ||
| 208 | $average=$req_sum/$lines; | ||
| 209 | if($average>$alert) { | ||
| 210 | printf "HTTPD CRITICAL: average response time %.0f | ||
| 211 | milliseconds\n", $average; | ||
| 212 | exit $ERRORS{"CRITICAL"}; | ||
| 213 | } | ||
| 214 | if($average>$warn) { | ||
| 215 | printf "HTTPD WARNING: average response time %.0f | ||
| 216 | milliseconds\n", $average; | ||
| 217 | exit $ERRORS{"WARNING"}; | ||
| 218 | } | ||
| 219 | if($average>0) { | ||
| 220 | printf "HTTPD ok: average response time %.0f milliseconds\n", | ||
| 221 | $average; | ||
| 222 | exit $ERRORS{"OK"}; | ||
| 223 | } | ||
| 224 | print "Unknown Status\n"; | ||
| 225 | exit $ERRORS{"UNKNOWN"}; | ||
| 226 | } | ||
| 227 | } else { | ||
| 228 | print "HTTP request failed\n"; | ||
| 229 | exit $ERRORS{"CRITICAL"}; | ||
| 230 | } | ||
| 231 | |||
| 232 | |||
| 233 | # | ||
| 234 | # ok, now we are almost through | ||
| 235 | # These last subroutines do the things for those that do not | ||
| 236 | # read source code. | ||
| 237 | # | ||
| 238 | sub print_usage () { | ||
| 239 | print "Usage: $0 -H <host> [-lhV] [-w <warn>] [-c <crit>] [-u <url>]\n"; } | ||
| 240 | |||
| 241 | sub print_help () { | ||
| 242 | print "\n"; | ||
| 243 | print "\n"; | ||
| 244 | print "check_apache nagios plugin version $version\n"; | ||
| 245 | print "\n"; | ||
| 246 | print "The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n"; | ||
| 247 | print "copies of the plugins under the terms of the GNU General Public License.\n"; | ||
| 248 | print "For more information about these matters, see the file named COPYING.\n"; | ||
| 249 | print "\n"; | ||
| 250 | print "Copyright (c) 2001 Sebastian Hetze Linux Information Systems AG\n"; | ||
| 251 | print "\n"; | ||
| 252 | print "\n"; | ||
| 253 | print "This plugin checks the apache HTTP service on the specified host.\n"; | ||
| 254 | print "It uses the mod_status facilities provided by the apache server.\n"; | ||
| 255 | print "The monitoring server must be authorized in httpd.conf.\n"; | ||
| 256 | print "\n"; | ||
| 257 | print "\n"; | ||
| 258 | print_usage(); | ||
| 259 | print "\n"; | ||
| 260 | print "Options:\n"; | ||
| 261 | print " -H, --hostname=ADDRESS\n"; | ||
| 262 | print " host name argument for server.\n"; | ||
| 263 | print " -l, --load\n"; | ||
| 264 | print " check load instead of performance.\n"; | ||
| 265 | print " -h, --help\n"; | ||
| 266 | print " print detailed help screen.\n"; | ||
| 267 | print " -V, --version\n"; | ||
| 268 | print " print version information.\n"; | ||
| 269 | print " -w, --warning=INTEGER\n"; | ||
| 270 | print " load / performance level at which a warning message will be gererated.\n"; | ||
| 271 | print " -c, --critical=INTEGER\n"; | ||
| 272 | print " load / performance level at which a critical message will be gererated.\n"; | ||
| 273 | print " -u, --url=PATH\n"; | ||
| 274 | print " location to call mod_status.\n"; | ||
| 275 | print "\n"; | ||
| 276 | print " Defaults for performance checking are $perf_w/$perf_c msec.\n"; | ||
| 277 | print " Defaults for load checking are $load_w/$load_c servers running.\n"; | ||
| 278 | print "\n"; | ||
| 279 | print "\n"; | ||
| 280 | } | ||
| 281 | # | ||
| 282 | # the end | ||
| 283 | # | ||
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 @@ | |||
| 1 | #! /usr/bin/perl -wT | ||
| 2 | # | ||
| 3 | # Check_apc_ups - Check APC UPS status via SNMP | ||
| 4 | # Shamelessly copied from check_breeze.pl | ||
| 5 | # | ||
| 6 | # To do: | ||
| 7 | # - Send SNMP queries directly, instead of forking `snmpget`. | ||
| 8 | # - Make the status less verbose. Maybe we can send an "onLine, time | ||
| 9 | # remaining: hh:mm:ss" if all is well, and a list of specific problems | ||
| 10 | # if something is broken. | ||
| 11 | |||
| 12 | BEGIN { | ||
| 13 | if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) { | ||
| 14 | $runtimedir = $1; | ||
| 15 | $PROGNAME = $2; | ||
| 16 | } | ||
| 17 | } | ||
| 18 | |||
| 19 | use strict; | ||
| 20 | use Getopt::Long; | ||
| 21 | use vars qw($opt_V $opt_h $opt_H $opt_T $opt_t $opt_R $opt_r | ||
| 22 | $opt_L $opt_l $PROGNAME); | ||
| 23 | use lib $main::runtimedir; | ||
| 24 | use utils qw(%ERRORS &print_revision &support &usage); | ||
| 25 | |||
| 26 | sub print_help (); | ||
| 27 | sub print_usage (); | ||
| 28 | sub get_snmp_int_val ($); | ||
| 29 | sub escalate_exitval ($); | ||
| 30 | |||
| 31 | $ENV{'PATH'}=''; | ||
| 32 | $ENV{'BASH_ENV'}=''; | ||
| 33 | $ENV{'ENV'}=''; | ||
| 34 | |||
| 35 | Getopt::Long::Configure('bundling'); | ||
| 36 | GetOptions | ||
| 37 | ("V" => \$opt_V, "version" => \$opt_V, | ||
| 38 | "h" => \$opt_h, "help" => \$opt_h, | ||
| 39 | "T=s" => \$opt_T, "temp-critical" => \$opt_T, | ||
| 40 | "t=s" => \$opt_t, "temp-warning" => \$opt_t, | ||
| 41 | "R=s" => \$opt_R, "runtime-critical" => \$opt_R, | ||
| 42 | "r=s" => \$opt_r, "runtime-warning" => \$opt_r, | ||
| 43 | "L=s" => \$opt_L, "load-critical" => \$opt_L, | ||
| 44 | "l=s" => \$opt_l, "load-warning" => \$opt_l, | ||
| 45 | "H=s" => \$opt_H, "hostname=s" => \$opt_H); | ||
| 46 | |||
| 47 | if ($opt_V) { | ||
| 48 | print_revision($PROGNAME,'$Revision$'); | ||
| 49 | exit $ERRORS{'OK'}; | ||
| 50 | } | ||
| 51 | |||
| 52 | if ($opt_h) {print_help(); exit $ERRORS{'OK'};} | ||
| 53 | |||
| 54 | ($opt_H) || ($opt_H = shift) || usage("Host name/address not specified\n"); | ||
| 55 | my $host = $1 if ($opt_H =~ /([-.A-Za-z0-9]+)/); | ||
| 56 | ($host) || usage("Invalid host: $opt_H\n"); | ||
| 57 | |||
| 58 | # Defaults | ||
| 59 | |||
| 60 | $opt_R *= 60 * 100 if (defined $opt_R); # Convert minutes to secs/100 | ||
| 61 | $opt_r *= 60 * 100 if (defined $opt_R); | ||
| 62 | |||
| 63 | my $tempcrit = $opt_T || 60; | ||
| 64 | my $tempwarn = $opt_t || 40; | ||
| 65 | my $runtimecrit = $opt_R || 30 * 60 * 100; # Secs / 100 | ||
| 66 | my $runtimewarn = $opt_r || 60 * 60 * 100; | ||
| 67 | my $loadcrit = $opt_L || 85; | ||
| 68 | my $loadwarn = $opt_l || 50; | ||
| 69 | |||
| 70 | if ($tempcrit !~ /\d+/) { usage ("Invalid critical temperature threshold.\n"); } | ||
| 71 | if ($tempwarn !~ /\d+/) { usage ("Invalid critical temperature threshold.\n"); } | ||
| 72 | |||
| 73 | if ($runtimecrit !~ /\d+/) { | ||
| 74 | usage ("Invalid critical run time threshold.\n"); | ||
| 75 | } | ||
| 76 | if ($runtimewarn !~ /\d+/) { | ||
| 77 | usage ("Invalid warning run time threshold.\n"); | ||
| 78 | } | ||
| 79 | |||
| 80 | if ($loadcrit !~ /\d+/ || $loadcrit < 0 || $loadcrit > 100) { | ||
| 81 | usage ("Invalid critical load threshold.\n"); | ||
| 82 | } | ||
| 83 | if ($loadwarn !~ /\d+/ || $loadwarn < 0 || $loadwarn > 100) { | ||
| 84 | usage ("Invalid warning load threshold.\n"); | ||
| 85 | } | ||
| 86 | |||
| 87 | |||
| 88 | # APC UPS OIDs | ||
| 89 | # APC MIBs are available at ftp://ftp.apcftp.com/software/pnetmib/mib | ||
| 90 | my $upsBasicOutputStatus = ".1.3.6.1.4.1.318.1.1.1.4.1.1.0"; | ||
| 91 | my $upsBasicBatteryStatus = ".1.3.6.1.4.1.318.1.1.1.2.1.1.0"; | ||
| 92 | my $upsAdvInputLineFailCause = ".1.3.6.1.4.1.318.1.1.1.3.2.5.0"; | ||
| 93 | my $upsAdvBatteryTemperature = ".1.3.6.1.4.1.318.1.1.1.2.2.2.0"; | ||
| 94 | my $upsAdvBatteryRunTimeRemaining = ".1.3.6.1.4.1.318.1.1.1.2.2.3.0"; | ||
| 95 | my $upsAdvBatteryReplaceIndicator = ".1.3.6.1.4.1.318.1.1.1.2.2.4.0"; | ||
| 96 | my $upsAdvOutputLoad = ".1.3.6.1.4.1.318.1.1.1.4.2.3.0"; | ||
| 97 | my $upsAdvTestDiagnosticsResults = ".1.3.6.1.4.1.318.1.1.1.7.2.3.0"; | ||
| 98 | |||
| 99 | my @outputStatVals = ( | ||
| 100 | [ undef, undef ], # pad 0 | ||
| 101 | [ undef, undef ], # pad 1 | ||
| 102 | [ "onLine", $ERRORS{'OK'} ], # 2 | ||
| 103 | [ "onBattery", $ERRORS{'WARNING'} ], # 3 | ||
| 104 | [ "onSmartBoost", $ERRORS{'WARNING'} ], # 4 | ||
| 105 | [ "timedSleeping", $ERRORS{'WARNING'} ], # 5 | ||
| 106 | [ "softwareBypass", $ERRORS{'WARNING'} ], # 6 | ||
| 107 | [ "off", $ERRORS{'CRITICAL'} ], # 7 | ||
| 108 | [ "rebooting", $ERRORS{'WARNING'} ], # 8 | ||
| 109 | [ "switchedBypass", $ERRORS{'WARNING'} ], # 9 | ||
| 110 | [ "hardwareFailureBypass", $ERRORS{'CRITICAL'} ], # 10 | ||
| 111 | [ "sleepingUntilPowerReturn", $ERRORS{'CRITICAL'} ], # 11 | ||
| 112 | [ "onSmartTrim", $ERRORS{'WARNING'} ], # 12 | ||
| 113 | ); | ||
| 114 | |||
| 115 | my @failCauseVals = ( | ||
| 116 | undef, | ||
| 117 | "noTransfer", | ||
| 118 | "highLineVoltage", | ||
| 119 | "brownout", | ||
| 120 | "blackout", | ||
| 121 | "smallMomentarySag", | ||
| 122 | "deepMomentarySag", | ||
| 123 | "smallMomentarySpike", | ||
| 124 | "largeMomentarySpike", | ||
| 125 | "selfTest", | ||
| 126 | "rateOfVoltageChnage", | ||
| 127 | ); | ||
| 128 | |||
| 129 | my @battStatVals = ( | ||
| 130 | [ undef, undef ], # pad 0 | ||
| 131 | [ undef, undef ], # pad 1 | ||
| 132 | [ "batteryNormal", $ERRORS{'OK'} ], # 2 | ||
| 133 | [ "batteryLow", $ERRORS{'CRITICAL'} ], # 3 | ||
| 134 | ); | ||
| 135 | |||
| 136 | my @battReplVals = ( | ||
| 137 | [ undef, undef ], # pad 0 | ||
| 138 | [ "noBatteryNeedsReplacing", $ERRORS{'OK'} ], # 1 | ||
| 139 | [ "batteryNeedsReplacing", $ERRORS{'CRITICAL'} ], # 2 | ||
| 140 | ); | ||
| 141 | |||
| 142 | my @diagnosticsResultsVals = ( | ||
| 143 | [ undef, undef ], # pad 0 | ||
| 144 | [ "OK", $ERRORS{'OK'} ], # 1 | ||
| 145 | [ "failed", $ERRORS{'CRITICAL'} ], # 2 | ||
| 146 | [ "invalidTest", $ERRORS{'CRITICAL'} ], # 3 | ||
| 147 | [ "testInProgress", $ERRORS{'OK'} ], # 4 | ||
| 148 | ); | ||
| 149 | |||
| 150 | my $exitval = $ERRORS{'UNKNOWN'}; | ||
| 151 | my $data; | ||
| 152 | my $onbattery = 3; | ||
| 153 | |||
| 154 | $data = get_snmp_int_val( $upsBasicOutputStatus ); | ||
| 155 | |||
| 156 | print "Output status: "; | ||
| 157 | if (defined ($data) && defined ($outputStatVals[$data][0])) { | ||
| 158 | print "$outputStatVals[$data][0] | "; | ||
| 159 | escalate_exitval($outputStatVals[$data][1]); | ||
| 160 | } else { | ||
| 161 | print "unknown | "; | ||
| 162 | } | ||
| 163 | |||
| 164 | $data = get_snmp_int_val( $upsAdvBatteryRunTimeRemaining ); | ||
| 165 | |||
| 166 | print "Rem time: "; | ||
| 167 | if (defined ($data)) { | ||
| 168 | my $hrs = int($data / (60 * 60 * 100)); # Data is hundredths of a second | ||
| 169 | my $mins = int($data / (60 * 100)) % 60; | ||
| 170 | my $secs = ($data % 100) / 100; | ||
| 171 | printf "%d:%02d:%05.2f | ", $hrs, $mins, $secs; | ||
| 172 | if ($data <= $runtimecrit) { | ||
| 173 | escalate_exitval($ERRORS{'CRITICAL'}); | ||
| 174 | } elsif ($data <= $runtimewarn) { | ||
| 175 | escalate_exitval($ERRORS{'WARNING'}); | ||
| 176 | } else { | ||
| 177 | escalate_exitval($ERRORS{'OK'}); | ||
| 178 | } | ||
| 179 | } else { | ||
| 180 | print "unknown | "; | ||
| 181 | } | ||
| 182 | |||
| 183 | $data = get_snmp_int_val( $upsBasicBatteryStatus ); | ||
| 184 | |||
| 185 | print "Battery status: "; | ||
| 186 | if (defined ($data) && defined ($battStatVals[$data][0])) { | ||
| 187 | my $failcause = "unknown"; | ||
| 188 | my $fc = get_snmp_int_val( $upsAdvInputLineFailCause ); | ||
| 189 | if ($data == $onbattery) { | ||
| 190 | if (defined ($failCauseVals[$fc])) { $failcause = $failCauseVals[$fc]; } | ||
| 191 | print "$battStatVals[$data][0] ($failcause) | "; | ||
| 192 | } else { | ||
| 193 | print "$battStatVals[$data][0] | "; | ||
| 194 | } | ||
| 195 | escalate_exitval($battStatVals[$data][1]); | ||
| 196 | } else { | ||
| 197 | print "unknown | "; | ||
| 198 | } | ||
| 199 | |||
| 200 | $data = get_snmp_int_val( $upsAdvBatteryTemperature ); | ||
| 201 | |||
| 202 | print "Battery temp(C): "; | ||
| 203 | if (defined ($data)) { | ||
| 204 | print "$data | "; | ||
| 205 | if ($data >= $tempcrit) { | ||
| 206 | escalate_exitval($ERRORS{'CRITICAL'}); | ||
| 207 | } elsif ($data >= $tempwarn) { | ||
| 208 | escalate_exitval($ERRORS{'WARNING'}); | ||
| 209 | } else { | ||
| 210 | escalate_exitval($ERRORS{'OK'}); | ||
| 211 | } | ||
| 212 | } else { | ||
| 213 | print "unknown | "; | ||
| 214 | } | ||
| 215 | |||
| 216 | $data = get_snmp_int_val( $upsAdvBatteryReplaceIndicator ); | ||
| 217 | |||
| 218 | print "Battery repl: "; | ||
| 219 | if (defined ($data) && defined ($battReplVals[$data][0])) { | ||
| 220 | print "$battReplVals[$data][0] | "; | ||
| 221 | escalate_exitval($battReplVals[$data][1]); | ||
| 222 | } else { | ||
| 223 | print "unknown | "; | ||
| 224 | } | ||
| 225 | |||
| 226 | $data = get_snmp_int_val( $upsAdvOutputLoad ); | ||
| 227 | |||
| 228 | print "Output load (%): "; | ||
| 229 | if (defined ($data)) { | ||
| 230 | print "$data | "; | ||
| 231 | if ($data >= $loadcrit) { | ||
| 232 | escalate_exitval($ERRORS{'CRITICAL'}); | ||
| 233 | } elsif ($data >= $loadwarn) { | ||
| 234 | escalate_exitval($ERRORS{'WARNING'}); | ||
| 235 | } else { | ||
| 236 | escalate_exitval($ERRORS{'OK'}); | ||
| 237 | } | ||
| 238 | } else { | ||
| 239 | print "unknown | "; | ||
| 240 | } | ||
| 241 | |||
| 242 | $data = get_snmp_int_val( $upsAdvTestDiagnosticsResults ); | ||
| 243 | |||
| 244 | print "Diag result: "; | ||
| 245 | if (defined ($data) && defined ($diagnosticsResultsVals[$data][0])) { | ||
| 246 | print "$diagnosticsResultsVals[$data][0]\n"; | ||
| 247 | escalate_exitval($diagnosticsResultsVals[$data][1]); | ||
| 248 | } else { | ||
| 249 | print "unknown\n"; | ||
| 250 | } | ||
| 251 | |||
| 252 | |||
| 253 | exit $exitval; | ||
| 254 | |||
| 255 | |||
| 256 | sub print_usage () { | ||
| 257 | print "Usage: $PROGNAME -H <host> -T temp -t temp -R minutes -r minutes\n"; | ||
| 258 | print " -L percent -l percent\n"; | ||
| 259 | } | ||
| 260 | |||
| 261 | sub print_help () { | ||
| 262 | print_revision($PROGNAME,'$Revision$'); | ||
| 263 | print "Copyright (c) 2001 Gerald Combs/Jeffrey Blank/Karl DeBisschop | ||
| 264 | |||
| 265 | This plugin reports the status of an APC UPS equipped with an SNMP management | ||
| 266 | module. | ||
| 267 | |||
| 268 | "; | ||
| 269 | print_usage(); | ||
| 270 | print " | ||
| 271 | -H, --hostname=HOST | ||
| 272 | Name or IP address of host to check | ||
| 273 | -T --temp-critical | ||
| 274 | Battery degrees C above which a CRITICAL status will result (default: 60) | ||
| 275 | -t --temp-warning | ||
| 276 | Battery degrees C above which a WARNING status will result (default: 40) | ||
| 277 | -R --runtime-critical | ||
| 278 | Minutes remaining below which a CRITICAL status will result (default: 30) | ||
| 279 | -r --runtime-warning | ||
| 280 | Minutes remaining below which a WARNING status will result (default: 60) | ||
| 281 | -L --load-critical | ||
| 282 | Output load pct above which a CRITICAL status will result (default: 85 | ||
| 283 | -l --load-warning | ||
| 284 | Output load pct above which a WARNING status will result (default: 50 | ||
| 285 | |||
| 286 | "; | ||
| 287 | support(); | ||
| 288 | } | ||
| 289 | |||
| 290 | sub get_snmp_int_val ($) { | ||
| 291 | my $val=0; | ||
| 292 | my $oid = shift(@_); | ||
| 293 | |||
| 294 | $val = `/usr/bin/snmpget $host public $oid 2> /dev/null`; | ||
| 295 | my @test = split(/ /,$val,3); | ||
| 296 | |||
| 297 | return undef unless (defined ($test[2])); | ||
| 298 | |||
| 299 | if ($test[2] =~ /\(\d+\)/) { # Later versions of UCD SNMP | ||
| 300 | ($val) = ($test[2] =~ /\((\d+)\)/); | ||
| 301 | } elsif ($test[2] =~ /: \d+/) { | ||
| 302 | ($val) = ($test[2] =~ /: (\d+)/); | ||
| 303 | } else { | ||
| 304 | $val = $test[2]; | ||
| 305 | } | ||
| 306 | |||
| 307 | return $val; | ||
| 308 | } | ||
| 309 | |||
| 310 | sub escalate_exitval ($) { | ||
| 311 | my $newval = shift(@_); | ||
| 312 | |||
| 313 | if ($newval > $exitval) { $exitval = $newval; } | ||
| 314 | } | ||
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 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | # | ||
| 3 | # check_bgpstate.pl - nagios plugin | ||
| 4 | # | ||
| 5 | # Copyright (C) 2000 Christoph Kron | ||
| 6 | # | ||
| 7 | # This program is free software; you can redistribute it and/or | ||
| 8 | # modify it under the terms of the GNU General Public License | ||
| 9 | # as published by the Free Software Foundation; either version 2 | ||
| 10 | # of the License, or (at your option) any later version. | ||
| 11 | # | ||
| 12 | # This program is distributed in the hope that it will be useful, | ||
| 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | # GNU General Public License for more details. | ||
| 16 | # | ||
| 17 | # You should have received a copy of the GNU General Public License | ||
| 18 | # along with this program; if not, write to the Free Software | ||
| 19 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 20 | # | ||
| 21 | # | ||
| 22 | # Report bugs to: ck@zet.net | ||
| 23 | # | ||
| 24 | # 11.01.2000 Version 1.0 | ||
| 25 | |||
| 26 | |||
| 27 | |||
| 28 | use strict; | ||
| 29 | |||
| 30 | use Net::SNMP; | ||
| 31 | use Getopt::Long; | ||
| 32 | &Getopt::Long::config('auto_abbrev'); | ||
| 33 | |||
| 34 | |||
| 35 | # whois programm for RIPE database queries | ||
| 36 | my $whois = '/usr/bin/whois'; | ||
| 37 | my $status; | ||
| 38 | my $TIMEOUT = 30; | ||
| 39 | |||
| 40 | # critical bgp sessions | ||
| 41 | my %uplinks = ( 1273, 'Uplink ECRC', | ||
| 42 | 1755, 'Uplink EBONE', | ||
| 43 | 3300, 'Uplink AUCS' | ||
| 44 | ); | ||
| 45 | |||
| 46 | my %ERRORS = ('UNKNOWN' , '-1', | ||
| 47 | 'OK' , '0', | ||
| 48 | 'WARNING', '1', | ||
| 49 | 'CRITICAL', '2'); | ||
| 50 | |||
| 51 | |||
| 52 | my %bgpPeerState = ( | ||
| 53 | '1',"idle", | ||
| 54 | '2',"connect", | ||
| 55 | '3',"active", | ||
| 56 | '4',"opensent", | ||
| 57 | '5',"openconfirm", | ||
| 58 | '6',"established" | ||
| 59 | ); | ||
| 60 | my $state = "UNKNOWN"; | ||
| 61 | my $answer = ""; | ||
| 62 | my $snmpkey; | ||
| 63 | my $snmpoid; | ||
| 64 | my $key; | ||
| 65 | my $community = "public"; | ||
| 66 | my $port = 161; | ||
| 67 | my @snmpoids; | ||
| 68 | my $snmpbgpPeerState = '1.3.6.1.2.1.15.3.1.2'; | ||
| 69 | my $snmpbgpPeerLocalAddr = '1.3.6.1.2.1.15.3.1.5'; | ||
| 70 | my $snmpbgpPeerRemoteAddr = '1.3.6.1.2.1.15.3.1.7'; | ||
| 71 | my $snmpbgpPeerRemoteAs = '1.3.6.1.2.1.15.3.1.9'; | ||
| 72 | my $hostname; | ||
| 73 | my $session; | ||
| 74 | my $error; | ||
| 75 | my $response; | ||
| 76 | my %bgpStatus; | ||
| 77 | my $bgpestablished =0 ; | ||
| 78 | my $bgpcritical =0; | ||
| 79 | my $bgpdown =0; | ||
| 80 | my $bgpidle =0; | ||
| 81 | my $bgpmessage; | ||
| 82 | my $asname; | ||
| 83 | my $remoteas; | ||
| 84 | my @output; | ||
| 85 | |||
| 86 | sub usage { | ||
| 87 | printf "\nMissing arguments!\n"; | ||
| 88 | printf "\n"; | ||
| 89 | printf "Perl bgpstate plugin for Nagios\n"; | ||
| 90 | printf "monitors all BGP sessions\n"; | ||
| 91 | printf "usage: \n"; | ||
| 92 | printf "check_bgpstate.pl -c <READCOMMUNITY> -p <PORT> <HOSTNAME>\n"; | ||
| 93 | printf "Copyright (C) 2000 Christoph Kron\n"; | ||
| 94 | printf "check_bgpstate.pl comes with ABSOLUTELY NO WARRANTY\n"; | ||
| 95 | printf "This programm is licensed under the terms of the "; | ||
| 96 | printf "GNU General Public License\n(check source code for details)\n"; | ||
| 97 | printf "\n\n"; | ||
| 98 | exit $ERRORS{"UNKNOWN"}; | ||
| 99 | } | ||
| 100 | |||
| 101 | # Just in case of problems, let's not hang Nagios | ||
| 102 | $SIG{'ALRM'} = sub { | ||
| 103 | print ("ERROR: No snmp response from $hostname (alarm)\n"); | ||
| 104 | exit $ERRORS{"UNKNOWN"}; | ||
| 105 | }; | ||
| 106 | alarm($TIMEOUT); | ||
| 107 | |||
| 108 | |||
| 109 | $status = GetOptions("community=s",\$community, | ||
| 110 | "port=i",\$port); | ||
| 111 | if ($status == 0) | ||
| 112 | { | ||
| 113 | &usage; | ||
| 114 | } | ||
| 115 | |||
| 116 | #shift; | ||
| 117 | $hostname = shift || &usage; | ||
| 118 | |||
| 119 | |||
| 120 | push(@snmpoids, $snmpbgpPeerState); | ||
| 121 | push(@snmpoids, $snmpbgpPeerLocalAddr); | ||
| 122 | push(@snmpoids, $snmpbgpPeerRemoteAddr); | ||
| 123 | push(@snmpoids, $snmpbgpPeerRemoteAs); | ||
| 124 | |||
| 125 | foreach $snmpoid (@snmpoids) { | ||
| 126 | |||
| 127 | ($session, $error) = Net::SNMP->session( | ||
| 128 | -hostname => $hostname, | ||
| 129 | -community => $community, | ||
| 130 | -port => $port | ||
| 131 | ); | ||
| 132 | |||
| 133 | if (!defined($session)) { | ||
| 134 | $state='UNKNOWN'; | ||
| 135 | $answer=$error; | ||
| 136 | print ("$state: $answer"); | ||
| 137 | exit $ERRORS{$state}; | ||
| 138 | } | ||
| 139 | |||
| 140 | if (!defined($response = $session->get_table($snmpoid))) { | ||
| 141 | $answer=$session->error; | ||
| 142 | $session->close; | ||
| 143 | $state = 'CRITICAL'; | ||
| 144 | print ("$state: $answer,$community,$snmpkey"); | ||
| 145 | exit $ERRORS{$state}; | ||
| 146 | } | ||
| 147 | |||
| 148 | foreach $snmpkey (keys %{$response}) { | ||
| 149 | $snmpkey =~ m/.*\.(\d+\.\d+\.\d+\.\d+$)/; | ||
| 150 | $key = $1; | ||
| 151 | # printf "debug: $snmpkey: $key -> $response->{$snmpkey}\n"; | ||
| 152 | $bgpStatus{$key}{$snmpoid} = $response->{$snmpkey}; | ||
| 153 | } | ||
| 154 | $session->close; | ||
| 155 | } | ||
| 156 | |||
| 157 | foreach $key (keys %bgpStatus) { | ||
| 158 | if ($bgpStatus{$key}{$snmpbgpPeerState} == 6 ) { | ||
| 159 | $bgpestablished++; | ||
| 160 | } | ||
| 161 | elsif ($bgpStatus{$key}{$snmpbgpPeerState} == 1 ) { | ||
| 162 | $bgpidle++; | ||
| 163 | } | ||
| 164 | else { | ||
| 165 | $bgpdown++ ; | ||
| 166 | if (exists($uplinks{$bgpStatus{$key}{$snmpbgpPeerRemoteAs}}) ) { | ||
| 167 | $bgpcritical++; | ||
| 168 | } | ||
| 169 | @output = `$whois -T aut-num AS$bgpStatus{$key}{$snmpbgpPeerRemoteAs}`; | ||
| 170 | |||
| 171 | $asname = ""; | ||
| 172 | foreach (@output) { | ||
| 173 | if (m/as-name/) { | ||
| 174 | $asname = $_; | ||
| 175 | $asname =~ s/as-name://; | ||
| 176 | last; | ||
| 177 | } | ||
| 178 | if ( $asname =~ "" && m/descr/ ) { | ||
| 179 | $asname = $_; | ||
| 180 | $asname =~ s/descr://; | ||
| 181 | } | ||
| 182 | } | ||
| 183 | $asname =~ s/^\s*//; | ||
| 184 | $asname =~ s/\s*$//; | ||
| 185 | $bgpmessage .= sprintf("Peering with AS%s not established -> %s<BR>", | ||
| 186 | $bgpStatus{$key}{$snmpbgpPeerRemoteAs}, | ||
| 187 | $asname); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | |||
| 192 | if ($bgpdown > 0) { | ||
| 193 | if ($bgpcritical > 0) { | ||
| 194 | $state = 'CRITICAL'; | ||
| 195 | } | ||
| 196 | else { | ||
| 197 | $state = 'WARNING'; | ||
| 198 | } | ||
| 199 | $answer = sprintf("host '%s', sessions up: %d, down: %d, shutdown: %d<BR>", | ||
| 200 | $hostname, | ||
| 201 | $bgpestablished, | ||
| 202 | $bgpdown, $bgpidle); | ||
| 203 | $answer = $answer . $bgpmessage . "\n"; | ||
| 204 | } | ||
| 205 | else { | ||
| 206 | $state = 'OK'; | ||
| 207 | $answer = sprintf("host '%s', sessions up: %d, down: %d, shutdown: %d\n", | ||
| 208 | $hostname, | ||
| 209 | $bgpestablished, | ||
| 210 | $bgpdown,$bgpidle); | ||
| 211 | } | ||
| 212 | |||
| 213 | print ("$state: $answer"); | ||
| 214 | exit $ERRORS{$state}; | ||
| 215 | |||
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 @@ | |||
| 1 | /****************************************************************************** | ||
| 2 | * | ||
| 3 | * CHECK_DHCP.C | ||
| 4 | * | ||
| 5 | * Program: DHCP plugin for Nagios | ||
| 6 | * License: GPL | ||
| 7 | * Copyright (c) 2001 Ethan Galstad (nagios@nagios.org) | ||
| 8 | * | ||
| 9 | * License Information: | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation; either version 2 of the License, or | ||
| 14 | * (at your option) any later version. | ||
| 15 | * | ||
| 16 | * This program is distributed in the hope that it will be useful, | ||
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 19 | * GNU General Public License for more details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 24 | * | ||
| 25 | *****************************************************************************/ | ||
| 26 | |||
| 27 | #include <stdio.h> | ||
| 28 | #include <stdlib.h> | ||
| 29 | #include <string.h> | ||
| 30 | #include <errno.h> | ||
| 31 | #include <unistd.h> | ||
| 32 | #include <sys/time.h> | ||
| 33 | #include <sys/ioctl.h> | ||
| 34 | #include <fcntl.h> | ||
| 35 | #include <features.h> | ||
| 36 | #include <linux/if_ether.h> | ||
| 37 | #include <getopt.h> | ||
| 38 | #include <net/if.h> | ||
| 39 | #include <sys/socket.h> | ||
| 40 | #include <sys/types.h> | ||
| 41 | #include <netinet/in.h> | ||
| 42 | #include <arpa/inet.h> | ||
| 43 | #include <netdb.h> | ||
| 44 | |||
| 45 | #define PROGNAME "check_dhcp" | ||
| 46 | |||
| 47 | /*#define DEBUG*/ | ||
| 48 | #define HAVE_GETOPT_H | ||
| 49 | |||
| 50 | |||
| 51 | /**** Common definitions ****/ | ||
| 52 | |||
| 53 | #define STATE_OK 0 | ||
| 54 | #define STATE_WARNING 1 | ||
| 55 | #define STATE_CRITICAL 2 | ||
| 56 | #define STATE_UNKNOWN -1 | ||
| 57 | |||
| 58 | #define OK 0 | ||
| 59 | #define ERROR -1 | ||
| 60 | |||
| 61 | #define FALSE 0 | ||
| 62 | #define TRUE 1 | ||
| 63 | |||
| 64 | |||
| 65 | /**** DHCP definitions ****/ | ||
| 66 | |||
| 67 | #define MAX_DHCP_CHADDR_LENGTH 16 | ||
| 68 | #define MAX_DHCP_SNAME_LENGTH 64 | ||
| 69 | #define MAX_DHCP_FILE_LENGTH 128 | ||
| 70 | #define MAX_DHCP_OPTIONS_LENGTH 312 | ||
| 71 | |||
| 72 | |||
| 73 | typedef struct dhcp_packet_struct{ | ||
| 74 | u_int8_t op; /* packet type */ | ||
| 75 | u_int8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ | ||
| 76 | u_int8_t hlen; /* length of hardware address (of this machine) */ | ||
| 77 | u_int8_t hops; /* hops */ | ||
| 78 | u_int32_t xid; /* random transaction id number - chosen by this machine */ | ||
| 79 | u_int16_t secs; /* seconds used in timing */ | ||
| 80 | u_int16_t flags; /* flags */ | ||
| 81 | struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ | ||
| 82 | struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ | ||
| 83 | struct in_addr siaddr; /* IP address of DHCP server */ | ||
| 84 | struct in_addr giaddr; /* IP address of DHCP relay */ | ||
| 85 | unsigned char chaddr [MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */ | ||
| 86 | char sname [MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */ | ||
| 87 | char file [MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */ | ||
| 88 | char options[MAX_DHCP_OPTIONS_LENGTH]; /* options */ | ||
| 89 | }dhcp_packet; | ||
| 90 | |||
| 91 | |||
| 92 | typedef struct dhcp_offer_struct{ | ||
| 93 | struct in_addr server_address; /* address of DHCP server that sent this offer */ | ||
| 94 | struct in_addr offered_address; /* the IP address that was offered to us */ | ||
| 95 | u_int32_t lease_time; /* lease time in seconds */ | ||
| 96 | u_int32_t renewal_time; /* renewal time in seconds */ | ||
| 97 | u_int32_t rebinding_time; /* rebinding time in seconds */ | ||
| 98 | struct dhcp_offer_struct *next; | ||
| 99 | }dhcp_offer; | ||
| 100 | |||
| 101 | |||
| 102 | typedef struct requested_server_struct{ | ||
| 103 | struct in_addr server_address; | ||
| 104 | struct requested_server_struct *next; | ||
| 105 | }requested_server; | ||
| 106 | |||
| 107 | |||
| 108 | #define BOOTREQUEST 1 | ||
| 109 | #define BOOTREPLY 2 | ||
| 110 | |||
| 111 | #define DHCPDISCOVER 1 | ||
| 112 | #define DHCPOFFER 2 | ||
| 113 | #define DHCPREQUEST 3 | ||
| 114 | #define DHCPDECLINE 4 | ||
| 115 | #define DHCPACK 5 | ||
| 116 | #define DHCPNACK 6 | ||
| 117 | #define DHCPRELEASE 7 | ||
| 118 | |||
| 119 | #define DHCP_OPTION_MESSAGE_TYPE 53 | ||
| 120 | #define DHCP_OPTION_HOST_NAME 12 | ||
| 121 | #define DHCP_OPTION_BROADCAST_ADDRESS 28 | ||
| 122 | #define DHCP_OPTION_REQUESTED_ADDRESS 50 | ||
| 123 | #define DHCP_OPTION_LEASE_TIME 51 | ||
| 124 | #define DHCP_OPTION_RENEWAL_TIME 58 | ||
| 125 | #define DHCP_OPTION_REBINDING_TIME 59 | ||
| 126 | |||
| 127 | #define DHCP_INFINITE_TIME 0xFFFFFFFF | ||
| 128 | |||
| 129 | #define DHCP_BROADCAST_FLAG 32768 | ||
| 130 | |||
| 131 | #define DHCP_SERVER_PORT 67 | ||
| 132 | #define DHCP_CLIENT_PORT 68 | ||
| 133 | |||
| 134 | #define ETHERNET_HARDWARE_ADDRESS 1 /* used in htype field of dhcp packet */ | ||
| 135 | #define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */ | ||
| 136 | |||
| 137 | unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH]=""; | ||
| 138 | |||
| 139 | char network_interface_name[8]="eth0"; | ||
| 140 | |||
| 141 | u_int32_t packet_xid=0; | ||
| 142 | |||
| 143 | u_int32_t dhcp_lease_time=0; | ||
| 144 | u_int32_t dhcp_renewal_time=0; | ||
| 145 | u_int32_t dhcp_rebinding_time=0; | ||
| 146 | |||
| 147 | int dhcpoffer_timeout=2; | ||
| 148 | |||
| 149 | dhcp_offer *dhcp_offer_list=NULL; | ||
| 150 | requested_server *requested_server_list=NULL; | ||
| 151 | |||
| 152 | int valid_responses=0; /* number of valid DHCPOFFERs we received */ | ||
| 153 | int requested_servers=0; | ||
| 154 | int requested_responses=0; | ||
| 155 | |||
| 156 | int request_specific_address=FALSE; | ||
| 157 | int received_requested_address=FALSE; | ||
| 158 | struct in_addr requested_address; | ||
| 159 | |||
| 160 | |||
| 161 | int process_arguments(int, char **); | ||
| 162 | int call_getopt(int, char **); | ||
| 163 | int validate_arguments(void); | ||
| 164 | void print_usage(void); | ||
| 165 | void print_help(void); | ||
| 166 | |||
| 167 | int get_hardware_address(int,char *); | ||
| 168 | |||
| 169 | int send_dhcp_discover(int); | ||
| 170 | int get_dhcp_offer(int); | ||
| 171 | |||
| 172 | int get_results(void); | ||
| 173 | |||
| 174 | int add_dhcp_offer(struct in_addr,dhcp_packet *); | ||
| 175 | int free_dhcp_offer_list(void); | ||
| 176 | int free_requested_server_list(void); | ||
| 177 | |||
| 178 | int create_dhcp_socket(void); | ||
| 179 | int close_dhcp_socket(int); | ||
| 180 | int send_dhcp_packet(void *,int,int,struct sockaddr_in *); | ||
| 181 | int receive_dhcp_packet(void *,int,int,int,struct sockaddr_in *); | ||
| 182 | |||
| 183 | |||
| 184 | |||
| 185 | int main(int argc, char **argv){ | ||
| 186 | int dhcp_socket; | ||
| 187 | int result; | ||
| 188 | |||
| 189 | if(process_arguments(argc,argv)!=OK){ | ||
| 190 | /*usage("Invalid command arguments supplied\n");*/ | ||
| 191 | printf("Invalid command arguments supplied\n"); | ||
| 192 | exit(STATE_UNKNOWN); | ||
| 193 | } | ||
| 194 | |||
| 195 | |||
| 196 | /* create socket for DHCP communications */ | ||
| 197 | dhcp_socket=create_dhcp_socket(); | ||
| 198 | |||
| 199 | /* get hardware address of client machine */ | ||
| 200 | get_hardware_address(dhcp_socket,network_interface_name); | ||
| 201 | |||
| 202 | /* send DHCPDISCOVER packet */ | ||
| 203 | send_dhcp_discover(dhcp_socket); | ||
| 204 | |||
| 205 | /* wait for a DHCPOFFER packet */ | ||
| 206 | get_dhcp_offer(dhcp_socket); | ||
| 207 | |||
| 208 | /* close socket we created */ | ||
| 209 | close_dhcp_socket(dhcp_socket); | ||
| 210 | |||
| 211 | /* determine state/plugin output to return */ | ||
| 212 | result=get_results(); | ||
| 213 | |||
| 214 | /* free allocated memory */ | ||
| 215 | free_dhcp_offer_list(); | ||
| 216 | free_requested_server_list(); | ||
| 217 | |||
| 218 | return result; | ||
| 219 | } | ||
| 220 | |||
| 221 | |||
| 222 | |||
| 223 | /* determines hardware address on client machine */ | ||
| 224 | int get_hardware_address(int sock,char *interface_name){ | ||
| 225 | struct ifreq ifr; | ||
| 226 | |||
| 227 | strncpy((char *)&ifr.ifr_name,interface_name,sizeof(ifr.ifr_name)); | ||
| 228 | |||
| 229 | /* try and grab hardware address of requested interface */ | ||
| 230 | if(ioctl(sock,SIOCGIFHWADDR,&ifr)<0){ | ||
| 231 | printf("Error: Could not get hardware address of interface '%s'\n",interface_name); | ||
| 232 | exit(STATE_UNKNOWN); | ||
| 233 | } | ||
| 234 | |||
| 235 | memcpy(&client_hardware_address[0],&ifr.ifr_hwaddr.sa_data,6); | ||
| 236 | |||
| 237 | #ifdef DEBUG | ||
| 238 | printf("Hardware address: %02x:%02x:%02x:",client_hardware_address[0],client_hardware_address[1],client_hardware_address[2]); | ||
| 239 | printf("%02x:",client_hardware_address[3]); | ||
| 240 | printf("%02x:%02x\n",client_hardware_address[4],client_hardware_address[5]); | ||
| 241 | printf("\n"); | ||
| 242 | #endif | ||
| 243 | |||
| 244 | return OK; | ||
| 245 | } | ||
| 246 | |||
| 247 | |||
| 248 | /* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */ | ||
| 249 | int send_dhcp_discover(int sock){ | ||
| 250 | dhcp_packet discover_packet; | ||
| 251 | struct sockaddr_in sockaddr_broadcast; | ||
| 252 | |||
| 253 | |||
| 254 | /* clear the packet data structure */ | ||
| 255 | bzero(&discover_packet,sizeof(discover_packet)); | ||
| 256 | |||
| 257 | |||
| 258 | /* boot request flag (backward compatible with BOOTP servers) */ | ||
| 259 | discover_packet.op=BOOTREQUEST; | ||
| 260 | |||
| 261 | /* hardware address type */ | ||
| 262 | discover_packet.htype=ETHERNET_HARDWARE_ADDRESS; | ||
| 263 | |||
| 264 | /* length of our hardware address */ | ||
| 265 | discover_packet.hlen=ETHERNET_HARDWARE_ADDRESS_LENGTH; | ||
| 266 | |||
| 267 | discover_packet.hops=0; | ||
| 268 | |||
| 269 | /* transaction id is supposed to be random */ | ||
| 270 | srand(time(NULL)); | ||
| 271 | packet_xid=random(); | ||
| 272 | discover_packet.xid=htonl(packet_xid); | ||
| 273 | |||
| 274 | /**** WHAT THE HECK IS UP WITH THIS?!? IF I DON'T MAKE THIS CALL, ONLY ONE SERVER RESPONSE IS PROCESSED!!!! ****/ | ||
| 275 | /* downright bizzarre... */ | ||
| 276 | ntohl(discover_packet.xid); | ||
| 277 | |||
| 278 | /*discover_packet.secs=htons(65535);*/ | ||
| 279 | discover_packet.secs=0xFF; | ||
| 280 | |||
| 281 | /* tell server it should broadcast its response */ | ||
| 282 | discover_packet.flags=htons(DHCP_BROADCAST_FLAG); | ||
| 283 | |||
| 284 | /* our hardware address */ | ||
| 285 | memcpy(discover_packet.chaddr,client_hardware_address,ETHERNET_HARDWARE_ADDRESS_LENGTH); | ||
| 286 | |||
| 287 | /* first four bytes of options field is magic cookie (as per RFC 2132) */ | ||
| 288 | discover_packet.options[0]='\x63'; | ||
| 289 | discover_packet.options[1]='\x82'; | ||
| 290 | discover_packet.options[2]='\x53'; | ||
| 291 | discover_packet.options[3]='\x63'; | ||
| 292 | |||
| 293 | /* DHCP message type is embedded in options field */ | ||
| 294 | discover_packet.options[4]=DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ | ||
| 295 | discover_packet.options[5]='\x01'; /* DHCP message option length in bytes */ | ||
| 296 | discover_packet.options[6]=DHCPDISCOVER; | ||
| 297 | |||
| 298 | /* the IP address we're requesting */ | ||
| 299 | if(request_specific_address==TRUE){ | ||
| 300 | discover_packet.options[7]=DHCP_OPTION_REQUESTED_ADDRESS; | ||
| 301 | discover_packet.options[8]='\x04'; | ||
| 302 | memcpy(&discover_packet.options[9],&requested_address,sizeof(requested_address)); | ||
| 303 | } | ||
| 304 | |||
| 305 | /* send the DHCPDISCOVER packet to broadcast address */ | ||
| 306 | sockaddr_broadcast.sin_family=AF_INET; | ||
| 307 | sockaddr_broadcast.sin_port=htons(DHCP_SERVER_PORT); | ||
| 308 | sockaddr_broadcast.sin_addr.s_addr=INADDR_BROADCAST; | ||
| 309 | bzero(&sockaddr_broadcast.sin_zero,sizeof(sockaddr_broadcast.sin_zero)); | ||
| 310 | |||
| 311 | |||
| 312 | #ifdef DEBUG | ||
| 313 | printf("DHCPDISCOVER to %s port %d\n",inet_ntoa(sockaddr_broadcast.sin_addr),ntohs(sockaddr_broadcast.sin_port)); | ||
| 314 | printf("DHCPDISCOVER XID: %lu (0x%X)\n",ntohl(discover_packet.xid),ntohl(discover_packet.xid)); | ||
| 315 | printf("DHCDISCOVER ciaddr: %s\n",inet_ntoa(discover_packet.ciaddr)); | ||
| 316 | printf("DHCDISCOVER yiaddr: %s\n",inet_ntoa(discover_packet.yiaddr)); | ||
| 317 | printf("DHCDISCOVER siaddr: %s\n",inet_ntoa(discover_packet.siaddr)); | ||
| 318 | printf("DHCDISCOVER giaddr: %s\n",inet_ntoa(discover_packet.giaddr)); | ||
| 319 | #endif | ||
| 320 | |||
| 321 | /* send the DHCPDISCOVER packet out */ | ||
| 322 | send_dhcp_packet(&discover_packet,sizeof(discover_packet),sock,&sockaddr_broadcast); | ||
| 323 | |||
| 324 | #ifdef DEBUG | ||
| 325 | printf("\n\n"); | ||
| 326 | #endif | ||
| 327 | |||
| 328 | return OK; | ||
| 329 | } | ||
| 330 | |||
| 331 | |||
| 332 | |||
| 333 | |||
| 334 | /* waits for a DHCPOFFER message from one or more DHCP servers */ | ||
| 335 | int get_dhcp_offer(int sock){ | ||
| 336 | dhcp_packet offer_packet; | ||
| 337 | struct sockaddr_in source; | ||
| 338 | int result=OK; | ||
| 339 | int timeout=1; | ||
| 340 | int responses=0; | ||
| 341 | int x; | ||
| 342 | time_t start_time; | ||
| 343 | time_t current_time; | ||
| 344 | |||
| 345 | time(&start_time); | ||
| 346 | |||
| 347 | /* receive as many responses as we can */ | ||
| 348 | for(responses=0,valid_responses=0;;){ | ||
| 349 | |||
| 350 | time(¤t_time); | ||
| 351 | if((current_time-start_time)>=dhcpoffer_timeout) | ||
| 352 | break; | ||
| 353 | |||
| 354 | #ifdef DEBUG | ||
| 355 | printf("\n\n"); | ||
| 356 | #endif | ||
| 357 | |||
| 358 | bzero(&source,sizeof(source)); | ||
| 359 | bzero(&offer_packet,sizeof(offer_packet)); | ||
| 360 | |||
| 361 | result=OK; | ||
| 362 | result=receive_dhcp_packet(&offer_packet,sizeof(offer_packet),sock,dhcpoffer_timeout,&source); | ||
| 363 | |||
| 364 | if(result!=OK){ | ||
| 365 | #ifdef DEBUG | ||
| 366 | printf("Result=ERROR\n"); | ||
| 367 | #endif | ||
| 368 | continue; | ||
| 369 | } | ||
| 370 | else{ | ||
| 371 | #ifdef DEBUG | ||
| 372 | printf("Result=OK\n"); | ||
| 373 | #endif | ||
| 374 | responses++; | ||
| 375 | } | ||
| 376 | |||
| 377 | #ifdef DEBUG | ||
| 378 | printf("DHCPOFFER from IP address %s\n",inet_ntoa(source.sin_addr)); | ||
| 379 | printf("DHCPOFFER XID: %lu (0x%X)\n",ntohl(offer_packet.xid),ntohl(offer_packet.xid)); | ||
| 380 | #endif | ||
| 381 | |||
| 382 | /* check packet xid to see if its the same as the one we used in the discover packet */ | ||
| 383 | if(ntohl(offer_packet.xid)!=packet_xid){ | ||
| 384 | #ifdef DEBUG | ||
| 385 | printf("DHCPOFFER XID (%lu) did not match DHCPDISCOVER XID (%lu) - ignoring packet\n",ntohl(offer_packet.xid),packet_xid); | ||
| 386 | #endif | ||
| 387 | continue; | ||
| 388 | } | ||
| 389 | |||
| 390 | /* check hardware address */ | ||
| 391 | result=OK; | ||
| 392 | #ifdef DEBUG | ||
| 393 | printf("DHCPOFFER chaddr: "); | ||
| 394 | #endif | ||
| 395 | for(x=0;x<ETHERNET_HARDWARE_ADDRESS_LENGTH;x++){ | ||
| 396 | #ifdef DEBUG | ||
| 397 | printf("%02X",(unsigned char)offer_packet.chaddr[x]); | ||
| 398 | #endif | ||
| 399 | if(offer_packet.chaddr[x]!=client_hardware_address[x]){ | ||
| 400 | result=ERROR; | ||
| 401 | } | ||
| 402 | } | ||
| 403 | #ifdef DEBUG | ||
| 404 | printf("\n"); | ||
| 405 | #endif | ||
| 406 | if(result==ERROR){ | ||
| 407 | #ifdef DEBUG | ||
| 408 | printf("DHCPOFFER hardware address did not match our own - ignoring packet\n"); | ||
| 409 | #endif | ||
| 410 | continue; | ||
| 411 | } | ||
| 412 | |||
| 413 | #ifdef DEBUG | ||
| 414 | printf("DHCPOFFER ciaddr: %s\n",inet_ntoa(offer_packet.ciaddr)); | ||
| 415 | printf("DHCPOFFER yiaddr: %s\n",inet_ntoa(offer_packet.yiaddr)); | ||
| 416 | printf("DHCPOFFER siaddr: %s\n",inet_ntoa(offer_packet.siaddr)); | ||
| 417 | printf("DHCPOFFER giaddr: %s\n",inet_ntoa(offer_packet.giaddr)); | ||
| 418 | #endif | ||
| 419 | |||
| 420 | add_dhcp_offer(source.sin_addr,&offer_packet); | ||
| 421 | |||
| 422 | valid_responses++; | ||
| 423 | } | ||
| 424 | |||
| 425 | #ifdef DEBUG | ||
| 426 | printf("Total responses seen on the wire: %d\n",responses); | ||
| 427 | printf("Valid responses for this machine: %d\n",valid_responses); | ||
| 428 | #endif | ||
| 429 | |||
| 430 | return OK; | ||
| 431 | } | ||
| 432 | |||
| 433 | |||
| 434 | |||
| 435 | /* sends a DHCP packet */ | ||
| 436 | int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in *dest){ | ||
| 437 | struct sockaddr_in myname; | ||
| 438 | int result; | ||
| 439 | |||
| 440 | result=sendto(sock,(char *)buffer,buffer_size,0,(struct sockaddr_in *)dest,sizeof(*dest)); | ||
| 441 | |||
| 442 | #ifdef DEBUG | ||
| 443 | printf("send_dhcp_packet result: %d\n",result); | ||
| 444 | #endif | ||
| 445 | |||
| 446 | if(result<0) | ||
| 447 | return ERROR; | ||
| 448 | |||
| 449 | return OK; | ||
| 450 | } | ||
| 451 | |||
| 452 | |||
| 453 | |||
| 454 | /* receives a DHCP packet */ | ||
| 455 | int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, struct sockaddr_in *address){ | ||
| 456 | struct timeval tv; | ||
| 457 | fd_set readfds; | ||
| 458 | int recv_result; | ||
| 459 | socklen_t address_size; | ||
| 460 | struct sockaddr_in source_address; | ||
| 461 | |||
| 462 | |||
| 463 | /* wait for data to arrive (up time timeout) */ | ||
| 464 | tv.tv_sec=timeout; | ||
| 465 | tv.tv_usec=0; | ||
| 466 | FD_ZERO(&readfds); | ||
| 467 | FD_SET(sock,&readfds); | ||
| 468 | select(sock+1,&readfds,NULL,NULL,&tv); | ||
| 469 | |||
| 470 | /* make sure some data has arrived */ | ||
| 471 | if(!FD_ISSET(sock,&readfds)){ | ||
| 472 | #ifdef DEBUG | ||
| 473 | printf("No (more) data recieved\n"); | ||
| 474 | #endif | ||
| 475 | return ERROR; | ||
| 476 | } | ||
| 477 | |||
| 478 | else{ | ||
| 479 | |||
| 480 | /* 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 | ||
| 481 | not being interpreted correctly. sigh... */ | ||
| 482 | bzero(&source_address,sizeof(source_address)); | ||
| 483 | recv_result=recvfrom(sock,(char *)buffer,buffer_size,MSG_PEEK,(struct sockaddr_in *)&source_address,&address_size); | ||
| 484 | #ifdef DEBUG | ||
| 485 | printf("recv_result_1: %d\n",recv_result); | ||
| 486 | #endif | ||
| 487 | recv_result=recvfrom(sock,(char *)buffer,buffer_size,0,(struct sockaddr_in *)&source_address,&address_size); | ||
| 488 | #ifdef DEBUG | ||
| 489 | printf("recv_result_2: %d\n",recv_result); | ||
| 490 | #endif | ||
| 491 | |||
| 492 | if(recv_result==-1){ | ||
| 493 | #ifdef DEBUG | ||
| 494 | printf("recvfrom() failed, "); | ||
| 495 | printf("errno: (%d) -> %s\n",errno,strerror(errno)); | ||
| 496 | #endif | ||
| 497 | return ERROR; | ||
| 498 | } | ||
| 499 | else{ | ||
| 500 | #ifdef DEBUG | ||
| 501 | printf("receive_dhcp_packet() result: %d\n",recv_result); | ||
| 502 | printf("receive_dhcp_packet() source: %s\n",inet_ntoa(source_address.sin_addr)); | ||
| 503 | #endif | ||
| 504 | |||
| 505 | memcpy(address,&source_address,sizeof(source_address)); | ||
| 506 | return OK; | ||
| 507 | } | ||
| 508 | } | ||
| 509 | |||
| 510 | return OK; | ||
| 511 | } | ||
| 512 | |||
| 513 | |||
| 514 | |||
| 515 | /* creates a socket for DHCP communication */ | ||
| 516 | int create_dhcp_socket(void){ | ||
| 517 | struct sockaddr_in myname; | ||
| 518 | int sock; | ||
| 519 | int flag=1; | ||
| 520 | |||
| 521 | /* Set up the address we're going to bind to. */ | ||
| 522 | bzero(&myname,sizeof(myname)); | ||
| 523 | myname.sin_family=AF_INET; | ||
| 524 | myname.sin_port=htons(DHCP_CLIENT_PORT); | ||
| 525 | myname.sin_addr.s_addr=INADDR_ANY; /* listen on any address */ | ||
| 526 | bzero(&myname.sin_zero,sizeof(myname.sin_zero)); | ||
| 527 | |||
| 528 | /* create a socket for DHCP communications */ | ||
| 529 | sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); | ||
| 530 | if(sock<0){ | ||
| 531 | printf("Error: Could not create socket!\n"); | ||
| 532 | exit(STATE_UNKNOWN); | ||
| 533 | } | ||
| 534 | |||
| 535 | #ifdef DEBUG | ||
| 536 | printf("DHCP socket: %d\n",sock); | ||
| 537 | #endif | ||
| 538 | |||
| 539 | /* set the reuse address flag so we don't get errors when restarting */ | ||
| 540 | flag=1; | ||
| 541 | if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){ | ||
| 542 | printf("Error: Could not set reuse address option on DHCP socket!\n"); | ||
| 543 | exit(STATE_UNKNOWN); | ||
| 544 | } | ||
| 545 | |||
| 546 | /* set the broadcast option - we need this to listen to DHCP broadcast messages */ | ||
| 547 | if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char *)&flag,sizeof flag)<0){ | ||
| 548 | printf("Error: Could not set broadcast option on DHCP socket!\n"); | ||
| 549 | exit(STATE_UNKNOWN); | ||
| 550 | } | ||
| 551 | |||
| 552 | /* bind the socket */ | ||
| 553 | if(bind(sock,(struct sockaddr *)&myname,sizeof(myname))<0){ | ||
| 554 | printf("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n",DHCP_CLIENT_PORT); | ||
| 555 | exit(STATE_UNKNOWN); | ||
| 556 | } | ||
| 557 | |||
| 558 | return sock; | ||
| 559 | } | ||
| 560 | |||
| 561 | |||
| 562 | |||
| 563 | |||
| 564 | |||
| 565 | /* closes DHCP socket */ | ||
| 566 | int close_dhcp_socket(int sock){ | ||
| 567 | |||
| 568 | close(sock); | ||
| 569 | |||
| 570 | return OK; | ||
| 571 | } | ||
| 572 | |||
| 573 | |||
| 574 | |||
| 575 | |||
| 576 | /* adds a requested server address to list in memory */ | ||
| 577 | int add_requested_server(struct in_addr server_address){ | ||
| 578 | requested_server *new_server; | ||
| 579 | |||
| 580 | new_server=(requested_server *)malloc(sizeof(requested_server)); | ||
| 581 | if(new_server==NULL) | ||
| 582 | return ERROR; | ||
| 583 | |||
| 584 | new_server->server_address=server_address; | ||
| 585 | |||
| 586 | new_server->next=requested_server_list; | ||
| 587 | requested_server_list=new_server; | ||
| 588 | |||
| 589 | requested_servers++; | ||
| 590 | |||
| 591 | #ifdef DEBUG | ||
| 592 | printf("Requested server address: %s\n",inet_ntoa(new_server->server_address)); | ||
| 593 | #endif | ||
| 594 | |||
| 595 | return OK; | ||
| 596 | } | ||
| 597 | |||
| 598 | |||
| 599 | |||
| 600 | |||
| 601 | /* adds a DHCP OFFER to list in memory */ | ||
| 602 | int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){ | ||
| 603 | dhcp_offer *new_offer; | ||
| 604 | int x; | ||
| 605 | int y; | ||
| 606 | unsigned option_type; | ||
| 607 | unsigned option_length; | ||
| 608 | |||
| 609 | if(offer_packet==NULL) | ||
| 610 | return ERROR; | ||
| 611 | |||
| 612 | /* process all DHCP options present in the packet */ | ||
| 613 | for(x=4;x<MAX_DHCP_OPTIONS_LENGTH;){ | ||
| 614 | |||
| 615 | /* end of options (0 is really just a pad, but bail out anyway) */ | ||
| 616 | if((int)offer_packet->options[x]==-1 || (int)offer_packet->options[x]==0) | ||
| 617 | break; | ||
| 618 | |||
| 619 | /* get option type */ | ||
| 620 | option_type=offer_packet->options[x++]; | ||
| 621 | |||
| 622 | /* get option length */ | ||
| 623 | option_length=offer_packet->options[x++]; | ||
| 624 | |||
| 625 | #ifdef DEBUG | ||
| 626 | printf("Option: %d (0x%02X)\n",option_type,option_length); | ||
| 627 | #endif | ||
| 628 | |||
| 629 | /* get option data */ | ||
| 630 | if(option_type==DHCP_OPTION_LEASE_TIME) | ||
| 631 | dhcp_lease_time=ntohl(*((u_int32_t *)&offer_packet->options[x])); | ||
| 632 | if(option_type==DHCP_OPTION_RENEWAL_TIME) | ||
| 633 | dhcp_renewal_time=ntohl(*((u_int32_t *)&offer_packet->options[x])); | ||
| 634 | if(option_type==DHCP_OPTION_REBINDING_TIME) | ||
| 635 | dhcp_rebinding_time=ntohl(*((u_int32_t *)&offer_packet->options[x])); | ||
| 636 | |||
| 637 | /* skip option data we're ignoring */ | ||
| 638 | else | ||
| 639 | for(y=0;y<option_length;y++,x++); | ||
| 640 | } | ||
| 641 | |||
| 642 | #ifdef DEBUG | ||
| 643 | if(dhcp_lease_time==DHCP_INFINITE_TIME) | ||
| 644 | printf("Lease Time: Infinite\n"); | ||
| 645 | else | ||
| 646 | printf("Lease Time: %lu seconds\n",(unsigned long)dhcp_lease_time); | ||
| 647 | if(dhcp_renewal_time==DHCP_INFINITE_TIME) | ||
| 648 | printf("Renewal Time: Infinite\n"); | ||
| 649 | else | ||
| 650 | printf("Renewal Time: %lu seconds\n",(unsigned long)dhcp_renewal_time); | ||
| 651 | if(dhcp_rebinding_time==DHCP_INFINITE_TIME) | ||
| 652 | printf("Rebinding Time: Infinite\n"); | ||
| 653 | printf("Rebinding Time: %lu seconds\n",(unsigned long)dhcp_rebinding_time); | ||
| 654 | #endif | ||
| 655 | |||
| 656 | new_offer=(dhcp_offer *)malloc(sizeof(dhcp_offer)); | ||
| 657 | |||
| 658 | if(new_offer==NULL) | ||
| 659 | return ERROR; | ||
| 660 | |||
| 661 | |||
| 662 | new_offer->server_address=source; | ||
| 663 | new_offer->offered_address=offer_packet->yiaddr; | ||
| 664 | new_offer->lease_time=dhcp_lease_time; | ||
| 665 | new_offer->renewal_time=dhcp_renewal_time; | ||
| 666 | new_offer->rebinding_time=dhcp_rebinding_time; | ||
| 667 | |||
| 668 | |||
| 669 | #ifdef DEBUG | ||
| 670 | printf("Added offer from server @ %s",inet_ntoa(new_offer->server_address)); | ||
| 671 | printf(" of IP address %s\n",inet_ntoa(new_offer->offered_address)); | ||
| 672 | #endif | ||
| 673 | |||
| 674 | /* add new offer to head of list */ | ||
| 675 | new_offer->next=dhcp_offer_list; | ||
| 676 | dhcp_offer_list=new_offer; | ||
| 677 | |||
| 678 | return OK; | ||
| 679 | } | ||
| 680 | |||
| 681 | |||
| 682 | |||
| 683 | |||
| 684 | /* frees memory allocated to DHCP OFFER list */ | ||
| 685 | int free_dhcp_offer_list(void){ | ||
| 686 | dhcp_offer *this_offer; | ||
| 687 | dhcp_offer *next_offer; | ||
| 688 | |||
| 689 | for(this_offer=dhcp_offer_list;this_offer!=NULL;this_offer=next_offer){ | ||
| 690 | next_offer=this_offer->next; | ||
| 691 | free(this_offer); | ||
| 692 | } | ||
| 693 | |||
| 694 | return OK; | ||
| 695 | } | ||
| 696 | |||
| 697 | |||
| 698 | |||
| 699 | |||
| 700 | /* frees memory allocated to requested server list */ | ||
| 701 | int free_requested_server_list(void){ | ||
| 702 | requested_server *this_server; | ||
| 703 | requested_server *next_server; | ||
| 704 | |||
| 705 | for(this_server=requested_server_list;this_server!=NULL;this_server=next_server){ | ||
| 706 | next_server=this_server->next; | ||
| 707 | free(this_server); | ||
| 708 | } | ||
| 709 | |||
| 710 | return OK; | ||
| 711 | } | ||
| 712 | |||
| 713 | |||
| 714 | /* gets state and plugin output to return */ | ||
| 715 | int get_results(void){ | ||
| 716 | dhcp_offer *temp_offer; | ||
| 717 | requested_server *temp_server; | ||
| 718 | int result; | ||
| 719 | u_int32_t max_lease_time=0; | ||
| 720 | |||
| 721 | received_requested_address=FALSE; | ||
| 722 | |||
| 723 | /* checks responses from requested servers */ | ||
| 724 | requested_responses=0; | ||
| 725 | if(requested_servers>0){ | ||
| 726 | |||
| 727 | for(temp_server=requested_server_list;temp_server!=NULL;temp_server=temp_server->next){ | ||
| 728 | |||
| 729 | for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next){ | ||
| 730 | |||
| 731 | /* get max lease time we were offered */ | ||
| 732 | if(temp_offer->lease_time>max_lease_time || temp_offer->lease_time==DHCP_INFINITE_TIME) | ||
| 733 | max_lease_time=temp_offer->lease_time; | ||
| 734 | |||
| 735 | /* see if we got the address we requested */ | ||
| 736 | if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) | ||
| 737 | received_requested_address=TRUE; | ||
| 738 | |||
| 739 | /* see if the servers we wanted a response from talked to us or not */ | ||
| 740 | if(!memcmp(&temp_offer->server_address,&temp_server->server_address,sizeof(temp_server->server_address))){ | ||
| 741 | #ifdef DEBUG | ||
| 742 | printf("DHCP Server Match: Offerer=%s",inet_ntoa(temp_offer->server_address)); | ||
| 743 | printf(" Requested=%s\n",inet_ntoa(temp_server->server_address)); | ||
| 744 | #endif | ||
| 745 | requested_responses++; | ||
| 746 | } | ||
| 747 | } | ||
| 748 | } | ||
| 749 | |||
| 750 | } | ||
| 751 | |||
| 752 | /* else check and see if we got our requested address from any server */ | ||
| 753 | else{ | ||
| 754 | |||
| 755 | for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next){ | ||
| 756 | |||
| 757 | /* get max lease time we were offered */ | ||
| 758 | if(temp_offer->lease_time>max_lease_time || temp_offer->lease_time==DHCP_INFINITE_TIME) | ||
| 759 | max_lease_time=temp_offer->lease_time; | ||
| 760 | |||
| 761 | /* see if we got the address we requested */ | ||
| 762 | if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) | ||
| 763 | received_requested_address=TRUE; | ||
| 764 | } | ||
| 765 | } | ||
| 766 | |||
| 767 | result=STATE_OK; | ||
| 768 | if(valid_responses==0) | ||
| 769 | result=STATE_CRITICAL; | ||
| 770 | else if(requested_servers>0 && requested_responses==0) | ||
| 771 | result=STATE_CRITICAL; | ||
| 772 | else if(requested_responses<requested_servers) | ||
| 773 | result=STATE_WARNING; | ||
| 774 | else if(request_specific_address==TRUE && received_requested_address==FALSE) | ||
| 775 | result=STATE_WARNING; | ||
| 776 | |||
| 777 | |||
| 778 | printf("DHCP %s: ",(result==STATE_OK)?"ok":"problem"); | ||
| 779 | |||
| 780 | /* we didn't receive any DHCPOFFERs */ | ||
| 781 | if(dhcp_offer_list==NULL){ | ||
| 782 | printf("No DHCPOFFERs were received.\n"); | ||
| 783 | return result; | ||
| 784 | } | ||
| 785 | |||
| 786 | printf("Received %d DHCPOFFER(s)",valid_responses); | ||
| 787 | |||
| 788 | if(requested_servers>0) | ||
| 789 | printf(", %s%d of %d requested servers responded",((requested_responses<requested_servers) && requested_responses>0)?"only ":"",requested_responses,requested_servers); | ||
| 790 | |||
| 791 | if(request_specific_address==TRUE) | ||
| 792 | printf(", requested address (%s) was %soffered",inet_ntoa(requested_address),(received_requested_address==TRUE)?"":"not "); | ||
| 793 | |||
| 794 | printf(", max lease time = "); | ||
| 795 | if(max_lease_time==DHCP_INFINITE_TIME) | ||
| 796 | printf("Infinity"); | ||
| 797 | else | ||
| 798 | printf("%lu sec",(unsigned long)max_lease_time); | ||
| 799 | |||
| 800 | printf(".\n"); | ||
| 801 | |||
| 802 | return result; | ||
| 803 | } | ||
| 804 | |||
| 805 | |||
| 806 | |||
| 807 | |||
| 808 | |||
| 809 | |||
| 810 | /* print usage help */ | ||
| 811 | void print_help(void){ | ||
| 812 | |||
| 813 | /*print_revision(PROGNAME,"$Revision$");*/ | ||
| 814 | |||
| 815 | printf("Copyright (c) 2001 Ethan Galstad (nagios@nagios.org)\n\n"); | ||
| 816 | printf("This plugin tests the availability of DHCP servers on a network.\n\n"); | ||
| 817 | |||
| 818 | print_usage(); | ||
| 819 | |||
| 820 | printf | ||
| 821 | ("\nOptions:\n" | ||
| 822 | " -s, --serverip=IPADDRESS\n" | ||
| 823 | " IP address of DHCP server that we must hear from\n" | ||
| 824 | " -r, --requestedip=IPADDRESS\n" | ||
| 825 | " IP address that should be offered by at least one DHCP server\n" | ||
| 826 | " -t, --timeout=INTEGER\n" | ||
| 827 | " Seconds to wait for DHCPOFFER before timeout occurs\n" | ||
| 828 | " -i, --interface=STRING\n" | ||
| 829 | " Interface to to use for listening (i.e. eth0)\n" | ||
| 830 | " -v, --verbose\n" | ||
| 831 | " Print extra information (command-line use only)\n" | ||
| 832 | " -h, --help\n" | ||
| 833 | " Print detailed help screen\n" | ||
| 834 | " -V, --version\n" | ||
| 835 | " Print version information\n\n" | ||
| 836 | ); | ||
| 837 | |||
| 838 | /*support();*/ | ||
| 839 | |||
| 840 | return; | ||
| 841 | } | ||
| 842 | |||
| 843 | |||
| 844 | /* prints usage information */ | ||
| 845 | void print_usage(void){ | ||
| 846 | |||
| 847 | printf("Usage: %s [-s serverip] [-r requestedip] [-t timeout] [-i interface]\n",PROGNAME); | ||
| 848 | printf(" %s --help\n",PROGNAME); | ||
| 849 | printf(" %s --version\n",PROGNAME); | ||
| 850 | |||
| 851 | return; | ||
| 852 | } | ||
| 853 | |||
| 854 | |||
| 855 | |||
| 856 | |||
| 857 | /* process command-line arguments */ | ||
| 858 | int process_arguments(int argc, char **argv){ | ||
| 859 | int c; | ||
| 860 | |||
| 861 | if(argc<1) | ||
| 862 | return ERROR; | ||
| 863 | |||
| 864 | c=0; | ||
| 865 | while((c+=(call_getopt(argc-c,&argv[c])))<argc){ | ||
| 866 | |||
| 867 | /* | ||
| 868 | if(is_option(argv[c])) | ||
| 869 | continue; | ||
| 870 | */ | ||
| 871 | } | ||
| 872 | |||
| 873 | return validate_arguments(); | ||
| 874 | } | ||
| 875 | |||
| 876 | |||
| 877 | |||
| 878 | int call_getopt(int argc, char **argv){ | ||
| 879 | int c=0; | ||
| 880 | int i=0; | ||
| 881 | struct in_addr ipaddress; | ||
| 882 | |||
| 883 | #ifdef HAVE_GETOPT_H | ||
| 884 | int option_index = 0; | ||
| 885 | static struct option long_options[] = | ||
| 886 | { | ||
| 887 | {"serverip", required_argument,0,'s'}, | ||
| 888 | {"requestedip", required_argument,0,'r'}, | ||
| 889 | {"timeout", required_argument,0,'t'}, | ||
| 890 | {"interface", required_argument,0,'i'}, | ||
| 891 | {"verbose", no_argument, 0,'v'}, | ||
| 892 | {"version", no_argument, 0,'V'}, | ||
| 893 | {"help", no_argument, 0,'h'}, | ||
| 894 | {0,0,0,0} | ||
| 895 | }; | ||
| 896 | #endif | ||
| 897 | |||
| 898 | while(1){ | ||
| 899 | #ifdef HAVE_GETOPT_H | ||
| 900 | c=getopt_long(argc,argv,"+hVvt:s:r:t:i:",long_options,&option_index); | ||
| 901 | #else | ||
| 902 | c=getopt(argc,argv,"+?hVvt:s:r:t:i:"); | ||
| 903 | #endif | ||
| 904 | |||
| 905 | i++; | ||
| 906 | |||
| 907 | if(c==-1||c==EOF||c==1) | ||
| 908 | break; | ||
| 909 | |||
| 910 | switch(c){ | ||
| 911 | case 'w': | ||
| 912 | case 'r': | ||
| 913 | case 't': | ||
| 914 | case 'i': | ||
| 915 | i++; | ||
| 916 | break; | ||
| 917 | default: | ||
| 918 | break; | ||
| 919 | } | ||
| 920 | |||
| 921 | switch(c){ | ||
| 922 | |||
| 923 | case 's': /* DHCP server address */ | ||
| 924 | if(inet_aton(optarg,&ipaddress)) | ||
| 925 | add_requested_server(ipaddress); | ||
| 926 | /* | ||
| 927 | else | ||
| 928 | usage("Invalid server IP address\n"); | ||
| 929 | */ | ||
| 930 | break; | ||
| 931 | |||
| 932 | case 'r': /* address we are requested from DHCP servers */ | ||
| 933 | if(inet_aton(optarg,&ipaddress)){ | ||
| 934 | requested_address=ipaddress; | ||
| 935 | request_specific_address=TRUE; | ||
| 936 | } | ||
| 937 | /* | ||
| 938 | else | ||
| 939 | usage("Invalid requested IP address\n"); | ||
| 940 | */ | ||
| 941 | break; | ||
| 942 | |||
| 943 | case 't': /* timeout */ | ||
| 944 | |||
| 945 | /* | ||
| 946 | if(is_intnonneg(optarg)) | ||
| 947 | */ | ||
| 948 | if(atoi(optarg)>0) | ||
| 949 | dhcpoffer_timeout=atoi(optarg); | ||
| 950 | /* | ||
| 951 | else | ||
| 952 | usage("Time interval must be a nonnegative integer\n"); | ||
| 953 | */ | ||
| 954 | break; | ||
| 955 | |||
| 956 | case 'i': /* interface name */ | ||
| 957 | |||
| 958 | strncpy(network_interface_name,optarg,sizeof(network_interface_name)-1); | ||
| 959 | network_interface_name[sizeof(network_interface_name)-1]='\x0'; | ||
| 960 | |||
| 961 | break; | ||
| 962 | |||
| 963 | case 'V': /* version */ | ||
| 964 | |||
| 965 | /*print_revision(PROGNAME,"$Revision$");*/ | ||
| 966 | exit(STATE_OK); | ||
| 967 | |||
| 968 | case 'h': /* help */ | ||
| 969 | |||
| 970 | print_help(); | ||
| 971 | exit(STATE_OK); | ||
| 972 | |||
| 973 | case '?': /* help */ | ||
| 974 | |||
| 975 | /*usage("Invalid argument\n");*/ | ||
| 976 | break; | ||
| 977 | |||
| 978 | default: | ||
| 979 | break; | ||
| 980 | } | ||
| 981 | } | ||
| 982 | |||
| 983 | return i; | ||
| 984 | } | ||
| 985 | |||
| 986 | |||
| 987 | |||
| 988 | int validate_arguments(void){ | ||
| 989 | |||
| 990 | return OK; | ||
| 991 | } | ||
| 992 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | # | ||
| 3 | # check_dlswcircuit.pl - nagios plugin | ||
| 4 | # | ||
| 5 | # Checks if a Cisco Dlsw circuit is connected. | ||
| 6 | # | ||
| 7 | # | ||
| 8 | # Copyright (C) 2000 Carsten Foss & Christoph Kron | ||
| 9 | # | ||
| 10 | # Basically this is an adapted version of Christoph Kron's (ck@zet.net) check_ifoperstatus.pl plugin. | ||
| 11 | # most of the thanks should go to him. | ||
| 12 | # | ||
| 13 | # This program is free software; you can redistribute it and/or | ||
| 14 | # modify it under the terms of the GNU General Public License | ||
| 15 | # as published by the Free Software Foundation; either version 2 | ||
| 16 | # of the License, or (at your option) any later version. | ||
| 17 | # | ||
| 18 | # This program is distributed in the hope that it will be useful, | ||
| 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | # GNU General Public License for more details. | ||
| 22 | # | ||
| 23 | # You should have received a copy of the GNU General Public License | ||
| 24 | # along with this program; if not, write to the Free Software | ||
| 25 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 26 | # | ||
| 27 | # Arguments : -s <SourceMac> -d <DestMac> -c <READCOMMUNITY> -p <PORT> <HOSTNAME or IP-Addr> | ||
| 28 | # - | ||
| 29 | # 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) | ||
| 30 | # | ||
| 31 | # 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 | ||
| 32 | # | ||
| 33 | # Sample host.cfg entry : | ||
| 34 | #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 | ||
| 35 | # remember to add the service to commands.cfg , something like this: | ||
| 36 | # command[check_dlswcircuit]=$USER1$/check_dlswcircuit.pl $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ | ||
| 37 | # | ||
| 38 | # Report bugs to: cfo@dmdata.dk | ||
| 39 | # | ||
| 40 | # 11.03.2000 Version 1.0 | ||
| 41 | |||
| 42 | use strict; | ||
| 43 | |||
| 44 | use Net::SNMP; | ||
| 45 | use Getopt::Long; | ||
| 46 | &Getopt::Long::config('auto_abbrev'); | ||
| 47 | |||
| 48 | |||
| 49 | my $status; | ||
| 50 | my $TIMEOUT = 15; | ||
| 51 | |||
| 52 | my %ERRORS = ('UNKNOWN' , '-1', | ||
| 53 | 'OK' , '0', | ||
| 54 | 'WARNING', '1', | ||
| 55 | 'CRITICAL', '2'); | ||
| 56 | |||
| 57 | my %dlswCircuitStatus = ( | ||
| 58 | '1','disconnected', | ||
| 59 | '2','circuitStart', | ||
| 60 | '3','resolvePending', | ||
| 61 | '4','circuitPending', | ||
| 62 | '5','circuitEstablished', | ||
| 63 | '6','connectPending', | ||
| 64 | '7','contactPending', | ||
| 65 | '8','connected', | ||
| 66 | '9','disconnectPending', | ||
| 67 | '10','haltPending', | ||
| 68 | '11','haltPendingNoack', | ||
| 69 | '13','circuitRestart', | ||
| 70 | '14','restartPending'); | ||
| 71 | |||
| 72 | my $state = "UNKNOWN"; | ||
| 73 | my $answer = ""; | ||
| 74 | my $smac = ""; | ||
| 75 | my $dmac = ""; | ||
| 76 | my $community = "public"; | ||
| 77 | my $port = 161; | ||
| 78 | #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 | ||
| 79 | my $enterpriseOid = "1.3.6.1.4.1"; | ||
| 80 | my $ciscoDlswCircuitOid = ".9.10.9.1.5.2.1.17."; | ||
| 81 | my $unknownOid = "6."; | ||
| 82 | my $smacOid = ""; | ||
| 83 | my $dmacOid = ""; | ||
| 84 | my $tmpOid = ""; | ||
| 85 | my @tmparg; | ||
| 86 | my $snmpoid; | ||
| 87 | my @snmpoids; | ||
| 88 | my $hostname; | ||
| 89 | my $session; | ||
| 90 | my $error; | ||
| 91 | my $response; | ||
| 92 | my $p = ""; | ||
| 93 | my $q = ""; | ||
| 94 | |||
| 95 | sub usage { | ||
| 96 | printf "\nMissing arguments!\n"; | ||
| 97 | printf "\n"; | ||
| 98 | printf "Perl Check Cisco Dlsw Circuit State plugin for Nagios\n"; | ||
| 99 | printf "checks operational status of specified DLSW Circuit\n"; | ||
| 100 | printf "usage: \n"; | ||
| 101 | printf "check_dlswcircuit.pl -s <SourceMac> -d <DestMac> -c <READCOMMUNITY> -p <PORT> <HOSTNAME>"; | ||
| 102 | printf "\nCopyright (C) 2000 Carsten Foss\n"; | ||
| 103 | printf "check_dlswcircuit.pl comes with ABSOLUTELY NO WARRANTY\n"; | ||
| 104 | printf "This programm is licensed under the terms of the "; | ||
| 105 | printf "GNU General Public License\n(check source code for details)\n"; | ||
| 106 | printf "\n\n"; | ||
| 107 | exit $ERRORS{"UNKNOWN"}; | ||
| 108 | } | ||
| 109 | |||
| 110 | # Just in case of problems, let's not hang Nagios | ||
| 111 | $SIG{'ALRM'} = sub { | ||
| 112 | print ("ERROR: No snmp response from $hostname (alarm)\n"); | ||
| 113 | exit $ERRORS{"UNKNOWN"}; | ||
| 114 | }; | ||
| 115 | alarm($TIMEOUT); | ||
| 116 | |||
| 117 | |||
| 118 | $status = GetOptions("sourcemac=s",\$smac,"destmac=s",\$dmac, | ||
| 119 | "community=s",\$community, | ||
| 120 | "port=i",\$port); | ||
| 121 | if ($status == 0) | ||
| 122 | { | ||
| 123 | &usage; | ||
| 124 | } | ||
| 125 | |||
| 126 | # | ||
| 127 | #Convert Source Mac & Sap | ||
| 128 | # | ||
| 129 | @tmparg = split(/\./,$smac); | ||
| 130 | #print "-$smac-\n"; | ||
| 131 | #print "@tmparg\n"; | ||
| 132 | #print "$#tmparg\n"; | ||
| 133 | if($#tmparg != 6) | ||
| 134 | { | ||
| 135 | print "SourceMac/Sap format $smac not valid\n"; | ||
| 136 | &usage; | ||
| 137 | } | ||
| 138 | while($p = shift @tmparg) | ||
| 139 | { | ||
| 140 | $q = hex($p); | ||
| 141 | $smacOid = $smacOid.$q; | ||
| 142 | $smacOid = $smacOid.'.'; | ||
| 143 | } | ||
| 144 | |||
| 145 | #print "@tmparg1\n"; | ||
| 146 | #print "$smacOid\n"; | ||
| 147 | |||
| 148 | # | ||
| 149 | #Convert Dest Mac & Sap | ||
| 150 | # | ||
| 151 | @tmparg = split(/\./,$dmac); | ||
| 152 | #print "-$dmac-\n"; | ||
| 153 | #print "@tmparg\n"; | ||
| 154 | #print "$#tmparg\n"; | ||
| 155 | if($#tmparg != 6) | ||
| 156 | { | ||
| 157 | print "DestMac/Sap format $dmac not valid\n"; | ||
| 158 | &usage; | ||
| 159 | } | ||
| 160 | |||
| 161 | while($p = shift @tmparg) | ||
| 162 | { | ||
| 163 | $q = hex($p); | ||
| 164 | $dmacOid = $dmacOid.$q; | ||
| 165 | $dmacOid = $dmacOid.'.'; | ||
| 166 | } | ||
| 167 | # Remove Trailing Dot | ||
| 168 | $dmacOid = substr($dmacOid,0,length($dmacOid)-1); | ||
| 169 | |||
| 170 | |||
| 171 | #print "@tmparg1\n"; | ||
| 172 | #print "$dmacOid\n"; | ||
| 173 | #Build the Dlsw Oic to use | ||
| 174 | $snmpoid = $enterpriseOid.$ciscoDlswCircuitOid.$unknownOid.$smacOid.$unknownOid.$dmacOid ; | ||
| 175 | #print "$snmpoid\n"; | ||
| 176 | |||
| 177 | #shift; | ||
| 178 | $hostname = shift || &usage; | ||
| 179 | |||
| 180 | ($session, $error) = Net::SNMP->session( | ||
| 181 | -hostname => $hostname, | ||
| 182 | -community => $community, | ||
| 183 | -port => $port | ||
| 184 | ); | ||
| 185 | |||
| 186 | if (!defined($session)) { | ||
| 187 | $state='UNKNOWN'; | ||
| 188 | $answer=$error; | ||
| 189 | print ("$state: $answer"); | ||
| 190 | exit $ERRORS{$state}; | ||
| 191 | } | ||
| 192 | |||
| 193 | push(@snmpoids,$snmpoid); | ||
| 194 | #push(@snmpoids,$snmpLocIfDescr); | ||
| 195 | |||
| 196 | if (!defined($response = $session->get_request(@snmpoids))) { | ||
| 197 | $answer=$session->error; | ||
| 198 | $session->close; | ||
| 199 | $state = 'CRITICAL'; | ||
| 200 | print ("$state: $answer,$community,$smac - $dmac"); | ||
| 201 | exit $ERRORS{$state}; | ||
| 202 | } | ||
| 203 | |||
| 204 | $answer = sprintf("dlsw circuit %s - %s at host '%s',is %s\n", | ||
| 205 | $smac, | ||
| 206 | $dmac, | ||
| 207 | $hostname, | ||
| 208 | $dlswCircuitStatus{$response->{$snmpoid}} | ||
| 209 | ); | ||
| 210 | |||
| 211 | $session->close; | ||
| 212 | |||
| 213 | if ( $response->{$snmpoid} == 8 ) { | ||
| 214 | $state = 'OK'; | ||
| 215 | } | ||
| 216 | else { | ||
| 217 | $state = 'CRITICAL'; | ||
| 218 | } | ||
| 219 | |||
| 220 | print ("$state: $answer"); | ||
| 221 | 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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | # ------------------------------------------------------------------------------ | ||
| 3 | # File Name: check_dns_random.pl | ||
| 4 | # Author: Richard Mayhew - South Africa | ||
| 5 | # Date: 2000/01/26 | ||
| 6 | # Version: 1.0 | ||
| 7 | # Description: This script will check to see if dns resolves hosts | ||
| 8 | # randomly from a list using the check_dns plugin. | ||
| 9 | # Email: netsaint@splash.co.za | ||
| 10 | # ------------------------------------------------------------------------------ | ||
| 11 | # Copyright 1999 (c) Richard Mayhew | ||
| 12 | # Credits go to Ethan Galstad for coding Nagios | ||
| 13 | # If any changes are made to this script, please mail me a copy of the | ||
| 14 | # changes :) | ||
| 15 | # License GPL | ||
| 16 | # ------------------------------------------------------------------------------ | ||
| 17 | # Date Author Reason | ||
| 18 | # ---- ------ ------ | ||
| 19 | # 1999/09/26 RM Creation | ||
| 20 | # ------------------------------------------------------------------------------ | ||
| 21 | |||
| 22 | # -----------------------------------------------------------------[ Require ]-- | ||
| 23 | require 5.004; | ||
| 24 | |||
| 25 | # --------------------------------------------------------------------[ Uses ]-- | ||
| 26 | use Socket; | ||
| 27 | use strict; | ||
| 28 | |||
| 29 | # --------------------------------------------------------------[ Enviroment ]-- | ||
| 30 | $ENV{PATH} = "/bin"; | ||
| 31 | $ENV{BASH_ENV} = ""; | ||
| 32 | $|=1; | ||
| 33 | |||
| 34 | my $host = shift || &usage; | ||
| 35 | |||
| 36 | my $domainfile = "/usr/local/nagios/etc/domains.list"; | ||
| 37 | my $wc = `/usr/bin/wc -l $domainfile`; | ||
| 38 | my $check = "/usr/local/nagios/libexec/check_dns"; | ||
| 39 | my $x = 0; | ||
| 40 | my $srv_file = ""; | ||
| 41 | my $z = ""; | ||
| 42 | my $y = ""; | ||
| 43 | |||
| 44 | open(DOMAIN,"<$domainfile") or die "Error Opening $domainfile File!\n"; | ||
| 45 | while (<DOMAIN>) { | ||
| 46 | $srv_file .= $_; | ||
| 47 | } | ||
| 48 | close(DOMAIN); | ||
| 49 | my @data = split(/\n/,$srv_file); | ||
| 50 | |||
| 51 | chomp $wc; | ||
| 52 | $wc =~ s/ //g; | ||
| 53 | $wc =~ s/domains//g; | ||
| 54 | |||
| 55 | $x = rand $wc; | ||
| 56 | ($z,$y) = split(/\./,$x); | ||
| 57 | |||
| 58 | print `$check $data[$z] $host`; | ||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | sub usage | ||
| 63 | { | ||
| 64 | print "Minimum arguments not supplied!\n"; | ||
| 65 | print "\n"; | ||
| 66 | print "Perl Check Random DNS plugin for Nagios\n"; | ||
| 67 | print "Copyright (c) 2000 Richard Mayhew\n"; | ||
| 68 | print "\n"; | ||
| 69 | print "Usage: check_dns_random.pl <host>\n"; | ||
| 70 | print "\n"; | ||
| 71 | print "<host> = DNS server you would like to query.\n"; | ||
| 72 | exit -1; | ||
| 73 | |||
| 74 | } | ||
| 75 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | # | ||
| 3 | # (c)2000 Benjamin Schmid, blueshift@gmx.net (emergency use only ;-) | ||
| 4 | # Copyleft by GNU GPL | ||
| 5 | # | ||
| 6 | # | ||
| 7 | # check_email_loop Nagios Plugin | ||
| 8 | # | ||
| 9 | # This script sends a mail with a specific id in the subject via | ||
| 10 | # an given smtp-server to a given email-adress. When the script | ||
| 11 | # is run again, it checks for this Email (with its unique id) on | ||
| 12 | # a given pop3 account and send another mail. | ||
| 13 | # | ||
| 14 | # | ||
| 15 | # Example: check_email_loop.pl -poph=mypop -popu=user -pa=password | ||
| 16 | # -smtph=mailer -from=returnadress@yoursite.com | ||
| 17 | # -to=remaileradress@friend.com -pendc=2 -lostc=0 | ||
| 18 | # | ||
| 19 | # This example will send eacht time this check is executed a new | ||
| 20 | # mail to remaileradress@friend.com using the SMTP-Host mailer. | ||
| 21 | # Then it looks for any back-forwarded mails in the POP3 host | ||
| 22 | # mypop. In this Configuration CRITICAL state will be reached if | ||
| 23 | # more than 2 Mails are pending (meaning that they did not came | ||
| 24 | # back till now) or if a mails got lost (meaning a mail, that was | ||
| 25 | # send later came back prior to another mail). | ||
| 26 | # | ||
| 27 | |||
| 28 | use Net::POP3; | ||
| 29 | use Net::SMTP; | ||
| 30 | use strict; | ||
| 31 | use Getopt::Long; | ||
| 32 | &Getopt::Long::config('auto_abbrev'); | ||
| 33 | |||
| 34 | # ---------------------------------------- | ||
| 35 | |||
| 36 | my $TIMEOUT = 120; | ||
| 37 | my %ERRORS = ('UNKNOWN' , '-1', | ||
| 38 | 'OK' , '0', | ||
| 39 | 'WARNING', '1', | ||
| 40 | 'CRITICAL', '2'); | ||
| 41 | |||
| 42 | my $state = "UNKNOWN"; | ||
| 43 | my ($sender,$receiver, $pophost, $popuser, $poppasswd, $smtphost); | ||
| 44 | my ($poptimeout,$smtptimeout,$pinginterval)=(60,60,5); | ||
| 45 | my ($lostwarn, $lostcrit,$pendwarn, $pendcrit); | ||
| 46 | |||
| 47 | # Internal Vars | ||
| 48 | my ($pop,$msgcount,@msglines,$statinfo,@messageids,$newestid); | ||
| 49 | my ($matchcount,$statfile) = (0,"check_email_loop.stat"); | ||
| 50 | |||
| 51 | # Subs declaration | ||
| 52 | sub usage; | ||
| 53 | sub messagematchs; | ||
| 54 | sub nsexit; | ||
| 55 | |||
| 56 | # Just in case of problems, let's not hang Nagios | ||
| 57 | $SIG{'ALRM'} = sub { | ||
| 58 | print ("ERROR: $0 Time-Out $TIMEOUT s \n"); | ||
| 59 | exit $ERRORS{"UNKNOWN"}; | ||
| 60 | }; | ||
| 61 | alarm($TIMEOUT); | ||
| 62 | |||
| 63 | |||
| 64 | # Evaluate Command Line Parameters | ||
| 65 | my $status = GetOptions( | ||
| 66 | "from=s",\$sender, | ||
| 67 | "to=s",\$receiver, | ||
| 68 | "pophost=s",\$pophost, | ||
| 69 | "popuser=s",\$popuser, | ||
| 70 | "passwd=s",\$poppasswd, | ||
| 71 | "poptimeout=i",\$poptimeout, | ||
| 72 | "smtphost=s",\$smtphost, | ||
| 73 | "smtptimeout=i",\$smtptimeout, | ||
| 74 | "statfile=s",\$statfile, | ||
| 75 | "interval=i",\$pinginterval, | ||
| 76 | "lostwarr=i",\$lostwarn, | ||
| 77 | "lostcrit=i",\$lostcrit, | ||
| 78 | "pendwarn=i",\$pendwarn, | ||
| 79 | "pendcrit=i",\$pendcrit, | ||
| 80 | ); | ||
| 81 | usage() if ($status == 0 || ! ($pophost && $popuser && $poppasswd && | ||
| 82 | $smtphost && $receiver && $sender )); | ||
| 83 | |||
| 84 | # Try to read the ids of the last send emails out of statfile | ||
| 85 | if (open STATF, "$statfile") { | ||
| 86 | @messageids = <STATF>; | ||
| 87 | chomp @messageids; | ||
| 88 | close STATF; | ||
| 89 | } | ||
| 90 | |||
| 91 | # Try to open statfile for writing | ||
| 92 | if (!open STATF, ">$statfile") { | ||
| 93 | nsexit("Failed to open mail-ID database $statfile for writing",'CRITICAL'); | ||
| 94 | } | ||
| 95 | |||
| 96 | # Ok - check if it's time to release another mail | ||
| 97 | |||
| 98 | # ... | ||
| 99 | |||
| 100 | # creating new serial id | ||
| 101 | my $serial = time(); | ||
| 102 | $serial = "ID#" . $serial . "#$$"; | ||
| 103 | |||
| 104 | # sending new ping email | ||
| 105 | my $smtp = Net::SMTP->new($smtphost,Timeout=>$smtptimeout) | ||
| 106 | || nsexit("SMTP connect timeout ($smtptimeout s)",'CRITICAL'); | ||
| 107 | ($smtp->mail($sender) && | ||
| 108 | $smtp->to($receiver) && | ||
| 109 | $smtp->data() && | ||
| 110 | $smtp->datasend("To: $receiver\nSubject: E-Mail Ping [$serial]\n\n". | ||
| 111 | "This is a automatically sended E-Mail.\n". | ||
| 112 | "It ist not intended for human reader.\n\n". | ||
| 113 | "Serial No: $serial\n") && | ||
| 114 | $smtp->dataend() && | ||
| 115 | $smtp->quit | ||
| 116 | ) || nsexit("Error delivering message",'CRITICAL'); | ||
| 117 | |||
| 118 | # no the interessting part: let's if they are receiving ;-) | ||
| 119 | |||
| 120 | $pop = Net::POP3->new( $pophost, | ||
| 121 | Timeout=>$poptimeout) | ||
| 122 | || nsexit("POP3 connect timeout (>$poptimeout s, host: $pophost)",'CRITICAL'); | ||
| 123 | |||
| 124 | $msgcount=$pop->login($popuser,$poppasswd); | ||
| 125 | |||
| 126 | $statinfo="$msgcount mails on POP3"; | ||
| 127 | |||
| 128 | nsexit("POP3 login failed (user:$popuser)",'CRITICAL') if (!defined($msgcount)); | ||
| 129 | |||
| 130 | # Count messages, that we are looking 4: | ||
| 131 | while ($msgcount > 0) { | ||
| 132 | @msglines = @{$pop->get($msgcount)}; | ||
| 133 | |||
| 134 | for (my $i=0; $i < scalar @messageids; $i++) { | ||
| 135 | if (messagematchsid(\@msglines,$messageids[$i])) { | ||
| 136 | $matchcount++; | ||
| 137 | # newest received mail than the others, ok remeber id. | ||
| 138 | $newestid = $messageids[$i] if ($messageids[$i] > $newestid || !defined $newestid); | ||
| 139 | $pop->delete($msgcount); # remove E-Mail from POP3 server | ||
| 140 | splice @messageids, $i, 1;# remove id from List | ||
| 141 | last; # stop looking in list | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | $msgcount--; | ||
| 146 | } | ||
| 147 | |||
| 148 | $pop->quit(); # necessary for pop3 deletion! | ||
| 149 | |||
| 150 | # traverse through the message list and mark the lost mails | ||
| 151 | # that mean mails that are older than the last received mail. | ||
| 152 | if (defined $newestid) { | ||
| 153 | $newestid =~ /\#(\d+)\#/; | ||
| 154 | $newestid = $1; | ||
| 155 | for (my $i=0; $i < scalar @messageids; $i++) { | ||
| 156 | $messageids[$i] =~ /\#(\d+)\#/; | ||
| 157 | my $akid = $1; | ||
| 158 | if ($akid < $newestid) { | ||
| 159 | $messageids[$i] =~ s/^ID/LI/; # mark lost | ||
| 160 | } | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 164 | # Write list to id-Database | ||
| 165 | foreach my $id (@messageids) { | ||
| 166 | print STATF "$id\n"; | ||
| 167 | } | ||
| 168 | print STATF "$serial\n"; # remember send mail of this session | ||
| 169 | close STATF; | ||
| 170 | |||
| 171 | # ok - count lost and pending mails; | ||
| 172 | my @tmp = grep /^ID/, @messageids; | ||
| 173 | my $pendingm = scalar @tmp; | ||
| 174 | @tmp = grep /^LI/, @messageids; | ||
| 175 | my $lostm = scalar @tmp; | ||
| 176 | |||
| 177 | # Evaluate the Warnin/Crit-Levels | ||
| 178 | if (defined $pendwarn && $pendingm > $pendwarn) { $state = 'WARNING'; } | ||
| 179 | if (defined $lostwarn && $lostm > $lostwarn) { $state = 'WARNING'; } | ||
| 180 | if (defined $pendcrit && $pendingm > $pendcrit) { $state = 'CRITICAL'; } | ||
| 181 | if (defined $lostcrit && $lostm > $lostcrit) { $state = 'CRITICAL'; } | ||
| 182 | |||
| 183 | if ((defined $pendwarn || defined $pendcrit || defined $lostwarn | ||
| 184 | || defined $lostcrit) && ($state eq 'UNKNOWN')) {$state='OK';} | ||
| 185 | |||
| 186 | |||
| 187 | # Append Status info | ||
| 188 | $statinfo = $statinfo . ", $matchcount mail(s) came back,". | ||
| 189 | " $pendingm pending, $lostm lost."; | ||
| 190 | |||
| 191 | # Exit in a Nagios-compliant way | ||
| 192 | nsexit($statinfo); | ||
| 193 | |||
| 194 | # ---------------------------------------------------------------------- | ||
| 195 | |||
| 196 | sub usage { | ||
| 197 | print "check_email_loop 1.0 Nagios Plugin - Real check of a E-Mail system\n"; | ||
| 198 | print "=" x 75,"\nERROR: Missing or wrong arguments!\n","=" x 75,"\n"; | ||
| 199 | print "This script sends a mail with a specific id in the subject via an given\n"; | ||
| 200 | print "smtp-server to a given email-adress. When the script is run again, it checks\n"; | ||
| 201 | print "for this Email (with its unique id) on a given pop3 account and sends \n"; | ||
| 202 | print "another mail.\n"; | ||
| 203 | print "\nThe following options are available:\n"; | ||
| 204 | print " -from=text email adress of send (for mail returnr on errors)\n"; | ||
| 205 | print " -to=text email adress to which the mails should send to\n"; | ||
| 206 | print " -pophost=text IP or name of the POP3-host to be checked\n"; | ||
| 207 | print " -popuser=text Username of the POP3-account\n"; | ||
| 208 | print " -passwd=text Password for the POP3-user\n"; | ||
| 209 | print " -poptimeout=num Timeout in seconds for the POP3-server\n"; | ||
| 210 | print " -smtphost=text IP oder name of the SMTP host\n"; | ||
| 211 | print " -smtptimeout=num Timeout in seconds for the SMTP-server\n"; | ||
| 212 | print " -statfile=text File to save ids of messages ($statfile)\n"; | ||
| 213 | # print " -interval=num Time (in minutes) that must pass by before sending\n" | ||
| 214 | # print " another Ping-mail (gibe a new try);\n"; | ||
| 215 | print " -lostwarn=num WARNING-state if more than num lost emails\n"; | ||
| 216 | print " -lostcrit=num CRITICAL \n"; | ||
| 217 | print " -pendwarn=num WARNING-state if more than num pending emails\n"; | ||
| 218 | print " -pendcrit=num CRITICAL \n"; | ||
| 219 | print " Options may abbreviated!\n"; | ||
| 220 | print " LOST mails are mails, being sent before the last mail arrived back.\n"; | ||
| 221 | print " PENDING mails are those, which are not. (supposed to be on the way)\n"; | ||
| 222 | print "\nExample: \n"; | ||
| 223 | print " $0 -poph=host -pa=pw -popu=popts -smtph=host -from=root\@me.com\n "; | ||
| 224 | print " -to=remailer\@testxy.com -lostc=0 -pendc=2\n"; | ||
| 225 | print "\nCopyleft 19.10.2000, Benjamin Schmid\n"; | ||
| 226 | print "This script comes with ABSOLUTELY NO WARRANTY\n"; | ||
| 227 | print "This programm is licensed under the terms of the "; | ||
| 228 | print "GNU General Public License\n\n"; | ||
| 229 | exit $ERRORS{"UNKNOWN"}; | ||
| 230 | } | ||
| 231 | |||
| 232 | # --------------------------------------------------------------------- | ||
| 233 | |||
| 234 | sub nsexit { | ||
| 235 | my ($msg,$code) = @_; | ||
| 236 | $code=$state if (!defined $code); | ||
| 237 | print "$code: $msg\n" if (defined $msg); | ||
| 238 | exit $ERRORS{$code}; | ||
| 239 | } | ||
| 240 | |||
| 241 | # --------------------------------------------------------------------- | ||
| 242 | |||
| 243 | sub messagematchsid { | ||
| 244 | my ($mailref,$id) = (@_); | ||
| 245 | my (@tmp); | ||
| 246 | my $match = 0; | ||
| 247 | |||
| 248 | # ID | ||
| 249 | $id =~ s/^LI/ID/; # evtl. remove lost mail mark | ||
| 250 | @tmp = grep /Subject: E-Mail Ping \[/, @$mailref; | ||
| 251 | chomp @tmp; | ||
| 252 | if (($tmp[0] =~ /$id/)) | ||
| 253 | { $match = 1; } | ||
| 254 | |||
| 255 | # Sender: | ||
| 256 | # @tmp = grep /^From:\s+/, @$mailref; | ||
| 257 | # if (@tmp && $sender ne "") | ||
| 258 | # { $match = $match && ($tmp[0]=~/$sender/); } | ||
| 259 | |||
| 260 | # Receiver: | ||
| 261 | # @tmp = grep /^To: /, @$mailref; | ||
| 262 | # if (@tmp && $receiver ne "") | ||
| 263 | # { $match = $match && ($tmp[0]=~/$receiver/); } | ||
| 264 | |||
| 265 | return $match; | ||
| 266 | } | ||
| 267 | |||
| 268 | # --------------------------------------------------------------------- | ||
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 @@ | |||
| 1 | /****************************************************************************** | ||
| 2 | * | ||
| 3 | * CHECK_INET_FPING.C | ||
| 4 | * | ||
| 5 | * Program: Fping plugin for Nagios | ||
| 6 | * License: GPL | ||
| 7 | * Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) | ||
| 8 | * $Id$ | ||
| 9 | * | ||
| 10 | * Modifications: | ||
| 11 | * | ||
| 12 | * 08-24-1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) | ||
| 13 | * Intial Coding | ||
| 14 | * 09-11-1999 Karl DeBisschop (kdebiss@alum.mit.edu) | ||
| 15 | * Change to spopen | ||
| 16 | * Fix so that state unknown is returned by default | ||
| 17 | * (formerly would give state ok if no fping specified) | ||
| 18 | * Add server_name to output | ||
| 19 | * Reformat to 80-character standard screen | ||
| 20 | * 11-18-1999 Karl DeBisschop (kdebiss@alum.mit.edu) | ||
| 21 | * set STATE_WARNING of stderr written or nonzero status returned | ||
| 22 | * 09-29-2000 Matthew Grant (matthewg@plain.co.nz) | ||
| 23 | * changes for monitoring multiple hosts for checking Internet | ||
| 24 | * reachibility | ||
| 25 | * | ||
| 26 | * Description: | ||
| 27 | * | ||
| 28 | * This plugin will use the /bin/fping command (from nagios) to ping | ||
| 29 | * the specified host for a fast check if the host is alive. Note that | ||
| 30 | * it is necessary to set the suid flag on fping. | ||
| 31 | ******************************************************************************/ | ||
| 32 | |||
| 33 | #include "config.h" | ||
| 34 | #include "common.h" | ||
| 35 | #include "popen.h" | ||
| 36 | #include "utils.h" | ||
| 37 | |||
| 38 | #define PROGNAME "check_fping" | ||
| 39 | #define PACKET_COUNT 15 | ||
| 40 | #define PACKET_SIZE 56 | ||
| 41 | #define CRITICAL_COUNT 2 | ||
| 42 | #define WARNING_COUNT 1 | ||
| 43 | #define UNKNOWN_PACKET_LOSS 200 /* 200% */ | ||
| 44 | #define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */ | ||
| 45 | |||
| 46 | #define STRSZ 100 | ||
| 47 | |||
| 48 | int textscan(char *buf); | ||
| 49 | int process_arguments(int, char **); | ||
| 50 | int get_threshold (char *arg, char *rv[2]); | ||
| 51 | void print_usage(void); | ||
| 52 | void print_help(void); | ||
| 53 | |||
| 54 | char *server_names=NULL; | ||
| 55 | char *name="INTERNET"; | ||
| 56 | int cthresh=CRITICAL_COUNT; | ||
| 57 | int wthresh=WARNING_COUNT; | ||
| 58 | int nnames=0; | ||
| 59 | int tpl=UNKNOWN_PACKET_LOSS; | ||
| 60 | double trta=UNKNOWN_TRIP_TIME; | ||
| 61 | int packet_size=PACKET_SIZE; | ||
| 62 | int packet_count=PACKET_COUNT; | ||
| 63 | int verbose=FALSE; | ||
| 64 | int fail = 0; | ||
| 65 | int not_found = 0; | ||
| 66 | int rta_fail = 0; | ||
| 67 | int pl_fail = 0; | ||
| 68 | int unreachable = 0; | ||
| 69 | |||
| 70 | int main(int argc, char **argv){ | ||
| 71 | int result; | ||
| 72 | int status=STATE_UNKNOWN; | ||
| 73 | char *servers=NULL; | ||
| 74 | char *command_line=NULL; | ||
| 75 | char *input_buffer=NULL; | ||
| 76 | char *pl_buffer=NULL; | ||
| 77 | char *rta_buffer=NULL; | ||
| 78 | input_buffer=malloc(MAX_INPUT_BUFFER); | ||
| 79 | rta_buffer = malloc(80); | ||
| 80 | pl_buffer = malloc(80); | ||
| 81 | memset(rta_buffer, 0, 80); | ||
| 82 | memset(pl_buffer, 0, 80); | ||
| 83 | |||
| 84 | if(process_arguments(argc,argv)==ERROR) | ||
| 85 | usage("Could not parse arguments\n"); | ||
| 86 | |||
| 87 | servers=strscpy(servers,server_names); | ||
| 88 | |||
| 89 | /* compose the command */ | ||
| 90 | command_line=ssprintf | ||
| 91 | (command_line,"%s -b %d -c %d %s", | ||
| 92 | PATH_TO_FPING, | ||
| 93 | packet_size, | ||
| 94 | packet_count, | ||
| 95 | servers); | ||
| 96 | |||
| 97 | if (verbose) printf("%s\n",command_line); | ||
| 98 | |||
| 99 | /* run the command */ | ||
| 100 | child_process=spopen(command_line); | ||
| 101 | if(child_process==NULL){ | ||
| 102 | printf("Unable to open pipe: %s\n",command_line); | ||
| 103 | return STATE_UNKNOWN; | ||
| 104 | } | ||
| 105 | |||
| 106 | child_stderr=fdopen(child_stderr_array[fileno(child_process)],"r"); | ||
| 107 | if(child_stderr==NULL){ | ||
| 108 | printf("Could not open stderr for %s\n",command_line); | ||
| 109 | } | ||
| 110 | |||
| 111 | while (fgets(input_buffer,MAX_INPUT_BUFFER-1,child_process)) { | ||
| 112 | if (verbose) printf("%s",input_buffer); | ||
| 113 | result = textscan(input_buffer); | ||
| 114 | status = max(status,result); | ||
| 115 | } | ||
| 116 | |||
| 117 | while(fgets(input_buffer,MAX_INPUT_BUFFER-1,child_stderr)) { | ||
| 118 | if (verbose) printf("%s",input_buffer); | ||
| 119 | result = textscan(input_buffer); | ||
| 120 | status = max(status,result); | ||
| 121 | } | ||
| 122 | |||
| 123 | (void)fclose(child_stderr); | ||
| 124 | |||
| 125 | /* close the pipe */ | ||
| 126 | if(spclose(child_process)) | ||
| 127 | status=max(status,STATE_WARNING); | ||
| 128 | |||
| 129 | /* Analyse fail count and produce results */ | ||
| 130 | if (fail >= wthresh) { | ||
| 131 | status = max(status, STATE_WARNING); | ||
| 132 | } | ||
| 133 | |||
| 134 | if (fail >= cthresh) { | ||
| 135 | status = max(status, STATE_CRITICAL); | ||
| 136 | } | ||
| 137 | |||
| 138 | if( tpl != UNKNOWN_PACKET_LOSS ) { | ||
| 139 | snprintf(pl_buffer, 80, ", %d PL", pl_fail); | ||
| 140 | } | ||
| 141 | |||
| 142 | if( trta != UNKNOWN_TRIP_TIME ) { | ||
| 143 | snprintf(rta_buffer, 80, ", %d RTA", rta_fail); | ||
| 144 | |||
| 145 | } | ||
| 146 | |||
| 147 | printf("FPING %s - %s, %d of %d fail, %d NF, %d UR%s%s\n", | ||
| 148 | state_text(status), | ||
| 149 | (name != NULL ? name : server_names), | ||
| 150 | fail, | ||
| 151 | nnames, | ||
| 152 | not_found, | ||
| 153 | unreachable, | ||
| 154 | pl_buffer, | ||
| 155 | rta_buffer); | ||
| 156 | |||
| 157 | return status; | ||
| 158 | } | ||
| 159 | |||
| 160 | |||
| 161 | |||
| 162 | /* analyse fping output - each event resulting in an increment of fail | ||
| 163 | * must be mutually exclusive. packet loss and round trip time analysed | ||
| 164 | * together, both at once just results in one increment of fail | ||
| 165 | */ | ||
| 166 | int textscan(char *buf) | ||
| 167 | { | ||
| 168 | char *rtastr=NULL; | ||
| 169 | char *losstr=NULL; | ||
| 170 | double loss; | ||
| 171 | double rta; | ||
| 172 | int status=STATE_OK; | ||
| 173 | |||
| 174 | if (strstr(buf,"not found")) { | ||
| 175 | fail++; | ||
| 176 | not_found++; | ||
| 177 | } else if(strstr(buf,"xmt/rcv/%loss") | ||
| 178 | && strstr(buf,"min/avg/max")) { | ||
| 179 | losstr = strstr(buf,"="); | ||
| 180 | losstr = 1+strstr(losstr,"/"); | ||
| 181 | losstr = 1+strstr(losstr,"/"); | ||
| 182 | rtastr = strstr(buf,"min/avg/max"); | ||
| 183 | rtastr = strstr(rtastr,"="); | ||
| 184 | rtastr = 1+index(rtastr,'/'); | ||
| 185 | loss = strtod(losstr,NULL); | ||
| 186 | rta = strtod(rtastr,NULL); | ||
| 187 | /* Increment fail counter | ||
| 188 | */ | ||
| 189 | if (tpl!=UNKNOWN_PACKET_LOSS && loss>tpl) { | ||
| 190 | fail++; | ||
| 191 | } | ||
| 192 | else if (trta!=UNKNOWN_TRIP_TIME && rta>trta) { | ||
| 193 | fail++; | ||
| 194 | } | ||
| 195 | else if (loss >= 100) { | ||
| 196 | fail++; | ||
| 197 | } | ||
| 198 | /* Increment other counters | ||
| 199 | */ | ||
| 200 | if (trta!=UNKNOWN_TRIP_TIME && rta>trta) | ||
| 201 | rta_fail++; | ||
| 202 | if (tpl!=UNKNOWN_PACKET_LOSS && loss>tpl) | ||
| 203 | pl_fail++; | ||
| 204 | if (loss >= 100) | ||
| 205 | unreachable++; | ||
| 206 | } else if(strstr(buf,"xmt/rcv/%loss") ) { | ||
| 207 | losstr = strstr(buf,"="); | ||
| 208 | losstr = 1+strstr(losstr,"/"); | ||
| 209 | losstr = 1+strstr(losstr,"/"); | ||
| 210 | loss = strtod(losstr,NULL); | ||
| 211 | /* Increment fail counter | ||
| 212 | */ | ||
| 213 | if (tpl!=UNKNOWN_PACKET_LOSS && loss>tpl) { | ||
| 214 | fail++; | ||
| 215 | } | ||
| 216 | else if (loss >= 100) { | ||
| 217 | fail++; | ||
| 218 | } | ||
| 219 | /* Increment other counters | ||
| 220 | */ | ||
| 221 | if (tpl!=UNKNOWN_PACKET_LOSS && loss>tpl) | ||
| 222 | pl_fail++; | ||
| 223 | if (loss >= 100) | ||
| 224 | unreachable++; | ||
| 225 | } | ||
| 226 | |||
| 227 | return status; | ||
| 228 | } | ||
| 229 | |||
| 230 | |||
| 231 | |||
| 232 | |||
| 233 | /* process command-line arguments */ | ||
| 234 | int process_arguments(int argc, char **argv) | ||
| 235 | { | ||
| 236 | int c; | ||
| 237 | |||
| 238 | #ifdef HAVE_GETOPT_H | ||
| 239 | int option_index = 0; | ||
| 240 | static struct option long_options[] = | ||
| 241 | { | ||
| 242 | {"hostname" ,required_argument,0,'H'}, | ||
| 243 | {"critical" ,required_argument,0,'c'}, | ||
| 244 | {"warning" ,required_argument,0,'w'}, | ||
| 245 | {"bytes" ,required_argument,0,'b'}, | ||
| 246 | {"number" ,required_argument,0,'n'}, | ||
| 247 | {"pl-threshold" ,required_argument,0,'p'}, | ||
| 248 | {"rta-threshold" ,required_argument,0,'r'}, | ||
| 249 | {"name" ,required_argument,0,'N'}, | ||
| 250 | {"verbose" ,no_argument, 0,'v'}, | ||
| 251 | {"version" ,no_argument, 0,'V'}, | ||
| 252 | {"help" ,no_argument, 0,'h'}, | ||
| 253 | {0,0,0,0} | ||
| 254 | }; | ||
| 255 | #else | ||
| 256 | |||
| 257 | if(argc<2) return ERROR; | ||
| 258 | |||
| 259 | if (!is_option(argv[1])){ | ||
| 260 | server_names=argv[1]; | ||
| 261 | argv[1]=argv[0]; | ||
| 262 | argv=&argv[1]; | ||
| 263 | argc--; | ||
| 264 | } | ||
| 265 | #endif | ||
| 266 | |||
| 267 | while (1){ | ||
| 268 | #ifdef HAVE_GETOPT_H | ||
| 269 | c = getopt_long(argc,argv,"+hVvH:c:w:b:n:N:p:r:",long_options,&option_index); | ||
| 270 | #else | ||
| 271 | c = getopt(argc,argv,"+hVvH:c:w:b:n:N:p:r:"); | ||
| 272 | #endif | ||
| 273 | |||
| 274 | if (c==-1||c==EOF||c==1) | ||
| 275 | break; | ||
| 276 | |||
| 277 | switch (c) | ||
| 278 | { | ||
| 279 | case '?': /* print short usage statement if args not parsable */ | ||
| 280 | printf("%s: Unknown argument: %s\n\n",my_basename(argv[0]),optarg); | ||
| 281 | print_usage(); | ||
| 282 | exit(STATE_UNKNOWN); | ||
| 283 | case 'h': /* help */ | ||
| 284 | print_help(); | ||
| 285 | exit(STATE_OK); | ||
| 286 | case 'V': /* version */ | ||
| 287 | print_revision(my_basename(argv[0]),"$Revision$"); | ||
| 288 | exit(STATE_OK); | ||
| 289 | case 'v': /* verbose mode */ | ||
| 290 | verbose=TRUE; | ||
| 291 | break; | ||
| 292 | case 'H': /* hostname */ | ||
| 293 | if(is_host(optarg)==FALSE){ | ||
| 294 | printf("Invalid host name/address\n\n"); | ||
| 295 | print_usage(); | ||
| 296 | exit(STATE_UNKNOWN); | ||
| 297 | } | ||
| 298 | if (server_names != NULL) | ||
| 299 | server_names=strscat(server_names," "); | ||
| 300 | server_names=strscat(server_names,optarg); | ||
| 301 | nnames++; | ||
| 302 | break; | ||
| 303 | case 'c': | ||
| 304 | if (is_intpos(optarg)) | ||
| 305 | cthresh = atoi(optarg); | ||
| 306 | else | ||
| 307 | usage("Critical threshold must be a positive integer"); | ||
| 308 | break; | ||
| 309 | case 'w': | ||
| 310 | if (is_intpos(optarg)) | ||
| 311 | wthresh = atoi(optarg); | ||
| 312 | else | ||
| 313 | usage("Warning threshold must be a postive integer"); | ||
| 314 | break; | ||
| 315 | case 'r': | ||
| 316 | if (is_intpos(optarg)) { | ||
| 317 | trta=strtod(optarg,NULL); | ||
| 318 | } | ||
| 319 | else { | ||
| 320 | usage("RTA threshold must be a positive integer"); | ||
| 321 | } | ||
| 322 | break; | ||
| 323 | case 'p': | ||
| 324 | if (is_intpos(optarg)) { | ||
| 325 | tpl=strtod(optarg,NULL); | ||
| 326 | } | ||
| 327 | else { | ||
| 328 | usage("RTA threshold must be a positive integer"); | ||
| 329 | } | ||
| 330 | break; | ||
| 331 | case 'b': /* bytes per packet */ | ||
| 332 | if (is_intpos(optarg)) | ||
| 333 | packet_size=atoi(optarg); | ||
| 334 | else | ||
| 335 | usage("Packet size must be a positive integer"); | ||
| 336 | break; | ||
| 337 | case 'N': /* Name of service */ | ||
| 338 | name = optarg; | ||
| 339 | break; | ||
| 340 | case 'n': /* number of packets */ | ||
| 341 | if (is_intpos(optarg)) | ||
| 342 | packet_count=atoi(optarg); | ||
| 343 | else | ||
| 344 | usage("Packet count must be a positive integer"); | ||
| 345 | break; | ||
| 346 | } | ||
| 347 | } | ||
| 348 | |||
| 349 | while (optind < argc) { | ||
| 350 | if(is_host(argv[optind])==FALSE) { | ||
| 351 | printf("Invalid host name/address\n\n"); | ||
| 352 | print_usage(); | ||
| 353 | exit(STATE_UNKNOWN); | ||
| 354 | } | ||
| 355 | if (server_names != NULL) | ||
| 356 | server_names=strscat(server_names," "); | ||
| 357 | server_names=strscat(server_names,argv[optind]); | ||
| 358 | nnames++; | ||
| 359 | optind++; | ||
| 360 | } | ||
| 361 | |||
| 362 | if (server_names==NULL || nnames < 2) | ||
| 363 | usage("At least 2 hostnames must be supplied\n\n"); | ||
| 364 | |||
| 365 | if (cthresh < 2) | ||
| 366 | usage("Critical threshold must be at least 2"); | ||
| 367 | if (cthresh > nnames) | ||
| 368 | usage("Critical threshold cannot be greater than number of hosts tested"); | ||
| 369 | if (wthresh < 1) | ||
| 370 | usage("Warning threshold must be at least 1"); | ||
| 371 | if (wthresh > nnames) | ||
| 372 | usage("Warning threshold cannot be greater than number of hosts tested"); | ||
| 373 | if(wthresh >= cthresh) | ||
| 374 | usage("Warning threshold must be less than the critical threshold"); | ||
| 375 | |||
| 376 | return OK; | ||
| 377 | } | ||
| 378 | |||
| 379 | |||
| 380 | void print_usage(void) | ||
| 381 | { | ||
| 382 | printf("Usage: %s <host_address> <host_address> [<host_address>] ...\n",PROGNAME); | ||
| 383 | } | ||
| 384 | |||
| 385 | |||
| 386 | |||
| 387 | |||
| 388 | |||
| 389 | void print_help(void) | ||
| 390 | { | ||
| 391 | |||
| 392 | print_revision(PROGNAME,"$Revision$"); | ||
| 393 | |||
| 394 | printf | ||
| 395 | ("Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)\n" | ||
| 396 | " (c) 2000 Matthew Grant (matthewg@plain.co.nz)\n" | ||
| 397 | "This plugin will use the /bin/fping command (from saint) to ping the\n" | ||
| 398 | "specified hosts for a fast check to see if the Internet is still \n" | ||
| 399 | "reachable, and the results of the testing aggregated. Note that it\n" | ||
| 400 | "is necessary to set the suid flag on fping.\n\n"); | ||
| 401 | |||
| 402 | print_usage(); | ||
| 403 | |||
| 404 | printf | ||
| 405 | ("\nOptions:\n" | ||
| 406 | "-b, --bytes=INTEGER\n" | ||
| 407 | " Size of ICMP packet (default: %d)\n" | ||
| 408 | "-c, --critical=INTEGER (default: %d)\n" | ||
| 409 | " critical threshold failure count\n" | ||
| 410 | "-n, --number=INTEGER\n" | ||
| 411 | " Number of ICMP packets to send (default: %d)\n" | ||
| 412 | "-H, --hostname=HOST\n" | ||
| 413 | " Name or IP Address of host to ping (IP Address bypasses name lookup,\n" | ||
| 414 | " reducing system load)\n" | ||
| 415 | "-h, --help\n" | ||
| 416 | " Print this help screen\n" | ||
| 417 | "-N, --name\n" | ||
| 418 | " Service name to print in results, defaults to INTERNET\n" | ||
| 419 | "-p, --pl-threshold\n" | ||
| 420 | " Packet loss threshold - specify to turn on packet loss testing\n" | ||
| 421 | "-r, --rta-threshold\n" | ||
| 422 | " Round trip average threshold - specify to turn on RTA testing\n" | ||
| 423 | "-V, --version\n" | ||
| 424 | " Print version information\n" | ||
| 425 | "-v, --verbose\n" | ||
| 426 | " Show details for command-line debugging (do not use with nagios server)\n" | ||
| 427 | "-w, --warning=INTEGER (default: %d)\n" | ||
| 428 | " warning threshold failure count\n", | ||
| 429 | PACKET_SIZE, CRITICAL_COUNT, PACKET_COUNT, WARNING_COUNT); | ||
| 430 | } | ||
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 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | ## Written 12/5/00 Jeremy Hanmer | ||
| 3 | # $Id$ | ||
| 4 | |||
| 5 | use strict; | ||
| 6 | use Net::FTP; | ||
| 7 | use Getopt::Std; | ||
| 8 | |||
| 9 | use vars qw($opt_H $opt_u $opt_p $opt_f); | ||
| 10 | getopts("H:u:p:f:"); | ||
| 11 | |||
| 12 | my $host = $opt_H || | ||
| 13 | die "usage: check_ftp.pl -h host [<-u user> <-p pass> <-f file>]\n"; | ||
| 14 | |||
| 15 | my $username = $opt_u || 'anonymous'; | ||
| 16 | my $pass = $opt_p || "$ENV{'LOGNAME'}\@$ENV{'HOSTNAME'}" ; | ||
| 17 | |||
| 18 | my $file = $opt_f; | ||
| 19 | |||
| 20 | my $status = 0; | ||
| 21 | my $problem; | ||
| 22 | my $output = "ftp ok"; | ||
| 23 | |||
| 24 | my $ftp = Net::FTP->new("$host") || | ||
| 25 | &crit("connect"); | ||
| 26 | |||
| 27 | $ftp->login("$username", "$pass") || | ||
| 28 | &crit("login"); | ||
| 29 | |||
| 30 | $ftp->get($file) || | ||
| 31 | &crit("get") if $file; | ||
| 32 | |||
| 33 | sub crit() | ||
| 34 | { | ||
| 35 | $problem = $_[0]; | ||
| 36 | $status = 2; | ||
| 37 | if ( $problem eq 'connect' ) { | ||
| 38 | $output = "can't connect"; | ||
| 39 | } elsif ( $problem eq 'login' ) { | ||
| 40 | $output = "can't log in"; | ||
| 41 | } elsif ( $problem eq 'get' ) { | ||
| 42 | $output = "cant get $file"; | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | print "$output\n"; | ||
| 47 | exit $status; | ||
| 48 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | # | ||
| 3 | # check_ifoperstatus.pl - nagios plugin | ||
| 4 | # | ||
| 5 | # | ||
| 6 | # | ||
| 7 | # | ||
| 8 | # Copyright (C) 2000 Christoph Kron | ||
| 9 | # | ||
| 10 | # This program is free software; you can redistribute it and/or | ||
| 11 | # modify it under the terms of the GNU General Public License | ||
| 12 | # as published by the Free Software Foundation; either version 2 | ||
| 13 | # of the License, or (at your option) any later version. | ||
| 14 | # | ||
| 15 | # This program is distributed in the hope that it will be useful, | ||
| 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | # GNU General Public License for more details. | ||
| 19 | # | ||
| 20 | # You should have received a copy of the GNU General Public License | ||
| 21 | # along with this program; if not, write to the Free Software | ||
| 22 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 23 | # | ||
| 24 | # | ||
| 25 | # Report bugs to: ck@zet.net | ||
| 26 | # | ||
| 27 | # 11.01.2000 Version 1.0 | ||
| 28 | |||
| 29 | use strict; | ||
| 30 | |||
| 31 | use Net::SNMP; | ||
| 32 | use Getopt::Long; | ||
| 33 | &Getopt::Long::config('auto_abbrev'); | ||
| 34 | |||
| 35 | |||
| 36 | my $status; | ||
| 37 | my $TIMEOUT = 15; | ||
| 38 | |||
| 39 | my %ERRORS = ('UNKNOWN' , '-1', | ||
| 40 | 'OK' , '0', | ||
| 41 | 'WARNING', '1', | ||
| 42 | 'CRITICAL', '2'); | ||
| 43 | |||
| 44 | my %ifOperStatus = ('1','up', | ||
| 45 | '2','down', | ||
| 46 | '3','testing', | ||
| 47 | '4','unknown', | ||
| 48 | '5','dormant', | ||
| 49 | '6','notPresent'); | ||
| 50 | |||
| 51 | my $state = "UNKNOWN"; | ||
| 52 | my $answer = ""; | ||
| 53 | my $snmpkey = 1; | ||
| 54 | my $community = "public"; | ||
| 55 | my $port = 161; | ||
| 56 | my @snmpoids; | ||
| 57 | my $snmpIfOperStatus; | ||
| 58 | my $snmpLocIfDescr; | ||
| 59 | my $hostname; | ||
| 60 | my $session; | ||
| 61 | my $error; | ||
| 62 | my $response; | ||
| 63 | |||
| 64 | |||
| 65 | sub usage { | ||
| 66 | printf "\nMissing arguments!\n"; | ||
| 67 | printf "\n"; | ||
| 68 | printf "Perl Check IfOperStatus plugin for Nagios\n"; | ||
| 69 | printf "checks operational status of specified interface\n"; | ||
| 70 | printf "usage: \n"; | ||
| 71 | printf "ifoperstatus.pl -k <IF_KEY> -c <READCOMMUNITY> -p <PORT> <HOSTNAME>"; | ||
| 72 | printf "\nCopyright (C) 2000 Christoph Kron\n"; | ||
| 73 | printf "check_ifoperstatus.pl comes with ABSOLUTELY NO WARRANTY\n"; | ||
| 74 | printf "This programm is licensed under the terms of the "; | ||
| 75 | printf "GNU General Public License\n(check source code for details)\n"; | ||
| 76 | printf "\n\n"; | ||
| 77 | exit $ERRORS{"UNKNOWN"}; | ||
| 78 | } | ||
| 79 | |||
| 80 | # Just in case of problems, let's not hang Nagios | ||
| 81 | $SIG{'ALRM'} = sub { | ||
| 82 | print ("ERROR: No snmp response from $hostname (alarm)\n"); | ||
| 83 | exit $ERRORS{"UNKNOWN"}; | ||
| 84 | }; | ||
| 85 | alarm($TIMEOUT); | ||
| 86 | |||
| 87 | |||
| 88 | $status = GetOptions("key=i",\$snmpkey, | ||
| 89 | "community=s",\$community, | ||
| 90 | "port=i",\$port); | ||
| 91 | if ($status == 0) | ||
| 92 | { | ||
| 93 | &usage; | ||
| 94 | } | ||
| 95 | |||
| 96 | #shift; | ||
| 97 | $hostname = shift || &usage; | ||
| 98 | |||
| 99 | ($session, $error) = Net::SNMP->session( | ||
| 100 | -hostname => $hostname, | ||
| 101 | -community => $community, | ||
| 102 | -port => $port | ||
| 103 | ); | ||
| 104 | |||
| 105 | if (!defined($session)) { | ||
| 106 | $state='UNKNOWN'; | ||
| 107 | $answer=$error; | ||
| 108 | print ("$state: $answer"); | ||
| 109 | exit $ERRORS{$state}; | ||
| 110 | } | ||
| 111 | |||
| 112 | $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8' . "." . $snmpkey; | ||
| 113 | $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28' . "." . $snmpkey; | ||
| 114 | |||
| 115 | |||
| 116 | push(@snmpoids,$snmpIfOperStatus); | ||
| 117 | push(@snmpoids,$snmpLocIfDescr); | ||
| 118 | |||
| 119 | if (!defined($response = $session->get_request(@snmpoids))) { | ||
| 120 | $answer=$session->error; | ||
| 121 | $session->close; | ||
| 122 | $state = 'CRITICAL'; | ||
| 123 | print ("$state: $answer,$community,$snmpkey"); | ||
| 124 | exit $ERRORS{$state}; | ||
| 125 | } | ||
| 126 | |||
| 127 | $answer = sprintf("host '%s',%s(%s) is %s\n", | ||
| 128 | $hostname, | ||
| 129 | $response->{$snmpLocIfDescr}, | ||
| 130 | $snmpkey, | ||
| 131 | $ifOperStatus{$response->{$snmpIfOperStatus}} | ||
| 132 | ); | ||
| 133 | |||
| 134 | $session->close; | ||
| 135 | |||
| 136 | if ( $response->{$snmpIfOperStatus} == 1 ) { | ||
| 137 | $state = 'OK'; | ||
| 138 | } | ||
| 139 | else { | ||
| 140 | $state = 'CRITICAL'; | ||
| 141 | } | ||
| 142 | |||
| 143 | print ("$state: $answer"); | ||
| 144 | exit $ERRORS{$state}; | ||
| 145 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | # | ||
| 3 | # check_ifstatus.pl - nagios plugin | ||
| 4 | # | ||
| 5 | # | ||
| 6 | # Copyright (C) 2000 Christoph Kron | ||
| 7 | # | ||
| 8 | # This program is free software; you can redistribute it and/or | ||
| 9 | # modify it under the terms of the GNU General Public License | ||
| 10 | # as published by the Free Software Foundation; either version 2 | ||
| 11 | # of the License, or (at your option) any later version. | ||
| 12 | # | ||
| 13 | # This program is distributed in the hope that it will be useful, | ||
| 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | # GNU General Public License for more details. | ||
| 17 | # | ||
| 18 | # You should have received a copy of the GNU General Public License | ||
| 19 | # along with this program; if not, write to the Free Software | ||
| 20 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 21 | # | ||
| 22 | # | ||
| 23 | # Report bugs to: ck@zet.net | ||
| 24 | # | ||
| 25 | # 11.01.2000 Version 1.0 | ||
| 26 | |||
| 27 | use strict; | ||
| 28 | |||
| 29 | use Net::SNMP; | ||
| 30 | use Getopt::Long; | ||
| 31 | &Getopt::Long::config('auto_abbrev'); | ||
| 32 | |||
| 33 | |||
| 34 | my $status; | ||
| 35 | my $TIMEOUT = 1500; | ||
| 36 | |||
| 37 | my %ERRORS = ('UNKNOWN' , '-1', | ||
| 38 | 'OK' , '0', | ||
| 39 | 'WARNING', '1', | ||
| 40 | 'CRITICAL', '2'); | ||
| 41 | |||
| 42 | my %ifOperStatus = ('1','up', | ||
| 43 | '2','down', | ||
| 44 | '3','testing', | ||
| 45 | '4','unknown', | ||
| 46 | '5','dormant', | ||
| 47 | '6','notPresent'); | ||
| 48 | |||
| 49 | my $state = "UNKNOWN"; | ||
| 50 | my $answer = ""; | ||
| 51 | my $snmpkey; | ||
| 52 | my $snmpoid; | ||
| 53 | my $key; | ||
| 54 | my $community = "public"; | ||
| 55 | my $port = 161; | ||
| 56 | my @snmpoids; | ||
| 57 | my $snmpIfAdminStatus = '1.3.6.1.2.1.2.2.1.7'; | ||
| 58 | my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; | ||
| 59 | my $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8'; | ||
| 60 | my $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28'; | ||
| 61 | my $hostname; | ||
| 62 | my $session; | ||
| 63 | my $error; | ||
| 64 | my $response; | ||
| 65 | my %ifStatus; | ||
| 66 | my $ifup =0 ; | ||
| 67 | my $ifdown =0; | ||
| 68 | my $ifdormant = 0; | ||
| 69 | my $ifmessage; | ||
| 70 | |||
| 71 | sub usage { | ||
| 72 | printf "\nMissing arguments!\n"; | ||
| 73 | printf "\n"; | ||
| 74 | printf "Perl Check IfStatus plugin for Nagios\n"; | ||
| 75 | printf "monitors operational status of each interface\n"; | ||
| 76 | printf "usage: \n"; | ||
| 77 | printf "check_ifstatus.pl -c <READCOMMUNITY> -p <PORT> <HOSTNAME>\n"; | ||
| 78 | printf "Copyright (C) 2000 Christoph Kron\n"; | ||
| 79 | printf "check_ifstatus.pl comes with ABSOLUTELY NO WARRANTY\n"; | ||
| 80 | printf "This programm is licensed under the terms of the "; | ||
| 81 | printf "GNU General Public License\n(check source code for details)\n"; | ||
| 82 | printf "\n\n"; | ||
| 83 | exit $ERRORS{"UNKNOWN"}; | ||
| 84 | } | ||
| 85 | |||
| 86 | # Just in case of problems, let's not hang Nagios | ||
| 87 | $SIG{'ALRM'} = sub { | ||
| 88 | print ("ERROR: No snmp response from $hostname (alarm)\n"); | ||
| 89 | exit $ERRORS{"UNKNOWN"}; | ||
| 90 | }; | ||
| 91 | alarm($TIMEOUT); | ||
| 92 | |||
| 93 | |||
| 94 | $status = GetOptions("community=s",\$community, | ||
| 95 | "port=i",\$port); | ||
| 96 | if ($status == 0) | ||
| 97 | { | ||
| 98 | &usage; | ||
| 99 | } | ||
| 100 | |||
| 101 | #shift; | ||
| 102 | $hostname = shift || &usage; | ||
| 103 | |||
| 104 | |||
| 105 | |||
| 106 | push(@snmpoids,$snmpIfOperStatus); | ||
| 107 | push(@snmpoids,$snmpLocIfDescr); | ||
| 108 | push(@snmpoids,$snmpIfAdminStatus); | ||
| 109 | push(@snmpoids,$snmpIfDescr); | ||
| 110 | |||
| 111 | foreach $snmpoid (@snmpoids) { | ||
| 112 | |||
| 113 | ($session, $error) = Net::SNMP->session( | ||
| 114 | -hostname => $hostname, | ||
| 115 | -community => $community, | ||
| 116 | -port => $port | ||
| 117 | ); | ||
| 118 | |||
| 119 | if (!defined($session)) { | ||
| 120 | $state='UNKNOWN'; | ||
| 121 | $answer=$error; | ||
| 122 | print ("$state: $answer"); | ||
| 123 | exit $ERRORS{$state}; | ||
| 124 | } | ||
| 125 | |||
| 126 | if (!defined($response = $session->get_table($snmpoid))) { | ||
| 127 | $answer=$session->error; | ||
| 128 | $session->close; | ||
| 129 | $state = 'CRITICAL'; | ||
| 130 | print ("$state: $answer,$community,$snmpkey"); | ||
| 131 | exit $ERRORS{$state}; | ||
| 132 | } | ||
| 133 | |||
| 134 | foreach $snmpkey (keys %{$response}) { | ||
| 135 | $snmpkey =~ /.*\.(\d+)$/; | ||
| 136 | $key = $1; | ||
| 137 | $ifStatus{$key}{$snmpoid} = $response->{$snmpkey}; | ||
| 138 | } | ||
| 139 | $session->close; | ||
| 140 | } | ||
| 141 | |||
| 142 | foreach $key (keys %ifStatus) { | ||
| 143 | # check only if interface is administratively up | ||
| 144 | if ($ifStatus{$key}{$snmpIfAdminStatus} == 1 ) { | ||
| 145 | if ($ifStatus{$key}{$snmpIfOperStatus} == 1 ) { $ifup++ ;} | ||
| 146 | if ($ifStatus{$key}{$snmpIfOperStatus} == 2 ) { | ||
| 147 | $ifdown++ ; | ||
| 148 | $ifmessage .= sprintf("%s: down -> %s<BR>", | ||
| 149 | $ifStatus{$key}{$snmpIfDescr}, | ||
| 150 | $ifStatus{$key}{$snmpLocIfDescr}); | ||
| 151 | |||
| 152 | } | ||
| 153 | if ($ifStatus{$key}{$snmpIfOperStatus} == 5 ) { $ifdormant++ ;} | ||
| 154 | } | ||
| 155 | } | ||
| 156 | |||
| 157 | |||
| 158 | if ($ifdown > 0) { | ||
| 159 | $state = 'CRITICAL'; | ||
| 160 | $answer = sprintf("host '%s', interfaces up: %d, down: %d, dormant: %d<BR>", | ||
| 161 | $hostname, | ||
| 162 | $ifup, | ||
| 163 | $ifdown, | ||
| 164 | $ifdormant); | ||
| 165 | $answer = $answer . $ifmessage . "\n"; | ||
| 166 | } | ||
| 167 | else { | ||
| 168 | $state = 'OK'; | ||
| 169 | $answer = sprintf("host '%s', interfaces up: %d, down: %d, dormant: %d\n", | ||
| 170 | $hostname, | ||
| 171 | $ifup, | ||
| 172 | $ifdown, | ||
| 173 | $ifdormant); | ||
| 174 | } | ||
| 175 | |||
| 176 | print ("$state: $answer"); | ||
| 177 | exit $ERRORS{$state}; | ||
| 178 | |||
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 @@ | |||
| 1 | /****************************************************************************************** | ||
| 2 | * | ||
| 3 | * CHECK_IPXPING.C | ||
| 4 | * | ||
| 5 | * Program: IPX ping plugin for Nagios | ||
| 6 | * License: GPL | ||
| 7 | * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) | ||
| 8 | * | ||
| 9 | * Last Modified: 09-24-1999 | ||
| 10 | * | ||
| 11 | * Command line: CHECK_IPXPING <dest_network> <dest_address> <wrtt> <crtt> | ||
| 12 | * | ||
| 13 | * Description: | ||
| 14 | * | ||
| 15 | * This plugin will use the /usr/bin/ipxping command to ping the specified host using the | ||
| 16 | * IPX protocol. Note: Linux users must have IPX support compiled into the kernerl and | ||
| 17 | * must have IPX configured correctly in order for this plugin to work. | ||
| 18 | * If the round trip time value is above the <wrtt> level, a STATE_WARNING is | ||
| 19 | * returned. If it exceeds the <crtt> level, a STATE_CRITICAL is returned. | ||
| 20 | * | ||
| 21 | * | ||
| 22 | * | ||
| 23 | * IMPORTANT!! | ||
| 24 | * | ||
| 25 | * This plugin will only work with the ipxping command that has been ported to Linux. | ||
| 26 | * The version for Sun takes different command line arguments and differs in its output. | ||
| 27 | * | ||
| 28 | *****************************************************************************************/ | ||
| 29 | |||
| 30 | #include "../common/config.h" | ||
| 31 | #include "../common/common.h" | ||
| 32 | #include "netutils.h" | ||
| 33 | |||
| 34 | /* this should be moved out to the configure script! */ | ||
| 35 | #define IPXPING_COMMAND "/tmp/ipxping/ipxping" | ||
| 36 | |||
| 37 | /* these should be moved to the common header file */ | ||
| 38 | #define MAX_IPXNET_ADDRESS_LENGTH 12 | ||
| 39 | #define MAX_IPXHOST_ADDRESS_LENGTH 18 | ||
| 40 | |||
| 41 | int socket_timeout=DEFAULT_SOCKET_TIMEOUT; | ||
| 42 | char dest_network[MAX_IPXNET_ADDRESS_LENGTH]; | ||
| 43 | char dest_address[MAX_IPXHOST_ADDRESS_LENGTH]; | ||
| 44 | int wrtt; | ||
| 45 | int crtt; | ||
| 46 | |||
| 47 | int process_arguments(int,char **); | ||
| 48 | |||
| 49 | FILE * spopen(const char *); | ||
| 50 | int spclose(FILE *); | ||
| 51 | |||
| 52 | int main(int argc, char **argv){ | ||
| 53 | char command_line[MAX_INPUT_BUFFER]; | ||
| 54 | int rtt; | ||
| 55 | int bytes_returned; | ||
| 56 | int result=STATE_OK; | ||
| 57 | FILE *fp; | ||
| 58 | char input_buffer[MAX_INPUT_BUFFER]; | ||
| 59 | char *substr; | ||
| 60 | int current_line; | ||
| 61 | |||
| 62 | if(process_arguments(argc,argv)!=OK){ | ||
| 63 | printf("Incorrect arguments supplied\n"); | ||
| 64 | printf("\n"); | ||
| 65 | printf("IPX ping plugin for Nagios\n"); | ||
| 66 | printf("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n"); | ||
| 67 | printf("Last Modified: 09-24-1999\n"); | ||
| 68 | printf("License: GPL\n"); | ||
| 69 | printf("\n"); | ||
| 70 | printf("Usage: %s <dest_network> <dest_address> <wrtt> <crtt> [-to to_sec]\n",argv[0]); | ||
| 71 | printf("\n"); | ||
| 72 | printf("Options:\n"); | ||
| 73 | printf(" <dest_network> = IPX network that the remote host lies on. (Hex Format - 00:00:00:00)\n"); | ||
| 74 | printf(" <dest_address> = MAC address of the remote host. (Hex Format - 00:00:00:00:00:00)\n"); | ||
| 75 | printf(" <wrtt> = Round trip time in milliseconds necessary to result in a WARNING state\n"); | ||
| 76 | printf(" <crtt> = Round trip time in milliseconds necessary to result in a CRITICAL state\n"); | ||
| 77 | printf(" [to_sec] = Seconds before we should timeout waiting for ping result. Default = %d sec\n",DEFAULT_SOCKET_TIMEOUT); | ||
| 78 | printf("\n"); | ||
| 79 | printf("Notes:\n"); | ||
| 80 | printf("This plugin will use the /usr/bin/ipxping command to ping the specified host using\n"); | ||
| 81 | printf("the IPX protocol. IPX support must be compiled into the kernel and your host must\n"); | ||
| 82 | printf("be correctly configured to use IPX before this plugin will work! An RPM package of\n"); | ||
| 83 | printf("the ipxping binary can be found at...\n"); | ||
| 84 | printf("http://www.rpmfind.net/linux/RPM/contrib/libc5/i386/ipxping-0.0-2.i386.shtml\n"); | ||
| 85 | printf("\n"); | ||
| 86 | return STATE_UNKNOWN; | ||
| 87 | } | ||
| 88 | |||
| 89 | /* create the command line to use... */ | ||
| 90 | sprintf(command_line,"%s %s %s",IPXPING_COMMAND,dest_network,dest_address); | ||
| 91 | |||
| 92 | /* initialize alarm signal handling */ | ||
| 93 | signal(SIGALRM,socket_timeout_alarm_handler); | ||
| 94 | |||
| 95 | /* set socket timeout */ | ||
| 96 | alarm(socket_timeout); | ||
| 97 | |||
| 98 | /* run the command */ | ||
| 99 | fp = spopen(command_line); | ||
| 100 | if(fp==NULL){ | ||
| 101 | printf("Unable to open pipe: %s",command_line); | ||
| 102 | return STATE_UNKNOWN; | ||
| 103 | } | ||
| 104 | |||
| 105 | current_line=0; | ||
| 106 | while(fgets(input_buffer,MAX_INPUT_BUFFER-1,fp)){ | ||
| 107 | |||
| 108 | current_line++; | ||
| 109 | |||
| 110 | /* skip the first line of the output */ | ||
| 111 | if(current_line==1) | ||
| 112 | continue; | ||
| 113 | |||
| 114 | /* we didn't get the "is alive" */ | ||
| 115 | if(current_line==2 && !strstr(input_buffer,"is alive")) | ||
| 116 | result=STATE_CRITICAL; | ||
| 117 | |||
| 118 | /* get the round trip time */ | ||
| 119 | if(current_line==3){ | ||
| 120 | substr=strtok(input_buffer,":"); | ||
| 121 | substr=strtok(NULL,"\n"); | ||
| 122 | rtt=atoi(substr); | ||
| 123 | } | ||
| 124 | |||
| 125 | /* get the number of bytes returned */ | ||
| 126 | if(current_line==4 && strstr(input_buffer,"bytes returned")){ | ||
| 127 | bytes_returned=atoi(input_buffer); | ||
| 128 | } | ||
| 129 | } | ||
| 130 | |||
| 131 | /* close the pipe */ | ||
| 132 | spclose(fp); | ||
| 133 | |||
| 134 | /* reset the alarm */ | ||
| 135 | alarm(0); | ||
| 136 | |||
| 137 | if(current_line==1 || result==STATE_CRITICAL) | ||
| 138 | printf("IPX Ping problem - No response from host\n"); | ||
| 139 | else{ | ||
| 140 | |||
| 141 | if(rtt>crtt) | ||
| 142 | result=STATE_CRITICAL; | ||
| 143 | else if(rtt>wrtt) | ||
| 144 | result=STATE_WARNING; | ||
| 145 | |||
| 146 | 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); | ||
| 147 | } | ||
| 148 | |||
| 149 | |||
| 150 | return result; | ||
| 151 | } | ||
| 152 | |||
| 153 | |||
| 154 | |||
| 155 | /* process all arguments passed on the command line */ | ||
| 156 | int process_arguments(int argc, char **argv){ | ||
| 157 | int x; | ||
| 158 | |||
| 159 | /* no options were supplied */ | ||
| 160 | if(argc<5) | ||
| 161 | return ERROR; | ||
| 162 | |||
| 163 | /* get the destination network address */ | ||
| 164 | strncpy(dest_network,argv[1],sizeof(dest_network)-1); | ||
| 165 | dest_network[sizeof(dest_network)-1]='\x0'; | ||
| 166 | |||
| 167 | /* get the destination host address */ | ||
| 168 | strncpy(dest_address,argv[2],sizeof(dest_address)-1); | ||
| 169 | dest_address[sizeof(dest_address)-1]='\x0'; | ||
| 170 | |||
| 171 | /* get the round trip time variables */ | ||
| 172 | wrtt=atoi(argv[3]); | ||
| 173 | crtt=atoi(argv[4]); | ||
| 174 | |||
| 175 | /* process remaining arguments */ | ||
| 176 | for(x=6;x<=argc;x++){ | ||
| 177 | |||
| 178 | /* we got the timeout to use */ | ||
| 179 | if(!strcmp(argv[x-1],"-to")){ | ||
| 180 | if(x<argc){ | ||
| 181 | socket_timeout=atoi(argv[x]); | ||
| 182 | if(socket_timeout<=0) | ||
| 183 | return ERROR; | ||
| 184 | x++; | ||
| 185 | } | ||
| 186 | else | ||
| 187 | return ERROR; | ||
| 188 | } | ||
| 189 | |||
| 190 | /* else we got something else... */ | ||
| 191 | else | ||
| 192 | return ERROR; | ||
| 193 | } | ||
| 194 | |||
| 195 | return OK; | ||
| 196 | } | ||
| 197 | |||
| 198 | |||
| 199 | |||
| 200 | |||
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 @@ | |||
| 1 | #! /bin/sh | ||
| 2 | |||
| 3 | PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin | ||
| 4 | |||
| 5 | PROGNAME=`basename $0` | ||
| 6 | PROGPATH=`echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,'` | ||
| 7 | REVISION=`echo '$Revision$' | sed -e 's/[^0-9.]//g'` | ||
| 8 | STATUS="" | ||
| 9 | |||
| 10 | . $PROGPATH/utils.sh | ||
| 11 | |||
| 12 | |||
| 13 | print_usage() { | ||
| 14 | echo "Usage: $PROGNAME /dev/js<#> <button #>" | ||
| 15 | } | ||
| 16 | |||
| 17 | print_help() { | ||
| 18 | print_revision $PROGNAME $REVISION | ||
| 19 | echo "" | ||
| 20 | print_usage | ||
| 21 | echo "" | ||
| 22 | echo "This plugin checks a joystick button status using the " | ||
| 23 | echo "joyreadbutton utility from the joyd package." | ||
| 24 | echo "" | ||
| 25 | support | ||
| 26 | exit 0 | ||
| 27 | } | ||
| 28 | |||
| 29 | if [ $# -ne 2 ]; then | ||
| 30 | print_usage | ||
| 31 | exit 0 | ||
| 32 | fi | ||
| 33 | |||
| 34 | case "$1" in | ||
| 35 | --help) | ||
| 36 | print_help | ||
| 37 | exit 0 | ||
| 38 | ;; | ||
| 39 | -h) | ||
| 40 | print_help | ||
| 41 | exit 0 | ||
| 42 | ;; | ||
| 43 | --version) | ||
| 44 | print_revision $PROGNAME $REVISION | ||
| 45 | exit 0 | ||
| 46 | ;; | ||
| 47 | -V) | ||
| 48 | print_revision $PROGNAME $REVISION | ||
| 49 | exit 0 | ||
| 50 | ;; | ||
| 51 | /dev/js*) | ||
| 52 | joyreadbutton $1 $2 1>&1 1>/dev/null | ||
| 53 | STATUS=$? | ||
| 54 | if [ "$STATUS" -eq 0 ]; then | ||
| 55 | echo OK | ||
| 56 | exit 0 | ||
| 57 | elif [ "$STATUS" -eq 1 ];then | ||
| 58 | echo CRITICAL | ||
| 59 | exit 2 | ||
| 60 | else | ||
| 61 | echo UNKNOWN | ||
| 62 | exit -1 | ||
| 63 | fi | ||
| 64 | ;; | ||
| 65 | *) | ||
| 66 | print_usage | ||
| 67 | exit 0 | ||
| 68 | ;; | ||
| 69 | 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 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | # | ||
| 3 | # check_maxchannels.pl - nagios plugin | ||
| 4 | # | ||
| 5 | # | ||
| 6 | # Copyright (C) 2000 Christoph Kron | ||
| 7 | # | ||
| 8 | # This program is free software; you can redistribute it and/or | ||
| 9 | # modify it under the terms of the GNU General Public License | ||
| 10 | # as published by the Free Software Foundation; either version 2 | ||
| 11 | # of the License, or (at your option) any later version. | ||
| 12 | # | ||
| 13 | # This program is distributed in the hope that it will be useful, | ||
| 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | # GNU General Public License for more details. | ||
| 17 | # | ||
| 18 | # You should have received a copy of the GNU General Public License | ||
| 19 | # along with this program; if not, write to the Free Software | ||
| 20 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 21 | # | ||
| 22 | # | ||
| 23 | # Report bugs to: ck@zet.net | ||
| 24 | # | ||
| 25 | # 11.01.2000 Version 1.0 | ||
| 26 | |||
| 27 | use strict; | ||
| 28 | |||
| 29 | use Net::SNMP; | ||
| 30 | use Getopt::Long; | ||
| 31 | &Getopt::Long::config('auto_abbrev'); | ||
| 32 | |||
| 33 | |||
| 34 | my $status; | ||
| 35 | my $TIMEOUT = 15; | ||
| 36 | |||
| 37 | my %ERRORS = ('UNKNOWN' , '-1', | ||
| 38 | 'OK' , '0', | ||
| 39 | 'WARNING', '1', | ||
| 40 | 'CRITICAL', '2'); | ||
| 41 | |||
| 42 | |||
| 43 | my $state = "UNKNOWN"; | ||
| 44 | my $answer = ""; | ||
| 45 | my $snmpkey; | ||
| 46 | my $snmpoid; | ||
| 47 | my $key; | ||
| 48 | my $community = "public"; | ||
| 49 | my $port = 161; | ||
| 50 | my @snmpoids; | ||
| 51 | # free channels | ||
| 52 | my $snmpWanAvailableChannels = '1.3.6.1.4.1.529.4.23.0'; | ||
| 53 | # maximum channels | ||
| 54 | my $snmpWanSwitchedChannels = '1.3.6.1.4.1.529.4.24.0'; | ||
| 55 | my $snmpWanDisabledChannels = '1.3.6.1.4.1.529.4.25.0'; | ||
| 56 | my $snmpWanActiveChannels = '1.3.6.1.4.1.529.4.26.0'; | ||
| 57 | my $snmpWanNailedChannels = '1.3.6.1.4.1.529.4.27.0'; | ||
| 58 | my $snmpWanOutOfServiceChannels = '1.3.6.1.4.1.529.4.28.0'; | ||
| 59 | my $snmpEventCurrentActiveSessions = '1.3.6.1.4.1.529.10.6.0'; | ||
| 60 | # since startup | ||
| 61 | my $snmpEventTotalNoModems = '1.3.6.1.4.1.529.10.15.0'; | ||
| 62 | # lan modem | ||
| 63 | my $snmpDeadLanModem = '1.3.6.1.4.1.529.15.7.0'; | ||
| 64 | my $snmpDisabledLanModem = '1.3.6.1.4.1.529.15.5.0'; | ||
| 65 | my $snmpSuspectLanModem = '1.3.6.1.4.1.529.15.3.0'; | ||
| 66 | my $snmpAvailLanModem = '1.3.6.1.4.1.529.15.1.0'; | ||
| 67 | my $snmpBusyLanModem = '1.3.6.1.4.1.529.15.9.0'; | ||
| 68 | # max modems | ||
| 69 | my $snmpMdmNumber = '1.3.6.1.2.1.38.1.1.0'; | ||
| 70 | my $hostname; | ||
| 71 | my $session; | ||
| 72 | my $error; | ||
| 73 | my $response; | ||
| 74 | my %wanStatus; | ||
| 75 | |||
| 76 | |||
| 77 | my $WanAvailableChannels; | ||
| 78 | my $WanSwitchedChannels; | ||
| 79 | my $WanDisabledChannels; | ||
| 80 | my $WanActiveChannels; | ||
| 81 | my $WanNailedChannels; | ||
| 82 | my $WanOutOfServiceChannels; | ||
| 83 | my $EventCurrentActiveSessions; | ||
| 84 | my $EventTotalNoModems; | ||
| 85 | my $DeadLanModem; | ||
| 86 | my $DisabledLanModem; | ||
| 87 | my $SuspectLanModem; | ||
| 88 | my $AvailLanModem; | ||
| 89 | my $BusyLanModem; | ||
| 90 | my $MdmNumber; | ||
| 91 | |||
| 92 | |||
| 93 | sub usage { | ||
| 94 | printf "\nMissing arguments!\n"; | ||
| 95 | printf "\n"; | ||
| 96 | printf "Perl Check maxchannels plugin for Nagios\n"; | ||
| 97 | printf "monitors ISDN lines and modems on Ascend MAX 2000/4000/6000/TNT\n"; | ||
| 98 | printf "usage: \n"; | ||
| 99 | printf "check_maxchannel.pl -c <READCOMMUNITY> -p <PORT> <HOSTNAME>\n"; | ||
| 100 | printf "Copyright (C) 2000 Christoph Kron\n"; | ||
| 101 | printf "check_maxchannels.pl comes with ABSOLUTELY NO WARRANTY\n"; | ||
| 102 | printf "This programm is licensed under the terms of the "; | ||
| 103 | printf "GNU General Public License\n(check source code for details)\n"; | ||
| 104 | printf "\n\n"; | ||
| 105 | exit $ERRORS{"UNKNOWN"}; | ||
| 106 | } | ||
| 107 | |||
| 108 | # Just in case of problems, let's not hang Nagios | ||
| 109 | $SIG{'ALRM'} = sub { | ||
| 110 | print ("ERROR: No snmp response from $hostname (alarm)\n"); | ||
| 111 | exit $ERRORS{"UNKNOWN"}; | ||
| 112 | }; | ||
| 113 | alarm($TIMEOUT); | ||
| 114 | |||
| 115 | |||
| 116 | $status = GetOptions("community=s",\$community, | ||
| 117 | "port=i",\$port); | ||
| 118 | if ($status == 0) | ||
| 119 | { | ||
| 120 | &usage; | ||
| 121 | } | ||
| 122 | |||
| 123 | #shift; | ||
| 124 | $hostname = shift || &usage; | ||
| 125 | |||
| 126 | |||
| 127 | |||
| 128 | push(@snmpoids,$snmpWanAvailableChannels); | ||
| 129 | push(@snmpoids,$snmpWanSwitchedChannels); | ||
| 130 | push(@snmpoids,$snmpWanDisabledChannels); | ||
| 131 | push(@snmpoids,$snmpWanActiveChannels); | ||
| 132 | push(@snmpoids,$snmpWanNailedChannels); | ||
| 133 | push(@snmpoids,$snmpWanOutOfServiceChannels); | ||
| 134 | |||
| 135 | push(@snmpoids,$snmpEventCurrentActiveSessions); | ||
| 136 | |||
| 137 | push(@snmpoids,$snmpEventTotalNoModems); | ||
| 138 | push(@snmpoids,$snmpDeadLanModem); | ||
| 139 | push(@snmpoids,$snmpDisabledLanModem); | ||
| 140 | push(@snmpoids,$snmpSuspectLanModem); | ||
| 141 | push(@snmpoids,$snmpAvailLanModem); | ||
| 142 | push(@snmpoids,$snmpBusyLanModem); | ||
| 143 | push(@snmpoids,$snmpMdmNumber); | ||
| 144 | |||
| 145 | ($session, $error) = Net::SNMP->session( | ||
| 146 | -hostname => $hostname, | ||
| 147 | -community => $community, | ||
| 148 | -port => $port | ||
| 149 | ); | ||
| 150 | |||
| 151 | if (!defined($session)) { | ||
| 152 | $state='UNKNOWN'; | ||
| 153 | $answer=$error; | ||
| 154 | print ("$state: $answer"); | ||
| 155 | exit $ERRORS{$state}; | ||
| 156 | } | ||
| 157 | |||
| 158 | if (!defined($response = $session->get_request(@snmpoids))) { | ||
| 159 | $answer=$session->error; | ||
| 160 | $session->close; | ||
| 161 | $state = 'CRITICAL'; | ||
| 162 | print ("$state: $answer,$community"); | ||
| 163 | exit $ERRORS{$state}; | ||
| 164 | } | ||
| 165 | |||
| 166 | |||
| 167 | $WanAvailableChannels = $response->{$snmpWanAvailableChannels}; | ||
| 168 | $WanSwitchedChannels = $response->{$snmpWanSwitchedChannels}; | ||
| 169 | $WanDisabledChannels = $response->{$snmpWanDisabledChannels}; | ||
| 170 | $WanActiveChannels = $response->{$snmpWanActiveChannels}; | ||
| 171 | $WanNailedChannels = $response->{$snmpWanNailedChannels}; | ||
| 172 | $WanOutOfServiceChannels = $response->{$snmpWanOutOfServiceChannels}; | ||
| 173 | $EventCurrentActiveSessions = $response->{$snmpEventCurrentActiveSessions}; | ||
| 174 | $EventTotalNoModems = $response->{$snmpEventTotalNoModems}; | ||
| 175 | $DeadLanModem = $response->{$snmpDeadLanModem}; | ||
| 176 | $DisabledLanModem = $response->{$snmpDisabledLanModem}; | ||
| 177 | $SuspectLanModem = $response->{$snmpSuspectLanModem}; | ||
| 178 | $AvailLanModem = $response->{$snmpAvailLanModem}; | ||
| 179 | $BusyLanModem = $response->{$snmpBusyLanModem}; | ||
| 180 | $MdmNumber = $response->{$snmpMdmNumber}; | ||
| 181 | |||
| 182 | # less than 50% -> WARNING | ||
| 183 | if ( 0 < $WanOutOfServiceChannels | ||
| 184 | && $WanOutOfServiceChannels < ($snmpWanSwitchedChannels * 0.5) ) { | ||
| 185 | $state = 'WARNING'; | ||
| 186 | } | ||
| 187 | elsif ($WanOutOfServiceChannels > 0) { | ||
| 188 | $state = 'CRITICAL'; | ||
| 189 | } | ||
| 190 | elsif ($DeadLanModem > 0) { | ||
| 191 | $state = 'CRITICAL'; | ||
| 192 | } | ||
| 193 | elsif ($SuspectLanModem > 0) { | ||
| 194 | $state = 'WARNING'; | ||
| 195 | } | ||
| 196 | elsif ($AvailLanModem == 0) { | ||
| 197 | $state = 'WARNING'; | ||
| 198 | } | ||
| 199 | else { | ||
| 200 | $state = 'OK'; | ||
| 201 | } | ||
| 202 | |||
| 203 | |||
| 204 | $answer = sprintf("active sessions: %d (%d), active modems: %d (%d)<BR>", | ||
| 205 | $EventCurrentActiveSessions, | ||
| 206 | $WanSwitchedChannels, | ||
| 207 | $BusyLanModem, | ||
| 208 | $MdmNumber); | ||
| 209 | |||
| 210 | $answer .= sprintf("channels available: %d, disabled: %d", | ||
| 211 | $WanAvailableChannels, | ||
| 212 | $WanDisabledChannels); | ||
| 213 | |||
| 214 | $answer .= sprintf(", out of service: %d, nailed: %d<BR>", | ||
| 215 | $WanOutOfServiceChannels, | ||
| 216 | $WanNailedChannels); | ||
| 217 | |||
| 218 | $answer .= sprintf("modems avail.: %d, disabled: %d, suspect: %d, dead: %d<BR>", | ||
| 219 | $AvailLanModem, | ||
| 220 | $DisabledLanModem, | ||
| 221 | $SuspectLanModem, | ||
| 222 | $DeadLanModem); | ||
| 223 | |||
| 224 | $answer .= sprintf("unserviced modem calls: %d (since startup)\n", | ||
| 225 | $EventTotalNoModems); | ||
| 226 | |||
| 227 | $session->close; | ||
| 228 | |||
| 229 | print ("$state: $answer"); | ||
| 230 | exit $ERRORS{$state}; | ||
| 231 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | # | ||
| 3 | # check_maxwanstate.pl - nagios plugin | ||
| 4 | # | ||
| 5 | # | ||
| 6 | # Copyright (C) 2000 Christoph Kron | ||
| 7 | # | ||
| 8 | # This program is free software; you can redistribute it and/or | ||
| 9 | # modify it under the terms of the GNU General Public License | ||
| 10 | # as published by the Free Software Foundation; either version 2 | ||
| 11 | # of the License, or (at your option) any later version. | ||
| 12 | # | ||
| 13 | # This program is distributed in the hope that it will be useful, | ||
| 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | # GNU General Public License for more details. | ||
| 17 | # | ||
| 18 | # You should have received a copy of the GNU General Public License | ||
| 19 | # along with this program; if not, write to the Free Software | ||
| 20 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 21 | # | ||
| 22 | # | ||
| 23 | # Report bugs to: ck@zet.net | ||
| 24 | # | ||
| 25 | # 11.01.2000 Version 1.0 | ||
| 26 | |||
| 27 | use strict; | ||
| 28 | |||
| 29 | use Net::SNMP; | ||
| 30 | use Getopt::Long; | ||
| 31 | &Getopt::Long::config('auto_abbrev'); | ||
| 32 | |||
| 33 | |||
| 34 | my $status; | ||
| 35 | my $TIMEOUT = 1500; | ||
| 36 | |||
| 37 | my %ERRORS = ('UNKNOWN' , '-1', | ||
| 38 | 'OK' , '0', | ||
| 39 | 'WARNING', '1', | ||
| 40 | 'CRITICAL', '2'); | ||
| 41 | |||
| 42 | my %wanLineState = ( | ||
| 43 | 1,'ls-unknown', | ||
| 44 | 2,'ls-does-not-exist', | ||
| 45 | 3,'ls-disabled', | ||
| 46 | 4,'ls-no-physical', | ||
| 47 | 5,'ls-no-logical', | ||
| 48 | 6,'ls-point-to-point', | ||
| 49 | 7,'ls-multipoint-1', | ||
| 50 | 8,'ls-multipoint-2', | ||
| 51 | 9,'ls-loss-of-sync', | ||
| 52 | 10,'ls-yellow-alarm', | ||
| 53 | 11,'ls-ais-receive', | ||
| 54 | 12,'ls-no-d-channel', | ||
| 55 | 13,'ls-active', | ||
| 56 | 14,'ls-maintenance'); | ||
| 57 | |||
| 58 | my %wanLineType = ( | ||
| 59 | '1.3.6.1.4.1.529.4.1','Any', | ||
| 60 | '1.3.6.1.4.1.529.4.2','T1', | ||
| 61 | '1.3.6.1.4.1.529.4.3','E1', | ||
| 62 | '1.3.6.1.4.1.529.4.4','Dpnss', | ||
| 63 | '1.3.6.1.4.1.529.4.5','Bri', | ||
| 64 | '1.3.6.1.4.1.529.4.6','S562', | ||
| 65 | '1.3.6.1.4.1.529.4.7','S564', | ||
| 66 | '1.3.6.1.4.1.529.4.8','Sdsl', | ||
| 67 | '1.3.6.1.4.1.529.4.9','AdslCap'); | ||
| 68 | |||
| 69 | my $state = "UNKNOWN"; | ||
| 70 | my $answer = ""; | ||
| 71 | my $snmpkey; | ||
| 72 | my $snmpoid; | ||
| 73 | my $key; | ||
| 74 | my $community = "public"; | ||
| 75 | my $port = 161; | ||
| 76 | my @snmpoids; | ||
| 77 | my $snmpWanLineName = '1.3.6.1.4.1.529.4.21.1.2'; | ||
| 78 | my $snmpWanLineType = '1.3.6.1.4.1.529.4.21.1.3'; | ||
| 79 | my $snmpWanLineState = '1.3.6.1.4.1.529.4.21.1.5'; | ||
| 80 | my $snmpWanLineUsage = '1.3.6.1.4.1.529.4.21.1.8'; | ||
| 81 | |||
| 82 | my $hostname; | ||
| 83 | my $session; | ||
| 84 | my $error; | ||
| 85 | my $response; | ||
| 86 | my %wanStatus; | ||
| 87 | my $ifup =0 ; | ||
| 88 | my $ifdown =0; | ||
| 89 | my $ifdormant = 0; | ||
| 90 | my $ifmessage; | ||
| 91 | |||
| 92 | sub usage { | ||
| 93 | printf "\nMissing arguments!\n"; | ||
| 94 | printf "\n"; | ||
| 95 | printf "Perl Check maxwanstate plugin for Nagios\n"; | ||
| 96 | printf "monitors E1/T1 interface status\n"; | ||
| 97 | printf "usage: \n"; | ||
| 98 | printf "check_maxwanstate.pl -c <READCOMMUNITY> -p <PORT> <HOSTNAME>"; | ||
| 99 | printf "Copyright (C) 2000 Christoph Kron\n"; | ||
| 100 | printf "check_maxwanstate.pl comes with ABSOLUTELY NO WARRANTY\n"; | ||
| 101 | printf "This programm is licensed under the terms of the "; | ||
| 102 | printf "GNU General Public License\n(check source code for details)\n"; | ||
| 103 | printf "\n\n"; | ||
| 104 | exit $ERRORS{"UNKNOWN"}; | ||
| 105 | } | ||
| 106 | |||
| 107 | # Just in case of problems, let's not hang Nagios | ||
| 108 | $SIG{'ALRM'} = sub { | ||
| 109 | print ("ERROR: No snmp response from $hostname (alarm)\n"); | ||
| 110 | exit $ERRORS{"UNKNOWN"}; | ||
| 111 | }; | ||
| 112 | alarm($TIMEOUT); | ||
| 113 | |||
| 114 | |||
| 115 | $status = GetOptions("community=s",\$community, | ||
| 116 | "port=i",\$port); | ||
| 117 | if ($status == 0) | ||
| 118 | { | ||
| 119 | &usage; | ||
| 120 | } | ||
| 121 | |||
| 122 | #shift; | ||
| 123 | $hostname = shift || &usage; | ||
| 124 | |||
| 125 | |||
| 126 | |||
| 127 | push(@snmpoids,$snmpWanLineUsage); | ||
| 128 | push(@snmpoids,$snmpWanLineState); | ||
| 129 | push(@snmpoids,$snmpWanLineName); | ||
| 130 | push(@snmpoids,$snmpWanLineType); | ||
| 131 | |||
| 132 | foreach $snmpoid (@snmpoids) { | ||
| 133 | |||
| 134 | ($session, $error) = Net::SNMP->session( | ||
| 135 | -hostname => $hostname, | ||
| 136 | -community => $community, | ||
| 137 | -port => $port | ||
| 138 | ); | ||
| 139 | |||
| 140 | if (!defined($session)) { | ||
| 141 | $state='UNKNOWN'; | ||
| 142 | $answer=$error; | ||
| 143 | print ("$state: $answer"); | ||
| 144 | exit $ERRORS{$state}; | ||
| 145 | } | ||
| 146 | |||
| 147 | if (!defined($response = $session->get_table($snmpoid))) { | ||
| 148 | $answer=$session->error; | ||
| 149 | $session->close; | ||
| 150 | $state = 'CRITICAL'; | ||
| 151 | print ("$state: $answer,$community,$snmpkey"); | ||
| 152 | exit $ERRORS{$state}; | ||
| 153 | } | ||
| 154 | |||
| 155 | foreach $snmpkey (keys %{$response}) { | ||
| 156 | $snmpkey =~ /.*\.(\d+)$/; | ||
| 157 | $key = $1; | ||
| 158 | $wanStatus{$key}{$snmpoid} = $response->{$snmpkey}; | ||
| 159 | } | ||
| 160 | $session->close; | ||
| 161 | } | ||
| 162 | |||
| 163 | foreach $key (keys %wanStatus) { | ||
| 164 | # look only at active Interfaces lu-trunk(5) | ||
| 165 | if ($wanStatus{$key}{$snmpWanLineUsage} == 5 ) { | ||
| 166 | |||
| 167 | # 13 -> active | ||
| 168 | if ($wanStatus{$key}{$snmpWanLineState} == 13 ) { | ||
| 169 | $ifup++; | ||
| 170 | } | ||
| 171 | else { | ||
| 172 | $ifdown++ ; | ||
| 173 | $ifmessage .= sprintf("%s interface status : %s (%s)<BR>", | ||
| 174 | $wanLineType{$wanStatus{$key}{$snmpWanLineType}}, | ||
| 175 | $wanLineState{$wanStatus{$key}{$snmpWanLineState}}, | ||
| 176 | $wanStatus{$key}{$snmpWanLineName}); | ||
| 177 | |||
| 178 | } | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | |||
| 183 | if ($ifdown > 0) { | ||
| 184 | $state = 'CRITICAL'; | ||
| 185 | $answer = sprintf("host '%s', interfaces up: %d, down: %d<BR>", | ||
| 186 | $hostname, | ||
| 187 | $ifup, | ||
| 188 | $ifdown); | ||
| 189 | $answer = $answer . $ifmessage . "\n"; | ||
| 190 | } | ||
| 191 | else { | ||
| 192 | $state = 'OK'; | ||
| 193 | $answer = sprintf("host '%s', interfaces up: %d, down: %d\n", | ||
| 194 | $hostname, | ||
| 195 | $ifup, | ||
| 196 | $ifdown); | ||
| 197 | } | ||
| 198 | |||
| 199 | print ("$state: $answer"); | ||
| 200 | exit $ERRORS{$state}; | ||
| 201 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | # $Id$ | ||
| 3 | |||
| 4 | # check_mem.pl Copyright (C) 2000 Dan Larsson <dl@tyfon.net> | ||
| 5 | # | ||
| 6 | # This program is free software; you can redistribute it and/or | ||
| 7 | # modify it under the terms of the GNU General Public License | ||
| 8 | # as published by the Free Software Foundation; either version 2 | ||
| 9 | # of the License, or (at your option) any later version. | ||
| 10 | # | ||
| 11 | # This program is distributed in the hope that it will be useful, | ||
| 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty | ||
| 13 | # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | # GNU General Public License for more details. | ||
| 15 | # | ||
| 16 | # you should have received a copy of the GNU General Public License | ||
| 17 | # along with this program (or with Nagios); if not, write to the | ||
| 18 | # Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 19 | # Boston, MA 02111-1307, USA | ||
| 20 | |||
| 21 | # Tell Perl what we need to use | ||
| 22 | use strict; | ||
| 23 | use Getopt::Std; | ||
| 24 | |||
| 25 | use vars qw($opt_c $opt_f $opt_u $opt_w | ||
| 26 | $free_memory $used_memory $total_memory | ||
| 27 | $crit_level $warn_level | ||
| 28 | %exit_codes @memlist | ||
| 29 | $percent $fmt_pct | ||
| 30 | $verb_err $command_line); | ||
| 31 | |||
| 32 | # Predefined exit codes for Nagios | ||
| 33 | %exit_codes = ('UNKNOWN' ,-1, | ||
| 34 | 'OK' , 0, | ||
| 35 | 'WARNING' , 1, | ||
| 36 | 'CRITICAL', 2,); | ||
| 37 | |||
| 38 | # Turn this to 1 to see reason for parameter errors (if any) | ||
| 39 | $verb_err = 0; | ||
| 40 | |||
| 41 | # This the unix command string that brings Perl the data | ||
| 42 | $command_line = `vmstat | tail -1 | awk '{print \$4,\$5}'`; | ||
| 43 | |||
| 44 | chomp $command_line; | ||
| 45 | @memlist = split(/ /, $command_line); | ||
| 46 | |||
| 47 | # Define the calculating scalars | ||
| 48 | $used_memory = $memlist[0]; | ||
| 49 | $free_memory = $memlist[1]; | ||
| 50 | $total_memory = $used_memory + $free_memory; | ||
| 51 | |||
| 52 | # Get the options | ||
| 53 | if ($#ARGV le 0) | ||
| 54 | { | ||
| 55 | &usage; | ||
| 56 | } | ||
| 57 | else | ||
| 58 | { | ||
| 59 | getopts('c:fuw:'); | ||
| 60 | } | ||
| 61 | |||
| 62 | # Shortcircuit the switches | ||
| 63 | if (!$opt_w or $opt_w == 0 or !$opt_c or $opt_c == 0) | ||
| 64 | { | ||
| 65 | print "*** You must define WARN and CRITICAL levels!" if ($verb_err); | ||
| 66 | &usage; | ||
| 67 | } | ||
| 68 | elsif (!$opt_f and !$opt_u) | ||
| 69 | { | ||
| 70 | print "*** You must select to monitor either USED or FREE memory!" if ($verb_err); | ||
| 71 | &usage; | ||
| 72 | } | ||
| 73 | |||
| 74 | # Check if levels are sane | ||
| 75 | if ($opt_w <= $opt_c and $opt_f) | ||
| 76 | { | ||
| 77 | print "*** WARN level must not be less than CRITICAL when checking FREE memory!" if ($verb_err); | ||
| 78 | &usage; | ||
| 79 | } | ||
| 80 | elsif ($opt_w >= $opt_c and $opt_u) | ||
| 81 | { | ||
| 82 | print "*** WARN level must not be greater than CRITICAL when checking USED memory!" if ($verb_err); | ||
| 83 | &usage; | ||
| 84 | } | ||
| 85 | |||
| 86 | $warn_level = $opt_w; | ||
| 87 | $crit_level = $opt_c; | ||
| 88 | |||
| 89 | if ($opt_f) | ||
| 90 | { | ||
| 91 | $percent = $free_memory / $total_memory * 100; | ||
| 92 | $fmt_pct = sprintf "%.1f", $percent; | ||
| 93 | if ($percent <= $crit_level) | ||
| 94 | { | ||
| 95 | print "Memory CRITICAL - $fmt_pct% ($free_memory kB) free\n"; | ||
| 96 | exit $exit_codes{'CRITICAL'}; | ||
| 97 | } | ||
| 98 | elsif ($percent <= $warn_level) | ||
| 99 | { | ||
| 100 | print "Memory WARNING - $fmt_pct% ($free_memory kB) free\n"; | ||
| 101 | exit $exit_codes{'WARNING'}; | ||
| 102 | } | ||
| 103 | else | ||
| 104 | { | ||
| 105 | print "Memory OK - $fmt_pct% ($free_memory kB) free\n"; | ||
| 106 | exit $exit_codes{'OK'}; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | elsif ($opt_u) | ||
| 110 | { | ||
| 111 | $percent = $used_memory / $total_memory * 100; | ||
| 112 | $fmt_pct = sprintf "%.1f", $percent; | ||
| 113 | if ($percent >= $crit_level) | ||
| 114 | { | ||
| 115 | print "Memory CRITICAL - $fmt_pct% ($used_memory kB) used\n"; | ||
| 116 | exit $exit_codes{'CRITICAL'}; | ||
| 117 | } | ||
| 118 | elsif ($percent >= $warn_level) | ||
| 119 | { | ||
| 120 | print "Memory WARNING - $fmt_pct% ($used_memory kB) used\n"; | ||
| 121 | exit $exit_codes{'WARNING'}; | ||
| 122 | } | ||
| 123 | else | ||
| 124 | { | ||
| 125 | print "Memory OK - $fmt_pct% ($used_memory kB) used\n"; | ||
| 126 | exit $exit_codes{'OK'}; | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | # Show usage | ||
| 131 | sub usage() | ||
| 132 | { | ||
| 133 | print "\ncheck_mem.pl v1.0 - Nagios Plugin\n\n"; | ||
| 134 | print "usage:\n"; | ||
| 135 | print " check_mem.pl -<f|u> -w <warnlevel> -c <critlevel>\n\n"; | ||
| 136 | print "options:\n"; | ||
| 137 | print " -f Check FREE memory\n"; | ||
| 138 | print " -u Check USED memory\n"; | ||
| 139 | print " -w PERCENT Percent free/used when to warn\n"; | ||
| 140 | print " -c PERCENT Percent free/used when critical\n"; | ||
| 141 | print "\nCopyright (C) 2000 Dan Larsson <dl\@tyfon.net>\n"; | ||
| 142 | print "check_mem.pl comes with absolutely NO WARRANTY either implied or explicit\n"; | ||
| 143 | print "This program is licensed under the terms of the\n"; | ||
| 144 | print "GNU General Public License (check source code for details)\n"; | ||
| 145 | exit $exit_codes{'UNKNOWN'}; | ||
| 146 | } | ||
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 @@ | |||
| 1 | /***************************************************************** | ||
| 2 | * | ||
| 3 | * Program: check_mysql.c | ||
| 4 | * License: GPL | ||
| 5 | * | ||
| 6 | * Written by Tim Weippert | ||
| 7 | * (based on plugins by Ethan Galstad and MySQL example code) | ||
| 8 | * | ||
| 9 | * Command line: check_mysql <host> [user] [passwd] | ||
| 10 | * <host> can be the FQDN or the IP-Adress | ||
| 11 | * [user] and [passwd] are optional | ||
| 12 | * | ||
| 13 | * Description: | ||
| 14 | * | ||
| 15 | * This plugin attempts to connect to an MySQL Server | ||
| 16 | * with the optional specified parameters user and passwd. | ||
| 17 | * Normaly the host and a user HAVE to assigned. | ||
| 18 | * | ||
| 19 | * The plugin returns | ||
| 20 | * STATE_OK and the Version Number of the Server when all is fine | ||
| 21 | * STATE_CRITICAL if the Connection can't be esablished | ||
| 22 | * STATE_WARNING if the connection was established but the | ||
| 23 | * program can't get the Versoin Number | ||
| 24 | * STATE_UNKNOWN if to many parameters are given | ||
| 25 | * | ||
| 26 | * Copyright (c) 1999 by Tim Weippert | ||
| 27 | * | ||
| 28 | * Changes: | ||
| 29 | * 16.12.1999: Changed the return codes from numbers to statements | ||
| 30 | * | ||
| 31 | *******************************************************************/ | ||
| 32 | |||
| 33 | #include "../common/config.h" | ||
| 34 | #include "../common/common.h" | ||
| 35 | #include "mysql.h" | ||
| 36 | |||
| 37 | MYSQL mysql; | ||
| 38 | |||
| 39 | int main(int argc, char **argv) | ||
| 40 | { | ||
| 41 | uint i = 0; | ||
| 42 | char *host; | ||
| 43 | char *user; | ||
| 44 | char *passwd; | ||
| 45 | |||
| 46 | char *status; | ||
| 47 | char *version; | ||
| 48 | |||
| 49 | if ( argc > 4 ) { | ||
| 50 | printf("Too many Arguments supplied - %i .\n", argc); | ||
| 51 | printf("Usage: %s <host> [user] [passwd]\n", argv[0]); | ||
| 52 | return STATE_UNKNOWN; | ||
| 53 | } | ||
| 54 | |||
| 55 | (host = argv[1]) || (host = NULL); | ||
| 56 | (user = argv[2]) || (user = NULL); | ||
| 57 | (passwd = argv[3]) || (passwd = NULL); | ||
| 58 | |||
| 59 | if (!(mysql_connect(&mysql,host,user,passwd))) { | ||
| 60 | printf("Can't connect to Mysql on Host: %s\n", host); | ||
| 61 | return STATE_CRITICAL; | ||
| 62 | } | ||
| 63 | |||
| 64 | if ( !(version = mysql_get_server_info(&mysql)) ) { | ||
| 65 | printf("Connect OK, but can't get Serverinfo ... something wrong !\n"); | ||
| 66 | return STATE_WARNING; | ||
| 67 | } | ||
| 68 | |||
| 69 | printf("Mysql ok - Running Version: %s\n", version); | ||
| 70 | |||
| 71 | mysql_close(&mysql); | ||
| 72 | return STATE_OK; | ||
| 73 | } | ||
| 74 | |||
| 75 | |||
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 @@ | |||
| 1 | #!/nyet/bin/perl | ||
| 2 | # | ||
| 3 | # (c)1999 Mitch Wright, NetLine Corporation | ||
| 4 | # Read the GNU copyright stuff for all the legalese | ||
| 5 | # | ||
| 6 | # Check to see that our MySQL server(s) are up and running. | ||
| 7 | # This plugin requires that mysqladmin(1) is installed on the system. | ||
| 8 | # Since it is part of the MySQL distribution, that should be a problem. | ||
| 9 | # | ||
| 10 | # If no parameters are giving, a usage statement is output. | ||
| 11 | # | ||
| 12 | # Exit 0 on success, providing some informational output | ||
| 13 | # Exit 2 on failure, provide what we can... | ||
| 14 | # | ||
| 15 | |||
| 16 | require 5.004; | ||
| 17 | |||
| 18 | sub usage; | ||
| 19 | |||
| 20 | my $TIMEOUT = 15; | ||
| 21 | my $MYSQLADMIN = "/usr/local/bin/mysqladmin"; | ||
| 22 | |||
| 23 | my %ERRORS = ('UNKNOWN' , '-1', | ||
| 24 | 'OK' , '0', | ||
| 25 | 'WARNING', '1', | ||
| 26 | 'CRITICAL', '2'); | ||
| 27 | |||
| 28 | my $host = shift || &usage(%ERRORS); | ||
| 29 | my $user = shift || &usage(%ERRORS); | ||
| 30 | my $pass = shift || ""; | ||
| 31 | my $warn = shift || 60; | ||
| 32 | my $crit = shift || 100; | ||
| 33 | |||
| 34 | my $state = "OK"; | ||
| 35 | |||
| 36 | # Just in case of problems, let's not hang Nagios | ||
| 37 | $SIG{'ALRM'} = sub { | ||
| 38 | print ("ERROR: No response from MySQL server (alarm)\n"); | ||
| 39 | exit $ERRORS{"UNKNOWN"}; | ||
| 40 | }; | ||
| 41 | alarm($TIMEOUT); | ||
| 42 | |||
| 43 | open (OUTPUT, | ||
| 44 | "$MYSQLADMIN -h $host -u $user --password=\"$pass\" version 2>&1 | ||
| 45 | |"); | ||
| 46 | |||
| 47 | while (<OUTPUT>) { | ||
| 48 | if (/failed/) { $state="CRITICAL"; s/.*://; $status=$_; last; } | ||
| 49 | next if /^\s*$/; | ||
| 50 | if (/^Server version\s+(\d+.*)/) { $version = $1; next; } | ||
| 51 | if (/^Uptime:\s+(\d.*)/) { $uptime = $1; next; } | ||
| 52 | if (/^Threads:\s+(\d+)\s+/) { $threads = $1; next; } | ||
| 53 | } | ||
| 54 | |||
| 55 | $status = "Version $version -- $threads Threads <br>Uptime $uptime" if | ||
| 56 | $state ne "CRITICAL"; | ||
| 57 | |||
| 58 | if ($threads >= $warn) { $state = "WARNING"; } | ||
| 59 | if ($threads >= $crit) { $state = "CRITICAL"; } | ||
| 60 | |||
| 61 | print $status; | ||
| 62 | exit $ERRORS{$state}; | ||
| 63 | |||
| 64 | sub usage { | ||
| 65 | print "Required arguments not given!\n\n"; | ||
| 66 | print "MySQL status checker plugin for Nagios, V1.01\n"; | ||
| 67 | print "Copyright (c) 1999-2000 Mitch Wright \n\n"; | ||
| 68 | print "Usage: check_mysql.pl <host> <user> [<pass> [<warn> | ||
| 69 | [<crit>]]]\n\n"; print " <pass> = password to use for <user> at | ||
| 70 | <host>\n"; print " <warn> = number of threads to warn us | ||
| 71 | about\n"; print " <crit> = number of threads to scream at us | ||
| 72 | about\n"; exit $ERRORS{"UNKNOWN"}; | ||
| 73 | } | ||
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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | # denao - denao@uol.com.br - Systems Engineering | ||
| 3 | # Universo Online - http://www.uol.com.br | ||
| 4 | use DBI; | ||
| 5 | use Time::Local; | ||
| 6 | |||
| 7 | my $t_lambuja = 5; # (expire_minutes) | ||
| 8 | my $databasename = ""; # The name of nagios database (i.e.: nagios) | ||
| 9 | my $table = "programstatus"; | ||
| 10 | my $where = "localhost"; # The machine where the database | ||
| 11 | my $port = "3306"; | ||
| 12 | my $base = "DBI:mysql:$databasename:$where:$port"; | ||
| 13 | my $user = ""; # the user to connect to the database | ||
| 14 | # (needs permission to "select at programstatus table only" | ||
| 15 | my $password = ""; # the password (if any) | ||
| 16 | my %results; | ||
| 17 | my @fields = qw( last_update ); | ||
| 18 | my $dbh = DBI->connect($base,$user,$password); | ||
| 19 | my $fields = join(', ', @fields); | ||
| 20 | my $query = "SELECT $fields FROM $table"; | ||
| 21 | |||
| 22 | my $sth = $dbh->prepare($query); | ||
| 23 | $sth->execute(); | ||
| 24 | |||
| 25 | @results{@fields} = (); | ||
| 26 | $sth->bind_columns(map { \$results{$_} } @fields); | ||
| 27 | |||
| 28 | $sth->fetch(); | ||
| 29 | $sth->finish(); | ||
| 30 | $dbh->disconnect(); | ||
| 31 | |||
| 32 | check_update(); | ||
| 33 | |||
| 34 | sub check_update { | ||
| 35 | ($yea,$mon,$day,$hou,$min,$sec)=($results{last_update}=~/(\d+)\-(\d+)\-(\d+)\s(\d+)\:(\d+)\:(\d+)/); | ||
| 36 | ($sec_now, $min_now, $hou_now, $day_now, $mon_now, $yea_now) = (localtime(time))[0,1,2,3,4,5]; | ||
| 37 | $mon_now+=1; $yea_now+=1900; | ||
| 38 | $unixdate=timelocal($sec,$min,$hou,$day,$mon,$yea); | ||
| 39 | $unixdate_now=timelocal($sec_now,$min_now,$hou_now,$day_now,$mon_now,$yea_now); | ||
| 40 | if (scalar($unixdate_now - $unixdate) > scalar($t_lambuja * 60)) { | ||
| 41 | print "Nagios problem: nagios is down, for at least " . scalar($t_lambuja) . " minutes.\n"; | ||
| 42 | exit(1); | ||
| 43 | } else { | ||
| 44 | print "Nagios ok: status data updated " . scalar($unixdate_now - $unixdate) . " seconds ago\n"; | ||
| 45 | exit(0); | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl -wT | ||
| 2 | # check_netapp | ||
| 3 | # | ||
| 4 | # Copyright (C) 2000 Leland E. Vandervort <leland@mmania.com> | ||
| 5 | # | ||
| 6 | # This program is free software; you can redistribute it and/or | ||
| 7 | # modify it under the terms of the GNU General Public License | ||
| 8 | # as published by the Free Software Foundation; either version 2 | ||
| 9 | # of the License, or (at your option) any later version. | ||
| 10 | # | ||
| 11 | # This program is distributed in the hope that it will be useful, | ||
| 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty | ||
| 13 | # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | # GNU General Public License for more details. | ||
| 15 | # | ||
| 16 | # you should have received a copy of the GNU General Public License | ||
| 17 | # along with this program (or with Nagios); if not, write to the | ||
| 18 | # Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 19 | # Boston, MA 02111-1307, USA | ||
| 20 | #################################### | ||
| 21 | # checks for overtemperature, fans, psu, and nfs operations/second on | ||
| 22 | # Network Appliance Filers. | ||
| 23 | # Returns: | ||
| 24 | # OK if temp, fans, psu OK and Ops/Sec below warning and critical | ||
| 25 | # Thresholds (default is warning=3500, critical=5000) | ||
| 26 | # ** Note: See the specifications for your Filer model for | ||
| 27 | # the thresholds ! | ||
| 28 | # Returns Warning if NFS Ops/Sec is above warning threshold | ||
| 29 | # (default 3500, or specified by -o command line option) | ||
| 30 | # Returns Critical if NFS Ops/Sec is above critical threshold | ||
| 31 | # ( -m option, or default 5000), or if overtem, psufault, or | ||
| 32 | # fanfault detected. | ||
| 33 | # | ||
| 34 | #################################### | ||
| 35 | # Notes on operational limits for NetApp Filers: | ||
| 36 | # Platform Maximum Ops/Second (recommended) | ||
| 37 | # ------------------------------------------------------------- | ||
| 38 | # F230 1000 | ||
| 39 | # F740 5500 | ||
| 40 | # F760 9000 | ||
| 41 | #################################### | ||
| 42 | |||
| 43 | use Net::SNMP; | ||
| 44 | use Getopt::Long; | ||
| 45 | &Getopt::Long::config('auto_abbrev'); | ||
| 46 | |||
| 47 | my $status; | ||
| 48 | my $response = ""; | ||
| 49 | my $TIMEOUT = 10; | ||
| 50 | my $community = "public"; | ||
| 51 | my $port = 161; | ||
| 52 | my $opsthresh = "3500"; | ||
| 53 | my $critical = "5000"; | ||
| 54 | |||
| 55 | my $status_string = ""; | ||
| 56 | |||
| 57 | my %OIDLIST = ( | ||
| 58 | overtemp => '1.3.6.1.4.1.789.1.2.4.1.0', | ||
| 59 | failedfan => '1.3.6.1.4.1.789.1.2.4.2.0', | ||
| 60 | failedpsu => '1.3.6.1.4.1.789.1.2.4.4.0', | ||
| 61 | nfsops => '1.3.6.1.4.1.789.1.2.2.1.0' | ||
| 62 | ); | ||
| 63 | |||
| 64 | |||
| 65 | |||
| 66 | my %STATUSCODE = ( 'UNKNOWN' => '-1', | ||
| 67 | 'OK' => '0', | ||
| 68 | 'WARNING' => '1', | ||
| 69 | 'CRITICAL' => '2'); | ||
| 70 | |||
| 71 | my $state = "UNKNOWN"; | ||
| 72 | |||
| 73 | |||
| 74 | $SIG{'ALRM'} = sub { | ||
| 75 | print "ERROR: No snmp response from $hostname (sigALRM)\n"; | ||
| 76 | exit($STATUSCODE{"UNKNOWN"}); | ||
| 77 | }; | ||
| 78 | |||
| 79 | alarm($TIMEOUT); | ||
| 80 | |||
| 81 | sub get_nfsops { | ||
| 82 | my $nfsops_start = &SNMPGET($OIDLIST{nfsops}); | ||
| 83 | sleep(1); | ||
| 84 | my $nfsops_end = &SNMPGET($OIDLIST{nfsops}); | ||
| 85 | my $nfsopspersec = $nfsops_end - $nfsops_start; | ||
| 86 | return($nfsopspersec); | ||
| 87 | } | ||
| 88 | |||
| 89 | |||
| 90 | sub show_help { | ||
| 91 | printf("\nPerl NetApp filer plugin for Nagios\n"); | ||
| 92 | printf("Usage:\n"); | ||
| 93 | printf(" | ||
| 94 | check_netapp [options] <hostname> | ||
| 95 | Options: | ||
| 96 | -c snmp-community | ||
| 97 | -p snmp-port | ||
| 98 | -o Operations per second warning threshold | ||
| 99 | -m Operations per second critical threshold | ||
| 100 | |||
| 101 | "); | ||
| 102 | printf("Copyright (C)2000 Leland E. Vandervort\n"); | ||
| 103 | printf("check_netapp comes with absolutely NO WARRANTY either implied or explicit\n"); | ||
| 104 | printf("This program is licensed under the terms of the\n"); | ||
| 105 | printf("GNU General Public License\n(check source code for details)\n\n\n"); | ||
| 106 | exit($STATUSCODE{"UNKNOWN"}); | ||
| 107 | } | ||
| 108 | |||
| 109 | |||
| 110 | $status = GetOptions( "community=s", \$community, | ||
| 111 | "port=i", \$port, | ||
| 112 | "opsthresh=i", \$opsthresh, | ||
| 113 | "maxops=i", \$critical ); | ||
| 114 | |||
| 115 | if($status == 0) { | ||
| 116 | &show_help; | ||
| 117 | } | ||
| 118 | |||
| 119 | sub SNMPGET { | ||
| 120 | $OID = shift; | ||
| 121 | ($session,$error) = Net::SNMP->session( | ||
| 122 | Hostname => $hostname, | ||
| 123 | Community => $community, | ||
| 124 | Port => $port | ||
| 125 | ); | ||
| 126 | if(!defined($session)) { | ||
| 127 | printf("$state %s\n", $error); | ||
| 128 | exit($STATUSCODE{$state}); | ||
| 129 | } | ||
| 130 | if(!defined($response = $session->get_request($OID))) { | ||
| 131 | printf("$state %s\n", $session->error()); | ||
| 132 | $session->close(); | ||
| 133 | exit($STATUSCODE{$state}); | ||
| 134 | } | ||
| 135 | $session->close(); | ||
| 136 | return($response->{$OID}); | ||
| 137 | } | ||
| 138 | |||
| 139 | $hostname = shift || &show_help; | ||
| 140 | |||
| 141 | my $tempcheck = &SNMPGET($OIDLIST{overtemp}); | ||
| 142 | if($tempcheck == 1) { | ||
| 143 | $state = "OK"; | ||
| 144 | $status_string .= "Temp OK "; | ||
| 145 | } | ||
| 146 | else { | ||
| 147 | $state = "CRITICAL"; | ||
| 148 | $status_string .= "Temp CRIT"; | ||
| 149 | } | ||
| 150 | |||
| 151 | foreach $element ('failedfan','failedpsu') { | ||
| 152 | my $my_return = &SNMPGET($OIDLIST{$element}); | ||
| 153 | if(($my_return =~ /no/) || ($my_return == 0)) { | ||
| 154 | $status_string .= "$element = $my_return "; | ||
| 155 | $state = "OK"; | ||
| 156 | } | ||
| 157 | else { | ||
| 158 | $status_string .= "$element = $my_return "; | ||
| 159 | $state = "CRITICAL"; | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | my $tmp_opssec = &get_nfsops(); | ||
| 164 | |||
| 165 | if ($tmp_opssec >= $critical) { | ||
| 166 | $state = "CRITICAL"; | ||
| 167 | } | ||
| 168 | elsif ($tmp_opssec >= $opsthresh) { | ||
| 169 | $state = "WARNING"; | ||
| 170 | } | ||
| 171 | else { | ||
| 172 | $state = "OK"; | ||
| 173 | } | ||
| 174 | |||
| 175 | $status_string .= "Ops\/Sec = $tmp_opssec "; | ||
| 176 | |||
| 177 | print "$state $status_string\n"; | ||
| 178 | 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 @@ | |||
| 1 | #!/usr/bin/python | ||
| 2 | # Change the above line if python is somewhere else | ||
| 3 | |||
| 4 | # | ||
| 5 | # check_nmap | ||
| 6 | # | ||
| 7 | # Program: nmap plugin for Nagios | ||
| 8 | # License: GPL | ||
| 9 | # Copyright (c) 2000 Jacob Lundqvist (jaclu@galdrion.com) | ||
| 10 | # | ||
| 11 | _version_ = '1.20' | ||
| 12 | # | ||
| 13 | # | ||
| 14 | # Description: | ||
| 15 | # | ||
| 16 | # Does a nmap scan, compares open ports to those given on command-line | ||
| 17 | # Reports warning for closed that should be open and error for | ||
| 18 | # open that should be closed. | ||
| 19 | # If optional ports are given, no warning is given if they are closed | ||
| 20 | # and they are included in the list of valid ports. | ||
| 21 | # | ||
| 22 | # Requirements: | ||
| 23 | # python | ||
| 24 | # nmap | ||
| 25 | # | ||
| 26 | # History | ||
| 27 | # ------- | ||
| 28 | # 1.20 2000-07-15 jaclu Updated params to correctly comply to plugin-standard | ||
| 29 | # moved support classes to utils.py | ||
| 30 | # 1.16 2000-07-14 jaclu made options and return codes more compatible with | ||
| 31 | # the plugin developer-guidelines | ||
| 32 | # 1.15 2000-07-14 jaclu added random string to temp-file name | ||
| 33 | # 1.14 2000-07-14 jaclu added check for error from subproc | ||
| 34 | # 1.10 2000-07-14 jaclu converted main part to class | ||
| 35 | # 1.08 2000-07-13 jaclu better param parsing | ||
| 36 | # 1.07 2000-07-13 jaclu changed nmap param to -P0 | ||
| 37 | # 1.06 2000-07-13 jaclu make sure tmp file is deleted on errors | ||
| 38 | # 1.05 2000-07-12 jaclu in debug mode, show exit code | ||
| 39 | # 1.03 2000-07-12 jaclu error handling on nmap output | ||
| 40 | # 1.01 2000-07-12 jaclu added license | ||
| 41 | # 1.00 2000-07-12 jaclu implemented timeout handling | ||
| 42 | # 0.20 2000-07-10 jaclu Initial release | ||
| 43 | |||
| 44 | |||
| 45 | import sys, os, string, whrandom | ||
| 46 | |||
| 47 | import tempfile | ||
| 48 | from getopt import getopt | ||
| 49 | |||
| 50 | # | ||
| 51 | # import generic Nagios-plugin stuff | ||
| 52 | # | ||
| 53 | import utils | ||
| 54 | |||
| 55 | # Where temp files should be placed | ||
| 56 | tempfile.tempdir='/usr/local/nagios/var' | ||
| 57 | |||
| 58 | # Base name for tempfile | ||
| 59 | tempfile.template='check_nmap_tmp.' | ||
| 60 | |||
| 61 | # location and possibly params for nmap | ||
| 62 | nmap_cmd='/usr/bin/nmap -P0' | ||
| 63 | |||
| 64 | |||
| 65 | |||
| 66 | |||
| 67 | |||
| 68 | |||
| 69 | # | ||
| 70 | # the class that does all the real work in this plugin... | ||
| 71 | # | ||
| 72 | # | ||
| 73 | class CheckNmap: | ||
| 74 | |||
| 75 | # Retcodes, so we are compatible with nagios | ||
| 76 | #ERROR= -1 | ||
| 77 | UNKNOWN= -1 | ||
| 78 | OK= 0 | ||
| 79 | WARNING= 1 | ||
| 80 | CRITICAL= 2 | ||
| 81 | |||
| 82 | |||
| 83 | def __init__(self,cmd_line=[]): | ||
| 84 | """Constructor. | ||
| 85 | arguments: | ||
| 86 | cmd_line: normaly sys.argv[1:] if called as standalone program | ||
| 87 | """ | ||
| 88 | self.tmp_file='' | ||
| 89 | self.host='' # host to check | ||
| 90 | self.timeout=10 | ||
| 91 | self.debug=0 # 1= show debug info | ||
| 92 | self.ports=[] # list of mandatory ports | ||
| 93 | self.opt_ports=[] # list of optional ports | ||
| 94 | self.ranges='' # port ranges for nmap | ||
| 95 | self.exit_code=0 # numerical exit-code | ||
| 96 | self.exit_msg='' # message to caller | ||
| 97 | |||
| 98 | self.ParseCmdLine(cmd_line) | ||
| 99 | |||
| 100 | def Run(self): | ||
| 101 | """Actually run the process. | ||
| 102 | This method should be called exactly once. | ||
| 103 | """ | ||
| 104 | |||
| 105 | # | ||
| 106 | # Only call check_host if cmd line was accepted earlier | ||
| 107 | # | ||
| 108 | if self.exit_code==0: | ||
| 109 | self.CheckHost() | ||
| 110 | |||
| 111 | self.CleanUp() | ||
| 112 | return self.exit_code,self.exit_msg | ||
| 113 | |||
| 114 | def Version(self): | ||
| 115 | return 'check_nmap %s' % _version_ | ||
| 116 | |||
| 117 | #----------------------------------------- | ||
| 118 | # | ||
| 119 | # class internal stuff below... | ||
| 120 | # | ||
| 121 | #----------------------------------------- | ||
| 122 | |||
| 123 | # | ||
| 124 | # Param checks | ||
| 125 | # | ||
| 126 | def param2int_list(self,s): | ||
| 127 | lst=string.split(string.replace(s,',',' ')) | ||
| 128 | try: | ||
| 129 | for i in range(len(lst)): | ||
| 130 | lst[i]=int(lst[i]) | ||
| 131 | except: | ||
| 132 | lst=[] | ||
| 133 | return lst | ||
| 134 | |||
| 135 | def ParseCmdLine(self,cmd_line): | ||
| 136 | try: | ||
| 137 | opt_list=getopt(cmd_line,'vH:ho:p:r:t:V',['debug','host=','help', | ||
| 138 | 'optional=','port=','range=','timeout','version']) | ||
| 139 | for opt in opt_list[0]: | ||
| 140 | if opt[0]=='-v' or opt[0]=='--debug': | ||
| 141 | self.debug=1 | ||
| 142 | elif opt[0]=='-H' or opt[0]=='--host': | ||
| 143 | self.host=opt[1] | ||
| 144 | elif opt[0]=='-h' or opt[0]=='--help': | ||
| 145 | doc_help() | ||
| 146 | self.exit_code=1 # request termination | ||
| 147 | break | ||
| 148 | elif opt[0]=='-o' or opt[0]=='--optional': | ||
| 149 | self.opt_ports=self.param2int_list(opt[1]) | ||
| 150 | elif opt[0]=='-p' or opt[0]=='--port': | ||
| 151 | self.ports=self.param2int_list(opt[1]) | ||
| 152 | elif opt[0]=='-r' or opt[0]=='--range': | ||
| 153 | r=string.replace(opt[1],':','-') | ||
| 154 | self.ranges=r | ||
| 155 | elif opt[0]=='-t' or opt[0]=='--timeout': | ||
| 156 | self.timeout=opt[1] | ||
| 157 | elif opt[0]=='-V' or opt[0]=='--version': | ||
| 158 | print self.Version() | ||
| 159 | self.exit_code=1 # request termination | ||
| 160 | break | ||
| 161 | else: | ||
| 162 | self.host='' | ||
| 163 | break | ||
| 164 | |||
| 165 | except: | ||
| 166 | # unknown param | ||
| 167 | self.host='' | ||
| 168 | |||
| 169 | if self.debug: | ||
| 170 | print 'Params:' | ||
| 171 | print '-------' | ||
| 172 | print 'host = %s' % self.host | ||
| 173 | print 'timeout = %s' % self.timeout | ||
| 174 | print 'ports = %s' % self.ports | ||
| 175 | print 'optional ports = %s' % self.opt_ports | ||
| 176 | print 'ranges = %s' % self.ranges | ||
| 177 | |||
| 178 | |||
| 179 | # | ||
| 180 | # a option that wishes us to terminate now has been given... | ||
| 181 | # | ||
| 182 | # This way, you can test params in debug mode and see what this | ||
| 183 | # program recognised by suplying a version param at the end of | ||
| 184 | # the cmd-line | ||
| 185 | # | ||
| 186 | if self.exit_code<>0: | ||
| 187 | sys.exit(self.UNKNOWN) | ||
| 188 | |||
| 189 | if self.host=='': | ||
| 190 | doc_syntax() | ||
| 191 | self.exit_code=self.UNKNOWN | ||
| 192 | self.exit_msg='UNKNOWN: bad params, try running without any params for syntax' | ||
| 193 | |||
| 194 | |||
| 195 | def CheckHost(self): | ||
| 196 | 'Check one host using nmap.' | ||
| 197 | # | ||
| 198 | # Create a tmp file for storing nmap output | ||
| 199 | # | ||
| 200 | # The tempfile module from python 1.5.2 is stupid | ||
| 201 | # two processes runing at aprox the same time gets | ||
| 202 | # the same tempfile... | ||
| 203 | # For this reason I use a random suffix for the tmp-file | ||
| 204 | # Still not 100% safe, but reduces the risk significally | ||
| 205 | # I also inserted checks at various places, so that | ||
| 206 | # _if_ two processes in deed get the same tmp-file | ||
| 207 | # the only result is a normal error message to nagios | ||
| 208 | # | ||
| 209 | r=whrandom.whrandom() | ||
| 210 | self.tmp_file=tempfile.mktemp('.%s')%r.randint(0,100000) | ||
| 211 | if self.debug: | ||
| 212 | print 'Tmpfile is: %s'%self.tmp_file | ||
| 213 | # | ||
| 214 | # If a range is given, only run nmap on this range | ||
| 215 | # | ||
| 216 | if self.ranges<>'': | ||
| 217 | global nmap_cmd # needed, to avoid error on next line | ||
| 218 | # since we assigns to nmap_cmd :) | ||
| 219 | nmap_cmd='%s -p %s' %(nmap_cmd,self.ranges) | ||
| 220 | # | ||
| 221 | # Prepare a task | ||
| 222 | # | ||
| 223 | t=utils.Task('%s %s' %(nmap_cmd,self.host)) | ||
| 224 | # | ||
| 225 | # Configure a time-out handler | ||
| 226 | # | ||
| 227 | th=utils.TimeoutHandler(t.Kill, time_to_live=self.timeout, | ||
| 228 | debug=self.debug) | ||
| 229 | # | ||
| 230 | # Fork of nmap cmd | ||
| 231 | # | ||
| 232 | t.Run(detach=0, stdout=self.tmp_file,stderr='/dev/null') | ||
| 233 | # | ||
| 234 | # Wait for completition, error or timeout | ||
| 235 | # | ||
| 236 | nmap_exit_code=t.Wait(idlefunc=th.Check, interval=1) | ||
| 237 | # | ||
| 238 | # Check for timeout | ||
| 239 | # | ||
| 240 | if th.WasTimeOut(): | ||
| 241 | self.exit_code=self.CRITICAL | ||
| 242 | self.exit_msg='CRITICAL - Plugin timed out after %s seconds' % self.timeout | ||
| 243 | return | ||
| 244 | # | ||
| 245 | # Check for exit status of subprocess | ||
| 246 | # Must do this after check for timeout, since the subprocess | ||
| 247 | # also returns error if aborted. | ||
| 248 | # | ||
| 249 | if nmap_exit_code <> 0: | ||
| 250 | self.exit_code=self.UNKNOWN | ||
| 251 | self.exit_msg='nmap program failed with code %s' % nmap_exit_code | ||
| 252 | return | ||
| 253 | # | ||
| 254 | # Read output | ||
| 255 | # | ||
| 256 | try: | ||
| 257 | f = open(self.tmp_file, 'r') | ||
| 258 | output=f.readlines() | ||
| 259 | f.close() | ||
| 260 | except: | ||
| 261 | self.exit_code=self.UNKNOWN | ||
| 262 | self.exit_msg='Unable to get output from nmap' | ||
| 263 | return | ||
| 264 | |||
| 265 | # | ||
| 266 | # Store open ports in list | ||
| 267 | # scans for lines where first word contains '/' | ||
| 268 | # and stores part before '/' | ||
| 269 | # | ||
| 270 | self.active_ports=[] | ||
| 271 | try: | ||
| 272 | for l in output: | ||
| 273 | if len(l)<2: | ||
| 274 | continue | ||
| 275 | s=string.split(l)[0] | ||
| 276 | if string.find(s,'/')<1: | ||
| 277 | continue | ||
| 278 | p=string.split(s,'/')[0] | ||
| 279 | self.active_ports.append(int(p)) | ||
| 280 | except: | ||
| 281 | # failure due to strange output... | ||
| 282 | pass | ||
| 283 | |||
| 284 | if self.debug: | ||
| 285 | print 'Ports found by nmap: ',self.active_ports | ||
| 286 | # | ||
| 287 | # Filter out optional ports, we don't check status for them... | ||
| 288 | # | ||
| 289 | try: | ||
| 290 | for p in self.opt_ports: | ||
| 291 | self.active_ports.remove(p) | ||
| 292 | |||
| 293 | if self.debug and len(self.opt_ports)>0: | ||
| 294 | print 'optional ports removed:',self.active_ports | ||
| 295 | except: | ||
| 296 | # under extreame loads the remove(p) above failed for me | ||
| 297 | # a few times, this exception hanlder handles | ||
| 298 | # this bug-alike situation... | ||
| 299 | pass | ||
| 300 | |||
| 301 | opened=self.CheckOpen() | ||
| 302 | closed=self.CheckClosed() | ||
| 303 | |||
| 304 | if opened <>'': | ||
| 305 | self.exit_code=self.CRITICAL | ||
| 306 | self.exit_msg='PORTS CRITICAL - Open:%s Closed:%s'%(opened,closed) | ||
| 307 | elif closed <>'': | ||
| 308 | self.exit_code=self.WARNING | ||
| 309 | self.exit_msg='PORTS WARNING - Closed:%s'%closed | ||
| 310 | else: | ||
| 311 | self.exit_code=self.OK | ||
| 312 | self.exit_msg='PORTS ok - Only defined ports open' | ||
| 313 | |||
| 314 | |||
| 315 | # | ||
| 316 | # Compares requested ports on with actually open ports | ||
| 317 | # returns all open that should be closed | ||
| 318 | # | ||
| 319 | def CheckOpen(self): | ||
| 320 | opened='' | ||
| 321 | for p in self.active_ports: | ||
| 322 | if p not in self.ports: | ||
| 323 | opened='%s %s' %(opened,p) | ||
| 324 | return opened | ||
| 325 | |||
| 326 | # | ||
| 327 | # Compares requested ports with actually open ports | ||
| 328 | # returns all ports that are should be open | ||
| 329 | # | ||
| 330 | def CheckClosed(self): | ||
| 331 | closed='' | ||
| 332 | for p in self.ports: | ||
| 333 | if p not in self.active_ports: | ||
| 334 | closed='%s %s' % (closed,p) | ||
| 335 | return closed | ||
| 336 | |||
| 337 | |||
| 338 | def CleanUp(self): | ||
| 339 | # | ||
| 340 | # If temp file exists, get rid of it | ||
| 341 | # | ||
| 342 | if self.tmp_file<>'' and os.path.isfile(self.tmp_file): | ||
| 343 | try: | ||
| 344 | os.remove(self.tmp_file) | ||
| 345 | except: | ||
| 346 | # temp-file colition, some other process already | ||
| 347 | # removed the same file... | ||
| 348 | pass | ||
| 349 | |||
| 350 | # | ||
| 351 | # Show numerical exits as string in debug mode | ||
| 352 | # | ||
| 353 | if self.debug: | ||
| 354 | print 'Exitcode:',self.exit_code, | ||
| 355 | if self.exit_code==self.UNKNOWN: | ||
| 356 | print 'UNKNOWN' | ||
| 357 | elif self.exit_code==self.OK: | ||
| 358 | print 'OK' | ||
| 359 | elif self.exit_code==self.WARNING: | ||
| 360 | print 'WARNING' | ||
| 361 | elif self.exit_code==self.CRITICAL: | ||
| 362 | print 'CRITICAL' | ||
| 363 | else: | ||
| 364 | print 'undefined' | ||
| 365 | # | ||
| 366 | # Check if invalid exit code | ||
| 367 | # | ||
| 368 | if self.exit_code<-1 or self.exit_code>2: | ||
| 369 | self.exit_msg=self.exit_msg+' - undefined exit code (%s)' % self.exit_code | ||
| 370 | self.exit_code=self.UNKNOWN | ||
| 371 | |||
| 372 | |||
| 373 | |||
| 374 | |||
| 375 | |||
| 376 | # | ||
| 377 | # Help texts | ||
| 378 | # | ||
| 379 | def doc_head(): | ||
| 380 | print """ | ||
| 381 | check_nmap plugin for Nagios | ||
| 382 | Copyright (c) 2000 Jacob Lundqvist (jaclu@galdrion.com) | ||
| 383 | License: GPL | ||
| 384 | Version: %s""" % _version_ | ||
| 385 | |||
| 386 | |||
| 387 | def doc_syntax(): | ||
| 388 | print """ | ||
| 389 | Usage: check_ports [-v|--debug] [-H|--host host] [-V|--version] [-h|--help] | ||
| 390 | [-o|--optional port1,port2,port3 ...] [-r|--range range] | ||
| 391 | [-p|--port port1,port2,port3 ...] [-t|--timeout timeout]""" | ||
| 392 | |||
| 393 | |||
| 394 | def doc_help(): | ||
| 395 | 'Help is displayed if run without params.' | ||
| 396 | doc_head() | ||
| 397 | doc_syntax() | ||
| 398 | print """ | ||
| 399 | Options: | ||
| 400 | -h = help (this screen ;-) | ||
| 401 | -v = debug mode, show some extra output | ||
| 402 | -H host = host to check (name or IP#) | ||
| 403 | -o ports = optional ports that can be open (one or more), | ||
| 404 | no warning is given if optional port is closed | ||
| 405 | -p ports = ports that should be open (one or more) | ||
| 406 | -r range = port range to feed to nmap. Example: :1024,2049,3000:7000 | ||
| 407 | -t timeout = timeout in seconds, default 10 | ||
| 408 | -V = Version info | ||
| 409 | |||
| 410 | This plugin attempts to verify open ports on the specified host. | ||
| 411 | |||
| 412 | If all specified ports are open, OK is returned. | ||
| 413 | If any of them are closed, WARNING is returned (except for optional ports) | ||
| 414 | If other ports are open, CRITICAL is returned | ||
| 415 | |||
| 416 | If possible, supply an IP address for the host address, | ||
| 417 | as this will bypass the DNS lookup. | ||
| 418 | """ | ||
| 419 | |||
| 420 | |||
| 421 | # | ||
| 422 | # Main | ||
| 423 | # | ||
| 424 | if __name__ == '__main__': | ||
| 425 | |||
| 426 | if len (sys.argv) < 2: | ||
| 427 | # | ||
| 428 | # No params given, show syntax and exit | ||
| 429 | # | ||
| 430 | doc_syntax() | ||
| 431 | sys.exit(-1) | ||
| 432 | |||
| 433 | nmap=CheckNmap(sys.argv[1:]) | ||
| 434 | exit_code,exit_msg=nmap.Run() | ||
| 435 | |||
| 436 | # | ||
| 437 | # Give Nagios a msg and a code | ||
| 438 | # | ||
| 439 | print exit_msg | ||
| 440 | 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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | # | ||
| 3 | # check_nwstat.pl: Nagios plugin that uses Jim Drews' nwstat.pl for | ||
| 4 | # MRTG instead of emulating it. For use particularly with Cliff | ||
| 5 | # Woolley's mrtgext.pl Unix companion to Drews' MRTGEXT.NLM, where | ||
| 6 | # mrtgext.pl can contain custom commands that check_nwstat won't recognize, | ||
| 7 | # though this also does its best to perfectly emulate the C version | ||
| 8 | # of check_nwstat. | ||
| 9 | # | ||
| 10 | |||
| 11 | |||
| 12 | ###################################################################### | ||
| 13 | # Configuration | ||
| 14 | ###################################################################### | ||
| 15 | |||
| 16 | $nwstatcmd = "/apps/mrtg/helpers/nwstat.pl"; | ||
| 17 | |||
| 18 | use Getopt::Long; | ||
| 19 | |||
| 20 | $::host = shift || &usage(%ERROR); | ||
| 21 | $::opt_v = undef; | ||
| 22 | $::opt_wv = undef; | ||
| 23 | $::opt_cv = undef; | ||
| 24 | $::opt_to = 10; | ||
| 25 | $::opt_url = undef; | ||
| 26 | |||
| 27 | GetOptions (qw(v=s wv=i cv=i to=i url=s)) || &usage(%ERROR); | ||
| 28 | |||
| 29 | my $cmd1 = ""; | ||
| 30 | my $cmd2 = "ZERO"; | ||
| 31 | my $backward = 0; | ||
| 32 | my $desc = ""; | ||
| 33 | my $okstr = "OK"; | ||
| 34 | my $probstr = "Problem"; | ||
| 35 | my $result = ""; | ||
| 36 | my @CMD; | ||
| 37 | my %ERROR = ("UNKNOWN" => -1, | ||
| 38 | "OK" => 0, | ||
| 39 | "WARNING" => 1, | ||
| 40 | "CRITICAL" => 2); | ||
| 41 | my $status = $ERROR{"OK"}; | ||
| 42 | |||
| 43 | |||
| 44 | ###################################################################### | ||
| 45 | # Main program | ||
| 46 | ###################################################################### | ||
| 47 | |||
| 48 | $SIG{'ALRM'} = sub { | ||
| 49 | print "Connection timed out\n"; | ||
| 50 | exit $ERROR{"CRITICAL"}; | ||
| 51 | }; | ||
| 52 | |||
| 53 | # translate table for compatability with | ||
| 54 | # check_nwstat (C version) | ||
| 55 | SWITCH: for ($::opt_v) { | ||
| 56 | /^LOAD(1|5|15)$/ | ||
| 57 | && do { $desc = "Load <status> - Up <cmd2>, ". | ||
| 58 | "$1-min load average = <cmd0>%"; | ||
| 59 | $cmd1 = "UTIL$1"; last; }; | ||
| 60 | /^CONNS$/ && do { $desc = "Conns <status>: ". | ||
| 61 | "<cmd0> current connections"; | ||
| 62 | $cmd1 = "CONNECT"; last; }; | ||
| 63 | /^CDBUFF$/ && do { $desc = "Dirty cache buffers = <cmd0>"; | ||
| 64 | $cmd1 = "S3"; last; }; | ||
| 65 | /^LTCH$/ && do { $desc = "Long term cache hits = <cmd0>%"; | ||
| 66 | $cmd1 = "S1"; | ||
| 67 | $backward = 1; last; }; | ||
| 68 | /^CBUFF$/ && do { $desc = "Total cache buffers = <cmd0>"; | ||
| 69 | $cmd1 = "S2"; | ||
| 70 | $backward = 1; last; }; | ||
| 71 | /^LRUM$/ && do { $desc = "LRU sitting time = <cmd0> minutes"; | ||
| 72 | $cmd1 = "S5"; | ||
| 73 | $backward = 1; last; }; | ||
| 74 | /^VPF(.*)$/ && do { $desc = "<status><int(cmd0/1024)> MB ". | ||
| 75 | "(<result>%) free on volume $1"; | ||
| 76 | $okstr = ""; $probstr = "Only "; | ||
| 77 | $cmd1 = "VKF$1"; | ||
| 78 | $cmd2 = "VKS$1"; | ||
| 79 | $backward = 1; last; }; | ||
| 80 | /^VKF/ && do { $desc = "<status><cmd0> KB free on volume $1"; | ||
| 81 | $okstr = ""; $probstr = "Only "; | ||
| 82 | $cmd1 = "$::opt_v"; | ||
| 83 | $backward = 1; last; }; | ||
| 84 | /^$/ && die "Nothing to check!"; | ||
| 85 | $desc = "<status>: <cmd0>"; | ||
| 86 | $cmd1 = "$::opt_v"; | ||
| 87 | } | ||
| 88 | |||
| 89 | |||
| 90 | # begin timeout period, run the check | ||
| 91 | alarm($::opt_to); | ||
| 92 | open ( CMD, "$nwstatcmd $host $cmd1 $cmd2|" ) || die "Couldn't execute nwstat"; | ||
| 93 | @CMD = <CMD>; | ||
| 94 | close ( CMD ); | ||
| 95 | alarm(0); | ||
| 96 | |||
| 97 | for (@CMD) { chomp; } | ||
| 98 | |||
| 99 | # for any variables that manipulate the results instead of | ||
| 100 | # just using <cmd0> directly, do that manipulation here into <result> | ||
| 101 | SWITCH: for ($::opt_v) { | ||
| 102 | /^VPF/ && do { $result=int(("$CMD[0]"/"$CMD[1]")*100); last; }; | ||
| 103 | $result = "$CMD[0]"; | ||
| 104 | } | ||
| 105 | |||
| 106 | if ("$result" == -1) { | ||
| 107 | $status = $ERROR{"UNKNOWN"}; | ||
| 108 | $desc = "Server returned \"variable unknown\""; | ||
| 109 | } elsif ("$result" == -2) { | ||
| 110 | $status = $ERROR{"CRITICAL"}; | ||
| 111 | $desc = "Connection failed"; | ||
| 112 | } | ||
| 113 | |||
| 114 | if (defined($::opt_cv) && $status == $ERROR{"OK"}) { | ||
| 115 | if ($backward) { | ||
| 116 | ("$result" <= "$::opt_cv") && ( $status = $ERROR{"CRITICAL"} ); | ||
| 117 | } else { | ||
| 118 | ("$result" >= "$::opt_cv") && ( $status = $ERROR{"CRITICAL"} ); | ||
| 119 | } | ||
| 120 | } | ||
| 121 | if (defined($::opt_wv) && $status == $ERROR{"OK"}) { | ||
| 122 | if ($backward) { | ||
| 123 | ("$result" <= "$::opt_wv") && ( $status = $ERROR{"WARNING"} ); | ||
| 124 | } else { | ||
| 125 | ("$result" >= "$::opt_wv") && ( $status = $ERROR{"WARNING"} ); | ||
| 126 | } | ||
| 127 | } | ||
| 128 | |||
| 129 | $desc =~ s/<status>/($status == $ERROR{"OK"})?"$okstr":"$probstr"/eg; | ||
| 130 | $desc =~ s/<([^>]*)cmd([0-3])([^>]*)>/eval("$1\"$CMD[$2]\"$3")/eg; | ||
| 131 | $desc =~ s/<result>/"$result"/eg; | ||
| 132 | |||
| 133 | if (defined($::opt_url)) { | ||
| 134 | print "<A HREF=\"$::opt_url\">$desc</A>\n"; | ||
| 135 | } else { | ||
| 136 | print "$desc\n"; | ||
| 137 | } | ||
| 138 | exit $status; | ||
| 139 | |||
| 140 | |||
| 141 | ###################################################################### | ||
| 142 | # Subroutines | ||
| 143 | ###################################################################### | ||
| 144 | |||
| 145 | sub usage { | ||
| 146 | |||
| 147 | %ERROR = shift; | ||
| 148 | |||
| 149 | print <<EOF | ||
| 150 | check_nwstat.pl plugin for Nagios | ||
| 151 | by Cliff Woolley, (c) 2000 | ||
| 152 | |||
| 153 | Usage: ./check_nwstat.pl <host_address> [-v variable] [-wv warn_value] [-cv crit_value] [-to to_sec] [-url url_value] | ||
| 154 | |||
| 155 | Options: | ||
| 156 | [variable] = Variable to check. Valid variables include: | ||
| 157 | LOAD1 = 1 minute average CPU load | ||
| 158 | LOAD5 = 5 minute average CPU load | ||
| 159 | LOAD15 = 15 minute average CPU load | ||
| 160 | CONNS = number of currently licensed connections | ||
| 161 | VPF<vol> = percent free space on volume <vol> | ||
| 162 | VKF<vol> = KB of free space on volume <vol> | ||
| 163 | LTCH = percent long term cache hits | ||
| 164 | CBUFF = current number of cache buffers | ||
| 165 | CDBUFF = current number of dirty cache buffers | ||
| 166 | LRUM = LRU sitting time in minutes | ||
| 167 | [warn_value] = Threshold for value necessary to result in a warning status | ||
| 168 | [crit_value] = Threshold for value necessary to result in a critical status | ||
| 169 | [to_sec] = Number of secs before connection times out - default is 10 sec | ||
| 170 | [url_value] = URL to use in output as a hyperlink. Useful to link to a page | ||
| 171 | with more details or history for this variable (ie an MRTG page) | ||
| 172 | |||
| 173 | This plugin attempts to contact the MRTGEXT NLM running on a Novell server | ||
| 174 | to gather the requested system information. | ||
| 175 | |||
| 176 | Notes: | ||
| 177 | - This plugin requres that the MRTGEXT.NLM file distributed with | ||
| 178 | James Drews' MRTG extension for NetWare (available from | ||
| 179 | http://www.engr.wisc.edu/~drews/mrtg/) be loaded on the Novell | ||
| 180 | servers you wish to check. | ||
| 181 | - Critical thresholds should be lower than warning thresholds when | ||
| 182 | the following variables are checked: VPF, VKF, LTCH, CBUFF, and LRUM. | ||
| 183 | EOF | ||
| 184 | ; | ||
| 185 | |||
| 186 | exit $ERROR{"UNKNOWN"}; | ||
| 187 | } | ||
| 188 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | # | ||
| 3 | # Program check_ora_table_space | ||
| 4 | # Written by: Erwan Arzur (erwan@netvalue.com) | ||
| 5 | # License: GPL | ||
| 6 | # | ||
| 7 | # Last Modified: $Date$ | ||
| 8 | # Revisiin: $Revision$ | ||
| 9 | # | ||
| 10 | # "check_ora_table_space.pl" plugin to check the state of Oracle | ||
| 11 | # table spaces. Scarce documentation. | ||
| 12 | # | ||
| 13 | # you need DBD-Oracle-1.03.tar.gz and DBI-1.13.tar.gz from CPAN.org as | ||
| 14 | # well as some Oracle client stuff to use it. | ||
| 15 | # | ||
| 16 | # The SQL request comes from www.dbasupport.com | ||
| 17 | # | ||
| 18 | |||
| 19 | use DBI; | ||
| 20 | $ENV{"ORACLE_HOME"}="/intranet/apps/oracle"; | ||
| 21 | |||
| 22 | my $host = shift || &usage ("no host specified"); | ||
| 23 | my $sid = shift || &usage ("no sid specified"); | ||
| 24 | my $port = shift || &usage ("no port specified"); | ||
| 25 | my $dbuser = shift || &usage ("no user specified"); | ||
| 26 | my $dbpass = shift || &usage ("no password specified"); | ||
| 27 | my $tablespace = shift || &usage ("no table space specified"); | ||
| 28 | |||
| 29 | my $alertpct = int(shift) || &usage ("no warning state percentage specified"); | ||
| 30 | my $critpct = int(shift) || &usage ("no critical state percentage specified"); | ||
| 31 | |||
| 32 | my $dbh = DBI->connect( "dbi:Oracle:host=$host;port=$port;sid=$sid", $dbuser, $dbpass, { PrintError => 0, AutoCommit => 1, RaiseError => 0 } ) | ||
| 33 | || &error ("cannot connect to $dbname: $DBI::errstr\n"); | ||
| 34 | |||
| 35 | #$sth = $dbh->prepare(q{SELECT tablespace_name, SUM(BYTES)/1024/1024 FreeSpace FROM dba_free_space group by tablespace_name}) | ||
| 36 | my $exit_code = -1; | ||
| 37 | $sth = $dbh->prepare(<<EOF | ||
| 38 | select a.TABLESPACE_NAME, a.total,nvl(b.used,0) USED, | ||
| 39 | nvl((b.used/a.total)*100,0) PCT_USED | ||
| 40 | from (select TABLESPACE_NAME, sum(bytes)/(1024*1024) total | ||
| 41 | from sys.dba_data_files group by TABLESPACE_NAME) a, | ||
| 42 | (select TABLESPACE_NAME,bytes/(1024*1024) used from sys.SM\$TS_USED) b | ||
| 43 | where a.TABLESPACE_NAME='$tablespace' and | ||
| 44 | a.TABLESPACE_NAME=b.TABLESPACE_NAME(+) | ||
| 45 | EOF | ||
| 46 | ) | ||
| 47 | || &error("Cannot prepare request : $DBI::errstr\n"); | ||
| 48 | $sth->execute | ||
| 49 | || &error("Cannot execute request : $DBI::errstr\n"); | ||
| 50 | |||
| 51 | while (($tbname, $total, $used, $pct_used) = $sth->fetchrow) | ||
| 52 | { | ||
| 53 | $pct_used=int($pct_used); | ||
| 54 | print STDOUT "size: " . $total . " MB Used:" . int($used) . " MB (" . int($pct_used) . "%)\n"; | ||
| 55 | #print "table space $answer\n"; | ||
| 56 | if ($pct_used > $alertpct) { | ||
| 57 | if ($pct_used > $critpct) { | ||
| 58 | $exit_code = 2 | ||
| 59 | } else { | ||
| 60 | $exit_code = 1; | ||
| 61 | } | ||
| 62 | } else { | ||
| 63 | $exit_code = 0; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | $rc = $dbh->disconnect | ||
| 68 | || &error ("Cannot disconnect from database : $dbh->errstr\n"); | ||
| 69 | |||
| 70 | exit ($exit_code); | ||
| 71 | |||
| 72 | sub usage { | ||
| 73 | print "@_\n" if @_; | ||
| 74 | print "usage : check_ora_table_space.pl <host> <sid> <port> <user> <passwd> <tablespace> <pctwarn> <pctcrit>\n"; | ||
| 75 | exit (-1); | ||
| 76 | } | ||
| 77 | |||
| 78 | sub error { | ||
| 79 | print "@_\n" if @_; | ||
| 80 | exit (2); | ||
| 81 | } | ||
| 82 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | # ------------------------------------------------------------------------------ | ||
| 3 | # File Name: check_pop3.pl | ||
| 4 | # Author: Richard Mayhew - South Africa | ||
| 5 | # Date: 2000/01/21 | ||
| 6 | # Version: 1.0 | ||
| 7 | # Description: This script will check to see if an POP3 is running | ||
| 8 | # and whether authentication can take place. | ||
| 9 | # Email: netsaint@splash.co.za | ||
| 10 | # ------------------------------------------------------------------------------ | ||
| 11 | # Copyright 1999 (c) Richard Mayhew | ||
| 12 | # Credits go to Ethan Galstad for coding Nagios | ||
| 13 | # If any changes are made to this script, please mail me a copy of the | ||
| 14 | # changes :) | ||
| 15 | # License GPL | ||
| 16 | # ------------------------------------------------------------------------------ | ||
| 17 | # Date Author Reason | ||
| 18 | # ---- ------ ------ | ||
| 19 | # 1999/09/20 RM Creation | ||
| 20 | # 1999/09/20 TP Changed script to use strict, more secure by | ||
| 21 | # specifying $ENV variables. The bind command is | ||
| 22 | # still insecure through. Did most of my work | ||
| 23 | # with perl -wT and 'use strict' | ||
| 24 | # 2000/01/20 RM Corrected POP3 Exit State. | ||
| 25 | # 2000/01/21 RM Fix Exit Codes Again!! | ||
| 26 | # ------------------------------------------------------------------------------ | ||
| 27 | |||
| 28 | # -----------------------------------------------------------------[ Require ]-- | ||
| 29 | require 5.004; | ||
| 30 | |||
| 31 | # --------------------------------------------------------------------[ Uses ]-- | ||
| 32 | use Socket; | ||
| 33 | use strict; | ||
| 34 | |||
| 35 | # --------------------------------------------------------------[ Enviroment ]-- | ||
| 36 | $ENV{PATH} = "/bin"; | ||
| 37 | $ENV{BASH_ENV} = ""; | ||
| 38 | $|=1; | ||
| 39 | # ------------------------------------------------------------------[ Global ]-- | ||
| 40 | my $TIMEOUT = 60; | ||
| 41 | |||
| 42 | # -------------------------------------------------------------------[ usage ]-- | ||
| 43 | sub usage | ||
| 44 | { | ||
| 45 | print "Minimum arguments not supplied!\n"; | ||
| 46 | print "\n"; | ||
| 47 | print "Perl Check POP3 plugin for Nagios\n"; | ||
| 48 | print "Copyright (c) 2000 Richard Mayhew\n"; | ||
| 49 | print "\n"; | ||
| 50 | print "Usage: check_pop3.pl <host> <username> <password> [port]\n"; | ||
| 51 | print "\n"; | ||
| 52 | print "<port> = Port that the pop3 daemon is running on <host>. Defaults to 110.\n"; | ||
| 53 | exit -1; | ||
| 54 | |||
| 55 | } | ||
| 56 | |||
| 57 | # --------------------------------------------------------------[ bindRemote ]-- | ||
| 58 | sub bindRemote | ||
| 59 | { | ||
| 60 | my ($in_remotehost, $in_remoteport, $in_hostname) = @_; | ||
| 61 | my $proto; | ||
| 62 | my $sockaddr; | ||
| 63 | my $this; | ||
| 64 | my $thisaddr; | ||
| 65 | my $that; | ||
| 66 | my ($name, $aliases,$type,$len,$thataddr) = gethostbyname($in_remotehost); | ||
| 67 | |||
| 68 | if (!socket(ClientSocket,AF_INET, SOCK_STREAM, $proto)) { die $!; } | ||
| 69 | $sockaddr = 'S n a4 x8'; | ||
| 70 | $this = pack($sockaddr, AF_INET, 0, $thisaddr); | ||
| 71 | $that = pack($sockaddr, AF_INET, $in_remoteport, $thataddr); | ||
| 72 | if (!bind(ClientSocket, $this)) { print "Connection Refused"; exit 2; } | ||
| 73 | if (!connect(ClientSocket, $that)) { print "Connection Refused"; exit 2; } | ||
| 74 | select(ClientSocket); $| = 1; select(STDOUT); | ||
| 75 | return \*ClientSocket; | ||
| 76 | } | ||
| 77 | |||
| 78 | # ====================================================================[ MAIN ]== | ||
| 79 | MAIN: | ||
| 80 | { | ||
| 81 | my $hostname; | ||
| 82 | my $remotehost = shift || &usage; | ||
| 83 | my $username = shift || &usage; | ||
| 84 | my $password = shift || &usage; | ||
| 85 | my $remoteport = shift || 110; | ||
| 86 | |||
| 87 | # Just in case of problems, let's not hang Nagios | ||
| 88 | $SIG{'ALRM'} = sub { | ||
| 89 | print "Something is Taking a Long Time, Increase Your TIMEOUT (Currently Set At $TIMEOUT Seconds)\n"; | ||
| 90 | exit -1; | ||
| 91 | }; | ||
| 92 | |||
| 93 | alarm($TIMEOUT); | ||
| 94 | |||
| 95 | chop($hostname = `hostname`); | ||
| 96 | my ($name, $alias, $proto) = getprotobyname('tcp'); | ||
| 97 | my $ClientSocket = &bindRemote($remotehost,$remoteport,$hostname); | ||
| 98 | |||
| 99 | |||
| 100 | print ClientSocket "user $username\n"; | ||
| 101 | |||
| 102 | #Debug Server | ||
| 103 | #print "user $username\n"; | ||
| 104 | |||
| 105 | #Sleep or 3 secs, incase server is slow. | ||
| 106 | sleep 3; | ||
| 107 | |||
| 108 | print ClientSocket "pass $password\n"; | ||
| 109 | |||
| 110 | #Debug Server | ||
| 111 | #print "pass $password\n"; | ||
| 112 | |||
| 113 | while (<ClientSocket>) { | ||
| 114 | |||
| 115 | print ClientSocket "pass $password\n"; | ||
| 116 | |||
| 117 | #Debug Server | ||
| 118 | #print $_; | ||
| 119 | |||
| 120 | err($_) if (m/\-ERR\s+(.*)\s+.*/); | ||
| 121 | message($_) if (m/\+OK Mailbox open,\s+(.*\d)\s+messages.*/); | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | sub message | ||
| 126 | { | ||
| 127 | my $answer = "UNKNOWN"; | ||
| 128 | $answer = "Pop3 OK - Total Messages On Server :- $1"; | ||
| 129 | alarm(0); | ||
| 130 | print ClientSocket "quit\n"; | ||
| 131 | print "$answer"; | ||
| 132 | exit 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | sub err | ||
| 136 | { | ||
| 137 | my $answer = "UNKNOWN"; | ||
| 138 | $answer = "Pop3 Error :- $1"; | ||
| 139 | alarm(0); | ||
| 140 | print ClientSocket "quit\n"; | ||
| 141 | print "$answer"; | ||
| 142 | exit 2; | ||
| 143 | } | ||
| 144 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | # | ||
| 3 | # check_qmailq.pl - nagios plugin | ||
| 4 | # This plugin allows you to check the number of Mails in a qmail- | ||
| 5 | # queue. PLUGIN NEEDS CONFIGURATION ! (see below) | ||
| 6 | # | ||
| 7 | # Copyright 2000 Benjamin Schmid | ||
| 8 | # | ||
| 9 | # This program is free software; you can redistribute it and/or | ||
| 10 | # modify it under the terms of the GNU General Public License | ||
| 11 | # as published by the Free Software Foundation; either version 2 | ||
| 12 | # of the License, or (at your option) any later version. | ||
| 13 | # | ||
| 14 | # This program is distributed in the hope that it will be useful, | ||
| 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | # GNU General Public License for more details. | ||
| 18 | # | ||
| 19 | # You should have received a copy of the GNU General Public License | ||
| 20 | # along with this program; if not, write to the Free Software | ||
| 21 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 22 | # | ||
| 23 | # | ||
| 24 | # Emergency E-Mail :) blueshift@gmx.net | ||
| 25 | # | ||
| 26 | |||
| 27 | ### CONFIGURATION SECTION #################### | ||
| 28 | |||
| 29 | my $statcommand = "/var/qmail/bin/qmail-qstat"; | ||
| 30 | my $queuewarn = 5; # Warning, if more than x mail in Queue | ||
| 31 | my $queuecrit = 10; # Critical if "--" | ||
| 32 | my $prewarn = 1; # Warning, if more than x unhandled mails | ||
| 33 | # (not in Queue | ||
| 34 | my $precrit = 5; # Critical, if "--" | ||
| 35 | |||
| 36 | ### CONFIURATION SECTION END ################ | ||
| 37 | |||
| 38 | use strict; | ||
| 39 | use Carp; | ||
| 40 | |||
| 41 | #use Getopt::Long; | ||
| 42 | #&Getopt::Long::config('auto_abbrev'); | ||
| 43 | |||
| 44 | |||
| 45 | |||
| 46 | my $TIMEOUT = 15; | ||
| 47 | |||
| 48 | my %ERRORS = ('UNKNOWN' , '-1', | ||
| 49 | 'OK' , '0', | ||
| 50 | 'WARNING', '1', | ||
| 51 | 'CRITICAL', '2'); | ||
| 52 | |||
| 53 | my $state = "UNKNOWN"; | ||
| 54 | my $answer = ""; | ||
| 55 | |||
| 56 | #sub usage { | ||
| 57 | # printf "\nMissing arguments!\n"; | ||
| 58 | # printf "\n"; | ||
| 59 | # printf "Printer Server Queue Nagios Plugin\n"; | ||
| 60 | # printf "monitors jobs in lpr queues\n"; | ||
| 61 | # printf "usage: \n"; | ||
| 62 | # printf "check_lpq.pl \n"; | ||
| 63 | # printf "Copyright (C) 2000 Benjamin Schmid\n"; | ||
| 64 | # printf "check_lpq.pl comes with ABSOLUTELY NO WARRANTY\n"; | ||
| 65 | # printf "This programm is licensed under the terms of the "; | ||
| 66 | # printf "GNU General Public License\n(check source code for details)\n"; | ||
| 67 | # printf "\n\n"; | ||
| 68 | # exit $ERRORS{"UNKNOWN"}; | ||
| 69 | #} | ||
| 70 | |||
| 71 | # Just in case of problems, let's not hang Nagios | ||
| 72 | $SIG{'ALRM'} = sub { | ||
| 73 | print ("ERROR: check_lpq.pl Time-Out $TIMEOUT s \n"); | ||
| 74 | exit $ERRORS{"UNKNOWN"}; | ||
| 75 | }; | ||
| 76 | alarm($TIMEOUT); | ||
| 77 | |||
| 78 | |||
| 79 | #$status = GetOptions("community=s",\$community, | ||
| 80 | # "port=i",\$port); | ||
| 81 | #if ($status == 0) | ||
| 82 | #{ | ||
| 83 | # &usage; | ||
| 84 | #} | ||
| 85 | |||
| 86 | # $hostname = shift || &usage; | ||
| 87 | |||
| 88 | if (! open STAT, "$statcommand|") { | ||
| 89 | print ("$state: $statcommand returns no result!"); | ||
| 90 | exit $ERRORS{$state}; | ||
| 91 | } | ||
| 92 | my @lines = <STAT>; | ||
| 93 | close STAT; | ||
| 94 | |||
| 95 | # Mails in Queues | ||
| 96 | if ($lines[0]=~/^messages in queue: (\d+)/) { | ||
| 97 | my $anzq = $1; | ||
| 98 | $answer = $answer . "$anzq"; | ||
| 99 | $state='WARNING' if ($anzq >= $queuewarn); | ||
| 100 | $state='CRITICAL' if ($anzq >= $queuecrit); | ||
| 101 | } else { | ||
| 102 | $state='CRITICAL'; | ||
| 103 | $answer="Keine gueltigte Antwort (Zeile #1) von $statcommand\n"; | ||
| 104 | } | ||
| 105 | |||
| 106 | # Unverarbeite Mails | ||
| 107 | if ($lines[1]=~/^messages in queue but not yet preprocessed: (\d+)/) { | ||
| 108 | my $anzp = $1; | ||
| 109 | $answer = $answer . " E-Mail(s) nicht ausgeliefert, $anzp unverarbeitet."; | ||
| 110 | $state='WARNING' if ($anzp >= $prewarn && $state eq 'UNKNOWN'); | ||
| 111 | $state='CRITICAL' if ($anzp >= $precrit); | ||
| 112 | } else { | ||
| 113 | $state='CRITICAL'; | ||
| 114 | $answer=$answer . "Keine gueltigte Antwort (Zeile #2) von $statcommand\n"; | ||
| 115 | } | ||
| 116 | |||
| 117 | $state = 'OK' if ($state eq 'UNKNOWN'); | ||
| 118 | |||
| 119 | print ("$state: $answer\n"); | ||
| 120 | exit $ERRORS{$state}; | ||
| 121 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl -wT | ||
| 2 | |||
| 3 | # check_rrd_data plugin for nagios | ||
| 4 | # | ||
| 5 | # usage: | ||
| 6 | # check_rrd machine_id perlexp_warn perlexp_crit perlexp_default [ds] | ||
| 7 | # | ||
| 8 | # Checks data from a RRD file. machine_id is normally an IP address, that has | ||
| 9 | # to be mapped to a RRD file, by means of the config file (by default | ||
| 10 | # /var/spool/nagios/rrd-files, a file with pairs of (machine_id,rrd_file), | ||
| 11 | # separated by whitespace). It can be a RRD file, too. | ||
| 12 | # | ||
| 13 | # The Perl expressions are expressions to be evaluated in the following cases: | ||
| 14 | # | ||
| 15 | # - perlexp_crit. The first one, to check if there is a critical situation. If | ||
| 16 | # it returns other than "", it will be a critical message. | ||
| 17 | # - perlexp_warn. The second one to be evaluated. If returns other than "", a | ||
| 18 | # warning will be issued to Nagios. | ||
| 19 | # - perlexp_default. If both of the above return "", it will be evaluated, and | ||
| 20 | # wathever returns this expression will be returned by the script. NOTE that | ||
| 21 | # this is different from the other two cases, to allow the user issue a | ||
| 22 | # warning or critical failure even if the other two don't return it. | ||
| 23 | # | ||
| 24 | # Use these hosts.cfg entries as examples | ||
| 25 | # | ||
| 26 | # command[check_ping]=$USER1$/check_rrd_data.pl $HOSTADDRESS$ \ | ||
| 27 | # 'return "CHECK_CRICKET_PING: Warning\n" if ($value > 10);' 'return \ | ||
| 28 | # "CHECK_CRICKET_PING: Critical\n" if ($value > 100);' 'printf \ | ||
| 29 | # "PING OK - RTA = %.2fms\n", $value; return 0;' 1 | ||
| 30 | # service[machine]=PING;0;24x7;3;5;1;router-admins;240;24x7;1;1;1;;check_ping | ||
| 31 | # | ||
| 32 | # initial version: 28 Nov 2000 by Esteban Manchado Velázquez | ||
| 33 | # current status: 0.1 | ||
| 34 | # | ||
| 35 | # Copyright Notice: GPL | ||
| 36 | # | ||
| 37 | |||
| 38 | # Doesn't work! Why? | ||
| 39 | # BEGIN { | ||
| 40 | # my $runtimedir = substr($0,0,rindex($0,'/')); | ||
| 41 | # require "$runtimedir/utils.pm"; | ||
| 42 | # } | ||
| 43 | |||
| 44 | require '/usr/libexec/nagios/plugins/utils.pm'; | ||
| 45 | use RRD::File; | ||
| 46 | # use strict; # RRD:File and utils.pm don't like this | ||
| 47 | |||
| 48 | my $configfilepath = "/var/spool/nagios/rrd-files"; # Change if needed | ||
| 49 | my %hostfile; # For storing config | ||
| 50 | my $rrdfile; # RRD file to open | ||
| 51 | |||
| 52 | $ENV{'PATH'} = "/bin:/usr/bin"; | ||
| 53 | $ENV{'ENV'} = ""; | ||
| 54 | |||
| 55 | if (scalar @ARGV != 4 && scalar @ARGV != 5) { | ||
| 56 | print STDERR join "' '", @ARGV, "\n"; | ||
| 57 | my $foo = 'check_rrd_data'; | ||
| 58 | print STDERR $foo, " <file.rrd> <perl_exp_warn> <perl_exp_crit> <perl_exp_default> [<ds>]\n\n"; | ||
| 59 | print STDERR "<perl_exp_*> is an expression that gets evaluated with \$_ at the current\n"; | ||
| 60 | print STDERR "value of the data source. If it returns something other than \"\", there\n"; | ||
| 61 | print STDERR "will be a warning or a critical failure. Else, the expression\n"; | ||
| 62 | print STDERR "<perl_exp_default> will be evaluated\n"; | ||
| 63 | exit; | ||
| 64 | } | ||
| 65 | |||
| 66 | # Check configuration file | ||
| 67 | open F, $configfilepath or do { | ||
| 68 | print "Can't open config file $configfilepath\n"; | ||
| 69 | return $ERRORS{'UNKNOWN'}; | ||
| 70 | }; | ||
| 71 | while (<F>) { | ||
| 72 | next unless /(.+)\s+(.+)/; | ||
| 73 | $hostfile{$1} = $2; | ||
| 74 | } | ||
| 75 | close F; | ||
| 76 | |||
| 77 | # Default | ||
| 78 | my $ds = defined $ARGV[4]?$ARGV[4]:0; | ||
| 79 | # print "\$ds = " . $ds . ":"; | ||
| 80 | # print "\$ARGV[4] = " . $ARGV[4] . ":"; | ||
| 81 | $ds =~ s/\$//g; # Sometimes Nagios gives 1$ as the last parameter | ||
| 82 | |||
| 83 | # Guess which RRD file have to be opened | ||
| 84 | $rrdfile = $ARGV[0] if (-r $ARGV[0]); # First the parameter | ||
| 85 | $rrdfile = $hostfile{$ARGV[0]} unless $rrdfile; # Second, the config file | ||
| 86 | # print "$ARGV[0]:"; | ||
| 87 | |||
| 88 | if (! $rrdfile) { | ||
| 89 | print "Can't open data file for $ARGV[0]\n"; # Aaaargh! | ||
| 90 | return $ERRORS{'UNKNOWN'}; # Unknown | ||
| 91 | } | ||
| 92 | |||
| 93 | # print "Opening file $rrdfile:"; | ||
| 94 | my $rrd = new RRD::File ( -file => $rrdfile ); | ||
| 95 | $rrd->open(); | ||
| 96 | if (! $rrd->loadHeader()) { | ||
| 97 | print "Couldn't read header from $rrdfile\n"; | ||
| 98 | exit $ERRORS{'UNKNOWN'}; # Unknown | ||
| 99 | } | ||
| 100 | my $value = $rrd->getDSCurrentValue($ds); | ||
| 101 | $rrd->close(); | ||
| 102 | |||
| 103 | # Perl expressions to evaluate | ||
| 104 | my ($perl_exp_warn, $perl_exp_crit, $perl_exp_default) = | ||
| 105 | ($ARGV[1], $ARGV[2], $ARGV[3]); | ||
| 106 | my $result; # Result of the expressions (will be printed) | ||
| 107 | my @data; # Special data reserved for the expressions, to pass data | ||
| 108 | |||
| 109 | # First check for critical errors | ||
| 110 | $perl_exp_crit =~ /(.*)/; | ||
| 111 | $perl_exp_crit = $1; | ||
| 112 | $result = eval $perl_exp_crit; | ||
| 113 | if ($result) { | ||
| 114 | print $result; | ||
| 115 | exit 2; # Critical | ||
| 116 | } | ||
| 117 | |||
| 118 | # Check for warnings | ||
| 119 | $perl_exp_warn =~ /(.*)/; | ||
| 120 | $perl_exp_warn = $1; | ||
| 121 | $result = eval $perl_exp_warn; | ||
| 122 | if ($result) { | ||
| 123 | print $result; | ||
| 124 | exit 1; # Warning | ||
| 125 | } | ||
| 126 | |||
| 127 | $perl_exp_default =~ /(.*)/; | ||
| 128 | $perl_exp_default = $1; | ||
| 129 | 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 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | ################################################################################ | ||
| 3 | # | ||
| 4 | # CHECK_SAP plugin for Nagios | ||
| 5 | # | ||
| 6 | # Written by Karel Salavec (karel.salavec@ct.cz) | ||
| 7 | # Last Modified: 20Apr2000 | ||
| 8 | # | ||
| 9 | # Command line: CHECK_SAP <typ_of_check> <param1> <param2> [<param3>] | ||
| 10 | # | ||
| 11 | # Description: | ||
| 12 | # This plugin will attempt to open an SAP connection with the message | ||
| 13 | # server or application server. | ||
| 14 | # It need the sapinfo program installed on your server (see Notes). | ||
| 15 | # | ||
| 16 | # Notes: | ||
| 17 | # - This plugin requires that the saprfc-devel-45A-1.i386.rpm (or higher) | ||
| 18 | # package be installed on your machine. Sapinfo program | ||
| 19 | # is a part of this package. | ||
| 20 | # - You can find this package at SAP ftp server in | ||
| 21 | # /general/misc/unsupported/linux | ||
| 22 | # | ||
| 23 | # | ||
| 24 | # Parameters: | ||
| 25 | # $1 - type of checking - valid values: "ms" = message server | ||
| 26 | # "as" = application server | ||
| 27 | # $2 - SAP server identification - can be IP address, DNS name or SAP | ||
| 28 | # connect string (for example: /H/saprouter/S/sapdp01/H/sapserv3) | ||
| 29 | # $3 - for $1="ms" - SAP system name (for example: DEV, TST, ... ) | ||
| 30 | # for $1="as" - SAP system number - note: central instance have sysnr=00 | ||
| 31 | # $4 - valid only for $1="ms" - logon group name - default: PUBLIC | ||
| 32 | # | ||
| 33 | # Example of command definitions for nagios: | ||
| 34 | # | ||
| 35 | # command[check_sap_ms]=/usr/local/nagios/libexec/check_sap ms $HOSTADDRESS$ $ARG1$ $ARG2$ | ||
| 36 | # command[check_sap_as]=/usr/local/nagios/libexec/check_sap as $HOSTADDRESS$ $ARG1$ | ||
| 37 | # command[check_sap_ex]=/usr/local/nagios/libexec/check_sap as $ARG1$ $ARG2$ | ||
| 38 | # (for ARG1 see SAP OOS1 transaction) | ||
| 39 | # | ||
| 40 | ############################################################################## | ||
| 41 | |||
| 42 | if [ $# -lt 3 ]; then | ||
| 43 | echo "Need min. 3 parameters" | ||
| 44 | exit 2 | ||
| 45 | fi | ||
| 46 | |||
| 47 | case "$1" | ||
| 48 | in | ||
| 49 | ms) | ||
| 50 | if [ $4 ] | ||
| 51 | then | ||
| 52 | params="r3name=$3 mshost=$2 group=$4" | ||
| 53 | else | ||
| 54 | params="r3name=$3 mshost=$2" | ||
| 55 | fi | ||
| 56 | ;; | ||
| 57 | as) | ||
| 58 | params="ashost=$2 sysnr=$3" | ||
| 59 | ;; | ||
| 60 | *) | ||
| 61 | echo "The first parametr must be ms (message server) or as (application server)!" | ||
| 62 | exit 2 | ||
| 63 | ;; | ||
| 64 | esac | ||
| 65 | |||
| 66 | if /usr/sap/rfcsdk/bin/sapinfo $params | grep -i ERROR ; then | ||
| 67 | exit 2 | ||
| 68 | else | ||
| 69 | exit 0 | ||
| 70 | 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 @@ | |||
| 1 | #! /usr/bin/perl | ||
| 2 | # ------------------------------------------------------------------------------ | ||
| 3 | # File Name: check_sockets.pl | ||
| 4 | # Author: Richard Mayhew - South Africa | ||
| 5 | # Date: 2000/07/11 | ||
| 6 | # Version: 1.0 | ||
| 7 | # Description: This script will check to see how may open sockets | ||
| 8 | # a server has and waron respectivly | ||
| 9 | # Email: netsaint@splash.co.za | ||
| 10 | # ------------------------------------------------------------------------------ | ||
| 11 | # Copyright 1999 (c) Richard Mayhew | ||
| 12 | # Credits go to Ethan Galstad for coding Nagios | ||
| 13 | # If any changes are made to this script, please mail me a copy of the | ||
| 14 | # changes :) | ||
| 15 | # Some code taken from Charlie Cook (check_disk.pl) | ||
| 16 | # License GPL | ||
| 17 | # | ||
| 18 | # ------------------------------------------------------------------------------ | ||
| 19 | # Date Author Reason | ||
| 20 | # ---- ------ ------ | ||
| 21 | # 1999/09/20 RM Creation | ||
| 22 | # 1999/09/20 TP Changed script to use strict, more secure by | ||
| 23 | # specifying $ENV variables. The bind command is | ||
| 24 | # still insecure through. Did most of my work | ||
| 25 | # with perl -wT and 'use strict' | ||
| 26 | # | ||
| 27 | # ------------------------------------------------------------------------------ | ||
| 28 | |||
| 29 | # -----------------------------------------------------------------[ Require ]-- | ||
| 30 | require 5.004; | ||
| 31 | # --------------------------------------------------------------------[ Uses ]-- | ||
| 32 | use Socket; | ||
| 33 | use strict; | ||
| 34 | # --------------------------------------------------------------[ Enviroment ]-- | ||
| 35 | $ENV{'PATH'}='/bin:/sbin:/usr/bin:/usr/sbin'; | ||
| 36 | $ENV{BASH_ENV} = ""; | ||
| 37 | # ------------------------------------------------------------------[ Global ]-- | ||
| 38 | my $TIMEOUT = 20; | ||
| 39 | my %ERRORS = ( | ||
| 40 | 'UNKNOWN', '-1', | ||
| 41 | 'OK', '0', | ||
| 42 | 'WARNING', '1', | ||
| 43 | 'CRITICAL', '2'); | ||
| 44 | # --------------------------------------------------------------[ connection ]-- | ||
| 45 | sub connection | ||
| 46 | { | ||
| 47 | my ($in_total,$in_warn,$in_crit,$in_high) = @_; | ||
| 48 | my $state; | ||
| 49 | my $answer; | ||
| 50 | |||
| 51 | $in_total =~ s/\ //g; | ||
| 52 | if ($in_total >= 0) { | ||
| 53 | |||
| 54 | if ($in_total > $in_crit) { | ||
| 55 | $state = "CRITICAL"; | ||
| 56 | $answer = "Critical Number Of Sockets Connected : $in_total (Limit = $in_crit)\n"; | ||
| 57 | |||
| 58 | } elsif ($in_total > $in_warn) { | ||
| 59 | $state = "WARNING"; | ||
| 60 | $answer = "Warning Number Of Sockets Connected : $in_total (Limit = $in_warn)\n"; | ||
| 61 | |||
| 62 | } else { | ||
| 63 | if ($in_high ne "") { | ||
| 64 | $answer = "Sockets OK - Current Sockets: $in_total : $in_high\n"; | ||
| 65 | } | ||
| 66 | if ($in_high eq "") { | ||
| 67 | $answer = "Sockets OK - Current Sockets: $in_total\n"; | ||
| 68 | } | ||
| 69 | $state = "OK"; | ||
| 70 | } | ||
| 71 | |||
| 72 | } else { | ||
| 73 | $state = "UNKNOWN"; | ||
| 74 | $answer = "Something is Really WRONG! Sockets Is A Negative Figure!\n"; | ||
| 75 | } | ||
| 76 | |||
| 77 | print $answer; | ||
| 78 | exit $ERRORS{$state}; | ||
| 79 | } | ||
| 80 | |||
| 81 | # -------------------------------------------------------------------[ usage ]-- | ||
| 82 | sub usage | ||
| 83 | { | ||
| 84 | print "Minimum arguments not supplied!\n"; | ||
| 85 | print "\n"; | ||
| 86 | print "Perl Check Sockets plugin for Nagios\n"; | ||
| 87 | print "Copyright (c) 2000 Richard Mayhew\n"; | ||
| 88 | print "\n"; | ||
| 89 | print "Usage: check_sockets.pl <type> <warn> <crit>\n"; | ||
| 90 | print "\n"; | ||
| 91 | print "<type> = TOTAL, TCP, UDP, RAW.\n"; | ||
| 92 | print "<warn> = Number of sockets connected at which a warning message will be generated.[Default = 256]\n"; | ||
| 93 | print "<crit> = Number of sockets connected at which a critical message will be generated.[Default = 512]\n"; | ||
| 94 | exit $ERRORS{"UNKNOWN"}; | ||
| 95 | |||
| 96 | } | ||
| 97 | |||
| 98 | # ====================================================================[ MAIN ]== | ||
| 99 | MAIN: | ||
| 100 | { | ||
| 101 | my $type = shift || &usage; | ||
| 102 | my $warn = shift || 256; | ||
| 103 | my $crit = shift || 512; | ||
| 104 | my $data; | ||
| 105 | my @data; | ||
| 106 | my $line; | ||
| 107 | my $data1; | ||
| 108 | my $data2; | ||
| 109 | my $data3; | ||
| 110 | my $junk; | ||
| 111 | my $total1; | ||
| 112 | my $total2; | ||
| 113 | $type = uc $type; | ||
| 114 | if ($type eq "TOTAL") { | ||
| 115 | $type = "sockets"; | ||
| 116 | } | ||
| 117 | |||
| 118 | # Just in case of problems, let's not hang Nagios | ||
| 119 | $SIG{'ALRM'} = sub { | ||
| 120 | print "Somthing is Taking a Long Time, Increase Your TIMEOUT (Currently Set At $TIMEOUT Seconds)\n"; | ||
| 121 | exit $ERRORS{"UNKNOWN"}; | ||
| 122 | }; | ||
| 123 | |||
| 124 | $data = `/bin/cat /proc/net/sockstat`; | ||
| 125 | @data = split("\n",$data); | ||
| 126 | alarm($TIMEOUT); | ||
| 127 | my $output = ""; | ||
| 128 | my $high; | ||
| 129 | |||
| 130 | |||
| 131 | foreach $line (@data) { | ||
| 132 | if ($line =~ /$type/) { | ||
| 133 | ($data1,$data2,$data3) = split(" ",$line,3); | ||
| 134 | |||
| 135 | if ($data3 =~ /highest/){ | ||
| 136 | ($total1,$junk,$total2) = split(" ",$data3,3); | ||
| 137 | $output = $total1; | ||
| 138 | $high = $total2; | ||
| 139 | } | ||
| 140 | else {$output = $data3;} | ||
| 141 | alarm(0); | ||
| 142 | connection($output,$warn,$crit,$high); | ||
| 143 | } | ||
| 144 | } | ||
| 145 | } | ||
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 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * CHECK_TIMEOUT.C | ||
| 4 | * | ||
| 5 | * Program: Plugin timeout tester for Nagios | ||
| 6 | * License: GPL | ||
| 7 | * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) | ||
| 8 | * | ||
| 9 | * Last Modified: 01-10-2000 | ||
| 10 | * | ||
| 11 | * Command line: CHECK_TIMEOUT <something..> | ||
| 12 | * | ||
| 13 | * Description: | ||
| 14 | * This 'plugin' - if you want to call it that - doesn't do anything. It | ||
| 15 | * just stays in a loop forever and never exits, and is therefore useful for | ||
| 16 | * testing service and host check timeouts in Nagios. You must supply at | ||
| 17 | * least one argument on the command line in order to activate the loop. | ||
| 18 | * | ||
| 19 | ****************************************************************************/ | ||
| 20 | |||
| 21 | #include <stdio.h> | ||
| 22 | #include <unistd.h> | ||
| 23 | |||
| 24 | |||
| 25 | int main(int argc, char **argv){ | ||
| 26 | |||
| 27 | if(argc==1){ | ||
| 28 | printf("Incorrect arguments supplied\n"); | ||
| 29 | printf("\n"); | ||
| 30 | printf("Plugin timeout tester for Nagios\n"); | ||
| 31 | printf("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n"); | ||
| 32 | printf("Last Modified: 01-10-2000\n"); | ||
| 33 | printf("License: GPL\n"); | ||
| 34 | printf("\n"); | ||
| 35 | printf("Usage: %s <something>\n",argv[0]); | ||
| 36 | printf("\n"); | ||
| 37 | printf("Options:\n"); | ||
| 38 | printf(" <something> = Anything at all...\n"); | ||
| 39 | printf("\n"); | ||
| 40 | printf("Notes:\n"); | ||
| 41 | printf("This 'plugin' doesn't do anything. It is designed to never exit and therefore\n"); | ||
| 42 | printf("provides an easy way of testing service and host check timeouts in Nagios.\n"); | ||
| 43 | printf("\n"); | ||
| 44 | return 0; | ||
| 45 | } | ||
| 46 | |||
| 47 | /* let's never leave here, okay? */ | ||
| 48 | while(1) | ||
| 49 | sleep(1); | ||
| 50 | |||
| 51 | return 0; | ||
| 52 | } | ||
| 53 | |||
| 54 | |||
| 55 | |||
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 @@ | |||
| 1 | /****************************************************************************** | ||
| 2 | * | ||
| 3 | * CHECK_UPTIME.C | ||
| 4 | * | ||
| 5 | * Program: Uptime plugin for Nagios | ||
| 6 | * License: GPL | ||
| 7 | * Copyright (c) 2000 Teresa Ramanan (teresa@redowl.org) | ||
| 8 | * | ||
| 9 | * Based on CHECK_LOAD.C | ||
| 10 | * Copyright (c) 1999 Felipe Gustavo de Almeida <galmeida@linux.ime.usp.br> | ||
| 11 | * | ||
| 12 | * Last Modified: $Date$ | ||
| 13 | * | ||
| 14 | * Command line: CHECK_UPTIME <host_address> | ||
| 15 | * | ||
| 16 | * Description: | ||
| 17 | * | ||
| 18 | * This plugin parses the output from "uptime", tokenizing it with ',' as the | ||
| 19 | * delimiter. Returning only the number of days and/or the hours and minutes | ||
| 20 | * a machine has been up and running. | ||
| 21 | * | ||
| 22 | *****************************************************************************/ | ||
| 23 | |||
| 24 | #include "common/config.h" | ||
| 25 | #include "common/common.h" | ||
| 26 | #include "common/utils.h" | ||
| 27 | #include "common/popen.h" | ||
| 28 | |||
| 29 | int main(int argc, char **argv) | ||
| 30 | { | ||
| 31 | |||
| 32 | int result; | ||
| 33 | char input_buffer[MAX_INPUT_BUFFER]; | ||
| 34 | int ct; | ||
| 35 | int i; | ||
| 36 | char *tok1 = NULL; | ||
| 37 | char *daytok = NULL; | ||
| 38 | char *hrmintok = NULL; | ||
| 39 | char *runstr = NULL; | ||
| 40 | char tempp; | ||
| 41 | char ch; | ||
| 42 | char delim[] = ","; | ||
| 43 | |||
| 44 | if(argc != 2){ | ||
| 45 | printf("Incorrect number of arguments supplied\n"); | ||
| 46 | printf("\n"); | ||
| 47 | print_revision(argv[0],"$Revision$"); | ||
| 48 | printf("Copyright (c) 2000 Teresa Ramanan (tlr@redowl.org)\n"); | ||
| 49 | printf("\n"); | ||
| 50 | printf("Usage: %s <host_address>\n",argv[0]); | ||
| 51 | printf("\n"); | ||
| 52 | return STATE_UNKNOWN; | ||
| 53 | } | ||
| 54 | |||
| 55 | child_process = spopen(PATH_TO_UPTIME); | ||
| 56 | if(child_process==NULL){ | ||
| 57 | printf("Error opening %s\n",PATH_TO_UPTIME); | ||
| 58 | return STATE_UNKNOWN; | ||
| 59 | } | ||
| 60 | child_stderr=fdopen(child_stderr_array[fileno(child_process)],"r"); | ||
| 61 | if(child_stderr==NULL){ | ||
| 62 | printf("Could not open stderr for %s\n",PATH_TO_UPTIME); | ||
| 63 | } | ||
| 64 | fgets(input_buffer,MAX_INPUT_BUFFER-1,child_process); | ||
| 65 | i = 0; | ||
| 66 | ct = 0; | ||
| 67 | |||
| 68 | /* Let's mark the end of this string for parsing purposes */ | ||
| 69 | input_buffer[strlen(input_buffer)-1]='\0'; | ||
| 70 | |||
| 71 | tempp = input_buffer[0]; | ||
| 72 | while(ch != '\0'){ | ||
| 73 | ch = (&tempp)[i]; | ||
| 74 | if (ch == ',') { ct++; } | ||
| 75 | i++; | ||
| 76 | } | ||
| 77 | runstr = input_buffer; | ||
| 78 | tok1 = strsep(&runstr, delim); | ||
| 79 | if (ct > 4) { | ||
| 80 | hrmintok = strsep(&runstr, delim); | ||
| 81 | hrmintok++; | ||
| 82 | daytok = strstr(tok1,"up"); | ||
| 83 | } | ||
| 84 | else { | ||
| 85 | hrmintok = strstr(tok1, "up"); | ||
| 86 | } | ||
| 87 | |||
| 88 | result = spclose(child_process); | ||
| 89 | if(result){ | ||
| 90 | printf("Error code %d returned in %s\n",result,PATH_TO_UPTIME); | ||
| 91 | return STATE_UNKNOWN; | ||
| 92 | } | ||
| 93 | if (hrmintok == NULL) { | ||
| 94 | printf("Problem - unexpected data returned\n"); | ||
| 95 | return STATE_UNKNOWN; | ||
| 96 | } | ||
| 97 | printf("%s%s%s\n",(daytok == NULL)?"":daytok,(daytok == NULL)?"":",",hrmintok); | ||
| 98 | return STATE_OK; | ||
| 99 | } | ||
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 @@ | |||
| 1 | #!/usr/bin/perl -wT | ||
| 2 | # check_ciscotemp.pl | ||
| 3 | # | ||
| 4 | # Copyright (C) 2000 Leland E. Vandervort <leland@mmania.com> | ||
| 5 | # | ||
| 6 | # This program is free software; you can redistribute it and/or | ||
| 7 | # modify it under the terms of the GNU General Public License | ||
| 8 | # as published by the Free Software Foundation; either version 2 | ||
| 9 | # of the License, or (at your option) any later version. | ||
| 10 | # | ||
| 11 | # This program is distributed in the hope that it will be useful, | ||
| 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty | ||
| 13 | # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | # GNU General Public License for more details. | ||
| 15 | # | ||
| 16 | # you should have received a copy of the GNU General Public License | ||
| 17 | # along with this program (or with Nagios); if not, write to the | ||
| 18 | # Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 19 | # Boston, MA 02111-1307, USA | ||
| 20 | #################################### | ||
| 21 | # Nagios pluging to check inlet and outlet temperatures on | ||
| 22 | # Cisco router platforms which support environmental monitoring | ||
| 23 | # (7200, 7500, GSR12000...) | ||
| 24 | #################################### | ||
| 25 | # default temperature thresholds are 30C for inlet, 40C outlet. | ||
| 26 | # if input or output is less than thresholds, returns OK | ||
| 27 | # if equal to (the temps don't change that rapidly) returns WARNING | ||
| 28 | # if greater than threshold, returns CRITICAL | ||
| 29 | # if undetermined, or cannot access environmental, returns UNKNOWN | ||
| 30 | # (in accordance with the plugin coding guidelines) | ||
| 31 | #################################### | ||
| 32 | |||
| 33 | use Net::SNMP; | ||
| 34 | use Getopt::Long; | ||
| 35 | &Getopt::Long::config('auto_abbrev'); | ||
| 36 | |||
| 37 | my $status; | ||
| 38 | my $response = ""; | ||
| 39 | my $timeout = 10; | ||
| 40 | my $community = "public"; | ||
| 41 | my $port = 161; | ||
| 42 | my $INTAKE_TEMP = "1.3.6.1.4.1.9.9.13.1.3.1.3.1"; | ||
| 43 | my $OUTLET_TEMP = "1.3.6.1.4.1.9.9.13.1.3.1.3.3"; | ||
| 44 | my $in_temp; | ||
| 45 | my $out_temp; | ||
| 46 | my $inlet_thresh = 30; | ||
| 47 | my $outlet_thresh = 40; | ||
| 48 | |||
| 49 | my %STATUSCODE = ( 'UNKNOWN' => '-1', | ||
| 50 | 'OK' => '0', | ||
| 51 | 'WARNING' => '1', | ||
| 52 | 'CRITICAL' => '2'); | ||
| 53 | |||
| 54 | my $state = "UNKNOWN"; | ||
| 55 | |||
| 56 | |||
| 57 | $SIG{'ALRM'} = sub { | ||
| 58 | print "ERROR: No snmp response from $hostname (sigALRM)\n"; | ||
| 59 | exit($STATUSCODE{"UNKNOWN"}); | ||
| 60 | }; | ||
| 61 | |||
| 62 | Getopt::Long::Configure('bundling'); | ||
| 63 | $status = GetOptions | ||
| 64 | ("community=s", \$community, | ||
| 65 | "C=s", \$community, | ||
| 66 | "H=s", \$hostname, | ||
| 67 | "hostname=s", \$hostname, | ||
| 68 | "port=i", \$port, | ||
| 69 | "timeout=i", \$timeout, | ||
| 70 | "c=s", \$critical_vals, | ||
| 71 | "w=s", \$warning_vals, | ||
| 72 | "ithresh=i", \$inlet_thresh, | ||
| 73 | "othresh=i", \$outlet_thresh); | ||
| 74 | |||
| 75 | if($status == 0) { | ||
| 76 | &show_help; | ||
| 77 | } | ||
| 78 | |||
| 79 | unless (defined($hostname)) { | ||
| 80 | $hostname = shift || &show_help; | ||
| 81 | } | ||
| 82 | |||
| 83 | if (defined($critical_vals)) { | ||
| 84 | die "Cannot Parse Critical Thresholds\n" | ||
| 85 | unless (split(/:/,$critical_vals)>=2); | ||
| 86 | ($inlet_thresh,$outlet_thresh) = @_ | ||
| 87 | } | ||
| 88 | die unless(defined($inlet_thresh) && defined($outlet_thresh)); | ||
| 89 | |||
| 90 | if (defined($warning_vals)) { | ||
| 91 | die "Cannot Parse Critical Thresholds\n" | ||
| 92 | unless (split(/:/,$warning_vals)>=2); | ||
| 93 | ($inlet_warn,$outlet_warn) = @_; | ||
| 94 | }else{ | ||
| 95 | $inlet_warn=$inlet_thresh; | ||
| 96 | $outlet_warn=$outlet_thresh; | ||
| 97 | } | ||
| 98 | |||
| 99 | alarm($timeout); | ||
| 100 | |||
| 101 | $in_temp = &SNMPGET($INTAKE_TEMP); | ||
| 102 | $out_temp = &SNMPGET($OUTLET_TEMP); | ||
| 103 | |||
| 104 | if (($in_temp < $inlet_thresh) && ($out_temp < $outlet_thresh)) { | ||
| 105 | $state = "OK"; | ||
| 106 | } | ||
| 107 | elsif (($in_temp == $inlet_thresh) || ($out_temp == $outlet_thresh)) { | ||
| 108 | if(($in_temp > $inlet_thresh) || ($out_temp > $outlet_thresh)) { | ||
| 109 | $state = "CRITICAL"; | ||
| 110 | } | ||
| 111 | else { | ||
| 112 | $state = "WARNING"; | ||
| 113 | } | ||
| 114 | } | ||
| 115 | elsif (($in_temp > $inlet_thresh) || ($out_temp > $outlet_thresh)) { | ||
| 116 | $state = "CRITICAL"; | ||
| 117 | } | ||
| 118 | else { | ||
| 119 | $state = "WARNING"; | ||
| 120 | } | ||
| 121 | |||
| 122 | print "$state Inlet Temp: $in_temp Outlet Temp: $out_temp\n"; | ||
| 123 | exit($STATUSCODE{$state}); | ||
| 124 | |||
| 125 | sub show_help { | ||
| 126 | printf("\nPerl envmon temperature plugin for Nagios\n"); | ||
| 127 | printf("Usage:\n"); | ||
| 128 | printf(" | ||
| 129 | check_ciscotemp [options] <hostname> | ||
| 130 | Options: | ||
| 131 | -C snmp-community | ||
| 132 | -p snmp-port | ||
| 133 | -i input temperature threshold | ||
| 134 | -o output temperature threshold | ||
| 135 | |||
| 136 | "); | ||
| 137 | printf("Copyright (C)2000 Leland E. Vandervort\n"); | ||
| 138 | printf("check_ciscotemp comes with absolutely NO WARRANTY either implied or explicit\n"); | ||
| 139 | printf("This program is licensed under the terms of the\n"); | ||
| 140 | printf("GNU General Public License\n(check source code for details)\n\n\n"); | ||
| 141 | exit($STATUSCODE{"UNKNOWN"}); | ||
| 142 | } | ||
| 143 | |||
| 144 | sub SNMPGET { | ||
| 145 | $OID = shift; | ||
| 146 | ($session,$error) = Net::SNMP->session( | ||
| 147 | Hostname => $hostname, | ||
| 148 | Community => $community, | ||
| 149 | Port => $port | ||
| 150 | ); | ||
| 151 | if(!defined($session)) { | ||
| 152 | printf("$state %s\n", $error); | ||
| 153 | exit($STATUSCODE{$state}); | ||
| 154 | } | ||
| 155 | if(!defined($response = $session->get_request($OID))) { | ||
| 156 | printf("$state %s\n", $session->error()); | ||
| 157 | $session->close(); | ||
| 158 | exit($STATUSCODE{$state}); | ||
| 159 | } | ||
| 160 | $session->close(); | ||
| 161 | return($response->{$OID}); | ||
| 162 | } | ||
| 163 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | |||
| 3 | # Oracle plugin submitted by Christopher Maser (maser@onvista.de) | ||
| 4 | # 12/31/1999 | ||
| 5 | |||
| 6 | my $host=$ARGV[0]; | ||
| 7 | my @test=`tnsping $host`; | ||
| 8 | my $arg=$test[6]; | ||
| 9 | chomp $arg; | ||
| 10 | if ($arg =~ /^OK (.*)/) | ||
| 11 | {print "$arg"; exit 0} | ||
| 12 | else {exit 2;} | ||
| 13 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | # | ||
| 3 | # mrtgext.pl v0.3 | ||
| 4 | # (c)2000 Cliff Woolley, Washington and Lee University | ||
| 5 | # jwoolley@wlu.edu | ||
| 6 | # | ||
| 7 | # A UNIX counterpart to Jim Drews' MRTG Extension for netware servers | ||
| 8 | # Mimics output of mrtgext.nlm using output of various standard UNIX | ||
| 9 | # programs (df, uptime, and uname) | ||
| 10 | # | ||
| 11 | # Dependencies: I make some assumptions about the output format of | ||
| 12 | # your df and uptime commands. If you have nonstandard outputs for | ||
| 13 | # any of these, either pick a different command that gives more | ||
| 14 | # standard output or modify the script below. Example: use /usr/bin/bdf | ||
| 15 | # on HP-UX instead of /usr/bin/df, because bdf follows the output format | ||
| 16 | # I expect while df does not. This was written on Linux and tested on | ||
| 17 | # HP-UX 10.20 (with changes to the subroutines at the bottom of the | ||
| 18 | # program to reflect HP's command parameters); similar tweaking could | ||
| 19 | # well be required to port this to other platforms. If you get it | ||
| 20 | # working on your platform, please send me any changes you had to | ||
| 21 | # make so I can try to incorporate them. | ||
| 22 | # | ||
| 23 | # | ||
| 24 | # Following is what I expect the programs' outputs to look like: | ||
| 25 | # | ||
| 26 | # ======= df ======== | ||
| 27 | # Filesystem 1k-blocks Used Available Use% Mounted on | ||
| 28 | # /dev/sda1 1014696 352708 609612 37% / | ||
| 29 | # /dev/sda2 2262544 586712 1559048 27% /apps | ||
| 30 | # /dev/sda3 4062912 566544 3286604 15% /share | ||
| 31 | # /dev/sr0 651758 651758 0 100% /cdrom | ||
| 32 | # =================== | ||
| 33 | # | ||
| 34 | # ===== uptime ====== | ||
| 35 | # 3:17pm up 15 days, 4:40, 5 users, load average: 0.12, 0.26, 0.33 | ||
| 36 | # =================== | ||
| 37 | # | ||
| 38 | |||
| 39 | ############################################################### | ||
| 40 | # Configuration section | ||
| 41 | ############################################################### | ||
| 42 | |||
| 43 | $dfcmd = "/bin/df 2>/dev/null"; | ||
| 44 | $uptimecmd = "/usr/bin/uptime"; | ||
| 45 | %customcmds = ( "PROCS" => "numprocesses", | ||
| 46 | "ZOMBIES" => "numzombies", | ||
| 47 | "MEMFREE" => "memfree", | ||
| 48 | "SWAPUSED" => "swapused", | ||
| 49 | "TCPCONNS" => "tcpconns", | ||
| 50 | "CLIENTS" => "ipclients" ); | ||
| 51 | # These are functions that you can | ||
| 52 | # define and customize for your system. | ||
| 53 | # You probably need to change the provided | ||
| 54 | # subroutines to work on your system (if | ||
| 55 | # not Linux). | ||
| 56 | |||
| 57 | $rootfsnickname = "root"; # this is necessary as a kludge to | ||
| 58 | # better match the netware behavior. | ||
| 59 | # if you already have a _filesystem_ | ||
| 60 | # mounted as /root, then you'll need | ||
| 61 | # to change this to something else | ||
| 62 | $DEBUG = 0; | ||
| 63 | $recvtimeout = 30; | ||
| 64 | |||
| 65 | |||
| 66 | ############################################################### | ||
| 67 | # Program section | ||
| 68 | ############################################################### | ||
| 69 | |||
| 70 | require 5.004; | ||
| 71 | |||
| 72 | use Sys::Hostname; | ||
| 73 | |||
| 74 | |||
| 75 | $DEBUG = $ARGV[0] unless ($DEBUG); | ||
| 76 | $SIG{'ALRM'} = sub { exit 1; }; | ||
| 77 | |||
| 78 | # some things never change | ||
| 79 | $hostname = hostname; | ||
| 80 | |||
| 81 | |||
| 82 | if ( $DEBUG ) { | ||
| 83 | $| = 1; | ||
| 84 | print scalar localtime,": mrtgext.pl started\n"; | ||
| 85 | } | ||
| 86 | |||
| 87 | # timeout period | ||
| 88 | alarm($recvtimeout); | ||
| 89 | my $items = <STDIN>; | ||
| 90 | alarm(0); | ||
| 91 | |||
| 92 | $items =~ s/[\r\n]//g; | ||
| 93 | ( $DEBUG ) && print scalar localtime,": request: \"$items\"\n"; | ||
| 94 | my @items = split (/\s+/,"$items"); | ||
| 95 | ( $DEBUG ) && print scalar localtime,": ",scalar @items," item(s) to process\n"; | ||
| 96 | |||
| 97 | my $uptime = `$uptimecmd`; | ||
| 98 | my @df = grep {/^\//} `$dfcmd`; | ||
| 99 | |||
| 100 | my $processed = 1; | ||
| 101 | |||
| 102 | foreach $_ (@items) { | ||
| 103 | ( $DEBUG ) && print scalar localtime,": processing item #$processed: \"$_\"\n"; | ||
| 104 | $_ = uc; #convert $_ to upper case | ||
| 105 | if ( /^UTIL1$/ ) { | ||
| 106 | $uptime =~ /load average: ([^,]+),/; | ||
| 107 | print $1 * 100,"\n"; | ||
| 108 | } | ||
| 109 | elsif ( /^UTIL5$/ ) { | ||
| 110 | $uptime =~ /load average: [^,]+, ([^,]+)/; | ||
| 111 | print $1 * 100,"\n"; | ||
| 112 | } | ||
| 113 | elsif ( /^UTIL15$/ ) { | ||
| 114 | $uptime =~ /load average: [^,]+, [^,]+, ([^,]+)/; | ||
| 115 | print $1 * 100,"\n"; | ||
| 116 | } | ||
| 117 | elsif ( /^CONNECT$/ ) { | ||
| 118 | $uptime =~ /(\d+) users?,/; | ||
| 119 | print "$1\n"; | ||
| 120 | } | ||
| 121 | elsif ( /^NAME$/ ) { | ||
| 122 | print "$hostname\n"; | ||
| 123 | } | ||
| 124 | elsif ( /^UPTIME$/ ) { | ||
| 125 | $uptime =~ /up (.*),\s+\d+\s+users?,/; | ||
| 126 | print "$1\n"; | ||
| 127 | } | ||
| 128 | elsif ( /^VOLUMES$/ ) { | ||
| 129 | foreach $dfline (@df) { | ||
| 130 | my $volname = (split(/\s+/, "$dfline"))[5]; | ||
| 131 | $volname =~ s/^\/$/$rootfsnickname/; | ||
| 132 | $volname =~ s/^\///; | ||
| 133 | $volname =~ s/\//_/g; | ||
| 134 | print "$volname\n"; | ||
| 135 | } | ||
| 136 | } | ||
| 137 | elsif ( /^VF(\w*)$/ ) { | ||
| 138 | my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1"; | ||
| 139 | foreach $dfline (@df) { | ||
| 140 | my @dfline = split(/\s+/, "$dfline"); | ||
| 141 | if ($dfline[5] =~ /^\/?$volname$/i ) { | ||
| 142 | print (($dfline[1]-$dfline[2]) * 1024,"\n"); | ||
| 143 | goto done; | ||
| 144 | } | ||
| 145 | } | ||
| 146 | ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n"; | ||
| 147 | print "-1\n"; | ||
| 148 | } | ||
| 149 | elsif ( /^VU(\w*)$/ ) { | ||
| 150 | my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1"; | ||
| 151 | foreach $dfline (@df) { | ||
| 152 | my @dfline = split(/\s+/, "$dfline"); | ||
| 153 | if ($dfline[5] =~ /^\/?$volname$/i ) { | ||
| 154 | print ($dfline[2] * 1024,"\n"); | ||
| 155 | goto done; | ||
| 156 | } | ||
| 157 | } | ||
| 158 | ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n"; | ||
| 159 | print "-1\n"; | ||
| 160 | } | ||
| 161 | elsif ( /^VS(\w*)$/ ) { | ||
| 162 | my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1"; | ||
| 163 | foreach $dfline (@df) { | ||
| 164 | my @dfline = split(/\s+/, "$dfline"); | ||
| 165 | if ($dfline[5] =~ /^\/?$volname$/i ) { | ||
| 166 | print ($dfline[1] * 1024,"\n"); | ||
| 167 | goto done; | ||
| 168 | } | ||
| 169 | } | ||
| 170 | ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n"; | ||
| 171 | print "-1\n"; | ||
| 172 | } | ||
| 173 | elsif ( /^VKF(\w*)$/ ) { | ||
| 174 | my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1"; | ||
| 175 | foreach $dfline (@df) { | ||
| 176 | my @dfline = split(/\s+/, "$dfline"); | ||
| 177 | if ($dfline[5] =~ /^\/?$volname$/i ) { | ||
| 178 | print (($dfline[1]-$dfline[2]),"\n"); | ||
| 179 | goto done; | ||
| 180 | } | ||
| 181 | } | ||
| 182 | ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n"; | ||
| 183 | print "-1\n"; | ||
| 184 | } | ||
| 185 | elsif ( /^VKU(\w*)$/ ) { | ||
| 186 | my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1"; | ||
| 187 | foreach $dfline (@df) { | ||
| 188 | my @dfline = split(/\s+/, "$dfline"); | ||
| 189 | if ($dfline[5] =~ /^\/?$volname$/i ) { | ||
| 190 | print ($dfline[2],"\n"); | ||
| 191 | goto done; | ||
| 192 | } | ||
| 193 | } | ||
| 194 | ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n"; | ||
| 195 | print "-1\n"; | ||
| 196 | } | ||
| 197 | elsif ( /^VKS(\w*)$/ ) { | ||
| 198 | my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1"; | ||
| 199 | foreach $dfline (@df) { | ||
| 200 | my @dfline = split(/\s+/, "$dfline"); | ||
| 201 | if ($dfline[5] =~ /^\/?$volname$/i ) { | ||
| 202 | print ($dfline[1],"\n"); | ||
| 203 | goto done; | ||
| 204 | } | ||
| 205 | } | ||
| 206 | ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n"; | ||
| 207 | print "-1\n"; | ||
| 208 | } | ||
| 209 | elsif ( /^ZERO$/ ) { | ||
| 210 | print "0\n"; | ||
| 211 | } | ||
| 212 | elsif (exists( $customcmds{"$_"} )) { | ||
| 213 | my $cmdsub = "$customcmds{$_}"; | ||
| 214 | print &$cmdsub."\n"; | ||
| 215 | } | ||
| 216 | else { | ||
| 217 | print "-1\n"; | ||
| 218 | } | ||
| 219 | done: $processed++; | ||
| 220 | } | ||
| 221 | ( $DEBUG ) && print scalar localtime,": done.\n"; | ||
| 222 | |||
| 223 | |||
| 224 | ############################################################### | ||
| 225 | # CUSTOMIZED PROCEDURES | ||
| 226 | ############################################################### | ||
| 227 | |||
| 228 | sub numprocesses { | ||
| 229 | |||
| 230 | my $num = `/bin/ps -eaf | /usr/bin/tail -n +2 | /usr/bin/wc -l`; | ||
| 231 | chomp ($num); | ||
| 232 | $num =~ s/\s+//g; | ||
| 233 | |||
| 234 | $num; | ||
| 235 | } | ||
| 236 | |||
| 237 | sub numzombies { | ||
| 238 | |||
| 239 | my $num = `/bin/ps -afx | /usr/bin/awk '{print \$3}' | /usr/bin/grep Z | /usr/bin/tail -n +2 | /usr/bin/wc -l`; | ||
| 240 | chomp ($num); | ||
| 241 | $num =~ s/\s+//g; | ||
| 242 | |||
| 243 | $num; | ||
| 244 | } | ||
| 245 | |||
| 246 | sub tcpconns { | ||
| 247 | |||
| 248 | my $num = `/bin/netstat -nt | /usr/bin/tail -n +3 | /usr/bin/wc -l`; | ||
| 249 | chomp ($num); | ||
| 250 | $num =~ s/\s+//g; | ||
| 251 | |||
| 252 | $num; | ||
| 253 | } | ||
| 254 | |||
| 255 | sub ipclients { | ||
| 256 | |||
| 257 | 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`; | ||
| 258 | chomp ($num); | ||
| 259 | $num =~ s/\s+//g; | ||
| 260 | |||
| 261 | $num; | ||
| 262 | } | ||
| 263 | |||
| 264 | sub memfree { | ||
| 265 | |||
| 266 | open( FP, "/proc/meminfo" ); | ||
| 267 | my @meminfo = <FP>; | ||
| 268 | close(FP); | ||
| 269 | |||
| 270 | # total: used: free: shared: buffers: cached: | ||
| 271 | # Mem: 994615296 592801792 401813504 91193344 423313408 93118464 | ||
| 272 | # Swap: 204791808 0 204791808 | ||
| 273 | my ($total,$free,$buffers,$cache) = (split(/ +/,$meminfo[1]))[1,3,5,6]; | ||
| 274 | |||
| 275 | int(($free+$buffers+$cache)/$total*100); | ||
| 276 | } | ||
| 277 | |||
| 278 | sub swapused { | ||
| 279 | |||
| 280 | open( FP, "/proc/meminfo" ); | ||
| 281 | my @meminfo = <FP>; | ||
| 282 | close(FP); | ||
| 283 | |||
| 284 | # total: used: free: shared: buffers: cached: | ||
| 285 | # Mem: 994615296 592424960 402190336 89821184 423313408 93077504 | ||
| 286 | # Swap: 204791808 0 204791808 | ||
| 287 | |||
| 288 | my ($total,$used) = (split(/ +/,$meminfo[2]))[1,2]; | ||
| 289 | |||
| 290 | int($used/$total*100); | ||
| 291 | } | ||
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 @@ | |||
| 1 | Contrib Plugins README | ||
| 2 | ---------------------- | ||
| 3 | |||
| 4 | This directory contains plugins which have been contributed by various people, but that | ||
| 5 | have not yet been incorporated into the core plugins distribution. | ||
| 6 | |||
| 7 | If you have questions regarding the use of these plugins, try contacting the author(s) | ||
| 8 | or post a message to the nagios-users mailing list (nagios-users@onelist.com) | ||
| 9 | requesting assistance. | ||
| 10 | |||
| 11 | |||
| 12 | Plugin Overview | ||
| 13 | --------------- | ||
| 14 | |||
| 15 | berger-ping.tar.gz - Perl script version of the check_ping plugin and a corresponding | ||
| 16 | CGI (mtr.cgi) that uses mtr to traceroute a path to a host. | ||
| 17 | (Gary Berger) | ||
| 18 | |||
| 19 | bowen-langley_plugins.tar.gz | ||
| 20 | - Several C plugins including check_inode, check_boot, etc. | ||
| 21 | (Adam Bown & Thomas Langley) | ||
| 22 | |||
| 23 | |||
| 24 | check_bgpstate.tar.gz - Perl script intended for monitoring BGP sessions on Cisco routers. | ||
| 25 | Only useful if you are using BGP4 as a routing protocol. For | ||
| 26 | critical alert the AS (autonomous system) number has to be in the | ||
| 27 | uplinks hash (see the source code). Requires SNMP read community. | ||
| 28 | (Christoph Kron) | ||
| 29 | |||
| 30 | check_breeze.tar.gz - Perl script to test signal strength on Breezecom wireless | ||
| 31 | equipment (Jeffrey Blank) | ||
| 32 | |||
| 33 | check_dns_random.tar.gz - Perl script to see if dns resolves hosts randomly from a list | ||
| 34 | using the check_dns plugin (Richard Mayhew) | ||
| 35 | |||
| 36 | check_flexlm.tar.gz - Perl script to check a flexlm licensing manager using lmtest | ||
| 37 | (Ernst-Dieter Martin) | ||
| 38 | |||
| 39 | check_hltherm.tar.gz - C program to check the temperature on a Hot Little Therm temperature | ||
| 40 | probe. The HLT device, along with temperature probes, can be obtained | ||
| 41 | from Spiderplant at http://www.spiderplant.com | ||
| 42 | (Ethan Galstad) | ||
| 43 | |||
| 44 | check_ifoperstatus.tar.gz | ||
| 45 | - Perl script that checks the operational interface status (up/down) for | ||
| 46 | one interface on cisco/ascend routers. Especially useful for monitoring | ||
| 47 | leased lines. Requires SNMP read community and SNMP interface key. | ||
| 48 | (Christoph Kron) | ||
| 49 | |||
| 50 | check_ifstatus.tar.gz - Perl script that checks operational interface status for every interface | ||
| 51 | on cisco routers. Requires SNMP read community. | ||
| 52 | (Christoph Kron) | ||
| 53 | |||
| 54 | check_ipxping.tar.gz - C program that it similiar to the check_ping plugin, except that it | ||
| 55 | send IPX ping packets to Novell servers or other IPX devices. This | ||
| 56 | requires the ipxping binary for Linux systems. It does NOT by work | ||
| 57 | without modification with the ipxping binary for SunOS/Solaris. | ||
| 58 | (Ethan Galstad) | ||
| 59 | |||
| 60 | check_maxchannels.tar.gz | ||
| 61 | - Perl script that can only be used for monitoring Ascend/Lucent Max/TNT | ||
| 62 | access server. Checks ISDN channels and modem cards. Also shows ISDN and | ||
| 63 | modem usage. Requires SNMP read community. | ||
| 64 | (Christoph Kron) | ||
| 65 | |||
| 66 | check_maxwanstate.tar.gz | ||
| 67 | - Perl script that can only be used for monitoring Ascend/Lucent Max/TNT | ||
| 68 | access server. Checks if every enabled E1/T1 interface is operational | ||
| 69 | (link active). Requires SNMP read community. | ||
| 70 | (Christoph Kron) | ||
| 71 | |||
| 72 | check_memory.tgz - C program to check available system memory - RAM, swap, buffers, | ||
| 73 | and cache (Joshua Jackson) | ||
| 74 | |||
| 75 | check_nfs.tar.gz - Perl script to test and NFS server using rpcinfo | ||
| 76 | (Ernst-Dieter Martin) | ||
| 77 | <NOW PART OF check_rpc IN CORE> | ||
| 78 | |||
| 79 | check_ntp.tar.gz - Perl script to check an NTP time source (Bo Kernsey) | ||
| 80 | <MOVED TO CORE> | ||
| 81 | |||
| 82 | check_ora.tar.gz - Shell script that will check an Oracle database and the TNS listener. | ||
| 83 | Unlike the check_oracle plugin, this plugin detects when a database is | ||
| 84 | down and does not create temp files (Jason Hedden) | ||
| 85 | <MOVED TO CORE> | ||
| 86 | |||
| 87 | check_pop3.tar.gz - Perl script that checks to see if POP3 is running and whether or not | ||
| 88 | authentication can take place (Richard Mayhew) | ||
| 89 | |||
| 90 | check_radius.tar.gz - C program to check RADIUS authentication. This is a hacked version of | ||
| 91 | the Cistron Radiusd program radtest that acts as a plugin for Nagios. | ||
| 92 | The vast majority of the code was written by someone at Livingston | ||
| 93 | Enterprises and Cistron. NOTE: Due to the copyright restrictions in | ||
| 94 | this code, it cannot be distributed under the GPL license, and thus | ||
| 95 | will not appear in the core plugin distribution! | ||
| 96 | (Adam Jacob) | ||
| 97 | |||
| 98 | check_real.tar.gz - C program to check the status of a REAL media server | ||
| 99 | (Pedro Leite) | ||
| 100 | <MOVED TO CORE> | ||
| 101 | |||
| 102 | check_rpc.pl.gz - Perl script to check rpc services. Will check to see if the a specified | ||
| 103 | program is running on the specified server (Chris Kolquist) | ||
| 104 | |||
| 105 | check_sap.tar.gz - Shell script to check an SAP message or application server. Requires | ||
| 106 | that you install the saprfc-devel-45A-1.i386.rpm (or higher) package | ||
| 107 | on your system. The package can be obtained from the SAP FTP site in | ||
| 108 | the /general/misc/unsupported/linux directory. (Kavel Salavec) | ||
| 109 | |||
| 110 | check_uptime.tar.gz - C program to check system uptime. Must be compiled with the release | ||
| 111 | 1.2.8 or later of the plugins. (Teresa Ramanan) | ||
| 112 | |||
| 113 | check_wave.tar.gz - Perl script to test signal strength on Speedlan wireless | ||
| 114 | equipment (Jeffrey Blank) | ||
| 115 | |||
| 116 | hopcroft-plugins.tar.gz - Various example plugin scripts contributed by Stanley Hopcroft. | ||
| 117 | Includes a plugin to check Internet connectivity by checking various | ||
| 118 | popular search engines, a plugin to check the availability of login | ||
| 119 | to a TN/3270 mainframe database using Expect to search for "usual" | ||
| 120 | screens, and another plugin to test the availability of a database | ||
| 121 | search via the web. | ||
| 122 | (Stanley Hopcroft) | ||
| 123 | |||
| 124 | maser-oracle.tar.gz - This is a modification to the check_oracle plugin script that returns | ||
| 125 | the response time in milliseconds. Requires the Oracle tnsping utility. | ||
| 126 | (Christoph Maser) | ||
| 127 | |||
| 128 | radius.tar.gz - Code modifications necessary to make the radexample app | ||
| 129 | supplied with the radiusclient code work as a RADIUS plugin | ||
| 130 | for Nagios (Nick Shore) | ||
| 131 | |||
| 132 | vincent-check_radius.tar.gz | ||
| 133 | - C program to check RADIUS authentication. Requires the radiusclient | ||
| 134 | library available from ftp://ftp.cityline.net/pub/radiusclient/ | ||
| 135 | (Robert August Vincent II) | ||
| 136 | <MOVED TO CORE> | ||
| 137 | |||
| 138 | weipert-mysql.tar.gz - C program to check a connection to a MySQL database server, with an | ||
| 139 | optional username and password. Requires mysql.h and libmysqlclient | ||
| 140 | to compile (Time Weipert) | ||
| 141 | |||
| 142 | wright-mysql.tar.gz - Perl script to check MySQL database servers. Requires that mysqladmin(1) | ||
| 143 | be installed on the system (included in the MySQL distribution). This | ||
| 144 | plugin can accept warning and critical thresholds for the number of threads | ||
| 145 | in use by the server (Mitch Wright) | ||
| 146 | |||
| 147 | |||
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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | |||
| 3 | eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' | ||
| 4 | if 0; | ||
| 5 | |||
| 6 | # Set this to your local Nagios plugin path | ||
| 7 | my $pluginpath = "/usr/libexec/nagios/plugins/"; | ||
| 8 | |||
| 9 | # Put all the legal commands (i.e. the commands that are | ||
| 10 | # not Nagios checks but are allowed to be executed anyway) | ||
| 11 | # in the following associative array. | ||
| 12 | my %legal_cmds = ("nc" => "/usr/sbin/nc"); | ||
| 13 | |||
| 14 | # This will not work on OpenSSH | ||
| 15 | # It does work on ssh-1.2.27-1i | ||
| 16 | @arg = split ' ',$ENV{'SSH_ORIGINAL_COMMAND'}; | ||
| 17 | |||
| 18 | $arg[0] =~ s/.*\///; # strip leading path | ||
| 19 | $arg[0] =~ tr/-_.a-zA-Z0-9/X/c; # change atypical chars to X | ||
| 20 | |||
| 21 | if (!defined ($cmd = $legal_cmds{$arg[0]})) | ||
| 22 | { | ||
| 23 | $cmd = $pluginpath . $arg[0]; | ||
| 24 | } | ||
| 25 | |||
| 26 | 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 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | # | ||
| 3 | # urlize.pl | ||
| 4 | # jcw, 5/12/00 | ||
| 5 | # | ||
| 6 | # A wrapper around Nagios plugins that provides a URL link in the output | ||
| 7 | # | ||
| 8 | |||
| 9 | ($#ARGV < 1) && die "Incorrect arguments"; | ||
| 10 | my $url = shift; | ||
| 11 | |||
| 12 | chomp ($result = `@ARGV`); | ||
| 13 | print "<A HREF=\"$url\">$result</A>\n"; | ||
| 14 | |||
| 15 | # exit with same exit value as the child produced | ||
| 16 | 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 @@ | |||
| 1 | # | ||
| 2 | # | ||
| 3 | # Util classes for Nagios plugins | ||
| 4 | # | ||
| 5 | # | ||
| 6 | |||
| 7 | |||
| 8 | |||
| 9 | #========================================================================== | ||
| 10 | # | ||
| 11 | # Version: = '$Id$' | ||
| 12 | # | ||
| 13 | # (C) Rob W.W. Hooft, Nonius BV, 1998 | ||
| 14 | # | ||
| 15 | # Contact r.hooft@euromail.net for questions/suggestions. | ||
| 16 | # See: <http://starship.python.net/crew/hooft/> | ||
| 17 | # Distribute freely. | ||
| 18 | # | ||
| 19 | # jaclu@galdrion.com 2000-07-14 | ||
| 20 | # Some changes in error handling of Run() to avoid error garbage | ||
| 21 | # when used from Nagios plugins | ||
| 22 | # I also removed the following functions: AbortableWait() and _buttonkill() | ||
| 23 | # since they are only usable with Tkinter | ||
| 24 | |||
| 25 | import sys,os,signal,time,string | ||
| 26 | |||
| 27 | class error(Exception): | ||
| 28 | pass | ||
| 29 | |||
| 30 | class _ready(Exception): | ||
| 31 | pass | ||
| 32 | |||
| 33 | def which(filename): | ||
| 34 | """Find the file 'filename' in the execution path. If no executable | ||
| 35 | file is found, return None""" | ||
| 36 | for dir in string.split(os.environ['PATH'],os.pathsep): | ||
| 37 | fn=os.path.join(dir,filename) | ||
| 38 | if os.path.exists(fn): | ||
| 39 | if os.stat(fn)[0]&0111: | ||
| 40 | return fn | ||
| 41 | else: | ||
| 42 | return None | ||
| 43 | |||
| 44 | class Task: | ||
| 45 | """Manage asynchronous subprocess tasks. | ||
| 46 | This differs from the 'subproc' package! | ||
| 47 | - 'subproc' connects to the subprocess via pipes | ||
| 48 | - 'task' lets the subprocess run autonomously. | ||
| 49 | After starting the task, we can just: | ||
| 50 | - ask whether it is finished yet | ||
| 51 | - wait until it is finished | ||
| 52 | - perform an 'idle' task (e.g. Tkinter's mainloop) while waiting for | ||
| 53 | subprocess termination | ||
| 54 | - kill the subprocess with a specific signal | ||
| 55 | - ask for the exit code. | ||
| 56 | Summarizing: | ||
| 57 | - 'subproc' is a sophisticated os.popen() | ||
| 58 | - 'task' is a sophisticated os.system() | ||
| 59 | Another difference of task with 'subproc': | ||
| 60 | - If the Task() object is deleted, before the subprocess status | ||
| 61 | was retrieved, the child process will stay. | ||
| 62 | It will never be waited for (i.e., the process will turn into | ||
| 63 | a zombie. Not a good idea in general). | ||
| 64 | |||
| 65 | Public data: | ||
| 66 | None. | ||
| 67 | |||
| 68 | Public methods: | ||
| 69 | __init__, __str__, Run, Wait, Kill, Done, Status. | ||
| 70 | """ | ||
| 71 | def __init__(self,command): | ||
| 72 | """Constructor. | ||
| 73 | arguments: | ||
| 74 | command: the command to run, in the form of a string, | ||
| 75 | or a tuple or list of words. | ||
| 76 | """ | ||
| 77 | if type(command)==type(''): | ||
| 78 | self.cmd=command | ||
| 79 | self.words=string.split(command) | ||
| 80 | elif type(command)==type([]) or type(command)==type(()): | ||
| 81 | # Surround each word by ' '. Limitation: words cannot contain ' chars | ||
| 82 | self.cmd="'"+string.join(command,"' '")+"'" | ||
| 83 | self.words=tuple(command) | ||
| 84 | else: | ||
| 85 | raise error("command must be tuple, list, or string") | ||
| 86 | self.pid=None | ||
| 87 | self.status=None | ||
| 88 | |||
| 89 | def Run(self,usesh=0,detach=0,stdout=None,stdin=None,stderr=None): | ||
| 90 | """Actually run the process. | ||
| 91 | This method should be called exactly once. | ||
| 92 | optional arguments: | ||
| 93 | usesh=0: if 1, run 'sh -c command', if 0, split the | ||
| 94 | command into words, and run it by ourselves. | ||
| 95 | If usesh=1, the 'Kill' method might not do what | ||
| 96 | you want (it will kill the 'sh' process, not the | ||
| 97 | command). | ||
| 98 | detach=0: if 1, run 'sh -c 'command&' (regardless of | ||
| 99 | 'usesh'). Since the 'sh' process will immediately | ||
| 100 | terminate, the task created will be inherited by | ||
| 101 | 'init', so you can safely forget it. Remember that if | ||
| 102 | detach=1, Kill(), Done() and Status() will manipulate | ||
| 103 | the 'sh' process; there is no way to find out about the | ||
| 104 | detached process. | ||
| 105 | stdout=None: filename to use as stdout for the child process. | ||
| 106 | If None, the stdout of the parent will be used. | ||
| 107 | stdin= None: filename to use as stdin for the child process. | ||
| 108 | If None, the stdin of the parent will be used. | ||
| 109 | stderr=None: filename to use as stderr for the child process. | ||
| 110 | If None, the stderr of the parent will be used. | ||
| 111 | return value: | ||
| 112 | None | ||
| 113 | """ | ||
| 114 | if self.pid!=None: | ||
| 115 | raise error("Second run on task forbidden") | ||
| 116 | self.pid=os.fork() | ||
| 117 | if not self.pid: | ||
| 118 | for fn in range(3,256): # Close all non-standard files in a safe way | ||
| 119 | try: | ||
| 120 | os.close(fn) | ||
| 121 | except os.error: | ||
| 122 | pass | ||
| 123 | # | ||
| 124 | # jaclu@galdrion.com 2000-07-14 | ||
| 125 | # | ||
| 126 | # I changed this bit somewhat, since Nagios plugins | ||
| 127 | # should send only limited errors to the caller | ||
| 128 | # The original setup here corupted output when there was an error. | ||
| 129 | # Instead the caller should check result of Wait() and anything | ||
| 130 | # not zero should be reported as a failure. | ||
| 131 | # | ||
| 132 | try: | ||
| 133 | if stdout: # Replace stdout by file | ||
| 134 | os.close(1) | ||
| 135 | i=os.open(stdout,os.O_CREAT|os.O_WRONLY|os.O_TRUNC,0666) | ||
| 136 | if i!=1: | ||
| 137 | sys.stderr.write("stdout not opened on 1!\n") | ||
| 138 | if stdin: # Replace stdin by file | ||
| 139 | os.close(0) | ||
| 140 | i=os.open(stdin,os.O_RDONLY) | ||
| 141 | if i!=0: | ||
| 142 | sys.stderr.write("stdin not opened on 0!\n") | ||
| 143 | if stderr: # Replace stderr by file | ||
| 144 | os.close(2) | ||
| 145 | i=os.open(stderr,os.O_CREAT|os.O_WRONLY|os.O_TRUNC,0666) | ||
| 146 | if i!=2: | ||
| 147 | sys.stdout.write("stderr not opened on 2!\n") | ||
| 148 | #try: | ||
| 149 | if detach: | ||
| 150 | os.execv('/bin/sh',('sh','-c',self.cmd+'&')) | ||
| 151 | elif usesh: | ||
| 152 | os.execv('/bin/sh',('sh','-c',self.cmd)) | ||
| 153 | else: | ||
| 154 | os.execvp(self.words[0],self.words) | ||
| 155 | except: | ||
| 156 | #print self.words | ||
| 157 | #sys.stderr.write("Subprocess '%s' execution failed!\n"%self.cmd) | ||
| 158 | sys.exit(1) | ||
| 159 | else: | ||
| 160 | # Mother process | ||
| 161 | if detach: | ||
| 162 | # Should complete "immediately" | ||
| 163 | self.Wait() | ||
| 164 | |||
| 165 | def Wait(self,idlefunc=None,interval=0.1): | ||
| 166 | """Wait for the subprocess to terminate. | ||
| 167 | If the process has already terminated, this function will return | ||
| 168 | immediately without raising an error. | ||
| 169 | optional arguments: | ||
| 170 | idlefunc=None: a callable object (function, class, bound method) | ||
| 171 | that will be called every 0.1 second (or see | ||
| 172 | the 'interval' variable) while waiting for | ||
| 173 | the subprocess to terminate. This can be the | ||
| 174 | Tkinter 'update' procedure, such that the GUI | ||
| 175 | doesn't die during the run. If this is set to | ||
| 176 | 'None', the process will really wait. idlefunc | ||
| 177 | should ideally not take a very long time to | ||
| 178 | complete... | ||
| 179 | interval=0.1: The interval (in seconds) with which the 'idlefunc' | ||
| 180 | (if any) will be called. | ||
| 181 | return value: | ||
| 182 | the exit status of the subprocess (0 if successful). | ||
| 183 | """ | ||
| 184 | if self.status!=None: | ||
| 185 | # Already finished | ||
| 186 | return self.status | ||
| 187 | if callable(idlefunc): | ||
| 188 | while 1: | ||
| 189 | try: | ||
| 190 | pid,status=os.waitpid(self.pid,os.WNOHANG) | ||
| 191 | if pid==self.pid: | ||
| 192 | self.status=status | ||
| 193 | return status | ||
| 194 | else: | ||
| 195 | idlefunc() | ||
| 196 | time.sleep(interval) | ||
| 197 | except KeyboardInterrupt: | ||
| 198 | # Send the interrupt to the inferior process. | ||
| 199 | self.Kill(signal=signal.SIGINT) | ||
| 200 | elif idlefunc: | ||
| 201 | raise error("Non-callable idle function") | ||
| 202 | else: | ||
| 203 | while 1: | ||
| 204 | try: | ||
| 205 | pid,status=os.waitpid(self.pid,0) | ||
| 206 | self.status=status | ||
| 207 | return status | ||
| 208 | except KeyboardInterrupt: | ||
| 209 | # Send the interrupt to the inferior process. | ||
| 210 | self.Kill(signal=signal.SIGINT) | ||
| 211 | |||
| 212 | def Kill(self,signal=signal.SIGTERM): | ||
| 213 | """Send a signal to the running subprocess. | ||
| 214 | optional arguments: | ||
| 215 | signal=SIGTERM: number of the signal to send. | ||
| 216 | (see os.kill) | ||
| 217 | return value: | ||
| 218 | see os.kill() | ||
| 219 | """ | ||
| 220 | if self.status==None: | ||
| 221 | # Only if it is not already finished | ||
| 222 | return os.kill(self.pid,signal) | ||
| 223 | |||
| 224 | def Done(self): | ||
| 225 | """Ask whether the process has already finished. | ||
| 226 | return value: | ||
| 227 | 1: yes, the process has finished. | ||
| 228 | 0: no, the process has not finished yet. | ||
| 229 | """ | ||
| 230 | if self.status!=None: | ||
| 231 | return 1 | ||
| 232 | else: | ||
| 233 | pid,status=os.waitpid(self.pid,os.WNOHANG) | ||
| 234 | if pid==self.pid: | ||
| 235 | #print "OK:",pid,status | ||
| 236 | self.status=status | ||
| 237 | return 1 | ||
| 238 | else: | ||
| 239 | #print "NOK:",pid,status | ||
| 240 | return 0 | ||
| 241 | |||
| 242 | def Status(self): | ||
| 243 | """Ask for the status of the task. | ||
| 244 | return value: | ||
| 245 | None: process has not finished yet (maybe not even started). | ||
| 246 | any integer: process exit status. | ||
| 247 | """ | ||
| 248 | self.Done() | ||
| 249 | return self.status | ||
| 250 | |||
| 251 | def __str__(self): | ||
| 252 | if self.pid!=None: | ||
| 253 | if self.status!=None: | ||
| 254 | s2="done, exit status=%d"%self.status | ||
| 255 | else: | ||
| 256 | s2="running" | ||
| 257 | else: | ||
| 258 | s2="prepared" | ||
| 259 | return "<%s: '%s', %s>"%(self.__class__.__name__,self.cmd,s2) | ||
| 260 | |||
| 261 | |||
| 262 | #========================================================================== | ||
| 263 | # | ||
| 264 | # | ||
| 265 | # Class: TimeoutHandler | ||
| 266 | # License: GPL | ||
| 267 | # Copyright (c) 2000 Jacob Lundqvist (jaclu@galdrion.com) | ||
| 268 | # | ||
| 269 | # Version: 1.0 2000-07-14 | ||
| 270 | # | ||
| 271 | # Description: | ||
| 272 | # On init, suply a call-back kill_func that should be called on timeout | ||
| 273 | # | ||
| 274 | # Make sure that what ever you are doing is calling Check periodically | ||
| 275 | # | ||
| 276 | # To check if timeout was triggered call WasTimeOut returns (true/false) | ||
| 277 | # | ||
| 278 | |||
| 279 | import time,sys | ||
| 280 | |||
| 281 | class TimeoutHandler: | ||
| 282 | def __init__(self,kill_func,time_to_live=10,debug=0): | ||
| 283 | 'Generic time-out handler.' | ||
| 284 | self.kill_func=kill_func | ||
| 285 | self.start_time=time.time() | ||
| 286 | self.stop_time=+self.start_time+int(time_to_live) | ||
| 287 | self.debug=debug | ||
| 288 | self.aborted=0 | ||
| 289 | |||
| 290 | def Check(self): | ||
| 291 | 'Call this periodically to check for time-out.' | ||
| 292 | if self.debug: | ||
| 293 | sys.stdout.write('.') | ||
| 294 | sys.stdout.flush() | ||
| 295 | if time.time()>=self.stop_time: | ||
| 296 | self.TimeOut() | ||
| 297 | |||
| 298 | def TimeOut(self): | ||
| 299 | 'Trigger the time-out callback.' | ||
| 300 | self.aborted=1 | ||
| 301 | if self.debug: | ||
| 302 | print 'Timeout, aborting' | ||
| 303 | self.kill_func() | ||
| 304 | |||
| 305 | def WasTimeOut(self): | ||
| 306 | 'Indicates if timeout was triggered 1=yes, 0=no.' | ||
| 307 | if self.debug: | ||
| 308 | print '' | ||
| 309 | print 'call duration: %.2f seconds' % (time.time()-self.start_time) | ||
| 310 | return self.aborted | ||
