From 44a321cb8a42d6c0ea2d96a1086a17f2134c89cc Mon Sep 17 00:00:00 2001 From: Ethan Galstad Date: Thu, 28 Feb 2002 06:42:51 +0000 Subject: Initial revision git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@2 f882894a-f735-0410-b71e-b25c423dba1c --- plugins/.cvsignore | 43 ++ plugins/Makefile.am | 139 ++++++ plugins/check_by_ssh.c | 412 +++++++++++++++++ plugins/check_dig.c | 296 +++++++++++++ plugins/check_disk.c | 353 +++++++++++++++ plugins/check_dns.c | 415 ++++++++++++++++++ plugins/check_dummy.c | 100 +++++ plugins/check_fping.c | 386 ++++++++++++++++ plugins/check_ftp.c | 337 ++++++++++++++ plugins/check_game.c | 287 ++++++++++++ plugins/check_hpjd.c | 571 ++++++++++++++++++++++++ plugins/check_http.c | 1067 +++++++++++++++++++++++++++++++++++++++++++++ plugins/check_ide-smart.c | 448 +++++++++++++++++++ plugins/check_imap.c | 340 +++++++++++++++ plugins/check_ldap.c | 291 +++++++++++++ plugins/check_load.c | 321 ++++++++++++++ plugins/check_mrtg.c | 413 ++++++++++++++++++ plugins/check_mrtgtraf.c | 419 ++++++++++++++++++ plugins/check_mysql.c | 297 +++++++++++++ plugins/check_nagios.c | 267 ++++++++++++ plugins/check_nntp.c | 418 ++++++++++++++++++ plugins/check_nt.c | 548 +++++++++++++++++++++++ plugins/check_nwstat.c | 821 ++++++++++++++++++++++++++++++++++ plugins/check_overcr.c | 489 +++++++++++++++++++++ plugins/check_pgsql.c | 440 +++++++++++++++++++ plugins/check_ping.c | 492 +++++++++++++++++++++ plugins/check_pop.c | 364 ++++++++++++++++ plugins/check_procs.c | 510 ++++++++++++++++++++++ plugins/check_radius.c | 345 +++++++++++++++ plugins/check_real.c | 661 ++++++++++++++++++++++++++++ plugins/check_smtp.c | 362 +++++++++++++++ plugins/check_snmp.c | 805 ++++++++++++++++++++++++++++++++++ plugins/check_ssh.c | 285 ++++++++++++ plugins/check_swap.c | 325 ++++++++++++++ plugins/check_tcp.c | 563 ++++++++++++++++++++++++ plugins/check_time.c | 370 ++++++++++++++++ plugins/check_udp.c | 315 +++++++++++++ plugins/check_ups.c | 649 +++++++++++++++++++++++++++ plugins/check_users.c | 257 +++++++++++ plugins/check_vsz.c | 287 ++++++++++++ plugins/common.h.in | 159 +++++++ plugins/getopt.c | 724 ++++++++++++++++++++++++++++++ plugins/getopt1.c | 176 ++++++++ plugins/netutils.c | 431 ++++++++++++++++++ plugins/netutils.h.in | 63 +++ plugins/popen.c | 314 +++++++++++++ plugins/popen.h.in | 9 + plugins/snprintf.c | 377 ++++++++++++++++ plugins/t/check_disk.t | 31 ++ plugins/t/check_dns.t | 29 ++ plugins/t/check_fping.t | 37 ++ plugins/t/check_ftp.t | 32 ++ plugins/t/check_hpjd.t | 32 ++ plugins/t/check_http.t | 22 + plugins/t/check_imap.t | 34 ++ plugins/t/check_load.t | 27 ++ plugins/t/check_mysql.t | 23 + plugins/t/check_ping.t | 33 ++ plugins/t/check_pop.t | 31 ++ plugins/t/check_procs.t | 51 +++ plugins/t/check_smtp.t | 31 ++ plugins/t/check_snmp.t | 52 +++ plugins/t/check_swap.t | 34 ++ plugins/t/check_tcp.t | 27 ++ plugins/t/check_time.t | 52 +++ plugins/t/check_udp.t | 24 + plugins/t/check_users.t | 28 ++ plugins/t/check_vsz.t | 28 ++ plugins/tests/check_disk | 9 + plugins/tests/check_dns | 9 + plugins/tests/check_ftp | 9 + plugins/tests/check_hpjd | 9 + plugins/tests/check_http | 9 + plugins/tests/check_load | 9 + plugins/tests/check_ping | 13 + plugins/tests/check_procs | 23 + plugins/tests/check_swap | 13 + plugins/tests/check_users | 9 + plugins/tests/check_vsz | 9 + plugins/urlize.c | 141 ++++++ plugins/utils.c | 610 ++++++++++++++++++++++++++ plugins/utils.h.in | 92 ++++ plugins/version.h.in | 2 + 83 files changed, 20385 insertions(+) create mode 100644 plugins/.cvsignore create mode 100644 plugins/Makefile.am create mode 100644 plugins/check_by_ssh.c create mode 100644 plugins/check_dig.c create mode 100644 plugins/check_disk.c create mode 100644 plugins/check_dns.c create mode 100644 plugins/check_dummy.c create mode 100644 plugins/check_fping.c create mode 100644 plugins/check_ftp.c create mode 100644 plugins/check_game.c create mode 100644 plugins/check_hpjd.c create mode 100644 plugins/check_http.c create mode 100644 plugins/check_ide-smart.c create mode 100644 plugins/check_imap.c create mode 100644 plugins/check_ldap.c create mode 100644 plugins/check_load.c create mode 100644 plugins/check_mrtg.c create mode 100644 plugins/check_mrtgtraf.c create mode 100644 plugins/check_mysql.c create mode 100644 plugins/check_nagios.c create mode 100644 plugins/check_nntp.c create mode 100644 plugins/check_nt.c create mode 100644 plugins/check_nwstat.c create mode 100644 plugins/check_overcr.c create mode 100644 plugins/check_pgsql.c create mode 100644 plugins/check_ping.c create mode 100644 plugins/check_pop.c create mode 100644 plugins/check_procs.c create mode 100644 plugins/check_radius.c create mode 100644 plugins/check_real.c create mode 100644 plugins/check_smtp.c create mode 100644 plugins/check_snmp.c create mode 100644 plugins/check_ssh.c create mode 100644 plugins/check_swap.c create mode 100644 plugins/check_tcp.c create mode 100644 plugins/check_time.c create mode 100644 plugins/check_udp.c create mode 100644 plugins/check_ups.c create mode 100644 plugins/check_users.c create mode 100644 plugins/check_vsz.c create mode 100644 plugins/common.h.in create mode 100644 plugins/getopt.c create mode 100644 plugins/getopt1.c create mode 100644 plugins/netutils.c create mode 100644 plugins/netutils.h.in create mode 100644 plugins/popen.c create mode 100644 plugins/popen.h.in create mode 100644 plugins/snprintf.c create mode 100644 plugins/t/check_disk.t create mode 100644 plugins/t/check_dns.t create mode 100644 plugins/t/check_fping.t create mode 100644 plugins/t/check_ftp.t create mode 100644 plugins/t/check_hpjd.t create mode 100644 plugins/t/check_http.t create mode 100644 plugins/t/check_imap.t create mode 100644 plugins/t/check_load.t create mode 100644 plugins/t/check_mysql.t create mode 100644 plugins/t/check_ping.t create mode 100644 plugins/t/check_pop.t create mode 100644 plugins/t/check_procs.t create mode 100644 plugins/t/check_smtp.t create mode 100644 plugins/t/check_snmp.t create mode 100644 plugins/t/check_swap.t create mode 100644 plugins/t/check_tcp.t create mode 100644 plugins/t/check_time.t create mode 100644 plugins/t/check_udp.t create mode 100644 plugins/t/check_users.t create mode 100644 plugins/t/check_vsz.t create mode 100644 plugins/tests/check_disk create mode 100644 plugins/tests/check_dns create mode 100644 plugins/tests/check_ftp create mode 100644 plugins/tests/check_hpjd create mode 100644 plugins/tests/check_http create mode 100644 plugins/tests/check_load create mode 100644 plugins/tests/check_ping create mode 100644 plugins/tests/check_procs create mode 100644 plugins/tests/check_swap create mode 100644 plugins/tests/check_users create mode 100644 plugins/tests/check_vsz create mode 100644 plugins/urlize.c create mode 100644 plugins/utils.c create mode 100644 plugins/utils.h.in create mode 100644 plugins/version.h.in (limited to 'plugins') diff --git a/plugins/.cvsignore b/plugins/.cvsignore new file mode 100644 index 00000000..58f14fe8 --- /dev/null +++ b/plugins/.cvsignore @@ -0,0 +1,43 @@ +check_disk +check_dns +check_dummy +check_ftp +check_http +check_imap +check_load +check_mrtg +check_mrtgtraf +check_nagios +check_nntp +check_nwstat +check_overcr +check_ping +check_pop +check_procs +check_real +check_reply +check_smtp +check_ssh +check_tcp +check_time +check_udp +check_ups +check_users +check_vsz +check_by_ssh +urlize +check_pgsql +check_radius +check_ldap +check_mysql +check_netsaint +check_hpjd +check_snmp +check_by_ssh +check_swap +stamp-h* +*.h +Makefile +Makefile.in +config.h.in +.deps diff --git a/plugins/Makefile.am b/plugins/Makefile.am new file mode 100644 index 00000000..64b14bfb --- /dev/null +++ b/plugins/Makefile.am @@ -0,0 +1,139 @@ +## Process this file with automake to produce Makefile.in + +VPATH = $(top_srcdir) $(top_srcdir)/plugins $(top_srcdir)/plugins/t + +INCLUDES = @LDAPINCLUDE@ @PGINCLUDE@ @SSLINCLUDE@ + +libexec_PROGRAMS = check_disk check_dummy check_ftp check_http \ + check_imap check_load check_mrtg check_mrtgtraf \ + check_nntp check_nwstat check_overcr \ + check_ping check_pop check_procs check_real \ + check_smtp check_ssh check_tcp check_time check_udp \ + check_ups check_users check_vsz urlize \ + @EXTRAS@ + +EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \ + check_swap check_fping check_ldap check_game check_dig \ + check_nagios check_by_ssh check_dns check_nt + +EXTRA_DIST = t utils.c netutils.c popen.c getopt.h getopt.c getopt1.c snprintf.c + +PLUGINHDRS = common.h config.h + +BASEOBJS = utils.o +NETOBJS = netutils.o $(BASEOBJS) +NETLIBS = $(NETOBJS) $(SOCKETLIBS) + +TESTS_ENVIRONMENT = perl -I $(top_builddir) -I $(top_srcdir) + +TESTS = @PLUGIN_TEST@ + +test: + perl -I $(top_builddir) -I $(top_srcdir) ../test.pl + +AM_INSTALL_PROGRAM_FLAGS = @INSTALL_OPTS@ + +############################################################################## +# the actual targets + +check_dig_LDADD = $(BASEOBJS) popen.o +check_disk_LDADD = $(BASEOBJS) popen.o +check_dns_LDADD = $(BASEOBJS) popen.o +check_dummy_LDADD = $(BASEOBJS) +check_fping_LDADD = $(BASEOBJS) popen.o +check_ftp_LDADD = $(NETLIBS) +check_game_LDADD = $(BASEOBJS) +check_http_LDADD = $(NETLIBS) $(SSLLIBS) +check_hpjd_LDADD = $(BASEOBJS) popen.o +check_imap_LDADD = $(NETLIBS) +check_ldap_LDADD = $(NETLIBS) $(LDAPLIBS) +check_load_LDADD = $(BASEOBJS) popen.o +check_mrtg_LDADD = $(BASEOBJS) +check_mrtgtraf_LDADD = $(BASEOBJS) +check_mysql_LDADD = $(BASEOBJS) $(MYSQLLIBS) +check_nagios_LDADD = $(BASEOBJS) popen.o +check_nntp_LDADD = $(NETLIBS) +check_nt_LDADD = $(NETLIBS) +check_nwstat_LDADD = $(NETLIBS) +check_overcr_LDADD = $(NETLIBS) +check_pgsql_LDADD = $(BASEOBJS) $(PGLIBS) +check_ping_LDADD = $(BASEOBJS) popen.o +check_pop_LDADD = $(NETLIBS) +check_procs_LDADD = $(BASEOBJS) popen.o +check_radius_LDADD = $(BASEOBJS) $(RADIUSLIBS) +check_real_LDADD = $(NETLIBS) +check_snmp_LDADD = $(BASEOBJS) popen.o +check_smtp_LDADD = $(NETLIBS) +check_ssh_LDADD = $(NETLIBS) +check_swap_LDADD = $(BASEOBJS) popen.o +check_tcp_LDADD = $(NETLIBS) $(SSLLIBS) +check_time_LDADD = $(NETLIBS) +check_udp_LDADD = $(NETLIBS) +check_ups_LDADD = $(NETLIBS) +check_users_LDADD = $(BASEOBJS) popen.o +check_vsz_LDADD = $(BASEOBJS) popen.o +check_by_ssh_LDADD = $(BASEOBJS) popen.o +urlize_LDADD = $(BASEOBJS) popen.o + +check_dig_DEPENDENCIES = check_dig.c $(BASEOBJS) popen.o $(DEPLIBS) +check_disk_DEPENDENCIES = check_disk.c $(BASEOBJS) popen.o $(DEPLIBS) +check_dns_DEPENDENCIES = check_dns.c $(BASEOBJS) popen.o $(DEPLIBS) +check_dummy_DEPENDENCIES = check_dummy.c $(DEPLIBS) +check_fping_DEPENDENCIES = check_fping.c $(BASEOBJS) popen.o $(DEPLIBS) +check_ftp_DEPENDENCIES = check_ftp.c $(NETOBJS) $(DEPLIBS) +check_game_DEPENDENCIES = check_game.c $(DEPLIBS) +check_http_DEPENDENCIES = check_http.c $(NETOBJS) $(DEPLIBS) +check_hpjd_DEPENDENCIES = check_hpjd.c $(BASEOBJS) popen.o $(DEPLIBS) +check_imap_DEPENDENCIES = check_imap.c $(NETOBJS) $(DEPLIBS) +check_ldap_DEPENDENCIES = check_ldap.c $(NETOBJS) $(DEPLIBS) +check_load_DEPENDENCIES = check_load.c $(BASEOBJS) popen.o $(DEPLIBS) +check_mrtg_DEPENDENCIES = check_mrtg.c $(DEPLIBS) +check_mrtgtraf_DEPENDENCIES = check_mrtgtraf.c $(DEPLIBS) +check_mysql_DEPENDENCIES = check_mysql.c $(DEPLIBS) +check_nagios_DEPENDENCIES = check_nagios.c $(BASEOBJS) popen.o $(DEPLIBS) +check_nntp_DEPENDENCIES = check_nntp.c $(NETOBJS) $(DEPLIBS) +check_nt_DEPENDENCIES = check_nt.c $(NETOBJS) $(DEPLIBS) +check_nwstat_DEPENDENCIES = check_nwstat.c $(NETOBJS) $(DEPLIBS) +check_overcr_DEPENDENCIES = check_overcr.c $(NETOBJS) $(DEPLIBS) +check_pgsql_DEPENDENCIES = check_pgsql.c $(DEPLIBS) +check_ping_DEPENDENCIES = check_ping.c $(BASEOBJS) popen.o $(DEPLIBS) +check_pop_DEPENDENCIES = check_pop.c $(NETOBJS) $(DEPLIBS) +check_procs_DEPENDENCIES = check_procs.c $(BASEOBJS) popen.o $(DEPLIBS) +check_radius_DEPENDENCIES = check_radius.c $(DEPLIBS) +check_real_DEPENDENCIES = check_real.c $(NETOBJS) $(DEPLIBS) +check_snmp_DEPENDENCIES = check_snmp.c $(BASEOBJS) popen.o $(DEPLIBS) +check_smtp_DEPENDENCIES = check_smtp.c $(NETOBJS) $(DEPLIBS) +check_ssh_DEPENDENCIES = check_ssh.c $(NETOBJS) $(DEPLIBS) +check_swap_DEPENDENCIES = check_swap.c $(BASEOBJS) popen.o $(DEPLIBS) +check_tcp_DEPENDENCIES = check_tcp.c $(NETOBJS) $(DEPLIBS) +check_time_DEPENDENCIES = check_time.c $(NETOBJS) $(DEPLIBS) +check_udp_DEPENDENCIES = check_udp.c $(NETOBJS) $(DEPLIBS) +check_ups_DEPENDENCIES = check_ups.c $(NETOBJS) $(DEPLIBS) +check_users_DEPENDENCIES = check_users.c $(BASEOBJS) popen.o $(DEPLIBS) +check_vsz_DEPENDENCIES = check_vsz.c $(BASEOBJS) popen.o $(DEPLIBS) +check_by_ssh_DEPENDENCIES = check_by_ssh.c $(BASEOBJS) popen.o $(DEPLIBS) +urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS) + +############################################################################## +# secondary dependencies + +popen.o: popen.c popen.h $(PLUGINHDRS) + +utils.o: utils.c utils.h $(PLUGINHDRS) + +netutils.o: netutils.c netutils.h $(PLUGINHDRS) + +getopt.o: getopt.c getopt.h + $(COMPILE) -c $(srcdir)/getopt.c -o $@ + +getopt1.o: getopt1.c getopt.h + $(COMPILE) -c $(srcdir)/getopt1.c -o $@ + +snprintf.o: snprintf.c + $(COMPILE) @NEED_VA_LIST@ -c $? -o $@ + +libgetopt.a: getopt.o getopt1.o + $(AR) -r $@ getopt.o getopt1.o + +libsnprintf.a: snprintf.o + $(AR) -r $@ snprintf.o diff --git a/plugins/check_by_ssh.c b/plugins/check_by_ssh.c new file mode 100644 index 00000000..a81b333f --- /dev/null +++ b/plugins/check_by_ssh.c @@ -0,0 +1,412 @@ +/****************************************************************************** + * + * This file is part of the Nagios Plugins. + * + * Copyright (c) 1999, 2000, 2001 Karl DeBisschop + * + * The Nagios Plugins are free software; you can redistribute them + * and/or modify them under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * + *****************************************************************************/ + +#define PROGRAM check_by_ssh +#define DESCRIPTION "Run checks on a remote system using ssh, wrapping the proper timeout around the ssh invocation." +#define AUTHOR "Karl DeBisschop" +#define EMAIL "karl@debisschop.net" +#define COPYRIGHTDATE "1999, 2000, 2001" + +#include "config.h" +#include "common.h" +#include "popen.h" +#include "utils.h" +#include + +#define PROGNAME "check_by_ssh" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +void print_help (char *command_name); +void print_usage (void); + + +int commands; +char *remotecmd = NULL; +char *comm = NULL; +char *hostname = NULL; +char *outputfile = NULL; +char *host_shortname = NULL; +char *servicelist = NULL; +int passive = FALSE; +int verbose = FALSE; + + +int +main (int argc, char **argv) +{ + + char input_buffer[MAX_INPUT_BUFFER] = ""; + char *result_text = NULL; + char *status_text; + char *output = NULL; + char *eol = NULL; + char *srvc_desc = NULL; + int cresult; + int result = STATE_UNKNOWN; + time_t local_time; + FILE *fp = NULL; + + + /* process arguments */ + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments\n"); + + + /* Set signal handling and alarm timeout */ + if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { + printf ("Cannot catch SIGALRM"); + return STATE_UNKNOWN; + } + alarm (timeout_interval); + + + /* run the command */ + + if (verbose) + printf ("%s\n", comm); + + child_process = spopen (comm); + + if (child_process == NULL) { + printf ("Unable to open pipe: %s", comm); + return STATE_UNKNOWN; + } + + + /* open STDERR for spopen */ + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) { + printf ("Could not open stderr for %s\n", SSH_COMMAND); + } + + + /* get results from remote command */ + result_text = realloc (result_text, 1); + result_text[0] = 0; + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) + result_text = strscat (result_text, input_buffer); + + + /* WARNING if output found on stderr */ + if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { + printf ("%s\n", input_buffer); + return STATE_WARNING; + } + (void) fclose (child_stderr); + + + /* close the pipe */ + result = spclose (child_process); + + + /* process output */ + if (passive) { + + if (!(fp = fopen (outputfile, "a"))) { + printf ("SSH WARNING: could not open %s\n", outputfile); + exit (STATE_UNKNOWN); + } + + time (&local_time); + srvc_desc = strtok (servicelist, ":"); + while (result_text != NULL) { + status_text = (strstr (result_text, "STATUS CODE: ")); + if (status_text == NULL) { + printf ("%s", result_text); + return result; + } + output = result_text; + result_text = strnl (status_text); + eol = strpbrk (output, "\r\n"); + if (eol != NULL) + eol[0] = 0; + if (srvc_desc && status_text + && sscanf (status_text, "STATUS CODE: %d", &cresult) == 1) { + fprintf (fp, "%d PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", + (int) local_time, host_shortname, srvc_desc, cresult, + output); + srvc_desc = strtok (NULL, ":"); + } + } + + } + + /* print the first line from the remote command */ + else { + eol = strpbrk (result_text, "\r\n"); + if (eol) + eol[0] = 0; + printf ("%s\n", result_text); + + } + + + /* return error status from remote command */ + return result; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + remotecmd = realloc (remotecmd, 1); + remotecmd[0] = 0; + + for (c = 1; c < argc; c++) + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + + comm = strscpy (comm, SSH_COMMAND); + + c = 0; + while (c += (call_getopt (argc - c, &argv[c]))) { + + if (argc <= c) + break; + + if (hostname == NULL) { + if (!is_host (argv[c])) + terminate (STATE_UNKNOWN, "%s: Invalid host name %s\n", PROGNAME, + argv[c]); + hostname = argv[c]; + } + else if (remotecmd == NULL) { + remotecmd = strscpy (remotecmd, argv[c++]); + for (; c < argc; c++) + remotecmd = ssprintf (remotecmd, "%s %s", remotecmd, argv[c]); + } + + } + + if (commands > 1) + remotecmd = strscat (remotecmd, ";echo STATUS CODE: $?;"); + + if (remotecmd == NULL || strlen (remotecmd) <= 1) + usage ("No remotecmd\n"); + + comm = ssprintf (comm, "%s %s '%s'", comm, hostname, remotecmd); + + return validate_arguments (); +} + + + + + +/* Call getopt */ +int +call_getopt (int argc, char **argv) +{ + int c, i = 1; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {"verbose", no_argument, 0, 'v'}, + {"fork", no_argument, 0, 'f'}, + {"timeout", required_argument, 0, 't'}, + {"host", required_argument, 0, 'H'}, + {"port", required_argument,0,'P'}, + {"output", required_argument, 0, 'O'}, + {"name", required_argument, 0, 'n'}, + {"services", required_argument, 0, 's'}, + {"identity", required_argument, 0, 'i'}, + {"user", required_argument, 0, 'u'}, + {"logname", required_argument, 0, 'l'}, + {"command", required_argument, 0, 'C'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+?Vvhft:H:O:P:p:i:u:l:C:n:s:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+?Vvhft:H:O:P:p:i:u:l:C:n:s:"); +#endif + + if (c == -1 || c == EOF) + break; + + i++; + switch (c) { + case 't': + case 'H': + case 'O': + case 'p': + case 'i': + case 'u': + case 'l': + case 'n': + case 's': + i++; + } + + switch (c) { + case '?': /* help */ + print_usage (); + exit (STATE_UNKNOWN); + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (PROGNAME); + exit (STATE_OK); + case 'v': /* help */ + verbose = TRUE; + break; + case 'f': /* fork to background */ + comm = ssprintf (comm, "%s -f", comm); + break; + case 't': /* timeout period */ + if (!is_integer (optarg)) + usage2 ("timeout interval must be an integer", optarg); + timeout_interval = atoi (optarg); + break; + case 'H': /* host */ + if (!is_host (optarg)) + usage2 ("invalid host name", optarg); + hostname = optarg; + break; + case 'P': /* port number */ + case 'p': /* port number */ + if (!is_integer (optarg)) + usage2 ("port must be an integer", optarg); + comm = ssprintf (comm,"%s -p %s", comm, optarg); + break; + case 'O': /* output file */ + outputfile = optarg; + passive = TRUE; + break; + case 's': /* description of service to check */ + servicelist = optarg; + break; + case 'n': /* short name of host in nagios configuration */ + host_shortname = optarg; + break; + case 'u': + c = 'l'; + case 'l': /* login name */ + case 'i': /* identity */ + comm = ssprintf (comm, "%s -%c %s", comm, c, optarg); + break; + case 'C': /* Command for remote machine */ + commands++; + if (commands > 1) + remotecmd = strscat (remotecmd, ";echo STATUS CODE: $?;"); + remotecmd = strscat (remotecmd, optarg); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + if (remotecmd == NULL || hostname == NULL) + return ERROR; + return OK; +} + + + + + +void +print_help (char *cmd) +{ + print_revision (cmd, "$Revision$"); + + printf + ("Copyright (c) 1999 Karl DeBisschop (kdebisschop@alum.mit.edu)\n\n" + "This plugin will execute a command on a remote host using SSH\n\n"); + + print_usage (); + + printf + ("\nOptions:\n" + "-H, --hostname=HOST\n" + " name or IP address of remote host\n" + "-C, --command='COMMAND STRING'\n" + " command to execute on the remote machine\n" + "-f tells ssh to fork rather than create a tty\n" + "-t, --timeout=INTEGER\n" + " specify timeout (default: %d seconds) [optional]\n" + "-l, --logname=USERNAME\n" + " SSH user name on remote host [optional]\n" + "-i, --identity=KEYFILE\n" + " identity of an authorized key [optional]\n" + "-O, --output=FILE\n" + " external command file for nagios [optional]\n" + "-s, --services=LIST\n" + " list of nagios service names, separated by ':' [optional]\n" + "-n, --name=NAME\n" + " short name of host in nagios configuration [optional]\n" + "\n" + "The most common mode of use is to refer to a local identity file with\n" + "the '-i' option. In this mode, the identity pair should have a null\n" + "passphrase and the public key should be listed in the authorized_keys\n" + "file of the remote host. Usually the key will be restricted to running\n" + "only one command on the remote server. If the remote SSH server tracks\n" + "invocation agruments, the one remote program may be an agent that can\n" + "execute additional commands as proxy\n" + "\n" + "To use passive mode, provide multiple '-C' options, and provide\n" + "all of -O, -s, and -n options (servicelist order must match '-C'\n" + "options)\n", DEFAULT_SOCKET_TIMEOUT); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage:\n" + "check_by_ssh [-f] [-t timeout] [-i identity] [-l user] -H \n" + " [-n name] [-s servicelist] [-O outputfile] [-P port]\n" + "check_by_ssh -V prints version info\n" + "check_by_ssh -h prints more detailed help\n"); +} diff --git a/plugins/check_dig.c b/plugins/check_dig.c new file mode 100644 index 00000000..57609acd --- /dev/null +++ b/plugins/check_dig.c @@ -0,0 +1,296 @@ +/****************************************************************************** +* +* check_dig.c +* +* Program: dig plugin for Nagios +* License: GPL +* Copyright (c) 2000 +* +* $Id$ +* +*****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "utils.h" +#include "popen.h" + +#define PROGNAME "check_dig" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +int check_disk (int usp, int free_disk); +void print_help (void); +void print_usage (void); + +char *query_address = NULL; +char *dns_server = NULL; +int verbose = FALSE; + +int +main (int argc, char **argv) +{ + char input_buffer[MAX_INPUT_BUFFER]; + char *command_line = NULL; + char *output = NULL; + int result = STATE_UNKNOWN; + + /* Set signal handling and alarm */ + if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) + usage ("Cannot catch SIGALRM\n"); + + if (process_arguments (argc, argv) != OK) + usage ("Could not parse arguments\n"); + + /* get the command to run */ + command_line = + ssprintf (command_line, "%s @%s %s", PATH_TO_DIG, dns_server, + query_address); + + alarm (timeout_interval); + time (&start_time); + + if (verbose) + printf ("%s\n", command_line); + /* run the command */ + child_process = spopen (command_line); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", command_line); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) + printf ("Could not open stderr for %s\n", command_line); + + output = strscpy (output, ""); + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + + /* the server is responding, we just got the host name... */ + if (strstr (input_buffer, ";; ANSWER SECTION:")) { + + /* get the host address */ + if (!fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) + break; + + if (strpbrk (input_buffer, "\r\n")) + input_buffer[strcspn (input_buffer, "\r\n")] = '\0'; + + if (strstr (input_buffer, query_address) == input_buffer) { + output = strscpy (output, input_buffer); + result = STATE_OK; + } + else { + strcpy (output, "Server not found in ANSWER SECTION"); + result = STATE_WARNING; + } + + continue; + } + + } + + if (result != STATE_OK) { + strcpy (output, "No ANSWER SECTION found"); + } + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { + /* If we get anything on STDERR, at least set warning */ + result = max (result, STATE_WARNING); + printf ("%s", input_buffer); + if (!strcmp (output, "")) + strcpy (output, 1 + index (input_buffer, ':')); + } + + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) { + result = max (result, STATE_WARNING); + if (!strcmp (output, "")) + strcpy (output, "nslookup returned error status"); + } + + (void) time (&end_time); + + if (result == STATE_OK) + printf ("DNS ok - %d seconds response time (%s)\n", + (int) (end_time - start_time), output); + else if (result == STATE_WARNING) + printf ("DNS WARNING - %s\n", + !strcmp (output, + "") ? " Probably a non-existent host/domain" : output); + else if (result == STATE_CRITICAL) + printf ("DNS CRITICAL - %s\n", + !strcmp (output, + "") ? " Probably a non-existent host/domain" : output); + else + printf ("DNS problem - %s\n", + !strcmp (output, + "") ? " Probably a non-existent host/domain" : output); + + return result; +} + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (dns_server == NULL) { + if (is_host (argv[c])) { + dns_server = argv[c]; + } + else { + usage ("Invalid host name"); + } + } + } + + if (dns_server == NULL) + dns_server = strscpy (NULL, "127.0.0.1"); + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"query_address", required_argument, 0, 'e'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+hVvt:l:H:", long_options, &option_index); +#else + c = getopt (argc, argv, "+?hVvt:l:H:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 't': + case 'l': + case 'H': + i++; + } + + switch (c) { + case 'H': /* hostname */ + if (is_host (optarg)) { + dns_server = optarg; + } + else { + usage ("Invalid host name\n"); + } + break; + case 'l': /* username */ + query_address = optarg; + break; + case 'v': /* verbose */ + verbose = TRUE; + break; + case 't': /* timeout */ + if (is_intnonneg (optarg)) { + timeout_interval = atoi (optarg); + } + else { + usage ("Time interval must be a nonnegative integer\n"); + } + break; + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + return OK; +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Karl DeBisschop\n\n" + "This plugin use dig to test the DNS service on the specified host.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -H, --hostname=STRING or IPADDRESS\n" + " Check server on the indicated host\n" + " -l, --lookup=STRING\n" + " machine name to lookup\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection attempt times out (default: %d)\n" + " -v, --verbose\n" + " Print extra information (command-line use only)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n", DEFAULT_SOCKET_TIMEOUT); + support (); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H host -l lookup [-t timeout] [-v]\n" + " %s --help\n" + " %s --version\n", PROGNAME, PROGNAME, PROGNAME); +} diff --git a/plugins/check_disk.c b/plugins/check_disk.c new file mode 100644 index 00000000..d7aad072 --- /dev/null +++ b/plugins/check_disk.c @@ -0,0 +1,353 @@ +/****************************************************************************** + * + * CHECK_DISK.C + * + * Program: Disk space plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net) + * + * $Id$ + * + * Description: + * + * This plugin will use the /bin/df command to check the free space on + * currently mounted filesystems. If the percent used disk space is + * above , a STATE_CRITICAL is returned. If the percent used + * disk space is above , a STATE_WARNING is returned. If the + * speicified filesystem cannot be read, a STATE_CRITICAL is returned, + * other errors with reading the output result in a STATE_UNKNOWN + * error. + * + * Notes: + * - IRIX support added by Charlie Cook 4-16-1999 + * - Modifications by Karl DeBisschop 1999-11-24 + * reformat code to 80 char screen width + * set STATE_WARNING if stderr is written or spclose status set + * set default result to STAT_UNKNOWN + * initailize usp to -1, eliminate 'found' variable + * accept any filename/filesystem + * use sscanf, drop while loop + * + *****************************************************************************/ + +#include "common.h" +#include "popen.h" +#include "utils.h" +#include + +#define PROGNAME "check_disk" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +int check_disk (int usp, int free_disk); +void print_help (void); +void print_usage (void); + +int w_df = -1; +int c_df = -1; +float w_dfp = -1.0; +float c_dfp = -1.0; +char *path = NULL; +int verbose = FALSE; + +int +main (int argc, char **argv) +{ + int len; + int usp = -1; + int total_disk = -1; + int used_disk = -1; + int free_disk = -1; + int result = STATE_UNKNOWN; + char *command_line = NULL; + char input_buffer[MAX_INPUT_BUFFER] = ""; + char file_system[MAX_INPUT_BUFFER] = ""; + char outbuf[MAX_INPUT_BUFFER] = ""; + char *output = NULL; + + if (process_arguments (argc, argv) != OK) + usage ("Could not parse arguments\n"); + + command_line = ssprintf (command_line, "%s %s", DF_COMMAND, path); + + if (verbose) + printf ("%s ==> ", command_line); + + child_process = spopen (command_line); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", command_line); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) { + printf ("Could not open stderr for %s\n", command_line); + } + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + + if (!index (input_buffer, '/')) + continue; + + if (sscanf + (input_buffer, "%s %d %d %d %d%%", file_system, &total_disk, + &used_disk, &free_disk, &usp) == 5 + || sscanf (input_buffer, "%s %*s %d %d %d %d%%", file_system, + &total_disk, &used_disk, &free_disk, &usp) == 5) { + result = max (result, check_disk (usp, free_disk)); + len = + snprintf (outbuf, MAX_INPUT_BUFFER - 1, + " [%d kB (%d%%) free on %s]", free_disk, 100 - usp, + file_system); + outbuf[len] = 0; + output = strscat (output, outbuf); + } + else { + printf ("Unable to read output:\n%s\n%s\n", command_line, input_buffer); + return result; + } + } + + /* If we get anything on stderr, at least set warning */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) + result = max (result, STATE_WARNING); + + /* close stderr */ + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) + result = max (result, STATE_WARNING); + + else if (usp < 0) + printf ("Disk %s not mounted or nonexistant\n", argv[3]); + else if (result == STATE_UNKNOWN) + printf ("Unable to read output\n%s\n%s\n", command_line, input_buffer); + else + printf ("DISK %s -%s\n", state_text (result), output); + + return result; +} + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) { + strcpy (argv[c], "-t"); + } + } + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (w_dfp == -1 && is_intnonneg (argv[c])) + w_dfp = (100.0 - atof (argv[c])); + else if (c_dfp == -1 && is_intnonneg (argv[c])) + c_dfp = (100.0 - atof (argv[c])); + else if (path == NULL || path[0] == 0) + path = strscpy (path, argv[c]); + } + + if (path == NULL) { + path = malloc (1); + if (path == NULL) + terminate (STATE_UNKNOWN, "Could not malloc empty path\n"); + path[0] = 0; + } + + return validate_arguments (); +} + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"warning", required_argument, 0, 'w'}, + {"critical", required_argument, 0, 'c'}, + {"timeout", required_argument, 0, 't'}, + {"path", required_argument, 0, 'p'}, + {"partition", required_argument, 0, 'p'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+?Vhvt:c:w:p:", long_options, &option_index); +#else + c = getopt (argc, argv, "+?Vhvt:c:w:p:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 't': + case 'c': + case 'w': + case 'p': + i++; + } + + switch (c) { + case 'w': /* warning time threshold */ + if (is_intnonneg (optarg)) { + w_df = atoi (optarg); + break; + } + else if (strpbrk (optarg, ",:") && + strstr (optarg, "%") && + sscanf (optarg, "%d%*[:,]%f%%", &w_df, &w_dfp) == 2) { + break; + } + else if (strstr (optarg, "%") && sscanf (optarg, "%f%%", &w_dfp) == 1) { + break; + } + else { + usage ("Warning threshold must be integer or percentage!\n"); + } + case 'c': /* critical time threshold */ + if (is_intnonneg (optarg)) { + c_df = atoi (optarg); + break; + } + else if (strpbrk (optarg, ",:") && + strstr (optarg, "%") && + sscanf (optarg, "%d%*[,:]%f%%", &c_df, &c_dfp) == 2) { + break; + } + else if (strstr (optarg, "%") && sscanf (optarg, "%f%%", &c_dfp) == 1) { + break; + } + else { + usage ("Critical threshold must be integer or percentage!\n"); + } + case 't': /* timeout period */ + if (is_integer (optarg)) { + timeout_interval = atoi (optarg); + break; + } + else { + usage ("Timeout Interval must be an integer!\n"); + } + case 'p': /* path or partition */ + path = optarg; + break; + case 'v': /* verbose */ + verbose = TRUE; + break; + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("check_disk: unrecognized option\n"); + break; + } + } + return i; +} + +int +validate_arguments () +{ + if (w_df < 0 && c_df < 0 && w_dfp < 0 && c_dfp < 0) { + printf ("INPUT ERROR: Unable to parse command line\n"); + return ERROR; + } + else if ((w_dfp >= 0 || c_dfp >= 0) + && (w_dfp < 0 || c_dfp < 0 || w_dfp > 100 || c_dfp > 100 + || c_dfp > w_dfp)) { + printf + ("INPUT ERROR: C_DFP (%f) should be less than W_DFP (%f) and both should be between zero and 100 percent, inclusive\n", + c_dfp, w_dfp); + return ERROR; + } + else if ((w_df > 0 || c_df > 0) && (w_df < 0 || c_df < 0 || c_df > w_df)) { + printf + ("INPUT ERROR: C_DF (%d) should be less than W_DF (%d) and both should be greater than zero\n", + c_df, w_df); + return ERROR; + } + else { + return OK; + } +} + +int +check_disk (usp, free_disk) +{ + int result = STATE_UNKNOWN; + /* check the percent used space against thresholds */ + if (usp >= 0 && usp >= (100.0 - c_dfp)) + result = STATE_CRITICAL; + else if (c_df >= 0 && free_disk <= c_df) + result = STATE_CRITICAL; + else if (usp >= 0 && usp >= (100.0 - w_dfp)) + result = STATE_WARNING; + else if (w_df >= 0 && free_disk <= w_df) + result = STATE_WARNING; + else if (usp >= 0.0) + result = STATE_OK; + return result; +} + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Ethan Galstad/Karl DeBisschop\n\n" + "This plugin will check the percent of used disk space on a mounted\n" + "file system and generate an alert if percentage is above one of the\n" + "threshold values.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -w, --warning=INTEGER\n" + " Exit with WARNING status if less than INTEGER kilobytes of disk are free\n" + " -w, --warning=PERCENT%%\n" + " Exit with WARNING status if more than PERCENT of disk space is free\n" + " -c, --critical=INTEGER\n" + " Exit with CRITICAL status if less than INTEGER kilobytes of disk are free\n" + " -c, --critical=PERCENT%%\n" + " Exit with CRITCAL status if more than PERCENT of disk space is free\n" + " -p, --path=PATH, --partition=PARTTION\n" + " Path or partition (checks all mounted partitions if unspecified)\n" + " -v, --verbose\n" + " Show details for command-line debugging (do not use with nagios server)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" " Print version information\n\n"); + support (); +} + +void +print_usage (void) +{ + printf + ("Usage: %s -w limit -c limit [-p path] [-t timeout] [--verbose]\n" + " %s (-h|--help)\n" + " %s (-V|--version)\n", PROGNAME, PROGNAME, PROGNAME); +} diff --git a/plugins/check_dns.c b/plugins/check_dns.c new file mode 100644 index 00000000..eaff4372 --- /dev/null +++ b/plugins/check_dns.c @@ -0,0 +1,415 @@ +/****************************************************************************** + * + * CHECK_DNS.C + * + * Program: DNS plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * Last Modified: $Date$ + * + * Notes: + * - Safe popen added by Karl DeBisschop 9-11-99 + * + * Command line: CHECK_DNS [dns_server] + * + * Description: + * + * This program will use the nslookup program to obtain the IP address + * for a given host name. A optional DNS server may be specified. If + * no DNS server is specified, the default server(s) for the system + * are used. + * + * Return Values: + * OK The DNS query was successful (host IP address was returned). + * WARNING The DNS server responded, but could not fulfill the request. + * CRITICAL The DNS server is not responding or encountered an error. + * + * License Information: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "common.h" +#include "popen.h" +#include "utils.h" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +void print_usage (char *); +void print_help (char *); +int error_scan (char *); + +#define ADDRESS_LENGTH 256 +char query_address[ADDRESS_LENGTH] = ""; +char dns_server[ADDRESS_LENGTH] = ""; +char ptr_server[ADDRESS_LENGTH] = ""; +int verbose = FALSE; + +int +main (int argc, char **argv) +{ + char *command_line = NULL; + char input_buffer[MAX_INPUT_BUFFER]; + char *output = NULL; + char *address = NULL; + char *temp_buffer = NULL; + int result = STATE_UNKNOWN; + + /* Set signal handling and alarm */ + if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { + printf ("Cannot catch SIGALRM"); + return STATE_UNKNOWN; + } + + if (process_arguments (argc, argv) != OK) { + print_usage (my_basename (argv[0])); + return STATE_UNKNOWN; + } + + /* get the command to run */ + command_line = ssprintf (command_line, "%s %s %s", NSLOOKUP_COMMAND, + query_address, dns_server); + + alarm (timeout_interval); + time (&start_time); + + if (verbose) + printf ("%s\n", command_line); + /* run the command */ + child_process = spopen (command_line); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", command_line); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) + printf ("Could not open stderr for %s\n", command_line); + + /* scan stdout */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + + if (verbose) + printf ("%s\n", input_buffer); + + if (strstr (input_buffer, ".in-addr.arpa")) { + if ((temp_buffer = strstr (input_buffer, "name = "))) + address = strscpy (address, temp_buffer + 7); + else { + output = strscpy (output, "Unknown error (plugin)"); + result = STATE_WARNING; + } + } + + /* the server is responding, we just got the host name... */ + if (strstr (input_buffer, "Name:")) { + + /* get the host address */ + if (!fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) + break; + + if (verbose) + printf ("%s\n", input_buffer); + + if ((temp_buffer = index (input_buffer, ':'))) { + address = strscpy (address, temp_buffer + 2); + strip (address); + result = STATE_OK; + } + else { + output = strscpy (output, "Unknown error (plugin)"); + result = STATE_WARNING; + } + + break; + } + + result = error_scan (input_buffer); + if (result != STATE_OK) { + output = strscpy (output, 1 + index (input_buffer, ':')); + break; + } + + } + + /* scan stderr */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { + if (error_scan (input_buffer) != STATE_OK) { + result = max (result, error_scan (input_buffer)); + output = strscpy (output, 1 + index (input_buffer, ':')); + } + } + + /* close stderr */ + (void) fclose (child_stderr); + + /* close stdout */ + if (spclose (child_process)) { + result = max (result, STATE_WARNING); + if (!strcmp (output, "")) + output = strscpy (output, "nslookup returned error status"); + } + + (void) time (&end_time); + + if (result == STATE_OK) + printf ("DNS ok - %d seconds response time, Address(es) is/are %s\n", + (int) (end_time - start_time), address); + else if (result == STATE_WARNING) + printf ("DNS WARNING - %s\n", + !strcmp (output, "") ? " Probably a non-existent host/domain" : output); + else if (result == STATE_CRITICAL) + printf ("DNS CRITICAL - %s\n", + !strcmp (output, "") ? " Probably a non-existent host/domain" : output); + else + printf ("DNS problem - %s\n", + !strcmp (output, "") ? " Probably a non-existent host/domain" : output); + + return result; +} + +int +error_scan (char *input_buffer) +{ + + /* the DNS lookup timed out */ + if (strstr (input_buffer, + "Note: nslookup is deprecated and may be removed from future releases.") + || strstr (input_buffer, + "Consider using the `dig' or `host' programs instead. Run nslookup with") + || strstr (input_buffer, + "the `-sil[ent]' option to prevent this message from appearing.")) + return STATE_OK; + + /* the DNS lookup timed out */ + else if (strstr (input_buffer, "Timed out")) + return STATE_WARNING; + + /* DNS server is not running... */ + else if (strstr (input_buffer, "No response from server")) + return STATE_CRITICAL; + + /* Host name is valid, but server doesn't have records... */ + else if (strstr (input_buffer, "No records")) + return STATE_WARNING; + + /* Host or domain name does not exist */ + else if (strstr (input_buffer, "Non-existent")) + return STATE_CRITICAL; + else if (strstr (input_buffer, "** server can't find")) + return STATE_CRITICAL; + else if(strstr(input_buffer,"NXDOMAIN")) /* 9.x */ + return STATE_CRITICAL; + + /* Connection was refused */ + else if (strstr (input_buffer, "Connection refused")) + return STATE_CRITICAL; + + /* Network is unreachable */ + else if (strstr (input_buffer, "Network is unreachable")) + return STATE_CRITICAL; + + /* Internal server failure */ + else if (strstr (input_buffer, "Server failure")) + return STATE_CRITICAL; + + /* DNS server refused to service request */ + else if (strstr (input_buffer, "Refused")) + return STATE_CRITICAL; + + /* Request error */ + else if (strstr (input_buffer, "Format error")) + return STATE_WARNING; + + else + return STATE_OK; + +} + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + + c = 0; + while (c += (call_getopt (argc - c, &argv[c]))) { + if (argc <= c) + break; + if (query_address[0] == 0) { + if (is_host (argv[c]) == FALSE) { + printf ("Invalid name/address: %s\n\n", argv[c]); + return ERROR; + } + if (strlen (argv[c]) >= ADDRESS_LENGTH) + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); + strcpy (query_address, argv[c]); + } + else if (dns_server[0] == 0) { + if (is_host (argv[c]) == FALSE) { + printf ("Invalid name/address: %s\n\n", argv[c]); + return ERROR; + } + if (strlen (argv[c]) >= ADDRESS_LENGTH) + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); + strcpy (dns_server, argv[c]); + } + } + + return validate_arguments (); + +} + +int +call_getopt (int argc, char **argv) +{ + int c, i = 1; + +#ifdef HAVE_GETOPT_H + int opt_index = 0; + static struct option long_opts[] = { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {"timeout", required_argument, 0, 't'}, + {"hostname", required_argument, 0, 'H'}, + {"server", required_argument, 0, 's'}, + {"reverse-server", required_argument, 0, 'r'}, + {0, 0, 0, 0} + }; +#endif + + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+?hVvt:H:s:r:", long_opts, &opt_index); +#else + c = getopt (argc, argv, "+?hVvt:H:s:r:"); +#endif + + if (c == -1 || c == EOF) + break; + + i++; + switch (c) { + case 't': + case 'H': + case 's': + case 'r': + i++; + } + + switch (c) { + case '?': /* args not parsable */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (my_basename (argv[0])); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'v': /* version */ + verbose = TRUE; + break; + case 't': /* timeout period */ + timeout_interval = atoi (optarg); + break; + case 'H': /* hostname */ + if (is_host (optarg) == FALSE) { + printf ("Invalid host name/address\n\n"); + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + } + if (strlen (optarg) >= ADDRESS_LENGTH) + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); + strcpy (query_address, optarg); + break; + case 's': /* server name */ + if (is_host (optarg) == FALSE) { + printf ("Invalid server name/address\n\n"); + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + } + if (strlen (optarg) >= ADDRESS_LENGTH) + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); + strcpy (dns_server, optarg); + break; + case 'r': /* reverse server name */ + if (is_host (optarg) == FALSE) { + printf ("Invalid host name/address\n\n"); + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + } + if (strlen (optarg) >= ADDRESS_LENGTH) + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); + strcpy (ptr_server, optarg); + break; + } + } + return i; +} + +int +validate_arguments () +{ + if (query_address[0] == 0) + return ERROR; + else + return OK; +} + +void +print_usage (char *cmd) +{ + printf ("Usage: %s -H host [-s server] [-t timeout]\n" " %s --help\n" + " %s --version\n", cmd, cmd, cmd); +} + +void +print_help (char *cmd) +{ + print_revision (cmd, "$Revision$"); + printf ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n\n"); + print_usage (cmd); + printf ("\n"); + printf + ("-H, --hostname=HOST\n" + " The name or address you want to query\n" + "-s, --server=HOST\n" + " Optional DNS server you want to use for the lookup\n" + "-t, --timeout=INTEGER\n" + " Seconds before connection times out (default: %d)\n" + "-h, --help\n" + " Print detailed help\n" + "-V, --version\n" + " Print version numbers and license information\n" + "\n" + "This plugin uses the nslookup program to obtain the IP address\n" + "for the given host/domain query. A optional DNS server to use may\n" + "be specified. If no DNS server is specified, the default server(s)\n" + "specified in /etc/resolv.conf will be used.\n", DEFAULT_SOCKET_TIMEOUT); +} diff --git a/plugins/check_dummy.c b/plugins/check_dummy.c new file mode 100644 index 00000000..c2a5b7eb --- /dev/null +++ b/plugins/check_dummy.c @@ -0,0 +1,100 @@ +/************************************************************* + * + * CHECK_DUMMY.C + * + * Program: Dummy plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * Last Modified: $Date$ + * + * Command line: CHECK_DUMMY + * + * Description: + * + * This plugin will simply return the state corresponding to the + * numerical value of the argument. + * + * License Information: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + **************************************************************/ + +#include "config.h" +#include "common.h" +#include "utils.h" + +void print_help (char *); +void print_usage (char *); + +int +main (int argc, char **argv) +{ + int result; + + if (argc != 2) { + printf ("Incorrect number of arguments supplied\n"); + exit (STATE_UNKNOWN); + } + else if (strcmp (argv[1], "-V") == 0 || strcmp (argv[1], "--version") == 0) { + print_revision (argv[0], "$Revision$"); + exit (STATE_OK); + } + else if (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0) { + print_help (argv[0]); + exit (STATE_OK); + } + else if (!is_integer (argv[1])) { + print_usage (argv[0]); + exit (STATE_UNKNOWN); + } + result = atoi (argv[1]); + + switch (result) { + case STATE_OK: + printf ("Status is OK\n"); + break; + case STATE_WARNING: + printf ("Status is at WARNING level\n"); + break; + case STATE_CRITICAL: + printf ("Status is CRITICAL\n"); + break; + default: + printf ("Status is UNKNOWN\n"); + result = STATE_UNKNOWN; + } + + return result; +} + +void +print_help (char *cmd) +{ + print_revision (cmd, "$Revision$"); + printf ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n" + "License: GPL\n\n"); + print_usage (cmd); + printf + ("\nThis plugin will simply return the state corresponding to the numeric value\n" + "of the argument.\n"); +} + +void +print_usage (char *cmd) +{ + printf ("Usage: %s \n", cmd); +} diff --git a/plugins/check_fping.c b/plugins/check_fping.c new file mode 100644 index 00000000..f6531a54 --- /dev/null +++ b/plugins/check_fping.c @@ -0,0 +1,386 @@ +/****************************************************************************** +* +* CHECK_FPING.C +* +* Program: Fping plugin for Nagios +* License: GPL +* Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) +* $Id$ +* +* Modifications: +* +* 08-24-1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) +* Intial Coding +* 09-11-1999 Karl DeBisschop (kdebiss@alum.mit.edu) +* Change to spopen +* Fix so that state unknown is returned by default +* (formerly would give state ok if no fping specified) +* Add server_name to output +* Reformat to 80-character standard screen +* 11-18-1999 Karl DeBisschop (kdebiss@alum.mit.edu) +* set STATE_WARNING of stderr written or nonzero status returned +* +* Description: +* +* This plugin will use the /bin/fping command (form saint) to ping +* the specified host for a fast check if the host is alive. Note that +* it is necessary to set the suid flag on fping. +******************************************************************************/ + +#include "config.h" +#include "common.h" +#include "popen.h" +#include "utils.h" + +#define PROGNAME "check_fping" +#define PACKET_COUNT 1 +#define PACKET_SIZE 56 +#define UNKNOWN_PACKET_LOSS 200 /* 200% */ +#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */ + +#define PL 0 +#define RTA 1 + +int textscan (char *buf); +int process_arguments (int, char **); +int get_threshold (char *arg, char *rv[2]); +void print_usage (void); +void print_help (void); + +char *server_name = NULL; +int cpl = UNKNOWN_PACKET_LOSS; +int wpl = UNKNOWN_PACKET_LOSS; +double crta = UNKNOWN_TRIP_TIME; +double wrta = UNKNOWN_TRIP_TIME; +int packet_size = PACKET_SIZE; +int packet_count = PACKET_COUNT; +int verbose = FALSE; + +int +main (int argc, char **argv) +{ + int status = STATE_UNKNOWN; + char *server = NULL; + char *command_line = NULL; + char *input_buffer = NULL; + input_buffer = malloc (MAX_INPUT_BUFFER); + + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments\n"); + + server = strscpy (server, server_name); + + /* compose the command */ + command_line = ssprintf + (command_line, "%s -b %d -c %d %s", + PATH_TO_FPING, packet_size, packet_count, server); + + if (verbose) + printf ("%s\n", command_line); + + /* run the command */ + child_process = spopen (command_line); + if (child_process == NULL) { + printf ("Unable to open pipe: %s\n", command_line); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) { + printf ("Could not open stderr for %s\n", command_line); + } + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + if (verbose) + printf ("%s", input_buffer); + status = max (status, textscan (input_buffer)); + } + + /* If we get anything on STDERR, at least set warning */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { + status = max (status, STATE_WARNING); + if (verbose) + printf ("%s", input_buffer); + status = max (status, textscan (input_buffer)); + } + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) + status = max (status, STATE_WARNING); + + printf ("FPING %s - %s\n", state_text (status), server_name); + + return status; +} + + + + +int +textscan (char *buf) +{ + char *rtastr = NULL; + char *losstr = NULL; + double loss; + double rta; + int status = STATE_UNKNOWN; + + if (strstr (buf, "not found")) { + terminate (STATE_CRITICAL, "FPING unknown - %s not found\n", server_name); + + } + else if (strstr (buf, "is unreachable") || strstr (buf, "Unreachable")) { + terminate (STATE_CRITICAL, "FPING critical - %s is unreachable\n", + "host"); + + } + else if (strstr (buf, "is down")) { + terminate (STATE_CRITICAL, "FPING critical - %s is down\n", server_name); + + } + else if (strstr (buf, "is alive")) { + status = STATE_OK; + + } + else if (strstr (buf, "xmt/rcv/%loss") && strstr (buf, "min/avg/max")) { + losstr = strstr (buf, "="); + losstr = 1 + strstr (losstr, "/"); + losstr = 1 + strstr (losstr, "/"); + rtastr = strstr (buf, "min/avg/max"); + rtastr = strstr (rtastr, "="); + rtastr = 1 + index (rtastr, '/'); + loss = strtod (losstr, NULL); + rta = strtod (rtastr, NULL); + if (cpl != UNKNOWN_PACKET_LOSS && loss > cpl) + status = STATE_CRITICAL; + else if (crta != UNKNOWN_TRIP_TIME && rta > crta) + status = STATE_CRITICAL; + else if (wpl != UNKNOWN_PACKET_LOSS && loss > wpl) + status = STATE_WARNING; + else if (wrta != UNKNOWN_TRIP_TIME && rta > wrta) + status = STATE_WARNING; + else + status = STATE_OK; + terminate (status, "FPING %s - %s (loss=%f%%, rta=%f ms)\n", + state_text (status), server_name, loss, rta); + + } + else { + status = max (status, STATE_WARNING); + } + + return status; +} + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + char *rv[2]; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"bytes", required_argument, 0, 'b'}, + {"number", required_argument, 0, 'n'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + rv[PL] = NULL; + rv[RTA] = NULL; + + if (argc < 2) + return ERROR; + + if (!is_option (argv[1])) { + server_name = argv[1]; + argv[1] = argv[0]; + argv = &argv[1]; + argc--; + } + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVvH:c:w:b:n:", long_options, &option_index); +#else + c = getopt (argc, argv, "+hVvH:c:w:b:n:"); +#endif + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case '?': /* print short usage statement if args not parsable */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'v': /* verbose mode */ + verbose = TRUE; + break; + case 'H': /* hostname */ + if (is_host (optarg) == FALSE) { + printf ("Invalid host name/address\n\n"); + print_usage (); + exit (STATE_UNKNOWN); + } + server_name = strscpy (server_name, optarg); + break; + case 'c': + get_threshold (optarg, rv); + if (rv[RTA]) { + crta = strtod (rv[RTA], NULL); + rv[RTA] = NULL; + } + if (rv[PL]) { + cpl = atoi (rv[PL]); + rv[PL] = NULL; + } + break; + case 'w': + get_threshold (optarg, rv); + if (rv[RTA]) { + wrta = strtod (rv[RTA], NULL); + rv[RTA] = NULL; + } + if (rv[PL]) { + wpl = atoi (rv[PL]); + rv[PL] = NULL; + } + break; + case 'b': /* bytes per packet */ + if (is_intpos (optarg)) + packet_size = atoi (optarg); + else + usage ("Packet size must be a positive integer"); + break; + case 'n': /* number of packets */ + if (is_intpos (optarg)) + packet_count = atoi (optarg); + else + usage ("Packet count must be a positive integer"); + break; + } + } + + + if (server_name == NULL) + usage ("Host name was not supplied\n\n"); + + return OK; +} + + + + + +int +get_threshold (char *arg, char *rv[2]) +{ + char *arg1 = NULL; + char *arg2 = NULL; + + arg1 = strscpy (arg1, arg); + if (strpbrk (arg1, ",:")) + arg2 = 1 + strpbrk (arg1, ",:"); + + if (arg2) { + arg1[strcspn (arg1, ",:")] = 0; + if (strstr (arg1, "%") && strstr (arg2, "%")) + terminate (STATE_UNKNOWN, + "%s: Only one threshold may be packet loss (%s)\n", PROGNAME, + arg); + if (!strstr (arg1, "%") && !strstr (arg2, "%")) + terminate (STATE_UNKNOWN, + "%s: Only one threshold must be packet loss (%s)\n", + PROGNAME, arg); + } + + if (arg2 && strstr (arg2, "%")) { + rv[PL] = arg2; + rv[RTA] = arg1; + } + else if (arg2) { + rv[PL] = arg1; + rv[RTA] = arg2; + } + else if (strstr (arg1, "%")) { + rv[PL] = arg1; + } + else { + rv[RTA] = arg1; + } + + return OK; +} + + + + + +void +print_usage (void) +{ + printf ("Usage: %s \n", PROGNAME); +} + + + + + +void +print_help (void) +{ + + print_revision (PROGNAME, "$Revision$"); + + printf + ("Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)\n\n" + "This plugin will use the /bin/fping command (from saint) to ping the\n" + "specified host for a fast check if the host is alive. Note that it is\n" + "necessary to set the suid flag on fping.\n\n"); + + print_usage (); + + printf + ("\nOptions:\n" + "-H, --hostname=HOST\n" + " Name or IP Address of host to ping (IP Address bypasses name lookup,\n" + " reducing system load)\n" + "-w, --warning=THRESHOLD\n" + " warning threshold pair\n" + "-c, --critical=THRESHOLD\n" + " critical threshold pair\n" + "-b, --bytes=INTEGER\n" + " Size of ICMP packet (default: %d)\n" + "-n, --number=INTEGER\n" + " Number of ICMP packets to send (default: %d)\n" + "-v, --verbose\n" + " Show details for command-line debugging (do not use with nagios server)\n" + "-h, --help\n" + " Print this help screen\n" + "-V, --version\n" + " Print version information\n" + "THRESHOLD is ,%% where is the round trip average travel\n" + "time (ms) which triggers a WARNING or CRITICAL state, and is the\n" + "percentage of packet loss to trigger an alarm state.\n", + PACKET_SIZE, PACKET_COUNT); +} diff --git a/plugins/check_ftp.c b/plugins/check_ftp.c new file mode 100644 index 00000000..1c65d642 --- /dev/null +++ b/plugins/check_ftp.c @@ -0,0 +1,337 @@ +/****************************************************************************** + * + * CHECK_FTP.C + * + * Program: FTP plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * $Id$ + * + * Description: + * + * This plugin will attempt to open an FTP connection with the host. + * Successul connects return STATE_OK, refusals and timeouts return + * STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful + * connects, but incorrect reponse messages from the host result in + * STATE_WARNING return values. + * + * License Information: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define PROGNAME "check_ftp" + +#define FTP_PORT 21 +#define FTP_EXPECT "220" +#define FTP_QUIT "QUIT\n" + +int process_arguments (int, char **); +int call_getopt (int, char **); +void print_usage (void); +void print_help (void); + +time_t start_time, end_time; +int server_port = FTP_PORT; +char *server_address = NULL; +char *server_expect = NULL; +int warning_time = 0; +int check_warning_time = FALSE; +int critical_time = 0; +int check_critical_time = FALSE; +int verbose = FALSE; + + +int +main (int argc, char **argv) +{ + int sd; + int result; + char buffer[MAX_INPUT_BUFFER]; + + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + + /* try to connect to the host at the given port number */ + time (&start_time); + result = my_tcp_connect (server_address, server_port, &sd); + + /* we connected, so close connection before exiting */ + if (result == STATE_OK) { + + /* watch for the FTP connection string */ + result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); + + /* strip the buffer of carriage returns */ + strip (buffer); + + /* return a WARNING status if we couldn't read any data */ + if (result == -1) { + printf ("recv() failed\n"); + result = STATE_WARNING; + } + + else { + + /* make sure we find the response we are looking for */ + if (!strstr (buffer, server_expect)) { + + if (server_port == FTP_PORT) + printf ("Invalid FTP response received from host\n"); + else + printf ("Invalid FTP response received from host on port %d\n", + server_port); + result = STATE_WARNING; + } + + else { + time (&end_time); + + result = STATE_OK; + + if (check_critical_time == TRUE + && (end_time - start_time) > critical_time) result = + STATE_CRITICAL; + else if (check_warning_time == TRUE + && (end_time - start_time) > warning_time) result = + STATE_WARNING; + + if (verbose == TRUE) + printf ("FTP %s - %d sec. response time, %s\n", + (result == STATE_OK) ? "ok" : "problem", + (int) (end_time - start_time), buffer); + else + printf ("FTP %s - %d second response time\n", + (result == STATE_OK) ? "ok" : "problem", + (int) (end_time - start_time)); + } + } + + /* close the connection */ + send (sd, FTP_QUIT, strlen (FTP_QUIT), 0); + close (sd); + } + + /* reset the alarm */ + alarm (0); + + return result; +} + + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + usage ("\n"); + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + c = 0; + while ((c += call_getopt (argc - c, &argv[c])) < argc) { + + if (is_option (argv[c])) + continue; + + if (server_address == NULL) { + if (argc > c) { + if (is_host (argv[c]) == FALSE) + usage ("Invalid host name/address\n"); + server_address = argv[c]; + } + else { + usage ("Host name was not supplied\n"); + } + } + } + + if (server_expect == NULL) + server_expect = strscpy (NULL, FTP_EXPECT); + + return OK; +} + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"expect", required_argument, 0, 'e'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"timeout", required_argument, 0, 'w'}, + {"port", required_argument, 0, 'p'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVvH:e:c:w:t:p:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+hVvH:e:c:w:t:p:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 'H': + case 'e': + case 'c': + case 'w': + case 't': + case 'p': + i++; + } + + switch (c) { + case '?': /* print short usage statement if args not parsable */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'v': /* verbose mode */ + verbose = TRUE; + break; + case 'H': /* hostname */ + if (is_host (optarg) == FALSE) + usage ("Invalid host name/address\n"); + server_address = optarg; + break; + case 'e': /* expect */ + server_expect = optarg; + break; + case 'c': /* critical */ + if (!is_intnonneg (optarg)) + usage ("Critical threshold must be a nonnegative integer\n"); + critical_time = atoi (optarg); + check_critical_time = TRUE; + break; + case 'w': /* warning */ + if (!is_intnonneg (optarg)) + usage ("Warning threshold must be a nonnegative integer\n"); + warning_time = atoi (optarg); + check_warning_time = TRUE; + break; + case 't': /* timeout */ + if (!is_intnonneg (optarg)) + usage ("Timeout interval must be a nonnegative integer\n"); + socket_timeout = atoi (optarg); + break; + case 'p': /* port */ + if (!is_intnonneg (optarg)) + usage ("Serevr port must be a nonnegative integer\n"); + server_port = atoi (optarg); + break; + } + } + return i; +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H [-e expect] [-p port] [-w warn_time]\n" + " [-c crit_time] [-t to_sec] [-v]\n", PROGNAME); +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n\n" + "This plugin tests an FTP connection with the specified host.\n\n"); + print_usage (); + printf + ("Options:\n" + " -H, --hostname=ADDRESS\n" + " Host name argument for servers using host headers (use numeric\n" + " address if possible to bypass DNS lookup).\n" + " -e, --expect=STRING\n" + " String to expect in first line of server response (default: %s)\n" + " -p, --port=INTEGER\n" + " Port number (default: %d)\n" + " -w, --warning=INTEGER\n" + " Response time to result in warning status (seconds)\n" + " -c, --critical=INTEGER\n" + " Response time to result in critical status (seconds)\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection times out (default: %d)\n" + " -v" + " Show details for command-line debugging (do not use with nagios server)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n", + FTP_EXPECT, FTP_PORT, DEFAULT_SOCKET_TIMEOUT); +} diff --git a/plugins/check_game.c b/plugins/check_game.c new file mode 100644 index 00000000..63d1be62 --- /dev/null +++ b/plugins/check_game.c @@ -0,0 +1,287 @@ +/****************************************************************************** + * + * CHECK_GAME.C + * + * Program: GAME plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ian Cass (ian@knowledge.com) + * + * Last Modified: $Date$ + * + * Mod History + * + * 25-8-99 Ethan Galstad + * Integrated with common plugin code, minor cleanup stuff + * + * 17-8-99 version 1.1b + * + * 17-8-99 make port a separate argument so we can use something like + * check_game q2s!27910 with the probe set up as + * check_game $ARG1$ $HOSTADDRESS$ $ARG2$ + * + * 17-8-99 Put in sanity check for ppl who enter the wrong server type + * + * 17-8-99 Release version 1.0b + * + * Command line: CHECK_GAME [port] + * + * server type = a server type that qstat understands (type qstat & look at the -default line) + * ip_address = either a dotted address or a FQD name + * port = defaults game default port + * + * + * Description: + * + * Needed to explore writing my own probes for nagios. It looked + * pretty simple so I thought I'd write one for monitoring the status + * of game servers. It uses qstat to do the actual monitoring and + * analyses the result. Doing it this way means I can support all the + * servers that qstat does and will do in the future. + * + * + * Dependencies: + * + * This plugin uses the 'qstat' command If you don't + * have the package installed you will need to download it from + * http://www.activesw.com/people/steve/qstat.html or any popular files archive + * before you can use this plugin. + * + * License Information: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "utils.h" + +int process_arguments (int, char **); + +#define QSTAT_DATA_DELIMITER "," + +#define QSTAT_HOST_ERROR "ERROR" +#define QSTAT_HOST_DOWN "DOWN" +#define QSTAT_HOST_TIMEOUT "TIMEOUT" +#define QSTAT_MAX_RETURN_ARGS 12 + +char server_ip[MAX_HOST_ADDRESS_LENGTH]; +char game_type[MAX_INPUT_BUFFER]; +char port[MAX_INPUT_BUFFER]; + +int qstat_game_field = 2; +int qstat_map_field = 3; +int qstat_ping_field = 5; + + +int +main (int argc, char **argv) +{ + char command_line[MAX_INPUT_BUFFER]; + int result; + FILE *fp; + char input_buffer[MAX_INPUT_BUFFER]; + char response[MAX_INPUT_BUFFER]; + char *temp_ptr; + int found; + char *p, *ret[QSTAT_MAX_RETURN_ARGS]; + int i; + + result = process_arguments (argc, argv); + + if (result != OK) { + printf ("Incorrect arguments supplied\n"); + printf ("\n"); + print_revision (argv[0], "$Revision$"); + printf ("Copyright (c) 1999 Ian Cass, Knowledge Matters Limited\n"); + printf ("License: GPL\n"); + printf ("\n"); + printf + ("Usage: %s [-p port] [-gf game_field] [-mf map_field] [-pf ping_field]\n", + argv[0]); + printf ("\n"); + printf ("Options:\n"); + printf + (" = Game type that is recognised by qstat (without the leading dash)\n"); + printf + (" = The IP address of the device you wish to query\n"); + printf (" [port] = Optional port of which to connect\n"); + printf + (" [game_field] = Field number in raw qstat output that contains game name\n"); + printf + (" [map_field] = Field number in raw qstat output that contains map name\n"); + printf + (" [ping_field] = Field number in raw qstat output that contains ping time\n"); + printf ("\n"); + printf ("Notes:\n"); + printf + ("- This plugin uses the 'qstat' command, the popular game server status query tool .\n"); + printf + (" If you don't have the package installed, you will need to download it from\n"); + printf + (" http://www.activesw.com/people/steve/qstat.html before you can use this plugin.\n"); + printf ("\n"); + return STATE_UNKNOWN; + } + + result = STATE_OK; + + /* create the command line to execute */ + snprintf (command_line, sizeof (command_line) - 1, "%s -raw %s -%s %s%s", + PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, game_type, server_ip, port); + command_line[sizeof (command_line) - 1] = 0; + + /* run the command */ + fp = popen (command_line, "r"); + if (fp == NULL) { + printf ("Error - Could not open pipe: %s\n", command_line); + return STATE_UNKNOWN; + } + + found = 0; + fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp); /* Only interested in the first line */ + + /* strip the newline character from the end of the input */ + input_buffer[strlen (input_buffer) - 1] = 0; + + /* sanity check */ + /* was thinking about running qstat without any options, capturing the + -default line, parsing it & making an array of all know server types + but thought this would be too much hassle considering this is a tool + for intelligent sysadmins (ha). Could put a static array of known + server types in a header file but then we'd be limiting ourselves + + In the end, I figured I'd simply let an error occur & then trap it + */ + + if (!strncmp (input_buffer, "unknown option", 14)) { + printf ("ERROR: Host type parameter incorrect!\n"); + result = STATE_CRITICAL; + return result; + } + + /* initialize the returned data buffer */ + for (i = 0; i < QSTAT_MAX_RETURN_ARGS; i++) + ret[i] = ""; + + i = 0; + p = (char *) strtok (input_buffer, QSTAT_DATA_DELIMITER); + while (p != NULL) { + ret[i] = p; + p = (char *) strtok (NULL, QSTAT_DATA_DELIMITER); + i++; + if (i >= QSTAT_MAX_RETURN_ARGS) + break; + } + + if (strstr (ret[2], QSTAT_HOST_ERROR)) { + printf ("ERROR: Host not found\n"); + result = STATE_CRITICAL; + } + else if (strstr (ret[2], QSTAT_HOST_DOWN)) { + printf ("ERROR: Game server down or unavailable\n"); + result = STATE_CRITICAL; + } + else if (strstr (ret[2], QSTAT_HOST_TIMEOUT)) { + printf ("ERROR: Game server timeout\n"); + result = STATE_CRITICAL; + } + else { + printf ("OK: %s (%s), Ping: %s ms\n", ret[qstat_game_field], + ret[qstat_map_field], ret[qstat_ping_field]); + } + + /* close the pipe */ + pclose (fp); + + return result; +} + + + +int +process_arguments (int argc, char **argv) +{ + int x; + + /* not enough options were supplied */ + if (argc < 3) + return ERROR; + + /* first option is always the game type */ + strncpy (game_type, argv[1], sizeof (game_type) - 1); + game_type[sizeof (game_type) - 1] = 0; + + /* Second option is always the server name */ + strncpy (server_ip, argv[2], sizeof (server_ip) - 1); + server_ip[sizeof (server_ip) - 1] = 0; + + /* process all remaining arguments */ + for (x = 4; x <= argc; x++) { + + /* we got the port number to connect to */ + if (!strcmp (argv[x - 1], "-p")) { + if (x < argc) { + snprintf (port, sizeof (port) - 2, ":%s", argv[x]); + port[sizeof (port) - 1] = 0; + x++; + } + else + return ERROR; + } + + /* we got the game field */ + else if (!strcmp (argv[x - 1], "-gf")) { + if (x < argc) { + qstat_game_field = atoi (argv[x]); + if (qstat_game_field < 0 || qstat_game_field > QSTAT_MAX_RETURN_ARGS) + return ERROR; + x++; + } + else + return ERROR; + } + + /* we got the map field */ + else if (!strcmp (argv[x - 1], "-mf")) { + if (x < argc) { + qstat_map_field = atoi (argv[x]); + if (qstat_map_field < 0 || qstat_map_field > QSTAT_MAX_RETURN_ARGS) + return ERROR; + x++; + } + else + return ERROR; + } + + /* we got the ping field */ + else if (!strcmp (argv[x - 1], "-pf")) { + if (x < argc) { + qstat_ping_field = atoi (argv[x]); + if (qstat_ping_field < 0 || qstat_ping_field > QSTAT_MAX_RETURN_ARGS) + return ERROR; + x++; + } + else + return ERROR; + } + + /* else we got something else... */ + else + return ERROR; + } + + return OK; +} diff --git a/plugins/check_hpjd.c b/plugins/check_hpjd.c new file mode 100644 index 00000000..8234abdf --- /dev/null +++ b/plugins/check_hpjd.c @@ -0,0 +1,571 @@ +/****************************************************************************** +* +* CHECK_HPJD.C +* +* Program: HP printer plugin for Nagios +* License: GPL +* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) +* +* Last Modified: $Date$ +* +* Command line: CHECK_HPJD [community] +* +* Description: +* +* This plugin will attempt to check the status of an HP printer. The +* printer must have a JetDirect card installed and TCP/IP protocol +* stack enabled. This plugin has only been tested on a few printers +* and may not work well on all models of JetDirect cards. Multiple +* port JetDirect devices must have an IP address assigned to each +* port in order to be monitored. +* +* Dependencies: +* +* This plugin used the 'snmpget' command included with the UCD-SNMP +* package. If you don't have the package installed you will need to +* download it from http://ucd-snmp.ucdavis.edu before you can use +* this plugin. +* +* Return Values: +* +* UNKNOWN = The plugin could not read/process the output from the printer +* OK = Printer looks normal +* WARNING = Low toner, paper jam, intervention required, paper out, etc. +* CRITICAL = The printer could not be reached (it's probably turned off) +* +* Acknowledgements: +* +* The idea for the plugin (as well as some code) were taken from Jim +* Trocki's pinter alert script in his "mon" utility, found at +* http://www.kernel.org/software/mon +* +* Notes: +* 'JetDirect' is copyrighted by Hewlett-Packard. +* HP, please don't sue me... :-) +* +* License Information: +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + +#include "common.h" +#include "popen.h" +#include "utils.h" + +#define PROGNAME "check_hpjd" + +#define HPJD_LINE_STATUS ".1.3.6.1.4.1.11.2.3.9.1.1.2.1" +#define HPJD_PAPER_STATUS ".1.3.6.1.4.1.11.2.3.9.1.1.2.2" +#define HPJD_INTERVENTION_REQUIRED ".1.3.6.1.4.1.11.2.3.9.1.1.2.3" +#define HPJD_GD_PERIPHERAL_ERROR ".1.3.6.1.4.1.11.2.3.9.1.1.2.6" +#define HPJD_GD_PAPER_JAM ".1.3.6.1.4.1.11.2.3.9.1.1.2.8" +#define HPJD_GD_PAPER_OUT ".1.3.6.1.4.1.11.2.3.9.1.1.2.9" +#define HPJD_GD_TONER_LOW ".1.3.6.1.4.1.11.2.3.9.1.1.2.10" +#define HPJD_GD_PAGE_PUNT ".1.3.6.1.4.1.11.2.3.9.1.1.2.11" +#define HPJD_GD_MEMORY_OUT ".1.3.6.1.4.1.11.2.3.9.1.1.2.12" +#define HPJD_GD_DOOR_OPEN ".1.3.6.1.4.1.11.2.3.9.1.1.2.17" +#define HPJD_GD_PAPER_OUTPUT ".1.3.6.1.4.1.11.2.3.9.1.1.2.19" +#define HPJD_GD_STATUS_DISPLAY ".1.3.6.1.4.1.11.2.3.9.1.1.3" + +#define ONLINE 0 +#define OFFLINE 1 + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +void print_help (void); +void print_usage (void); + +char *community = NULL; +char *address = NULL; + +int +main (int argc, char **argv) +{ + char command_line[1024]; + int result; + int line; + char input_buffer[MAX_INPUT_BUFFER]; + char query_string[512]; + char error_message[MAX_INPUT_BUFFER]; + char *temp_buffer; + int line_status = ONLINE; + int paper_status = 0; + int intervention_required = 0; + int peripheral_error = 0; + int paper_jam = 0; + int paper_out = 0; + int toner_low = 0; + int page_punt = 0; + int memory_out = 0; + int door_open = 0; + int paper_output = 0; + char display_message[MAX_INPUT_BUFFER]; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + + /* removed ' 2>1' at end of command 10/27/1999 - EG */ + /* create the query string */ + sprintf + (query_string, + "%s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0", + HPJD_LINE_STATUS, + HPJD_PAPER_STATUS, + HPJD_INTERVENTION_REQUIRED, + HPJD_GD_PERIPHERAL_ERROR, + HPJD_GD_PAPER_JAM, + HPJD_GD_PAPER_OUT, + HPJD_GD_TONER_LOW, + HPJD_GD_PAGE_PUNT, + HPJD_GD_MEMORY_OUT, + HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, HPJD_GD_STATUS_DISPLAY); + + /* get the command to run */ + sprintf (command_line, "%s -v 1 %s %s %s", PATH_TO_SNMPGET, address, + community, query_string); + + /* run the command */ + child_process = spopen (command_line); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", command_line); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) { + printf ("Could not open stderr for %s\n", command_line); + } + + result = STATE_OK; + + line = 0; + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + + /* strip the newline character from the end of the input */ + if (input_buffer[strlen (input_buffer) - 1] == '\n') + input_buffer[strlen (input_buffer) - 1] = 0; + + line++; + + temp_buffer = strtok (input_buffer, "="); + temp_buffer = strtok (NULL, "="); + + switch (line) { + + case 1: /* 1st line should contain the line status */ + if (temp_buffer != NULL) + line_status = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 2: /* 2nd line should contain the paper status */ + if (temp_buffer != NULL) + paper_status = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 3: /* 3rd line should be intervention required */ + if (temp_buffer != NULL) + intervention_required = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 4: /* 4th line should be peripheral error */ + if (temp_buffer != NULL) + peripheral_error = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 5: /* 5th line should contain the paper jam status */ + if (temp_buffer != NULL) + paper_jam = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 6: /* 6th line should contain the paper out status */ + if (temp_buffer != NULL) + paper_out = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 7: /* 7th line should contain the toner low status */ + if (temp_buffer != NULL) + toner_low = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 8: /* did data come too slow for engine */ + if (temp_buffer != NULL) + page_punt = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 9: /* did we run out of memory */ + if (temp_buffer != NULL) + memory_out = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 10: /* is there a door open */ + if (temp_buffer != NULL) + door_open = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 11: /* is output tray full */ + if (temp_buffer != NULL) + paper_output = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 12: /* display panel message */ + if (temp_buffer != NULL) + strcpy (display_message, temp_buffer + 1); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + default: + break; + } + + /* break out of the read loop if we encounter an error */ + if (result != STATE_OK) + break; + } + + /* WARNING if output found on stderr */ + if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) + result = max (result, STATE_WARNING); + + /* close stderr */ + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) + result = max (result, STATE_WARNING); + + /* if there wasn't any output, display an error */ + if (line == 0) { + + /* + result=STATE_UNKNOWN; + strcpy(error_message,"Error: Could not read plugin output\n"); + */ + + /* might not be the problem, but most likely is.. */ + result = STATE_UNKNOWN; + sprintf (error_message, "Timeout: No response from %s\n", address); + } + + /* if we had no read errors, check the printer status results... */ + if (result == STATE_OK) { + + if (paper_jam) { + result = STATE_WARNING; + strcpy (error_message, "Paper Jam"); + } + else if (paper_out) { + result = STATE_WARNING; + strcpy (error_message, "Out of Paper"); + } + else if (line_status == OFFLINE) { + if (strcmp (error_message, "POWERSAVE ON") != 0) { + result = STATE_WARNING; + strcpy (error_message, "Printer Offline"); + } + } + else if (peripheral_error) { + result = STATE_WARNING; + strcpy (error_message, "Peripheral Error"); + } + else if (intervention_required) { + result = STATE_WARNING; + strcpy (error_message, "Intervention Required"); + } + else if (toner_low) { + result = STATE_WARNING; + strcpy (error_message, "Toner Low"); + } + else if (memory_out) { + result = STATE_WARNING; + strcpy (error_message, "Insufficient Memory"); + } + else if (door_open) { + result = STATE_WARNING; + strcpy (error_message, "A Door is Open"); + } + else if (paper_output) { + result = STATE_WARNING; + strcpy (error_message, "Output Tray is Full"); + } + else if (page_punt) { + result = STATE_WARNING; + strcpy (error_message, "Data too Slow for Engine"); + } + else if (paper_status) { + result = STATE_WARNING; + strcpy (error_message, "Unknown Paper Error"); + } + } + + if (result == STATE_OK) + printf ("Printer ok - (%s)\n", display_message); + + else if (result == STATE_UNKNOWN) { + + printf ("%s\n", error_message); + + /* if printer could not be reached, escalate to critical */ + if (strstr (error_message, "Timeout")) + result = STATE_CRITICAL; + } + + else if (result == STATE_WARNING) + printf ("%s (%s)\n", error_message, display_message); + + return result; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (address == NULL) { + if (is_host (argv[c])) { + address = argv[c]; + } + else { + usage ("Invalid host name"); + } + } + else if (community == NULL) { + community = argv[c]; + } + } + + if (address == NULL) + address = strscpy (NULL, "127.0.0.1"); + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"expect", required_argument, 0, 'e'}, +/* {"critical", required_argument,0,'c'}, */ +/* {"warning", required_argument,0,'w'}, */ +/* {"port", required_argument,0,'P'}, */ + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+hVH:C:", long_options, &option_index); +#else + c = getopt (argc, argv, "+?hVH:C:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 'H': + case 'C': + i++; + } + + switch (c) { + case 'H': /* hostname */ + if (is_host (optarg)) { + address = optarg; + } + else { + usage ("Invalid host name\n"); + } + break; + case 'C': /* community */ + community = optarg; + break; + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + return OK; +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Ethan Galstad/Karl DeBisschop\n\n" + "This plugin tests the STATUS of an HP printer with a JetDirect card.\n" + "Ucd-snmp must be installed on the computer running the plugin.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -H, --hostname=STRING or IPADDRESS\n" + " Check server on the indicated host\n" + " -C, --community=STRING\n" + " The SNMP community name\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" " Print version information\n\n"); + support (); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H host [-C community]\n" + " %s --help\n" + " %s --version\n", PROGNAME, PROGNAME, PROGNAME); +} + + +/* + if(argc<2||argc>3){ + printf("Incorrect number of arguments supplied\n"); + printf("\n"); + print_revision(argv[0],"$Revision$"); + printf("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n"); + printf("License: GPL\n"); + printf("\n"); + printf("Usage: %s [community]\n",argv[0]); + printf("\n"); + printf("Note:\n"); + printf(" = The IP address of the JetDirect card\n"); + printf(" [community] = An optional community string used for SNMP communication\n"); + printf(" with the JetDirect card. The default is 'public'.\n"); + printf("\n"); + return STATE_UNKNOWN; + } + + // get the IP address of the JetDirect device + strcpy(address,argv[1]); + + // get the community name to use for SNMP communication + if(argc>=3) + strcpy(community,argv[2]); + else + strcpy(community,"public"); +*/ diff --git a/plugins/check_http.c b/plugins/check_http.c new file mode 100644 index 00000000..db5d50dd --- /dev/null +++ b/plugins/check_http.c @@ -0,0 +1,1067 @@ +/**************************************************************************** + * + * Program: HTTP plugin for Nagios + * License: GPL + * + * License Information: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * + *****************************************************************************/ + +#define PROGNAME "check_http" +#define REVISION "$Revision$" +#define COPYRIGHT "1999-2001" +#define AUTHORS "Ethan Galstad/Karl DeBisschop" +#define EMAIL "kdebisschop@users.sourceforge.net" + +#include "config.h" +#include "common.h" +#include "version.h" +#include "netutils.h" +#include "utils.h" + +#define SUMMARY "\ +This plugin tests the HTTP service on the specified host. It can test\n\ +normal (http) and secure (https) servers, follow redirects, search for\n\ +strings and regular expressions, check connection times, and report on\n\ +certificate expiration times.\n" + +#define OPTIONS "\ +\(-H | -I ) [-u ] [-p ]\n\ + [-w ] [-c ] [-t ] [-L]\n\ + [-a auth] [-f ] [-e ]\n\ + [-s string] [-r | -R ]\n\ + [-P string]" + +#define LONGOPTIONS "\ + -H, --hostname=ADDRESS\n\ + Host name argument for servers using host headers (virtual host)\n\ + -I, --IP-address=ADDRESS\n\ + IP address or name (use numeric address if possible to bypass DNS lookup).\n\ + -e, --expect=STRING\n\ + String to expect in first line of server response (default: %s)\n\ + -s, --string=STRING\n\ + String to expect in the content\n\ + -u, --url=PATH\n\ + URL to GET or POST (default: /)\n\ + -p, --port=INTEGER\n\ + Port number (default: %d)\n\ + -P, --post=STRING\n\ + URL encoded http POST data\n\ + -w, --warning=INTEGER\n\ + Response time to result in warning status (seconds)\n\ + -c, --critical=INTEGER\n\ + Response time to result in critical status (seconds)\n\ + -t, --timeout=INTEGER\n\ + Seconds before connection times out (default: %d)\n\ + -a, --authorization=AUTH_PAIR\n\ + Username:password on sites with basic authentication\n\ + -L, --link=URL\n\ + Wrap output in HTML link (obsoleted by urlize)\n\ + -f, --onredirect=\n\ + How to handle redirected pages\n%s\ + -v, --verbose\n\ + Show details for command-line debugging (do not use with nagios server)\n\ + -h, --help\n\ + Print detailed help screen\n\ + -V, --version\n\ + Print version information\n" + +#ifdef HAVE_SSL +#define SSLOPTIONS "\ + -S, --ssl\n\ + Connect via SSL\n\ + -C, --certificate=INTEGER\n\ + Minimum number of days a certificate has to be valid.\n\ + (when this option is used the url is not checked.)\n" +#else +#define SSLOPTIONS "" +#endif + +#define DESCRIPTION "\ +This plugin will attempt to open an HTTP connection with the host. Successul\n\ +connects return STATE_OK, refusals and timeouts return STATE_CRITICAL, other\n\ +errors return STATE_UNKNOWN. Successful connects, but incorrect reponse\n\ +messages from the host result in STATE_WARNING return values. If you are\n\ +checking a virtual server that uses \"host headers\" you must supply the FQDN\n\ +\(fully qualified domain name) as the [host_name] argument.\n" + +#define SSLDESCRIPTION "\ +This plugin can also check whether an SSL enabled web server is able to\n\ +serve content (optionally within a specified time) or whether the X509 \n\ +certificate is still valid for the specified number of days.\n\n\ +CHECK CONTENT: check_http -w 5 -c 10 --ssl www.verisign.com\n\n\ +When the 'www.verisign.com' server returns its content within 5 seconds, a\n\ +STATE_OK will be returned. When the server returns its content but exceeds\n\ +the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,\n\ +a STATE_CRITICAL will be returned.\n\n\ +CHECK CERTIFICATE: check_http www.verisign.com -C 14\n\n\ +When the certificate of 'www.verisign.com' is valid for more than 14 days, a\n\ +STATE_OK is returned. When the certificate is still valid, but for less than\n\ +14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when\n\ +the certificate is expired.\n" + +#ifdef HAVE_SSL_H +#include +#include +#include +#include +#include +#include +#include +#endif + +#ifdef HAVE_OPENSSL_SSL_H +#include +#include +#include +#include +#include +#include +#include +#endif + +#ifdef HAVE_SSL +int check_cert = FALSE; +int days_till_exp; +unsigned char *randbuff; +SSL_CTX *ctx; +SSL *ssl; +X509 *server_cert; +int connect_SSL (void); +int check_certificate (X509 **); +#endif + +#ifdef HAVE_REGEX_H +#define REGS 2 +#define MAX_RE_SIZE 256 +#include +regex_t preg; +regmatch_t pmatch[REGS]; +char regexp[MAX_RE_SIZE]; +char errbuf[MAX_INPUT_BUFFER]; +int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; +int errcode; +#endif + +#define server_type_check(server_type) \ +(strcmp (server_type, "https") ? FALSE : TRUE) + +#define server_port_check(use_ssl) (use_ssl ? HTTPS_PORT : HTTP_PORT) + +#define MAX_IPV4_HOSTLENGTH 64 +#define HDR_LOCATION "%*[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]: " +#define URI_HTTP "%[HTPShtps]://" +#define URI_HOST "%[a-zA-Z0-9.-]" +#define URI_PORT ":%[0-9]" +#define URI_PATH "%[/a-zA-Z0-9._-=@,]" + +#define HTTP_PORT 80 +#define HTTPS_PORT 443 +#define HTTP_EXPECT "HTTP/1." +#define HTTP_URL "/" + +time_t start_time, end_time; +char timestamp[10] = ""; +int specify_port = FALSE; +int server_port = HTTP_PORT; +char server_port_text[6] = ""; +char server_type[6] = "http"; +char *server_address = NULL; +char *host_name = NULL; +char *server_url = NULL; +int server_url_length = 0; +char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT; +char string_expect[MAX_INPUT_BUFFER] = ""; +int warning_time = 0; +int check_warning_time = FALSE; +int critical_time = 0; +int check_critical_time = FALSE; +char user_auth[MAX_INPUT_BUFFER] = ""; +int display_html = FALSE; +int onredirect = STATE_OK; +int use_ssl = FALSE; +int verbose = FALSE; +int sd; +char *http_method = NULL; +char *http_post_data = NULL; +char buffer[MAX_INPUT_BUFFER]; + +void print_usage (void); +void print_help (void); +int process_arguments (int, char **); +int call_getopt (int, char **); +static char *base64 (char *bin, int len); +int check_http (void); +int my_recv (void); +int my_close (void); + +int +main (int argc, char **argv) +{ + int result = STATE_UNKNOWN; + + if (process_arguments (argc, argv) == ERROR) + usage ("check_http: could not parse arguments\n"); + + if (strstr (timestamp, ":")) { + if (strstr (server_url, "?")) + sprintf (server_url, "%s&%s", server_url, timestamp); + else + sprintf (server_url, "%s?%s", server_url, timestamp); + } + + if (display_html == TRUE) + printf ("", + host_name, server_port, server_url); + + /* initialize alarm signal handling, set socket timeout, start timer */ + signal (SIGALRM, socket_timeout_alarm_handler); + alarm (socket_timeout); + time (&start_time); + +#ifdef HAVE_SSL + if (use_ssl && check_cert == TRUE) { + if (connect_SSL () != OK) + terminate (STATE_CRITICAL, + "HTTP CRITICAL - Could not make SSL connection\n"); + if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { + result = check_certificate (&server_cert); + X509_free (server_cert); + } + else { + printf ("ERROR: Cannot retrieve server certificate.\n"); + result = STATE_CRITICAL; + } + SSL_shutdown (ssl); + SSL_free (ssl); + SSL_CTX_free (ctx); + close (sd); + } + else { + result = check_http (); + } +#else + result = check_http (); +#endif + return result; +} + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c, i = 1; + char optchars[MAX_INPUT_BUFFER]; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + STD_OPTS_LONG, + {"link", no_argument, 0, 'L'}, + {"nohtml", no_argument, 0, 'n'}, + {"ssl", no_argument, 0, 'S'}, + {"verbose", no_argument, 0, 'v'}, + {"post", required_argument, 0, 'P'}, + {"IP-address", required_argument, 0, 'I'}, + {"string", required_argument, 0, 's'}, + {"regex", required_argument, 0, 'r'}, + {"ereg", required_argument, 0, 'r'}, + {"eregi", required_argument, 0, 'R'}, + {"onredirect", required_argument, 0, 'f'}, + {"certificate", required_argument, 0, 'C'}, + {0, 0, 0, 0} + }; +#endif + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + if (strcmp ("-hn", argv[c]) == 0) + strcpy (argv[c], "-H"); + if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + if (strcmp ("-nohtml", argv[c]) == 0) + strcpy (argv[c], "-n"); + } + + snprintf (optchars, MAX_INPUT_BUFFER, "%s%s", STD_OPTS, + "P:I:a:e:p:s:R:r:u:f:C:nLS"); + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, optchars, long_options, &option_index); +#else + c = getopt (argc, argv, optchars); +#endif + if (c == -1 || c == EOF) + break; + + switch (c) { + case '?': /* usage */ + usage2 ("unknown argument", optarg); + break; + case 'h': /* help */ + print_help (); + exit (STATE_OK); + break; + case 'V': /* version */ + print_revision (PROGNAME, REVISION); + exit (STATE_OK); + break; + case 't': /* timeout period */ + if (!is_intnonneg (optarg)) + usage2 ("timeout interval must be a non-negative integer", optarg); + socket_timeout = atoi (optarg); + break; + case 'c': /* critical time threshold */ + if (!is_intnonneg (optarg)) + usage2 ("invalid critical threshold", optarg); + critical_time = atoi (optarg); + check_critical_time = TRUE; + break; + case 'w': /* warning time threshold */ + if (!is_intnonneg (optarg)) + usage2 ("invalid warning threshold", optarg); + warning_time = atoi (optarg); + check_warning_time = TRUE; + break; + case 'L': /* show html link */ + display_html = TRUE; + break; + case 'n': /* do not show html link */ + display_html = FALSE; + break; + case 'S': /* use SSL */ +#ifndef HAVE_SSL + usage ("check_http: invalid option - SSL is not available\n"); +#endif + use_ssl = TRUE; + if (specify_port == FALSE) + server_port = HTTPS_PORT; + break; + case 'C': /* warning time threshold */ +#ifdef HAVE_SSL + if (!is_intnonneg (optarg)) + usage2 ("invalid certificate expiration period", optarg); + days_till_exp = atoi (optarg); + check_cert = TRUE; +#else + usage ("check_http: invalid option - SSL is not available\n"); +#endif + break; + case 'f': /* onredirect */ + if (!strcmp (optarg, "follow")) + onredirect = STATE_DEPENDENT; + if (!strcmp (optarg, "unknown")) + onredirect = STATE_UNKNOWN; + if (!strcmp (optarg, "ok")) + onredirect = STATE_OK; + if (!strcmp (optarg, "warning")) + onredirect = STATE_WARNING; + if (!strcmp (optarg, "critical")) + onredirect = STATE_CRITICAL; + break; + /* Note: H, I, and u must be malloc'd or will fail on redirects */ + case 'H': /* Host Name (virtual host) */ + host_name = strscpy (host_name, optarg); + break; + case 'I': /* Server IP-address */ + server_address = strscpy (server_address, optarg); + break; + case 'u': /* Host or server */ + server_url = strscpy (server_url, optarg); + server_url_length = strlen (optarg); + break; + case 'p': /* Host or server */ + if (!is_intnonneg (optarg)) + usage2 ("invalid port number", optarg); + server_port = atoi (optarg); + specify_port = TRUE; + break; + case 'a': /* authorization info */ + strncpy (user_auth, optarg, MAX_INPUT_BUFFER - 1); + user_auth[MAX_INPUT_BUFFER - 1] = 0; + break; + case 'P': /* HTTP POST data in URL encoded format */ + http_method = strscpy (http_method, "POST"); + http_post_data = strscpy (http_post_data, optarg); + break; + case 's': /* string or substring */ + strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); + string_expect[MAX_INPUT_BUFFER - 1] = 0; + break; + case 'e': /* string or substring */ + strncpy (server_expect, optarg, MAX_INPUT_BUFFER - 1); + server_expect[MAX_INPUT_BUFFER - 1] = 0; + break; + case 'R': /* regex */ +#ifdef HAVE_REGEX_H + cflags = REG_ICASE; +#else + usage ("check_http: call for regex which was not a compiled option\n"); +#endif + case 'r': /* regex */ +#ifdef HAVE_REGEX_H + cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; + strncpy (regexp, optarg, MAX_INPUT_BUFFER - 1); + regexp[MAX_INPUT_BUFFER - 1] = 0; + errcode = regcomp (&preg, regexp, cflags); + if (errcode != 0) { + regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); + printf ("Could Not Compile Regular Expression: %s", errbuf); + return ERROR; + } +#else + usage ("check_http: call for regex which was not a compiled option\n"); +#endif + break; + case 'v': /* verbose */ + verbose = TRUE; + break; + } + } + + c = optind; + + if (server_address == NULL && host_name == NULL) { + server_address = strscpy (NULL, argv[c]); + host_name = strscpy (NULL, argv[c++]); + } + + if (server_address == NULL && host_name == NULL) + usage ("check_http: you must specify a host name\n"); + + if (server_address == NULL) + server_address = strscpy (NULL, host_name); + + if (host_name == NULL) + host_name = strscpy (NULL, server_address); + + if (http_method == NULL) + http_method = strscpy (http_method, "GET"); + + if (server_url == NULL) { + server_url = strscpy (NULL, "/"); + server_url_length = strlen(HTTP_URL); + } + + return TRUE; +} + + + +/* written by lauri alanko */ +static char * +base64 (char *bin, int len) +{ + + char *buf = (char *) malloc ((len + 2) / 3 * 4 + 1); + int i = 0, j = 0; + + char BASE64_END = '='; + char base64_table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + + while (j < len - 2) { + buf[i++] = base64_table[bin[j] >> 2]; + buf[i++] = base64_table[((bin[j] & 3) << 4) | (bin[j + 1] >> 4)]; + buf[i++] = base64_table[((bin[j + 1] & 15) << 2) | (bin[j + 2] >> 6)]; + buf[i++] = base64_table[bin[j + 2] & 63]; + j += 3; + } + + switch (len - j) { + case 1: + buf[i++] = base64_table[bin[j] >> 2]; + buf[i++] = base64_table[(bin[j] & 3) << 4]; + buf[i++] = BASE64_END; + buf[i++] = BASE64_END; + break; + case 2: + buf[i++] = base64_table[bin[j] >> 2]; + buf[i++] = base64_table[((bin[j] & 3) << 4) | (bin[j + 1] >> 4)]; + buf[i++] = base64_table[(bin[j + 1] & 15) << 2]; + buf[i++] = BASE64_END; + break; + case 0: + break; + } + + buf[i] = '\0'; + return buf; +} + + + +int +check_http (void) +{ + char *msg = NULL; + char *status_line = NULL; + char *header = NULL; + char *page = NULL; + char *auth = NULL; + int i = 0; + size_t pagesize = 0; + char *full_page = NULL; + char *pos = NULL; + + /* try to connect to the host at the given port number */ +#ifdef HAVE_SSL + if (use_ssl == TRUE) { + + if (connect_SSL () != OK) { + msg = ssprintf (msg, "Unable to open TCP socket"); + terminate (STATE_CRITICAL, msg); + } + + if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { + X509_free (server_cert); + } + else { + printf ("ERROR: Cannot retrieve server certificate.\n"); + return STATE_CRITICAL; + } + + sprintf (buffer, "%s %s HTTP/1.0\r\n", http_method, server_url); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + + /* optionally send the host header info (not clear if it's usable) */ + if (strcmp (host_name, "")) { + sprintf (buffer, "Host: %s\r\n", host_name); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + } + + /* send user agent */ + sprintf (buffer, "User-Agent: check_http/%s (nagios-plugins %s)\r\n", + clean_revstring (REVISION), PACKAGE_VERSION); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + + /* optionally send the authentication info */ + if (strcmp (user_auth, "")) { + auth = base64 (user_auth, strlen (user_auth)); + sprintf (buffer, "Authorization: Basic %s\r\n", auth); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + } + + /* optionally send http POST data */ + if (http_post_data) { + sprintf (buffer, "Content-Type: application/x-www-form-urlencoded\r\n"); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + sprintf (buffer, "Content-Length: %i\r\n\r\n", strlen (http_post_data)); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + http_post_data = strscat (http_post_data, "\r\n"); + if (SSL_write (ssl, http_post_data, strlen (http_post_data)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + } + + /* send a newline so the server knows we're done with the request */ + sprintf (buffer, "\r\n\r\n"); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + + } + else { +#endif + if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) { + msg = ssprintf (msg, "Unable to open TCP socket"); + terminate (STATE_CRITICAL, msg); + } + sprintf (buffer, "%s %s HTTP/1.0\r\n", http_method, server_url); + send (sd, buffer, strlen (buffer), 0); + + /* optionally send the host header info */ + if (strcmp (host_name, "")) { + sprintf (buffer, "Host: %s\r\n", host_name); + send (sd, buffer, strlen (buffer), 0); + } + + /* send user agent */ + sprintf (buffer, + "User-Agent: check_http/%s (nagios-plugins %s)\r\n", + clean_revstring (REVISION), PACKAGE_VERSION); + send (sd, buffer, strlen (buffer), 0); + + /* optionally send the authentication info */ + if (strcmp (user_auth, "")) { + auth = base64 (user_auth, strlen (user_auth)); + sprintf (buffer, "Authorization: Basic %s\r\n", auth); + send (sd, buffer, strlen (buffer), 0); + } + + /* optionally send http POST data */ + /* written by Chris Henesy */ + if (http_post_data) { + sprintf (buffer, "Content-Type: application/x-www-form-urlencoded\r\n"); + send (sd, buffer, strlen (buffer), 0); + sprintf (buffer, "Content-Length: %i\r\n\r\n", strlen (http_post_data)); + send (sd, buffer, strlen (buffer), 0); + http_post_data = strscat (http_post_data, "\r\n"); + send (sd, http_post_data, strlen (http_post_data), 0); + } + + /* send a newline so the server knows we're done with the request */ + sprintf (buffer, "\r\n\r\n"); + send (sd, buffer, strlen (buffer), 0); +#ifdef HAVE_SSL + } +#endif + + /* fetch the page */ + pagesize = (size_t) 0; + while ((i = my_recv ()) > 0) { + full_page = strscat (full_page, buffer); + pagesize += i; + } + + if (i < 0) + terminate (STATE_CRITICAL, "Error in recv()"); + + /* return a CRITICAL status if we couldn't read any data */ + if (pagesize == (size_t) 0) + terminate (STATE_CRITICAL, "No data received %s", timestamp); + + /* close the connection */ + my_close (); + + /* reset the alarm */ + alarm (0); + + /* leave full_page untouched so we can free it later */ + page = full_page; + + if (verbose) + printf ("Page is %d characters\n", pagesize); + + /* find status line and null-terminate it */ + status_line = page; + page += (size_t) strcspn (page, "\r\n"); + pos = page; + page += (size_t) strspn (page, "\r\n"); + status_line[pos - status_line] = 0; + strip (status_line); + if (verbose) + printf ("STATUS: %s\n", status_line); + + /* find header info and null terminate it */ + header = page; + while (strcspn (page, "\r\n") > 0) { + page += (size_t) strcspn (page, "\r\n"); + pos = page; + if ((strspn (page, "\r") == 1 && strspn (page, "\r\n") >= 2) || + (strspn (page, "\n") == 1 && strspn (page, "\r\n") >= 2)) + page += (size_t) 2; + else + page += (size_t) 1; + } + page += (size_t) strspn (page, "\r\n"); + header[pos - header] = 0; + if (verbose) + printf ("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", header, page); + + /* make sure the status line matches the response we are looking for */ + if (!strstr (status_line, server_expect)) { + if (server_port == HTTP_PORT) + msg = ssprintf (msg, "Invalid HTTP response received from host\n"); + else + msg = ssprintf (msg, + "Invalid HTTP response received from host on port %d\n", + server_port); + terminate (STATE_CRITICAL, msg); + } + + /* check the return code */ + /* server errors result in a critical state */ + if (strstr (status_line, "500") || + strstr (status_line, "501") || + strstr (status_line, "502") || + strstr (status_line, "503")) { + msg = ssprintf (msg, "HTTP CRITICAL: %s\n", status_line); + terminate (STATE_CRITICAL, msg); + } + + /* client errors result in a warning state */ + if (strstr (status_line, "400") || + strstr (status_line, "401") || + strstr (status_line, "402") || + strstr (status_line, "403") || + strstr (status_line, "404")) { + msg = ssprintf (msg, "HTTP WARNING: %s\n", status_line); + terminate (STATE_WARNING, msg); + } + + /* check redirected page if specified */ + if (strstr (status_line, "300") || + strstr (status_line, "301") || + strstr (status_line, "302") || + strstr (status_line, "303") || + strstr (status_line, "304")) { + if (onredirect == STATE_DEPENDENT) { + + pos = header; + while (pos) { + server_address = realloc (server_address, MAX_IPV4_HOSTLENGTH); + if (server_address == NULL) + terminate (STATE_UNKNOWN, + "HTTP UNKNOWN: could not allocate server_address"); + if (strspn (pos, "\r\n") > server_url_length) { + server_url = realloc (server_url, strspn (pos, "\r\n")); + if (server_url == NULL) + terminate (STATE_UNKNOWN, + "HTTP UNKNOWN: could not allocate server_url"); + server_url_length = strspn (pos, "\r\n"); + } + if (sscanf (pos, HDR_LOCATION URI_HTTP URI_HOST URI_PORT URI_PATH, server_type, server_address, server_port_text, server_url) == 4) { + host_name = strscpy (host_name, server_address); + use_ssl = server_type_check (server_type); + server_port = atoi (server_port_text); + check_http (); + } + else if (sscanf (pos, HDR_LOCATION URI_HTTP URI_HOST URI_PATH, server_type, server_address, server_url) == 3) { + host_name = strscpy (host_name, server_address); + use_ssl = server_type_check (server_type); + server_port = server_port_check (use_ssl); + check_http (); + } + else if (sscanf (pos, HDR_LOCATION URI_HTTP URI_HOST URI_PORT, server_type, server_address, server_port_text) == 3) { + host_name = strscpy (host_name, server_address); + strcpy (server_url, "/"); + use_ssl = server_type_check (server_type); + server_port = atoi (server_port_text); + check_http (); + } + else if (sscanf (pos, HDR_LOCATION URI_HTTP URI_HOST, server_type, server_address) == 2) { + host_name = strscpy (host_name, server_address); + strcpy (server_url, "/"); + use_ssl = server_type_check (server_type); + server_port = server_port_check (use_ssl); + check_http (); + } + else if (sscanf (pos, HDR_LOCATION URI_PATH, server_url) == 1) { + check_http (); + } + pos += (size_t) strcspn (pos, "\r\n"); + pos += (size_t) strspn (pos, "\r\n"); + } /* end while (pos) */ + printf ("HTTP UNKNOWN: Could not find redirect location - %s%s", + status_line, (display_html ? "" : "")); + exit (STATE_UNKNOWN); + } /* end if (onredirect == STATE_DEPENDENT) */ + else if (onredirect == STATE_UNKNOWN) + printf ("HTTP UNKNOWN"); + else if (onredirect == STATE_OK) + printf ("HTTP ok"); + else if (onredirect == STATE_WARNING) + printf ("HTTP WARNING"); + else if (onredirect == STATE_CRITICAL) + printf ("HTTP CRITICAL"); + time (&end_time); + msg = ssprintf (msg, ": %s - %d second response time %s%s\n", + status_line, (int) (end_time - start_time), + timestamp, (display_html ? "" : "")); + terminate (onredirect, msg); + } /* end if (strstr (status_line, "30[0-4]") */ + + /* check elapsed time */ + time (&end_time); + msg = ssprintf (msg, "HTTP problem: %s - %d second response time %s%s\n", + status_line, (int) (end_time - start_time), + timestamp, (display_html ? "" : "")); + if (check_critical_time == TRUE && (end_time - start_time) > critical_time) + terminate (STATE_CRITICAL, msg); + if (check_warning_time == TRUE && (end_time - start_time) > warning_time) + terminate (STATE_WARNING, msg); + + /* Page and Header content checks go here */ + /* these checks should be last */ + + if (strlen (string_expect)) { + if (strstr (page, string_expect)) { + printf ("HTTP ok: %s - %d second response time %s%s\n", + status_line, (int) (end_time - start_time), + timestamp, (display_html ? "" : "")); + exit (STATE_OK); + } + else { + printf ("HTTP CRITICAL: string not found%s\n", + (display_html ? "" : "")); + exit (STATE_CRITICAL); + } + } +#ifdef HAVE_REGEX_H + if (strlen (regexp)) { + errcode = regexec (&preg, page, REGS, pmatch, 0); + if (errcode == 0) { + printf ("HTTP ok: %s - %d second response time %s%s\n", + status_line, (int) (end_time - start_time), + timestamp, (display_html ? "" : "")); + exit (STATE_OK); + } + else { + if (errcode == REG_NOMATCH) { + printf ("HTTP CRITICAL: pattern not found%s\n", + (display_html ? "" : "")); + exit (STATE_CRITICAL); + } + else { + regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); + printf ("Execute Error: %s\n", errbuf); + exit (STATE_CRITICAL); + } + } + } +#endif + + /* We only get here if all tests have been passed */ + msg = ssprintf (msg, "HTTP ok: %s - %d second response time %s%s\n", + status_line, (int) (end_time - start_time), + timestamp, (display_html ? "" : "")); + terminate (STATE_OK, msg); + return STATE_UNKNOWN; +} + + + +#ifdef HAVE_SSL +int +connect_SSL (void) +{ + SSL_METHOD *meth; + + randbuff = strscpy (NULL, "qwertyuiopasdfghjkl"); + RAND_seed (randbuff, strlen (randbuff)); + /* Initialize SSL context */ + SSLeay_add_ssl_algorithms (); + meth = SSLv23_client_method (); + SSL_load_error_strings (); + if ((ctx = SSL_CTX_new (meth)) == NULL) { + printf ("ERROR: Cannot create SSL context.\n"); + return STATE_CRITICAL; + } + + /* Initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* Set socket timeout */ + alarm (socket_timeout); + + /* Save start time */ + time (&start_time); + + /* Make TCP connection */ + if (my_tcp_connect (server_address, server_port, &sd) == STATE_OK) { + /* Do the SSL handshake */ + if ((ssl = SSL_new (ctx)) != NULL) { + SSL_set_cipher_list(ssl, "ALL"); + SSL_set_fd (ssl, sd); + if (SSL_connect (ssl) != -1) + return OK; + ERR_print_errors_fp (stderr); + } + else { + printf ("ERROR: Cannot initiate SSL handshake.\n"); + } + SSL_free (ssl); + } + + SSL_CTX_free (ctx); + close (sd); + + return STATE_CRITICAL; +} +#endif + +#ifdef HAVE_SSL +int +check_certificate (X509 ** certificate) +{ + ASN1_STRING *tm; + int offset; + struct tm stamp; + int days_left; + /* int result = STATE_OK; */ + /* char timestamp[14]; */ + + + /* Retrieve timestamp of certificate */ + tm = X509_get_notAfter (*certificate); + + /* Generate tm structure to process timestamp */ + if (tm->type == V_ASN1_UTCTIME) { + if (tm->length < 10) { + printf ("ERROR: Wrong time format in certificate.\n"); + return STATE_CRITICAL; + } + else { + stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0'); + if (stamp.tm_year < 50) + stamp.tm_year += 100; + offset = 0; + } + } + else { + if (tm->length < 12) { + printf ("ERROR: Wrong time format in certificate.\n"); + return STATE_CRITICAL; + } + else { + stamp.tm_year = + (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 + + (tm->data[2] - '0') * 10 + (tm->data[3] - '0'); + stamp.tm_year -= 1900; + offset = 2; + } + } + stamp.tm_mon = + (tm->data[2 + offset] - '0') * 10 + (tm->data[3 + offset] - '0') - 1; + stamp.tm_mday = + (tm->data[4 + offset] - '0') * 10 + (tm->data[5 + offset] - '0'); + stamp.tm_hour = + (tm->data[6 + offset] - '0') * 10 + (tm->data[7 + offset] - '0'); + stamp.tm_min = + (tm->data[8 + offset] - '0') * 10 + (tm->data[9 + offset] - '0'); + stamp.tm_sec = 0; + stamp.tm_isdst = -1; + + days_left = (mktime (&stamp) - time (NULL)) / 86400; + sprintf + (timestamp, "%02d/%02d/%04d %02d:%02d", + stamp.tm_mon + 1, + stamp.tm_mday, stamp.tm_year + 1900, stamp.tm_hour, stamp.tm_min); + + if (days_left > 0 && days_left <= days_till_exp) { + printf ("Certificate expires in %d day(s) (%s).\n", days_left, timestamp); + return STATE_WARNING; + } + if (days_left < 0) { + printf ("Certificate expired on %s.\n", timestamp); + return STATE_CRITICAL; + } + + if (days_left == 0) { + printf ("Certificate expires today (%s).\n", timestamp); + return STATE_WARNING; + } + + printf ("Certificate will expire on %s.\n", timestamp); + + return STATE_OK; +} +#endif + + + +int +my_recv (void) +{ + int i; +#ifdef HAVE_SSL + if (use_ssl) { + i = SSL_read (ssl, buffer, MAX_INPUT_BUFFER - 1); + } + else { + i = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); + } +#else + i = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); +#endif + return i; +} + + +int +my_close (void) +{ +#ifdef HAVE_SSL + if (use_ssl == TRUE) { + SSL_shutdown (ssl); + SSL_free (ssl); + SSL_CTX_free (ctx); + return 0; + } + else { +#endif + return close (sd); +#ifdef HAVE_SSL + } +#endif +} + + + +void +print_help (void) +{ + print_revision (PROGNAME, REVISION); + printf + ("Copyright (c) %s %s <%s>\n\n%s\n", + COPYRIGHT, AUTHORS, EMAIL, SUMMARY); + print_usage (); + printf ("NOTE: One or both of -H and -I must be specified\n"); + printf ("\nOptions:\n" LONGOPTIONS "\n", HTTP_EXPECT, HTTP_PORT, + DEFAULT_SOCKET_TIMEOUT, SSLOPTIONS); +#ifdef HAVE_SSL + printf (SSLDESCRIPTION); +#endif +} + + +void +print_usage (void) +{ + printf ("Usage:\n" " %s %s\n" +#ifdef HAVE_GETOPT_H + " %s (-h | --help) for detailed help\n" + " %s (-V | --version) for version information\n", +#else + " %s -h for detailed help\n" + " %s -V for version information\n", +#endif + PROGNAME, OPTIONS, PROGNAME, PROGNAME); +} diff --git a/plugins/check_ide-smart.c b/plugins/check_ide-smart.c new file mode 100644 index 00000000..869f7dc0 --- /dev/null +++ b/plugins/check_ide-smart.c @@ -0,0 +1,448 @@ +/* + * check_ide-smart v.1 - hacked version of ide-smart for Nagios + * Copyright (C) 2000 Robert Dale + * + * Net Saint - http://www.nagios.org + * + * Notes: + * ide-smart has the same functionality as before. Some return + * values were changed, otherwise the --net-saint option was added. + * + * Run with: check_ide-smart --net-saint [-d] + * Where DRIVE is an IDE drive, ie. /dev/hda, /dev/hdb, /dev/hdc + * + * - Returns 0 on no errors + * - Returns 1 on advisories + * - Returns 2 on prefailure + * - Returns -1 not too often + * + * ide-smart 1.3 - IDE S.M.A.R.T. cheking tool + * Copyright (C) 1998-1999 Ragnar Hojland Espinosa + * 1998 Gadi Oxman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NR_ATTRIBUTES 30 + +#ifndef TRUE +#define TRUE 1 +#endif /* */ + +#define PREFAILURE 2 +#define ADVISORY 1 +#define OPERATIONAL 0 +#define UNKNOWN -1 + typedef struct threshold_s +{ + __u8 id; + __u8 threshold; + __u8 reserved[10]; +} +__attribute__ ((packed)) threshold_t; +typedef struct thresholds_s +{ + __u16 revision; + threshold_t thresholds[NR_ATTRIBUTES]; + __u8 reserved[18]; + __u8 vendor[131]; + __u8 checksum; +} +__attribute__ ((packed)) thresholds_t; +typedef struct value_s +{ + __u8 id; + __u16 status; + __u8 value; + __u8 vendor[8]; +} +__attribute__ ((packed)) value_t; +typedef struct values_s +{ + __u16 revision; + value_t values[NR_ATTRIBUTES]; + __u8 offline_status; + __u8 vendor1; + __u16 offline_timeout; + __u8 vendor2; + __u8 offline_capability; + __u16 smart_capability; + __u8 reserved[16]; + __u8 vendor[125]; + __u8 checksum; +} +__attribute__ ((packed)) values_t; +struct +{ + __u8 value; + char *text; + } +offline_status_text[] = +{ + { + 0x00, "NeverStarted"} + , { + 0x02, "Completed"} + , { + 0x04, "Suspended"} + , { + 0x05, "Aborted"} + , { + 0x06, "Failed"} + , { + 0, 0} +}; +struct +{ + __u8 value; + char *text; + } +smart_command[] = +{ + { + SMART_ENABLE, "SMART_ENABLE"} + , { + SMART_DISABLE, "SMART_DISABLE"} + , { + SMART_IMMEDIATE_OFFLINE, "SMART_IMMEDIATE_OFFLINE"} + , { + SMART_AUTO_OFFLINE, "SMART_AUTO_OFFLINE"} +, }; + + +/* Index to smart_command table, keep in order */ +enum SmartCommand +{ SMART_CMD_ENABLE, SMART_CMD_DISABLE, SMART_CMD_IMMEDIATE_OFFLINE, + SMART_CMD_AUTO_OFFLINE +}; +char * +get_offline_text (int status) +{ + int i; + for (i = 0; offline_status_text[i].text; i++) { + if (offline_status_text[i].value == status) { + return offline_status_text[i].text; + } + } + return "unknown"; +} +int +smart_read_values (int fd, values_t * values) +{ + __u8 args[4 + 512] = { + WIN_SMART, 0, SMART_READ_VALUES, 1,}; + if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { + int e = errno; + printf ("Critical: SMART_READ_VALUES: %s\n", strerror (errno)); + return e; + } + memcpy (values, args + 4, 512); + return 0; +} +int +values_not_passed (values_t * p, thresholds_t * t) +{ + value_t * value = p->values; + threshold_t * threshold = t->thresholds; + int failed = 0; + int passed = 0; + int i; + for (i = 0; i < NR_ATTRIBUTES; i++) { + if (value->id && threshold->id && value->id == threshold->id) { + if (value->value <= threshold->threshold) { + ++failed; + } + else { + ++passed; + } + } + ++value; + ++threshold; + } + return (passed ? -failed : 2); +} +int +net_saint (values_t * p, thresholds_t * t) +{ + value_t * value = p->values; + threshold_t * threshold = t->thresholds; + int status = OPERATIONAL; + int prefailure = 0; + int advisory = 0; + int failed = 0; + int passed = 0; + int total = 0; + int i; + for (i = 0; i < NR_ATTRIBUTES; i++) { + if (value->id && threshold->id && value->id == threshold->id) { + if (value->value <= threshold->threshold) { + ++failed; + if (value->status & 1) { + status = PREFAILURE; + ++prefailure; + } + else { + status = ADVISORY; + ++advisory; + } + } + else { + ++passed; + } + ++total; + } + ++value; + ++threshold; + } + switch (status) { + case PREFAILURE: + printf ("Critical: %d Harddrive PreFailure%cDetected! " + "%d/%d tests failed.\n", prefailure, prefailure > 1 ? 's' : ' ', + failed, total); + break; + case ADVISORY: + printf ("Warning: %d Harddrive Advisor%s Detected. " + "%d/%d tests failed.\n", advisory, advisory > 1 ? "ies" : "y", + failed, total); + break; + case OPERATIONAL: + printf ("Status: Operational (%d/%d tests passed)\n", passed, total); + break; + default: + printf ("Error: Status '%d' uknown. %d/%d tests passed\n", status, + passed, total); + status = -1; + break; + } + return status; +} +void +print_value (value_t * p, threshold_t * t) +{ + printf ("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n", + p->id, p->status, p->status & 1 ? "PreFailure" : "Advisory ", + p->status & 2 ? "OnLine " : "OffLine", p->value, t->threshold, + p->value > t->threshold ? "Passed" : "Failed"); +} +void +print_values (values_t * p, thresholds_t * t) +{ + value_t * value = p->values; + threshold_t * threshold = t->thresholds; + int i; + for (i = 0; i < NR_ATTRIBUTES; i++) { + if (value->id && threshold->id && value->id == threshold->id) { + print_value (value++, threshold++); + } + } + printf + ("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n", + p->offline_status, get_offline_text (p->offline_status & 0x7f), + (p->offline_status & 0x80 ? "Yes" : "No"), p->offline_timeout / 60); + printf ("OffLineCapability=%d {%s %s %s}\n", p->offline_capability, + p->offline_capability & 1 ? "Immediate" : "", + p->offline_capability & 2 ? "Auto" : "", + p->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd"); + printf ("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n", + p->revision, p->checksum, p->smart_capability, + p->smart_capability & 1 ? "SaveOnStandBy" : "", + p->smart_capability & 2 ? "AutoSave" : ""); +} +void +print_thresholds (thresholds_t * p) +{ + threshold_t * threshold = p->thresholds; + int i; + printf ("\n"); + printf ("SmartRevision=%d\n", p->revision); + for (i = 0; i < NR_ATTRIBUTES; i++) { + if (threshold->id) { + printf ("Id=%3d, Threshold=%3d\n", threshold->id, + threshold->threshold); } + ++threshold; + } + printf ("CheckSum=%d\n", p->checksum); +} +int +smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, + char show_error) +{ + __u8 args[4] = { + WIN_SMART, val0, smart_command[command].value, 0}; + int e = 0; + if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { + e = errno; + if (show_error) { + printf ("Critical: %s: %s\n", smart_command[command].text, + strerror (errno)); } + } + return e; +} +int +smart_read_thresholds (int fd, thresholds_t * thresholds) +{ + __u8 args[4 + 512] = { + WIN_SMART, 0, SMART_READ_THRESHOLDS, 1,}; + if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { + int e = errno; + printf ("Critical: SMART_READ_THRESHOLDS: %s\n", strerror (errno)); + return e; + } + memcpy (thresholds, args + 4, 512); + return 0; +} +void +show_version () +{ + printf ("check_ide-smart v.1 - FREE Software with NO WARRANTY\n"); + printf ("Nagios feature - Robert Dale \n"); + printf ("(C) 1999 Ragnar Hojland Espinosa \n"); +} +void +show_help () +{ + printf ("Usage: check_ide-smart [DEVICE] [OPTION]\n" + " -d, --device=DEVICE Select device DEVICE\n" + " -i, --immediate Perform immediately offline tests\n" + " -q, --quiet-check Returns the number of failed tests\n" + " -1, --auto-on Turn on automatic offline tests\n" + " -0, --auto-off Turn off automatic offline tests\n" + " -n, --net-saint Output suitable for Net Saint\n" + " -h, --help\n" " -V, --version\n"); +} +int +main (int argc, char *argv[]) +{ + char *device = NULL; + int command = -1; + int o, longindex; + int retval = 0; + +#ifdef HAVE_GETOPT_H + const struct option longopts[] = { + {"device", required_argument, 0, 'd'}, + {"immediate", no_argument, 0, 'i'}, + {"quiet-check", no_argument, 0, 'q'}, + {"auto-on", no_argument, 0, '1'}, + {"auto-off", no_argument, 0, '0'}, + {"net-saint", no_argument, 0, 'n'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, {0, 0, 0, 0} + }; + +#endif /* */ + while (1) { + +#ifdef HAVE_GETOPT_H + o = getopt_long (argc, argv, "+d:iq10nhV", longopts, &longindex); + +#else /* */ + o = getopt (argc, argv, "+d:iq10nhV"); + +#endif /* */ + if (o == -1 || o == EOF) + break; + switch (o) { + case 'd': + device = optarg; + break; + case 'q': + command = 3; + break; + case 'i': + command = 2; + break; + case '1': + command = 1; + break; + case '0': + command = 0; + break; + case 'n': + command = 4; + break; + case 'h': + show_help (); + return 0; + case 'V': + show_version (); + return 0; + default: + printf ("Try `%s --help' for more information.\n", argv[0]); + return 1; + } + if (optind < argc) { + device = argv[optind]; + } + if (!device) { + show_help (); + show_version (); + return -1; + } + if (1) { + thresholds_t thresholds; + values_t values; + int fd = open (device, O_RDONLY); + if (fd < 0) { + printf ("Critical: Couldn't open device: %s\n", strerror (errno)); + return 2; + } + if (smart_cmd_simple (fd, SMART_CMD_ENABLE, 0, TRUE)) { + printf ("Critical: SMART_CMD_ENABLE\n"); + return 2; + } + switch (command) { + case 0: + retval = smart_cmd_simple (fd, SMART_CMD_AUTO_OFFLINE, 0, TRUE); + break; + case 1: + retval = smart_cmd_simple (fd, SMART_CMD_AUTO_OFFLINE, 0xF8, TRUE); + break; + case 2: + retval = smart_cmd_simple (fd, SMART_CMD_IMMEDIATE_OFFLINE, 0, TRUE); + break; + case 3: + smart_read_values (fd, &values); + smart_read_thresholds (fd, &thresholds); + retval = values_not_passed (&values, &thresholds); + break; + case 4: + smart_read_values (fd, &values); + smart_read_thresholds (fd, &thresholds); + retval = net_saint (&values, &thresholds); + break; + default: + smart_read_values (fd, &values); + smart_read_thresholds (fd, &thresholds); + print_values (&values, &thresholds); + break; + } + close (fd); + } + return retval; + } + diff --git a/plugins/check_imap.c b/plugins/check_imap.c new file mode 100644 index 00000000..5ec0439b --- /dev/null +++ b/plugins/check_imap.c @@ -0,0 +1,340 @@ +/****************************************************************************** +* +* CHECK_IMAP.C +* +* Program: IMAP4 plugin for Nagios +* License: GPL +* Copyright (c) 1999 Tom Shields (tom.shields@basswood.com) +* +* $Id$ +* +* Description: +* +* This plugin will attempt to open an IMAP connection with the host. +* Successul connects return STATE_OK, refusals and timeouts return +* STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful +* connects, but incorrect reponse messages from the host result in +* STATE_WARNING return values. +* +* Modifications: +* 04-13-1999 Tom Shields +* Initial code +* 08-18-1999 Ethan Galstad +* Modified code to work with common plugin functions, added socket +* timeout, string * length checking +* 09-19-1999 Ethan Galstad +* Changed expect string from "+OK" to "* OK" and default port to 143 +*****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define PROGNAME "check_imap" + +#define PORT 143 +#define EXPECT "* OK" +#define QUIT "a1 LOGOUT\n" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +int check_disk (int usp, int free_disk); +void print_help (void); +void print_usage (void); + +int server_port = PORT; +char *server_address = NULL; +char *server_expect = NULL; +int warning_time = 0; +int check_warning_time = FALSE; +int critical_time = 0; +int check_critical_time = FALSE; +int verbose = FALSE; + +int +main (int argc, char **argv) +{ + int sd; + int result; + char buffer[MAX_INPUT_BUFFER]; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + + /* try to connect to the host at the given port number */ + time (&start_time); + result = my_tcp_connect (server_address, server_port, &sd); + + /* we connected, so close connection before exiting */ + if (result == STATE_OK) { + + /* watch for the IMAP connection string */ + result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); + + /* strip carriange returns */ + strip (buffer); + + /* return a WARNING status if we couldn't read any data */ + if (result == -1) { + printf ("recv() failed\n"); + result = STATE_WARNING; + } + + else { + + /* make sure we find the response we are looking for */ + if (!strstr (buffer, server_expect)) { + if (server_port == server_port) + printf ("Invalid IMAP response received from host\n"); + else + printf ("Invalid IMAP response received from host on port %d\n", + server_port); + result = STATE_WARNING; + } + + else { + time (&end_time); + printf ("IMAP ok - %d second response time\n", + (int) (end_time - start_time)); + result = STATE_OK; + } + } + + /* close the connection */ + send (sd, QUIT, strlen (QUIT), 0); + close (sd); + } + + /* reset the alarm handler */ + alarm (0); + + return result; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (server_address == NULL) { + if (is_host (argv[c])) { + server_address = argv[c]; + } + else { + usage ("Invalid host name"); + } + } + } + + if (server_address == NULL) + server_address = strscpy (NULL, "127.0.0.1"); + + if (server_expect == NULL) + server_expect = strscpy (NULL, EXPECT); + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"expect", required_argument, 0, 'e'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"port", required_argument, 0, 'P'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVvt:p:e:c:w:H:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+?hVvt:p:e:c:w:H:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 't': + case 'p': + case 'e': + case 'c': + case 'w': + case 'H': + i++; + } + + switch (c) { + case 'H': /* hostname */ + if (is_host (optarg)) { + server_address = optarg; + } + else { + usage ("Invalid host name\n"); + } + break; + case 'p': /* port */ + if (is_intpos (optarg)) { + server_port = atoi (optarg); + } + else { + usage ("Server port must be a positive integer\n"); + } + break; + case 'e': /* username */ + server_expect = optarg; + break; + case 'c': /* critical time threshold */ + if (is_intnonneg (optarg)) { + critical_time = atoi (optarg); + check_critical_time = TRUE; + } + else { + usage ("Critical time must be a nonnegative integer\n"); + } + break; + case 'w': /* warning time threshold */ + if (is_intnonneg (optarg)) { + warning_time = atoi (optarg); + check_warning_time = TRUE; + } + else { + usage ("Warning time must be a nonnegative integer\n"); + } + break; + case 'v': /* verbose */ + verbose = TRUE; + break; + case 't': /* timeout */ + if (is_intnonneg (optarg)) { + socket_timeout = atoi (optarg); + } + else { + usage ("Time interval must be a nonnegative integer\n"); + } + break; + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + return OK; +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Tom Shields/Karl DeBisschop\n\n" + "This plugin tests the IMAP4 service on the specified host.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -H, --hostname=STRING or IPADDRESS\n" + " Check server on the indicated host\n" + " -p, --port=INTEGER\n" + " Make connection on the indicated port (default: %d)\n" + " -e, --expect=STRING\n" + " String to expect in first line of server response (default: %s)\n" + " -w, --warning=INTEGER\n" + " Seconds necessary to result in a warning status\n" + " -c, --critical=INTEGER\n" + " Seconds necessary to result in a critical status\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection attempt times out (default: %d)\n" + " -v, --verbose\n" + " Print extra information (command-line use only)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n", + PORT, EXPECT, DEFAULT_SOCKET_TIMEOUT); + support (); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H host [-e expect] [-p port] [-w warn] [-c crit]\n" + " [-t timeout] [-v]\n" + " %s --help\n" + " %s --version\n", PROGNAME, PROGNAME, PROGNAME); +} diff --git a/plugins/check_ldap.c b/plugins/check_ldap.c new file mode 100644 index 00000000..d3f06158 --- /dev/null +++ b/plugins/check_ldap.c @@ -0,0 +1,291 @@ +/***************************************************************************** * + * CHECK_LDAP.C + * + * Program: Ldap plugin for Nagios + * License: GPL + * Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) + * + * Last Modified: $Date$ + * + * Command line: check_ldap -h -b -p -w -w + * + * Description: + * + * This plugin is for testing a ldap server. + * + * Modifications: + * + * 08-25-1999 Ethan Galstad (nagios@nagios.org) + * Modified to use common plugin include file + * + *****************************************************************************/ + +#define PROGNAME "check_ldap" +#define REVISION "$Revision$" + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#include +#include + +#define UNKNOWN -1 + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +static void print_help (void); +static void print_usage (void); + +char ld_defattr[] = "(objectclass=*)"; +char *ld_attr = ld_defattr; +char *ld_host = NULL, *ld_base = NULL, *ld_passwd = NULL, *ld_binddn = NULL; +unsigned int ld_port = 389; +int warn_time = UNKNOWN, crit_time = UNKNOWN; + +int +main (int argc, char *argv[]) +{ + + LDAP *ld; + LDAPMessage *result; + + int t_diff; + time_t time0, time1; + + if (process_arguments (argc, argv) == ERROR) + usage ("check_ldap: could not parse arguments\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + + /* get the start time */ + time (&time0); + + /* initialize ldap */ + if (!(ld = ldap_open (ld_host, ld_port))) { + /*ldap_perror(ld, "ldap_open"); */ + printf ("Could not connect to the server at port %i\n", ld_port); + return STATE_CRITICAL; + } + + /* bind to the ldap server */ + if (ldap_bind_s (ld, ld_binddn, ld_passwd, LDAP_AUTH_SIMPLE) != + LDAP_SUCCESS) { + /*ldap_perror(ld, "ldap_bind"); */ + printf ("Could not bind to the ldap-server\n"); + return STATE_CRITICAL; + } + + /* do a search of all objectclasses in the base dn */ + if (ldap_search_s (ld, ld_base, LDAP_SCOPE_BASE, ld_attr, NULL, 0, &result) + != LDAP_SUCCESS) { + /*ldap_perror(ld, "ldap_search"); */ + printf ("Could not search/find objectclasses in %s\n", ld_base); + return STATE_CRITICAL; + } + + /* unbind from the ldap server */ + ldap_unbind (ld); + + /* reset the alarm handler */ + alarm (0); + + /* get the finish time */ + time (&time1); + + /* calcutate the elapsed time */ + t_diff = time1 - time0; + + /* check if warn_time or crit_time was exceeded */ + if ((t_diff >= warn_time) && (t_diff < crit_time)) { + printf ("LDAP warning - %i seconds response time\n", t_diff); + return STATE_WARNING; + } + if (t_diff >= crit_time) { + printf ("LDAP critical - %i seconds response time\n", t_diff); + return STATE_CRITICAL; + } + + /* print out the result */ + printf ("LDAP ok - %i seconds response time\n", t_diff); + + return STATE_OK; +} + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + } + + c = 0; + while (c += (call_getopt (argc - c, &argv[c]))) { + if (argc <= c) + break; + if (ld_host[0] == 0) { + strncpy (ld_host, argv[c], sizeof (ld_host) - 1); + ld_host[sizeof (ld_host) - 1] = 0; + } + } + + return c; +} + +int +call_getopt (int argc, char **argv) +{ + int c, i = 1; +#ifdef HAVE_GETOPT_H + int option_index = 0; + /* initialize the long option struct */ + static struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"timeout", required_argument, 0, 't'}, + {"host", required_argument, 0, 'H'}, + {"base", required_argument, 0, 'b'}, + {"attr", required_argument, 0, 'a'}, + {"bind", required_argument, 0, 'D'}, + {"pass", required_argument, 0, 'P'}, + {"port", required_argument, 0, 'p'}, + {"warn", required_argument, 0, 'w'}, + {"crit", required_argument, 0, 'c'}, + {0, 0, 0, 0} + }; +#endif + + for (c = 1; c < argc; c++) + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVt:c:w:H:b:p:a:D:P:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+?hVt:c:w:H:b:p:a:D:P:"); +#endif + + if (c == -1 || c == EOF) + break; + + i++; + switch (c) { + case 't': + case 'c': + case 'w': + case 'H': + case 'b': + case 'p': + case 'a': + case 'D': + case 'P': + i++; + } + + switch (c) { + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (PROGNAME, REVISION); + exit (STATE_OK); + case 't': /* timeout period */ + if (!is_intnonneg (optarg)) + usage2 ("timeout interval must be an integer", optarg); + socket_timeout = atoi (optarg); + break; + case 'H': + ld_host = optarg; + break; + case 'b': + ld_base = optarg; + break; + case 'p': + ld_port = atoi (optarg); + break; + case 'a': + ld_attr = optarg; + break; + case 'D': + ld_binddn = optarg; + break; + case 'P': + ld_passwd = optarg; + break; + case 'w': + warn_time = atoi (optarg); + break; + case 'c': + crit_time = atoi (optarg); + break; + default: + usage ("check_ldap: could not parse arguments\n"); + break; + } + } + return i; +} + +int +validate_arguments () +{ + if (ld_host[0] == 0 || + ld_base[0] == 0 || + ld_port == UNKNOWN || warn_time == UNKNOWN || crit_time == UNKNOWN) { + return ERROR; + } + else { + return OK; + } +} + + + +/* function print_help */ +static void +print_help () +{ + print_revision (PROGNAME, REVISION); + printf + ("Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)\n" + "License: GPL\n" "\n"); + print_usage (); + printf + ("\n" + "Options:\n" + "\t-H [--host] ... host\n" + "\t-a [--attr] ... ldap attribute to search (default: \"(objectclass=*)\"\n" + "\t-b [--base] ... ldap base (eg. ou=my unit, o=my org, c=at)\n" + "\t-D [--bind] ... ldap bind DN (if required)\n" + "\t-P [--pass] ... ldap password (if required)\n" + "\t-p [--port] ... ldap port (normaly 389)\n" + "\t-w [--warn] ... time in secs. - if the exceeds the STATE_WARNING will be returned\n" + "\t-c [--crit] ... time in secs. - if the exceeds the STATE_CRITICAL will be returned\n" + "\n"); +} + + +static void +print_usage () +{ + printf + ("Usage: %s -H -b -p [-a ] [-D ]\n" + " [-P ] [-w ] [-c ] [-t timeout]\n" + "(Note: all times are in seconds.)\n", PROGNAME); +} diff --git a/plugins/check_load.c b/plugins/check_load.c new file mode 100644 index 00000000..6673b1dc --- /dev/null +++ b/plugins/check_load.c @@ -0,0 +1,321 @@ +/****************************************************************************** + * + * CHECK_LOAD.C + * + * Written by Felipe Gustavo de Almeida + * License: GPL + * Command line: CHECK_LOAD + * First Written: 04/17/99 + * + * Modifications: + * + * 05/18/1999 - Modified to work getloadavg where available, and use uptime + * where neither proc or getloadavg are found. Also use autoconf. + * mods by Karl DeBisschop (kdebiss@alum.mit.edu) + * 07/01/1999 - Added some #DEFINEs to allow compilation under NetBSD, as + * suggested by Andy Doran. + * mods by Ethan Galstad (nagios@nagios.org) + * 07/17/1999 - Initialized la[] array to prevent NetBSD from complaining + * mods by Ethan Galstad (nagios@nagios.org) + * 08/18/1999 - Integrated some code with common plugin utilities + * mods by Ethan Galstad (nagios@nagios.org) + * $Date$ + * Note: The load format is the same used by "uptime" and "w" + * + *****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "utils.h" + +#ifdef HAVE_SYS_LOADAVG_H +#include +#endif + +/* needed for compilation under NetBSD, as suggested by Andy Doran */ +#ifndef LOADAVG_1MIN +#define LOADAVG_1MIN 0 +#define LOADAVG_5MIN 1 +#define LOADAVG_15MIN 2 +#endif /* !defined LOADAVG_1MIN */ + +#include "popen.h" +#ifdef HAVE_PROC_LOADAVG + +#endif + +#define PROGNAME "check_load" + +int process_arguments (int argc, char **argv); +int call_getopt (int argc, char **argv); +int validate_arguments (void); +void print_usage (void); +void print_help (void); + +float wload1 = -1, wload5 = -1, wload15 = -1; +float cload1 = -1, cload5 = -1, cload15 = -1; + +int +main (int argc, char **argv) +{ +#if HAVE_GETLOADAVG==1 + int result; + double la[3] = { 0.0, 0.0, 0.0 }; /* NetBSD complains about unitialized arrays */ +#elif HAVE_PROC_LOADAVG==1 + FILE *fp; + char input_buffer[MAX_INPUT_BUFFER]; + char *tmp_ptr; +#else + int result; + char input_buffer[MAX_INPUT_BUFFER]; +#endif + + float la1, la5, la15; + + if (process_arguments (argc, argv) == ERROR) + usage ("\n"); + +#if HAVE_GETLOADAVG==1 + result = getloadavg (la, 3); + if (result == -1) + return STATE_UNKNOWN; + la1 = la[LOADAVG_1MIN]; + la5 = la[LOADAVG_5MIN]; + la15 = la[LOADAVG_15MIN]; +#elif HAVE_PROC_LOADAVG==1 + fp = fopen (PROC_LOADAVG, "r"); + if (fp == NULL) { + printf ("Error opening %s\n", PROC_LOADAVG); + return STATE_UNKNOWN; + } + + la1 = la5 = la15 = -1; + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) { + tmp_ptr = strtok (input_buffer, " "); + la1 = atof (tmp_ptr); + tmp_ptr = strtok (NULL, " "); + la5 = atof (tmp_ptr); + tmp_ptr = strtok (NULL, " "); + la15 = atof (tmp_ptr); + } + + fclose (fp); +#else + child_process = spopen (PATH_TO_UPTIME); + if (child_process == NULL) { + printf ("Error opening %s\n", PATH_TO_UPTIME); + return STATE_UNKNOWN; + } + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) { + printf ("Could not open stderr for %s\n", PATH_TO_UPTIME); + } + fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process); + sscanf (input_buffer, "%*[^l]load average: %f, %f, %f", &la1, &la5, &la15); + + result = spclose (child_process); + if (result) { + printf ("Error code %d returned in %s\n", result, PATH_TO_UPTIME); + return STATE_UNKNOWN; + } +#endif + + if ((la1 == -1) || (la5 == -1) || (la15 == -1)) { +#if HAVE_GETLOADAVG==1 + printf ("Error in getloadavg()\n"); +#elif HAVE_PROC_LOADAVG==1 + printf ("Error processing %s\n", PROC_LOADAVG); +#else + printf ("Error processing %s\n", PATH_TO_UPTIME); +#endif + return STATE_UNKNOWN; + } + printf ("load average: %.2f, %.2f, %.2f", la1, la5, la15); + if ((la1 >= cload1) || (la5 >= cload5) || (la15 >= cload15)) { + printf (" CRITICAL\n"); + return STATE_CRITICAL; + } + if ((la1 >= wload1) || (la5 >= wload5) || (la15 >= wload15)) { + printf (" WARNING\n"); + return STATE_WARNING; + } + printf ("\n"); + return STATE_OK; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + c = 0; + while (c += (call_getopt (argc - c, &argv[c]))) { + if (argc <= c) + break; + + if (wload1 < 0 && is_nonnegative (argv[c])) + wload1 = atof (argv[c]); + else if (cload1 < 0 && is_nonnegative (argv[c])) + cload1 = atof (argv[c]); + else if (wload5 < 0 && is_nonnegative (argv[c])) + wload5 = atof (argv[c]); + else if (cload5 < 0 && is_nonnegative (argv[c])) + cload5 = atof (argv[c]); + else if (wload15 < 0 && is_nonnegative (argv[c])) + wload15 = atof (argv[c]); + else if (cload15 < 0 && is_nonnegative (argv[c])) + cload15 = atof (argv[c]); + } + + return validate_arguments (); +} + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"warning", required_argument, 0, 'w'}, + {"critical", required_argument, 0, 'c'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+?Vhc:w:", long_options, &option_index); +#else + c = getopt (argc, argv, "+?Vhc:w:"); +#endif + + i++; + + if (c == -1 || c == EOF) + break; + + switch (c) { + case 'c': + case 'w': + i++; + } + + switch (c) { + case 'w': /* warning time threshold */ + if (is_intnonneg (optarg)) { + if (wload1 < 0 && is_nonnegative (argv[c])) + wload1 = atof (argv[c]); + else if (wload5 < 0 && is_nonnegative (argv[c])) + wload5 = atof (argv[c]); + else if (wload15 < 0 && is_nonnegative (argv[c])) + wload15 = atof (argv[c]); + break; + } + else if (strstr (optarg, ",") && + sscanf (optarg, "%f,%f,%f", &wload1, &wload5, &wload15) == 3) { + break; + } + else { + usage ("Warning threshold must be float or float triplet!\n"); + } + case 'c': /* critical time threshold */ + if (is_intnonneg (optarg)) { + if (cload1 < 0 && is_nonnegative (argv[c])) + cload1 = atof (argv[c]); + else if (cload5 < 0 && is_nonnegative (argv[c])) + cload5 = atof (argv[c]); + else if (cload15 < 0 && is_nonnegative (argv[c])) + cload15 = atof (argv[c]); + break; + } + else if (strstr (optarg, ",") && + sscanf (optarg, "%f,%f,%f", &cload1, &cload5, &cload15) == 3) { + break; + } + else { + usage ("Critical threshold must be float or float triplet!\n"); + } + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + if ((wload1 > cload1) || (wload5 > cload5) || (wload15 > cload15)) { + printf + ("Inconsistence in parameters: \"warning load\" greater than \"critical load\".\n"); + return STATE_UNKNOWN; + } + + return OK; +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: check_load -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15\n" + " check_load --version\n" " check_load --help\n"); +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 1999 Felipe Gustavo de Almeida \n" + "Copyright (c) 2000 Karl DeBisschop\n\n" + "This plugin tests the current system load average.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -w, --warning=WLOAD1,WLOAD5,WLOAD15\n" + " Exit with WARNING status if load average exceeds WLOADn\n" + " -c, --critical=CLOAD1,CLOAD5,CLOAD15\n" + " Exit with CRITICAL status if load average exceed CLOADn\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n" + "the load average format is the same used by \"uptime\" and \"w\"\n\n"); + support (); +} diff --git a/plugins/check_mrtg.c b/plugins/check_mrtg.c new file mode 100644 index 00000000..b86686d7 --- /dev/null +++ b/plugins/check_mrtg.c @@ -0,0 +1,413 @@ +/****************************************************************************** + * + * Program: MRTG (Multi-Router Traffic Grapher) generic plugin for Nagios + * License: GPL + * + * License Information: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * + *****************************************************************************/ + +#define PROGNAME "check_mrtg" +#define REVISION "$Revision$" +#define COPYRIGHT "Copyright (c) 1999-2001 Ethan Galstad" + +#define SUMMARY "\ +This plugin will check either the average or maximum value of one of the\n\ +two variables recorded in an MRTG log file.\n" + +/* old command line: +