aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Stanley Hopcroft <stanleyhopcroft@users.sourceforge.net> 2005-01-27 04:46:08 +0000
committerGravatar Stanley Hopcroft <stanleyhopcroft@users.sourceforge.net> 2005-01-27 04:46:08 +0000
commitfce1f09f770fc5bbc6d323865af709ff515c803c (patch)
tree1e997a0bc1ace6217cc0dab87b65de52bca8be20
parentccf789e017547e1f71b5945b2e1d85ce5b9cb8e4 (diff)
downloadmonitoring-plugins-fce1f09f770fc5bbc6d323865af709ff515c803c.tar.gz
New /contrib plugin
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1112 f882894a-f735-0410-b71e-b25c423dba1c
-rw-r--r--contrib/check_arping.pl120
-rw-r--r--contrib/check_cpqarray.c430
-rw-r--r--contrib/check_frontpage151
-rw-r--r--contrib/check_logins.c351
-rw-r--r--contrib/check_oracle_tbs206
-rw-r--r--contrib/check_pcpmetric.py106
-rw-r--r--contrib/check_pfstate75
7 files changed, 1439 insertions, 0 deletions
diff --git a/contrib/check_arping.pl b/contrib/check_arping.pl
new file mode 100644
index 00000000..b78ec68f
--- /dev/null
+++ b/contrib/check_arping.pl
@@ -0,0 +1,120 @@
+#! /usr/bin/perl -w
+#
+# check_arping.pl - Nagios plugin to check host status via ARP ping
+#
+# usage:
+# check_arping -H hostname -I interface -T timeout
+#
+#
+# Copyright (C) 2003 Kenny Root
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#
+# Report bugs to: kenny@the-b.org, nagiosplug-help@lists.sf.net
+
+use POSIX;
+use strict;
+use lib "/usr/lib/nagios/plugins" ;
+use utils qw($TIMEOUT %ERRORS &print_revision &support);
+
+use Net::Arping;
+use Getopt::Long;
+
+my $PROGNAME = "check_arping";
+
+my($status, $state, $answer);
+my($opt_V, $opt_h, $opt_t, $opt_I, $opt_H);
+
+
+#Option checking
+$status = GetOptions(
+ "V|version" => \$opt_V,
+ "help" => \$opt_h,
+ "I|interface=s" => \$opt_I,
+ "H|host=s" => \$opt_H,
+ "t|timeout=i" => \$opt_t);
+
+if ($status == 0)
+{
+ print_help() ;
+ exit $ERRORS{'OK'};
+}
+
+
+if ($opt_V) {
+ print_revision($PROGNAME,'$Revision$ ');
+ exit $ERRORS{'OK'};
+}
+
+if ($opt_h) {
+ print_help();
+ exit $ERRORS{'OK'};
+}
+
+if ($opt_t) {
+ if ($opt_t ne int($opt_t)) {
+ print "Timeout not in seconds!\n";
+ print_help();
+ exit $ERRORS{'OK'};
+ }
+ $opt_t = int($opt_t);
+} else {
+ $opt_t = 3;
+}
+
+if (! utils::is_hostname($opt_H)){
+ usage();
+ exit $ERRORS{"UNKNOWN"};
+}
+
+my $ping = Net::Arping->new();
+
+my $reply = $ping->arping(Host => $opt_H, Interface => $opt_I, Timeout => $opt_t);
+
+if ($reply eq "0") {
+ $state = "CRITICAL";
+ print "$state: no reply from $opt_H on interface $opt_I in $opt_t seconds.\n";
+ exit $ERRORS{$state};
+} else {
+ $state = "OK";
+ $answer = "replied with MAC address $reply";
+}
+
+print "ARPING $state - $answer\n";
+exit $ERRORS{$state};
+
+
+sub usage {
+ print "\nMissing arguments!\n";
+ print "\n";
+ print "check_arping -I <interface> -H <host IP> [-t <timeout>]\n";
+ print "\n\n";
+ support();
+ exit $ERRORS{"UNKNOWN"};
+}
+
+sub print_help {
+ print "check_arping pings hosts that normally wouldn't allow\n";
+ print "ICMP packets but are still on the local network.\n";
+ print "\nUsage:\n";
+ print " -H (--host) IP to query - (required)\n";
+ print " -I (--interface) Interface to use.\n";
+ print " -t (--timeout) Timeout in seconds.\n";
+ print " -V (--version) Plugin version\n";
+ print " -h (--help) usage help \n\n";
+ print_revision($PROGNAME, '$Revision$');
+
+}
diff --git a/contrib/check_cpqarray.c b/contrib/check_cpqarray.c
new file mode 100644
index 00000000..badffeb4
--- /dev/null
+++ b/contrib/check_cpqarray.c
@@ -0,0 +1,430 @@
+/*
+ check_cpqarray, an extension for Netsaint / Nagios to check the
+ status of a Compaq SmartArray controller from the commandline.
+ Copyright (C) 2003 Guenther Mair
+
+ based on the work and using main parts of
+
+ CpqArray Deamon, a program to monitor and remotely configure a
+ SmartArray controller.
+ Copyright (C) 1999 Hugo Trippaers
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/utsname.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#include "/usr/src/linux/drivers/block/ida_ioctl.h"
+#include "/usr/src/linux/drivers/block/ida_cmd.h"
+#include "/usr/src/linux/drivers/block/cpqarray.h"
+
+
+const char *controllers[] =
+{
+ "/dev/ida/c0d0",
+ "/dev/ida/c1d0",
+ "/dev/ida/c2d0",
+ "/dev/ida/c3d0",
+ "/dev/ida/c4d0",
+ "/dev/ida/c5d0",
+ "/dev/ida/c6d0",
+ "/dev/ida/c7d0"
+};
+
+const char *statusstr[] = {
+ "Logical drive /dev/ida/c%dd%d: OK\n",
+ "Logical drive /dev/ida/c%dd%d: FAILED\n",
+ "Logical drive /dev/ida/c%dd%d: not configured.\n",
+ "Logical drive /dev/ida/c%dd%d: using interim recovery mode, %3.2f%% done.\n",
+ "Logical drive /dev/ida/c%dd%d: ready for recovery operation.\n",
+ "Logical drive /dev/ida/c%dd%d: is currently recovering, %3.2f%% done.\n",
+ "Wrong physical drive was replaced.\n",
+ "A physical drive is not properly connected.\n",
+ "Hardware is overheating.\n",
+ "Hardware has overheated.\n",
+ "Logical drive /dev/ida/c%dd%d: currently expanding, %3.2f%% done.\n",
+ "Logical drive /dev/ida/c%dd%d: not yet available.\n",
+ "Logical drive /dev/ida/c%dd%d: queued for expansion.\n",
+};
+
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+int ctrls_found_num;
+int exit_code = 0;
+struct controller ctrls_found[8];
+
+#define DEBUG(x) fprintf(stderr, x)
+
+struct opts
+{
+ char debug;
+};
+
+struct slog_disk
+{
+ int status;
+ float pvalue;
+};
+
+struct controller
+{
+ char ctrl_devicename[20];
+ int num_logd_found;
+ struct slog_disk log_disk[16];
+};
+
+
+
+int status_check (struct opts opts)
+{
+ int devicefd;
+ int ctrl_cntr;
+ int logd_cntr;
+ ida_ioctl_t io, io2;
+ int status, nr_blks, blks_tr;
+ float pvalue;
+ int counter;
+
+ for ( ctrl_cntr=0;
+ ctrl_cntr < ctrls_found_num;
+ ctrl_cntr++) {
+
+ devicefd = open (controllers[ctrl_cntr], O_RDONLY);
+
+ for ( logd_cntr=0;
+ logd_cntr < ctrls_found[ctrl_cntr].num_logd_found;
+ logd_cntr++) {
+
+ memset (&io, 0, sizeof (io));
+
+ io.cmd = SENSE_LOG_DRV_STAT;
+ io.unit = logd_cntr | UNITVALID;
+
+ if (ioctl (devicefd, IDAPASSTHRU, &io) < 0)
+ {
+ perror ("SENSE_LOG_DRV_STAT ioctl");
+ return 0;
+ }
+
+ status=io.c.sense_log_drv_stat.status;
+
+ if ((status == 3) || (status == 5) || (status == 7)) {
+ /* is a progress indicator required?
+ */
+ memset (&io2, 0, sizeof (io));
+
+ io2.cmd = ID_LOG_DRV;
+ io2.unit = logd_cntr | UNITVALID;
+
+ if (ioctl (devicefd, IDAPASSTHRU, &io2) < 0)
+ {
+ perror ("ID_LOG_DRV ioctl");
+ /* return 0; no return this isn't fatal for now */
+ }
+ else
+ {
+ nr_blks = io2.c.id_log_drv.nr_blks;
+ blks_tr = io.c.sense_log_drv_stat.blks_to_recover;
+
+ pvalue = ((float)(nr_blks - blks_tr)/(float)nr_blks) * 100;
+ }
+ }
+ else {
+ pvalue = 0.0;
+ }
+
+ if (opts.debug) {
+ fprintf(stdout, "DEBUG: Status of controller %d unit %d is %d\n",
+ ctrl_cntr, logd_cntr, status);
+ fprintf(stdout, "DEBUG: ");
+ fprintf(stdout, statusstr[status],
+ ctrl_cntr, logd_cntr, pvalue);
+ fprintf(stdout, "\n");
+ }
+
+ printf(statusstr[status], ctrl_cntr, logd_cntr, pvalue);
+
+ switch(status)
+ {
+ case 1:
+ case 2:
+ case 6:
+ case 7:
+ case 9:
+ /* CRITICAL */
+ exit_code = 2;
+ break;
+ case 3:
+ case 4:
+ case 5:
+ case 8:
+ case 10:
+ case 11:
+ case 12:
+ /* WARNING (only if not yet at CRITICAL LEVEL) */
+ if (exit_code < 2) exit_code = 1;
+ break;
+ case 0:
+ default:
+ /* do nothing */
+ break;
+ }
+
+ ctrls_found[ctrl_cntr].log_disk[logd_cntr].pvalue = pvalue;
+ ctrls_found[ctrl_cntr].log_disk[logd_cntr].status = status;
+ }
+ close (devicefd);
+ }
+
+ return 1;
+}
+
+int discover_controllers (struct opts opts)
+{
+ int cntr;
+ int foundone = 0;
+
+ for (cntr = 0; cntr < 8; cntr++)
+ {
+ /* does this device exist ? */
+ if ((access (controllers[cntr], R_OK | F_OK)) == 0)
+ {
+ /* it does :) */
+ if (interrogate_controller (opts, cntr))
+ {
+ foundone = 1;
+ if (opts.debug)
+ fprintf (stderr, "DEBUG: %s is a existing controller\n",
+ controllers[cntr]);
+ }
+ }
+ else if (opts.debug)
+ {
+ fprintf (stderr, "DEBUG: Device %s could not be opened\n", controllers[cntr]);
+ perror ("DEBUG: reason");
+ }
+ }
+ return foundone;
+}
+
+void boardid2str (unsigned long board_id, char *name)
+{
+ switch (board_id)
+ {
+ case 0x0040110E: /* IDA */
+ strcpy (name, "Compaq IDA");
+ break;
+ case 0x0140110E: /* IDA-2 */
+ strcpy (name, "Compaq IDA-2");
+ break;
+ case 0x1040110E: /* IAES */
+ strcpy (name, "Compaq IAES");
+ break;
+ case 0x2040110E: /* SMART */
+ strcpy (name, "Compaq SMART");
+ break;
+ case 0x3040110E: /* SMART-2/E */
+ strcpy (name, "Compaq SMART-2/E");
+ break;
+ case 0x40300E11: /* SMART-2/P or SMART-2DH */
+ strcpy (name, "Compaq SMART-2/P (2DH)");
+ break;
+ case 0x40310E11: /* SMART-2SL */
+ strcpy (name, "Compaq SMART-2SL");
+ break;
+ case 0x40320E11: /* SMART-3200 */
+ strcpy (name, "Compaq SMART-3200");
+ break;
+ case 0x40330E11: /* SMART-3100ES */
+ strcpy (name, "Compaq SMART-3100ES");
+ break;
+ case 0x40340E11: /* SMART-221 */
+ strcpy (name, "Compaq SMART-221");
+ break;
+ case 0x40400E11: /* Integrated Array */
+ strcpy (name, "Compaq Integrated Array");
+ break;
+ case 0x40500E11: /* Smart Array 4200 */
+ strcpy (name, "Compaq Smart Array 4200");
+ break;
+ case 0x40510E11: /* Smart Array 4250ES */
+ strcpy (name, "Compaq Smart Array 4250ES");
+ break;
+ case 0x40580E11: /* Smart Array 431 */
+ strcpy (name, "Compaq Smart Array 431");
+ break;
+ default:
+ /*
+ * Well, its a SMART-2 or better, don't know which
+ * kind.
+ */
+ strcpy (name, "Unknown Controller Type");
+ }
+}
+
+int interrogate_controller (struct opts opts, int contrnum)
+{
+ int devicefd;
+ ida_ioctl_t io;
+ char buffer[30];
+ int foundone = 0;
+ int cntr;
+
+ devicefd = open (controllers[contrnum], O_RDONLY);
+ /* no checks, did that before */
+
+ /* clear io */
+ memset (&io, 0, sizeof (io));
+
+ io.cmd = ID_CTLR;
+
+ if (ioctl (devicefd, IDAPASSTHRU, &io) < 0)
+ {
+ if (opts.debug) perror ("DEBUG: ioctl");
+ return 0;
+ }
+
+ boardid2str (io.c.id_ctlr.board_id, buffer);
+
+ strncpy (ctrls_found[ctrls_found_num].ctrl_devicename,
+ buffer, 20);
+
+ ctrls_found[ctrls_found_num].num_logd_found = 0;
+
+ for (cntr = 0; cntr < io.c.id_ctlr.nr_drvs; cntr++)
+ {
+ if (interrogate_logical (opts, devicefd, cntr))
+ {
+ /* logical drive found, this could be used later one */
+ foundone = 1;
+ }
+ }
+
+ switch (ctrls_found[ctrls_found_num].num_logd_found)
+ {
+ case 0:
+ printf("Found a %s with no logical drives.\n", buffer);
+ break;
+ case 1:
+ printf("Found a %s with one Logical drive.\n", buffer,
+ ctrls_found[ctrls_found_num].num_logd_found);
+ break;
+ default:
+ printf("Found a %s with %d Logical drives.\n", buffer,
+ ctrls_found[ctrls_found_num].num_logd_found);
+ break;
+ }
+
+ ctrls_found_num++;
+
+ close (devicefd);
+ return 1;
+}
+
+int interrogate_logical (struct opts opts, int devicefd, int unit_nr)
+{
+ ida_ioctl_t io;
+ ida_ioctl_t io2;
+ int nr_blks, blks_tr;
+
+ if (opts.debug) printf ("DEBUG: interrogating unit %d\n", unit_nr);
+
+ memset (&io, 0, sizeof (io));
+
+ io.cmd = ID_LOG_DRV;
+ io.unit = unit_nr | UNITVALID;
+
+ if (ioctl (devicefd, IDAPASSTHRU, &io) < 0)
+ {
+ perror ("FATAL: ID_LOG_DRV ioctl");
+ return 0;
+ }
+
+ memset (&io2, 0, sizeof (io2));
+
+ io2.cmd = SENSE_LOG_DRV_STAT;
+ io2.unit = unit_nr | UNITVALID;
+
+ if (ioctl (devicefd, IDAPASSTHRU, &io2) < 0)
+ {
+ perror ("FATAL: SENSE_LOG_DRV_STAT ioctl");
+ return 0;
+ }
+
+ ctrls_found[ctrls_found_num].num_logd_found++;
+ /* ctrls_found[ctrls_found_num].log_disk[unit_nr].status =
+ * io2.c.sense_log_drv_stat.status;
+
+ * nr_blks = io2.c.id_log_drv.nr_blks;
+ * blks_tr = io.c.sense_log_drv_stat.blks_to_recover;
+ * ctrls_found[ctrls_found_num].log_disk[unit_nr].pvalue =
+ * ((float)(nr_blks - blks_tr)/(float)nr_blks) * 100;
+ */
+ ctrls_found[ctrls_found_num].log_disk[unit_nr].status = 0;
+ ctrls_found[ctrls_found_num].log_disk[unit_nr].pvalue = 0;
+
+ return 1;
+}
+
+
+void print_usage()
+{
+ printf("cpqarrayd [options]\n");
+ printf(" -h prints this text\n");
+ printf(" -d enables debugging\n");
+}
+
+
+int main(int argc, char *argv[])
+{
+ char option;
+ struct opts opts; /* commandline options */
+
+ memset(&opts, 0, sizeof(struct opts));
+
+ /* check options */
+ while ((option = getopt (argc, argv, "dh:")) != EOF)
+ {
+ switch (option)
+ {
+ case 'd':
+ opts.debug = 1;
+ break;
+ case '?':
+ case 'h':
+ default:
+ print_usage();
+ exit(0);
+ break;
+ }
+ }
+
+ /* Check for existance of array controllers */
+ if (!discover_controllers(opts)) {
+ printf("No array controller found!\n\n");
+ exit(1);
+ }
+
+ status_check(opts);
+
+ return exit_code;
+}
diff --git a/contrib/check_frontpage b/contrib/check_frontpage
new file mode 100644
index 00000000..ee958d30
--- /dev/null
+++ b/contrib/check_frontpage
@@ -0,0 +1,151 @@
+#! /usr/bin/perl -w
+#
+# $Id$
+#
+# Check that FrontPage extensions appear to be working on a specified host.
+# Currently only checks that the hit counter is not returning an error.
+#
+# Probably not a good idea to use this on a host that someone's counting
+# the hits on, so create a separate vhost for frontpage extensions testing,
+# or just install the extensions on the default/root host for your server, and
+# point it against that hostname, running it against all vhosts on a server is
+# probably rather wasteful.
+#
+# Kev Green, oRe Net (http://www.orenet.co.uk/).
+
+
+use strict;
+use lib "/usr/lib/nagios/plugins";
+use utils qw($TIMEOUT %ERRORS &print_revision &support);
+use vars qw($PROGNAME);
+use Getopt::Long;
+use LWP;
+use vars qw($opt_V $opt_h $verbose $opt_w $opt_c $opt_H);
+my ($tt,$url,$response,$stime, $etime,$warning,$critical,$mimetype,$failtype,$temp,$message);
+my $rt = 0;
+
+$PROGNAME = "check_frontpage";
+sub print_help ();
+sub print_usage ();
+
+$ENV{'PATH'}='';
+$ENV{'BASH_ENV'}='';
+$ENV{'ENV'}='';
+
+Getopt::Long::Configure('bundling');
+GetOptions
+ ("V" => \$opt_V, "version" => \$opt_V,
+ "h" => \$opt_h, "help" => \$opt_h,
+ "v" => \$verbose, "verbose" => \$verbose,
+ "w=s" => \$opt_w, "warning=s" => \$opt_w,
+ "c=s" => \$opt_c, "critical=s" => \$opt_c,
+ "H=s" => \$opt_H, "hostname=s" => \$opt_H);
+
+if ($opt_V) {
+ print_revision($PROGNAME,'$Revision$'); #'
+ exit $ERRORS{'OK'};
+}
+
+if ($opt_h) {
+ print_help();
+ exit $ERRORS{'OK'};
+}
+
+$opt_H = shift unless ($opt_H);
+print_usage() unless $opt_H;
+my $host = $1 if ($opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0-9]+(\.[a-zA-Z0-9][-a-zA-Z0-9]+)*)$/);
+print_usage() unless $host;
+
+($opt_c) || ($opt_c = shift) || ($opt_c = 120);
+if ($opt_c =~ /([0-9]+)/) {
+ $critical = $1;
+} else {
+ $critical = 10;
+}
+
+($opt_w) || ($opt_w = shift) || ($opt_w = 60);
+if ($opt_w =~ /([0-9]+)/) {
+ $warning = $1;
+} else {
+ $warning = 5;
+}
+
+# Guts go here, once we're through argument parsing and have warning and
+# critical thresholds.
+my $browser = LWP::UserAgent->new;
+
+my @urls = (
+ # This is the "Hit Counter", which continues to work if frontpage extensions
+ # are 'uninstall'ed from the site, but not when they are 'fulluninstall'ed.
+ {
+ url => "_vti_bin/fpcount.exe?Page=_borders/right.htm|Image=4",
+ mimetype => "image/gif",
+ message => "None, or broken frontpage extensions on server, or virtual site 'fulluninstall'ed?",
+ failtype => "CRITICAL"
+ },
+ # This is the "FrontPage Configuration Information" file, which is removed
+ # when you 'uninstall' the extensions from a site.
+ {
+ url => "_vti_inf.html",
+ mimetype => "text/html",
+ message => "Someone 'uninstall'ed extensions on virtual site?",
+ failtype => "WARNING"
+ }
+);
+
+print "FRONTPAGE: ";
+
+foreach $temp (@urls) {
+ $url = $temp->{'url'};
+ $mimetype = $temp->{'mimetype'};
+ $failtype = $temp->{'failtype'};
+ $message = $temp->{'message'};
+ $stime = time();
+ $response=$browser->get("http://".$host."/".$url);
+ $etime = time();
+ $tt = $etime - $stime;
+
+# If we got a server error, or unknown output type, report back as critical.
+ if ($response->status_line !~ "^200") {
+ print $message." (".$response->status_line.")\r\n";
+ exit $ERRORS{$failtype};
+ } elsif ($response->content_type !~ $mimetype) {
+ print $message." (Wrong Content-type: ".$response->content_type.")\r\n";
+ exit $ERRORS{$failtype};
+ } else {
+ # Because we're dealing with multiple URL's
+ $rt += $tt;
+ }
+
+# Decide if the response time was critical or not.
+#
+ if ($rt > $critical) {
+ print "Response time ".$rt." over critical threshold ".$critical."\r\n";
+ exit($ERRORS{'CRITICAL'});
+ } elsif ($rt > $warning) {
+ print "Response time ".$rt." over warning threshold ".$warning."\r\n";
+ exit($ERRORS{'WARNING'});
+ }
+}
+printf(" %s - %s second response time, ",$response->status_line, $rt);
+
+# If all the required URL's give the right responses quick enough, then we
+# should be okay.
+exit($ERRORS{'OK'});
+
+sub print_usage () {
+ print "Usage: $PROGNAME -H <host> [-w <warn>] [-c <crit>]\n";
+ exit;
+}
+
+sub print_help () {
+ print_revision($PROGNAME,'$Revision$');
+ print "Copyright (c) 2003 Kev Green\n";
+ print "\n";
+ print "FrontPage remains a copyright/trademark of Microsoft Corporation.\n";
+ print_usage();
+ print "\n";
+ print "<warn> = Unknown.\n";
+ print "<crit> = Server error from FrontPage extensions.\n\n";
+ support();
+}
diff --git a/contrib/check_logins.c b/contrib/check_logins.c
new file mode 100644
index 00000000..fa3ed177
--- /dev/null
+++ b/contrib/check_logins.c
@@ -0,0 +1,351 @@
+/*=================================
+ * check_logins - Nagios plugin
+ * Copyright (C) 2003 Dag Robøle
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors email: drobole@broadpark.no
+ */
+//=================================
+#include <sys/types.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "config.h"
+#include "common.h"
+#include "utils.h"
+#include "popen.h"
+//=================================
+#define REVISION "$Revision$"
+#define COPYRIGHT "2003"
+#define AUTHOR "Dag Robole"
+#define EMAIL "drobole@broadpark.no"
+#define SUMMARY "Check for multiple user logins"
+
+#define check(func, errmsg) { if((func) == -1) die(STATE_UNKNOWN, errmsg); }
+#define checkz(func, errmsg) { if(!(func)) die(STATE_UNKNOWN, errmsg); }
+//=================================
+typedef struct USERNODE_TYP {
+ char *name;
+ char *host;
+ struct USERNODE_TYP* next;
+} USERNODE;
+//=================================
+char *progname = NULL;
+USERNODE *userlist = NULL, *adminlist = NULL;
+int warning_limit = 0, critical_limit = 0;
+
+void print_usage();
+void print_help();
+void process_arguments(int argc, char* *argv);
+void parse_wholine(const char *line, char *name, char *host);
+void node_create(USERNODE* *node, const char *name, const char *host);
+void node_free(USERNODE* *node);
+USERNODE* list_insert_sort_uniq(USERNODE* *list, USERNODE* *node);
+void list_free(USERNODE* *list);
+void cleanup();
+//=================================
+int main(int argc, char* *argv)
+{
+ FILE *who;
+ USERNODE *newnode, *nptra, *nptrb;
+ char buffer[BUFSIZ], username[BUFSIZ], hostname[BUFSIZ], *cptra, *cptrb;
+ char max_login_name[BUFSIZ], currname[BUFSIZ];
+ int max_login_count = 0, counter = 0, skip;
+ void (*old_sig_alrm)();
+
+ progname = argv[0];
+ if(atexit(cleanup))
+ die(STATE_UNKNOWN, "atexit failed\n");
+
+ if((old_sig_alrm = signal((int)SIGALRM, timeout_alarm_handler)) == SIG_ERR)
+ die(STATE_UNKNOWN, "signal failed\n");
+ alarm(timeout_interval);
+
+ process_arguments(argc, argv);
+
+ checkz(who = spopen(PATH_TO_WHO), "spopen failed\n");
+
+ while(fgets(buffer, sizeof(buffer), who) != NULL) {
+ parse_wholine(buffer, username, hostname);
+ skip = 0;
+ nptra = adminlist;
+
+ while(nptra != NULL) {
+ if(!strcmp(nptra->name, username)) {
+ skip = 1;
+ break;
+ }
+ nptra = nptra->next;
+ }
+ if(!skip) {
+ node_create(&newnode, username, hostname);
+ if(!list_insert_sort_uniq(&userlist, &newnode))
+ node_free(&newnode);
+ }
+ }
+
+ check(spclose(who), "spclose failed\n");
+
+ if(userlist != NULL) {
+ nptra = userlist;
+ strcpy(currname, nptra->name);
+ strcpy(max_login_name, nptra->name);
+ max_login_count = 1;
+ while(nptra != NULL) {
+ if(!strcmp(currname, nptra->name))
+ ++counter;
+ else {
+ if(counter > max_login_count) {
+ max_login_count = counter;
+ strcpy(max_login_name, currname);
+ }
+ strcpy(currname, nptra->name);
+ counter = 1;
+ }
+ nptra = nptra->next;
+ }
+
+ if(counter > max_login_count) {
+ max_login_count = counter;
+ strcpy(max_login_name, currname);
+ }
+ }
+
+ if(signal((int)SIGALRM, old_sig_alrm) == SIG_ERR)
+ die(STATE_UNKNOWN, "signal failed\n");
+
+ if(max_login_count) {
+ if(critical_limit && max_login_count >= critical_limit) {
+ printf("CRITICAL - User %s has logged in from %d different hosts\n", max_login_name, max_login_count);
+ return STATE_CRITICAL;
+ }
+ else if(warning_limit && max_login_count >= warning_limit) {
+ printf("WARNING - User %s has logged in from %d different hosts\n", max_login_name, max_login_count);
+ return STATE_WARNING;
+ }
+ }
+
+ printf("OK - No users has exceeded the login limits\n");
+ return STATE_OK;
+}
+//=================================
+void print_usage()
+{
+ fprintf(stderr, "Usage: %s [ -hV ] [ -w limit ] [ -c limit ] [ -u username1, ... ,usernameN ]\n", progname);
+}
+//=================================
+void print_help()
+{
+ print_revision(progname, REVISION);
+ printf("Copyright (c) %s %s <%s>\n\n%s\n\n", COPYRIGHT, AUTHOR, EMAIL, SUMMARY);
+ print_usage();
+ printf("\nDescription:\n"
+ "\tThis plugin supports the w (warning) and c (critical) options indicating the upper limits\n"
+ "\tof logins allowed before a warning is given.\n"
+ "\tThe output from %s is the username and number of login sessions for the user\n"
+ "\twho has the most login sessions (from different hosts) running at a given point in time.\n"
+ "\tThe u (users) option takes a comma separated list of usernames that will be ignored\n"
+ "\twhile scannig users.\n"
+ "\nOptions:\n"
+ "\t-h | --help\n\t\tShow this help message and exit\n"
+ "\t-V | --version\n\t\tShow version description\n"
+ "\t-w | --warning=INTEGER\n\t\tSet warning limit for logins (minimum value is 2)\n"
+ "\t-c | --critical=INTEGER\n\t\tSet critical limit for logins (minimum value is 2)\n"
+ "\t-u | --users=STRING\n\t\tSet usernames to be ignored\n"
+ "\nExamples:\n\t%s -w 3 -c 5\n"
+ "\t%s -w 3 -c 5 -u root,guest,jcarmack\n\n", progname, progname, progname);
+}
+//=================================
+void process_arguments(int argc, char* *argv)
+{
+ USERNODE *newnode;
+ int optch;
+ char buffer[BUFSIZ], *cptra;
+ static struct option long_opts[] = {
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'V'},
+ {"warning", required_argument, 0, 'w'},
+ {"critical", required_argument, 0, 'c'},
+ {"users", required_argument, 0, 'u'},
+ {0, 0, 0, 0},
+ };
+
+ while((optch = getopt_long(argc, argv, "hVw:c:u:", long_opts, NULL)) != -1) {
+ switch(optch) {
+ case 'h':
+ print_help();
+ exit(STATE_OK);
+ break;
+ case 'V':
+ print_revision(progname, REVISION);
+ exit(STATE_OK);
+ break;
+ case 'w':
+ if(!is_numeric(optarg)) {
+ print_usage();
+ die(STATE_UNKNOWN, "invalid options\n");
+ }
+ warning_limit = atoi(optarg) > 2 ? atoi(optarg) : 2;
+ break;
+ case 'c':
+ if(!is_numeric(optarg)) {
+ print_usage();
+ die(STATE_UNKNOWN, "invalid options\n");
+ }
+ critical_limit = atoi(optarg) > 2 ? atoi(optarg) : 2;
+ break;
+ case 'u':
+ strcpy(buffer, optarg);
+ cptra = strtok(buffer, ",");
+ while(cptra != NULL) {
+ node_create(&newnode, cptra, "(adminhost)");
+ list_insert_sort_uniq(&adminlist, &newnode);
+ cptra = strtok(NULL, ",");
+ }
+ break;
+ default:
+ print_usage();
+ exit(STATE_UNKNOWN);
+ break;
+ }
+ }
+
+ if(argc > optind) {
+ print_usage();
+ die(STATE_UNKNOWN, "invalid options\n");
+ }
+
+ if(!warning_limit && !critical_limit) {
+ print_usage();
+ die(STATE_UNKNOWN, "you must provide a limit for this plugin\n");
+ }
+
+ if(critical_limit && warning_limit > critical_limit) {
+ print_usage();
+ die(STATE_UNKNOWN, "warning limit must be less or equal critical limit\n");
+ }
+}
+//=================================
+void parse_wholine(const char *line, char *name, char *host)
+{
+ char buffer[BUFSIZ], *cptra, *cptrb, *display;
+ strcpy(buffer, line);
+
+ cptra = buffer;
+ checkz(cptrb = (char*)strchr(buffer, ' '), "strchr failed\n");
+ strncpy(name, cptra, cptrb-cptra);
+ name[cptrb-cptra] = '\0';
+
+ if((cptra = strchr(buffer, '(')) != NULL) // hostname found in source arg...
+ {
+ if(cptra[1] == ':') // local host
+ strcpy(host, "(localhost)");
+ else // extern host
+ {
+ checkz(cptrb = strchr(cptra, ')'), "strchr failed\n");
+ cptrb++;
+ strncpy(host, cptra, cptrb-cptra);
+ host[cptrb-cptra] = '\0';
+ }
+ }
+ else // no hostname in source arg, look in line arg...
+ {
+ checkz(cptra = strtok(buffer, " \t\r\n"), "strtok failed\n");
+ checkz(cptra = strtok(NULL, " \t\r\n"), "strtok failed\n");
+ if(cptra[0] == ':') // local host
+ strcpy(host, "(localhost)");
+ else // extern host
+ sprintf(host, "(%s)", cptra);
+ }
+
+ if((cptra = strchr(host, ':')) != NULL) // remove display if any...
+ strcpy(cptra, ")");
+}
+//=================================
+void node_create(USERNODE* *node, const char *name, const char *host)
+{
+ checkz(*node = (USERNODE*)malloc(sizeof(USERNODE)), "malloc failed\n");
+ checkz((*node)->name = (char*)malloc(strlen(name)+1), "malloc failed\n");
+ checkz((*node)->host = (char*)malloc(strlen(host)+1), "malloc failed\n");
+ (*node)->next = NULL;
+ strcpy((*node)->name, name);
+ strcpy((*node)->host, host);
+}
+//=================================
+void node_free(USERNODE* *node)
+{
+ free((*node)->name);
+ free((*node)->host);
+ free(*node);
+ *node = NULL;
+}
+//=================================
+USERNODE* list_insert_sort_uniq(USERNODE* *list, USERNODE* *node)
+{
+ char n1[BUFSIZ], n2[BUFSIZ];
+ USERNODE *last_nptr = NULL, *nptr = *list;
+
+ if(*list == NULL)
+ return(*list = *node);
+ else {
+ sprintf(n1, "%s %s", (*node)->name, (*node)->host);
+ while(nptr != NULL) {
+ sprintf(n2, "%s %s", nptr->name, nptr->host);
+ if(!strcmp(n1, n2))
+ return NULL;
+ else if(strcmp(n1, n2) < 0) {
+ if(last_nptr) {
+ last_nptr->next = *node;
+ (*node)->next = nptr;
+ }
+ else {
+ (*node)->next = *list;
+ *list = *node;
+ }
+ break;
+ }
+ else {
+ last_nptr = nptr;
+ nptr = nptr->next;
+ }
+ }
+ if(nptr == NULL)
+ last_nptr->next = *node;
+ }
+ return *node;
+}
+//=================================
+void list_free(USERNODE* *list)
+{
+ USERNODE *doe, *nptr = *list;
+ while(nptr != NULL) {
+ doe = nptr;
+ nptr = nptr->next;
+ node_free(&doe);
+ }
+ *list = NULL;
+}
+//=================================
+void cleanup()
+{
+ list_free(&userlist);
+ list_free(&adminlist);
+}
+//=================================
diff --git a/contrib/check_oracle_tbs b/contrib/check_oracle_tbs
new file mode 100644
index 00000000..bcc4af87
--- /dev/null
+++ b/contrib/check_oracle_tbs
@@ -0,0 +1,206 @@
+#!/usr/local/bin/perl -w
+
+# (c)2003 John Koyle, RFP Depot, LLC.
+# This is free software use it however you would like.
+# Thanks to the folks at http://www.think-forward.com for the SQL query
+
+
+use strict;
+use DBI;
+use Getopt::Long 2.16;
+use lib "/usr/local/nagios/libexec";
+use utils qw(%ERRORS);
+
+
+#*******************************************************************************
+# Set user configureable options here.
+#
+# Global Oracle info set here rather than command line to avoid output in ps -ef
+# Make sure this script is mode 700 and owner of the nrpe user
+#
+#*******************************************************************************
+my $orasid = "";
+my $orauser = "";
+my $orapwd = "";
+
+
+if (!$ENV{ORACLE_HOME}) {
+ $ENV{ORACLE_HOME} = '/a01/app/oracle/product/9.2.0.1';
+}
+
+#*****************You shouldn't need to modify anything below here *************
+my $state = $ERRORS{'UNKNOWN'};
+my $answer = undef;
+
+my ($MAJOR_VERSION, $MINOR_VERSION) = q$Revision$ =~ /(\d+)\.(\d+)/;
+my $VERSION = sprintf("%d.%02d", $MAJOR_VERSION - 1, $MINOR_VERSION);
+
+my $opt_debug; # -d|--debug
+my $opt_help; # -h|--help
+my $opt_version; # -V|--version
+my $opt_warn_space; # -w|--warn-space
+my $opt_crit_space; # -c|--crit-space
+
+my $help = <<MARK; # help statement
+
+check_oracle_tbs v$VERSION
+
+Checks the tablespaces in an Oracle database for available free space.
+Usage: check_oracle_tbs [-w <warn>] [-c <crit>]
+
+ -d, --debug Output debug to screen.
+ -h, --help Displays this help and exits.
+ -w, --warn-space=... Warning threshold % free (default 15)
+ -c, --crit-space=... Critical threshold % free (default 10)
+ -V, --version Output version information and exit.
+
+MARK
+
+## We want exact matches to the switches
+
+Getopt::Long::config('no_auto_abbrev', 'no_ignore_case');
+
+my $rc = GetOptions(
+ "debug|d" => \$opt_debug,
+ "help|h" => \$opt_help,
+ "w|warn-space=s" => \$opt_warn_space,
+ "c|crit-space=s" => \$opt_crit_space,
+ "V|version" => \$opt_version,
+ );
+
+
+#***********************************************************************
+# Process command-line switches
+#***********************************************************************
+
+if (! $rc || defined $opt_help)
+{
+ print STDERR $help;
+ exit (defined $opt_help ? 0 : 1);
+}
+
+if (defined $opt_version)
+{
+ print STDERR "check_oracle_tbs v$VERSION\n";
+ exit 0;
+}
+
+if (! defined $opt_warn_space)
+{
+ if(defined $opt_debug) {
+ print STDOUT "Warn space not defined, using 80%\n\n";
+ }
+ $opt_warn_space = 15;
+}
+
+if (! defined $opt_crit_space)
+{
+ if(defined $opt_debug) {
+ print STDOUT "Crit space not defined, using 90%\n\n";
+ }
+ $opt_crit_space = 10;
+}
+
+my $array_ref = executeSQL();
+
+foreach my $row (@$array_ref) {
+ my ( $tbs_name, $tot_mb, $free_mb, $free_pct, $used_pct, $fsfi) = @$row;
+ if ($opt_debug) { print STDOUT "Output: $tbs_name\t$tot_mb\t$free_mb\t$free_pct\t$used_pct\t$fsfi\n\n"; }
+ if ($used_pct > (100 - $opt_crit_space) && $tbs_name !~ /RBS/) {
+ $state = $ERRORS{'CRITICAL'};
+ $answer .= "$tbs_name = $used_pct\% ";
+ last;
+ }
+ if ($used_pct > (100 - $opt_warn_space) && $tbs_name !~ /RBS/) {
+ $state = $ERRORS{'WARNING'};
+ $answer .= "$tbs_name = $used_pct\% ";
+ }
+}
+
+if ($state != $ERRORS{'CRITICAL'} && $state != $ERRORS{'WARNING'}) {
+ $state = $ERRORS{'OK'};
+ $answer = "All Tablespaces OK";
+}
+
+if ($opt_debug && $state != $ERRORS{'OK'}) { print STDOUT "The following tablespaces are in question: $answer\n\n"; }
+
+foreach my $key (keys %ERRORS) {
+ if ($state==$ERRORS{$key}) {
+ print ("$key: $answer");
+ last;
+ }
+}
+exit $state;
+
+sub executeSQL
+{
+ my ($dbh, $sth, $results);
+
+ $dbh = openOracle();
+
+ eval {
+ $dbh->{RaiseError} = 1;
+ # This query is taken from this URL and used with permission: http://www.think-forward.com/sql/tspace.htm
+ $sth = $dbh->prepare(q{
+ select df.tablespace_name tspace,
+ df.bytes/(1024*1024) tot_ts_size,
+ sum(fs.bytes)/(1024*1024) free_ts_size,
+ round(sum(fs.bytes)*100/df.bytes) ts_pct,
+ round((df.bytes-sum(fs.bytes))*100/df.bytes) ts_pct1,
+ ROUND(100*SQRT(MAX(fs.bytes)/SUM(fs.bytes))*
+ (1/SQRT(SQRT(COUNT(fs.bytes)))) ,2) FSFI
+ from dba_free_space fs, (select tablespace_name, sum(bytes) bytes
+ from dba_data_files
+ group by tablespace_name ) df
+ where fs.tablespace_name = df.tablespace_name
+ group by df.tablespace_name, df.bytes
+ });
+
+ $sth->execute();
+ $results = $sth->fetchall_arrayref();
+ $sth->finish;
+ $dbh->{RaiseError} = 0;
+ };
+
+ if ($@) {
+ closeOracle($dbh);
+ if($opt_debug) { print STDOUT "DB Failed Query: $@\n"; }
+ CleanupAndExit($ERRORS{'UNKNOWN'});
+ }
+
+ closeOracle($dbh);
+
+ return $results;
+}
+
+#------ Open the connection to the database and return the handle
+sub openOracle
+{
+ my ($dbh);
+
+ $dbh = DBI->connect("$orasid", "$orauser", "$orapwd", "Oracle");
+
+ if (!$dbh) {
+ if ($opt_debug) { print "ERROR: Could not connect to Oracle!\n\n"; }
+ CleanupAndExit($ERRORS{'UNKNOWN'});
+ }
+ if ($opt_debug) { print "Connected to Oracle SID $orasid\n\n"; }
+ return $dbh;
+}
+
+#------- Close the database connection
+sub closeOracle()
+{
+ my ($dbh) = @_;
+
+ $dbh->disconnect;
+}
+
+#------ Exit with the current return code
+sub CleanupAndExit
+{
+ my ($rc) = @_;
+
+ exit($rc);
+}
+
diff --git a/contrib/check_pcpmetric.py b/contrib/check_pcpmetric.py
new file mode 100644
index 00000000..71d816d4
--- /dev/null
+++ b/contrib/check_pcpmetric.py
@@ -0,0 +1,106 @@
+#! /usr/bin/env python
+#
+# Nagios client for checking Performance Co-Pilot metrics
+#
+#
+
+from sys import argv,exit
+import popen2, getopt, string, types
+
+DEBUG=0
+
+nagios_pcpclient_version = 0.01
+PMVAL='/usr/bin/pmval'
+COMMANDLINE=PMVAL + " -s 1"
+METRIC='undefined'
+CRITICAL=0
+WARNING=0
+
+def usage():
+ print "Usage:", argv[0], "[options]"
+ print "Options:"
+ print "\t[-H host]\tHostname to contact"
+ print "\t[-m metric]\tPCP metric to check"
+ print "\t[-i instance]\tPCP metric instance"
+ print "\t[-w warn]\tIssue warning alert if value is larger than this"
+ print "\t[-c critical]\tIssue critical alert value is larger than this"
+ print "\t[-V]\t\tProgram version"
+ print "\t[-h]\t\tThis helptext"
+ print ""
+ print "F.ex. to check 5 minute loadaverage, warn if the load is above 2,"
+ print "and give critical warning if it's above 10:"
+ print "\n\t%", argv[0], " -i 5 -m kernel.all.load -w 2 -c 10"
+ print ""
+ print "A list of all PCP metrics can be found with the command 'pminfo'."
+ print "A list of all instances within a metric can be found with 'pminfo -f metric'."
+ print "F.ex. to see all available instances of 'filesys.full' execute:"
+ print "\n\t% pminfo -f filesys.full"
+ print "\tfilesys.full"
+ print """\t\tinst [0 or "/dev/root"] value 45.35514044640914"""
+ print """\t\tinst [1 or "/dev/sda1"] value 46.74285959344712"""
+ print """\t\tinst [2 or "/dev/sdb1"] value 0.807766570678168"""
+ print ""
+ print "And the command to have nagios monitor the /dev/sda1 filesystem would be:"
+ print "\n\t", argv[0], " -i /dev/sda1 -m filesys.full -w 70 -c 90"
+
+
+opts, args = getopt.getopt(argv[1:],'hH:c:w:m:i:V')
+for opt in opts:
+ key,value = opt
+ if key == '-H':
+ COMMANDLINE = COMMANDLINE + " -h " + value
+ elif key == '-m':
+ METRIC=value
+ elif key == '-i':
+ COMMANDLINE = COMMANDLINE + " -i " + value
+ elif key == '-c':
+ CRITICAL = value
+ elif key == '-w':
+ WARNING = value
+ elif key == '-h':
+ usage()
+ exit(0)
+ elif key == '-V':
+ print "Nagios Performance CoPilot client v%.2f" % nagios_pcpclient_version
+ print "Written by Jan-Frode Myklebust <janfrode@parallab.uib.no>"
+ exit(0)
+
+if METRIC == 'undefined':
+ usage()
+ exit(3)
+
+COMMANDLINE = COMMANDLINE + " " + METRIC
+if DEBUG: print COMMANDLINE
+p=popen2.Popen4(COMMANDLINE)
+exitcode=p.wait()
+
+# Get the last line of output from 'pmval':
+buffer = p.fromchild.readline()
+while (buffer != ''):
+ output=buffer
+ buffer = p.fromchild.readline()
+
+returndata = string.split(output)[0]
+
+
+# Confirm that we have gotten a float, and not
+# some errormessage in the returndata. If not,
+# print the error, and give the UNKNOWN exit code:
+
+try:
+ retval = string.atof(returndata)
+except ValueError, e:
+ print e
+ exit(3)
+
+if (retval < WARNING):
+ EXITCODE=0
+elif (retval > CRITICAL):
+ EXITCODE=2
+elif (retval > WARNING):
+ EXITCODE=1
+else:
+ EXITCODE=3
+
+print retval
+exit(EXITCODE)
diff --git a/contrib/check_pfstate b/contrib/check_pfstate
new file mode 100644
index 00000000..6fe0d9b0
--- /dev/null
+++ b/contrib/check_pfstate
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+
+use strict;
+use Getopt::Long;
+use vars qw($opt_V $opt_h $opt_P $opt_H $opt_w $opt_c $PROGNAME);
+use lib "/usr/local/nagios/libexec" ;
+use utils qw(%ERRORS &print_revision &support &usage);
+
+my $remote_user = "root";
+my $path_to_ssh = "/usr/bin/ssh";
+my $path_to_grep = "/usr/bin/grep";
+my $path_to_awk = "/usr/bin/awk";
+my $warn = 50000;
+my $crit = 60000;
+
+$PROGNAME = "check_pfstate";
+$ENV{'PATH'}='';
+$ENV{'BASH_ENV'}='';
+$ENV{'ENV'}='';
+
+Getopt::Long::Configure('bundling');
+GetOptions
+ ("V" => \$opt_V, "version" => \$opt_V,
+ "h" => \$opt_h, "help" => \$opt_h,
+ "H=s" => \$opt_H, "hostname=s" => \$opt_H,
+ "w=s" => \$opt_w, "warning=s" => \$opt_w,
+ "c=s" => \$opt_c, "critical=s" => \$opt_c);
+
+if ($opt_V) {
+ print_revision($PROGNAME,'$Revision$');
+ exit $ERRORS{'OK'};
+}
+if ($opt_h) {
+ print_help();
+ exit $ERRORS{'OK'};
+}
+if ($opt_w) {
+ if ($opt_w =~ /(\d+)/) {
+ $warn = $1;
+ } else {
+ usage("Invalid values: $opt_w\n");
+ exit $ERRORS{'OK'};
+ }
+}
+if ($opt_c) {
+ if ($opt_c =~ /(\d+)/) {
+ $crit = $1;
+ } else {
+ usage("Invalid values: $opt_c\n");
+ exit $ERRORS{'OK'};
+ }
+}
+($opt_H) || usage("Host name/address not specified\n");
+my $host = $1 if ($opt_H =~ /([-.A-Za-z0-9]+)/);
+($host) || usage("Invalid host: $opt_H\n");
+
+my $result = `$path_to_ssh -l $remote_user $host '/sbin/pfctl -s info' | $path_to_grep entries`;
+chomp $result;
+$result =~ /(\d+)/;
+$result = $1;
+
+print "$result PF state entries\n";
+
+exit $ERRORS{'CRITICAL'} if ($result >= $crit);
+exit $ERRORS{'WARNING'} if ($result >= $warn);
+exit $ERRORS{'OK'};
+
+
+sub print_help {
+ print_revision($PROGNAME,'$Revision$');
+ print "Copyright (c) 2002 Jason Dixon\n\nThis plugin checks the number of state table entries on a PF-enabled OpenBSD system.\n\n";
+ print "Usage:\t-H, --hostname=<HOST> [-w, --warning=<WARNING>] [-c, --critical=<CRITICAL>]\n\n\tDefault warning is 50000 and critical is 60000.\n\n";
+ support();
+}
+