diff options
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 | ||