index 2f03552f948538faf0c4ee067520251e8b6c0778..7e3b00f36a0a2f6b887e0433ef4868f7b453ff74 100644 (file)
-/*
- * $Id$
- *
- * Author: Andreas Ericsson <ae@op5.se>
- *
- * License: GNU GPL 2.0 or any later version.
- *
- * Relevant RFC's: 792 (ICMP), 791 (IP)
- *
- * This program was modeled somewhat after the check_icmp program,
- * which was in turn a hack of fping (www.fping.org) but has been
- * completely rewritten since to generate higher precision rta values,
- * and support several different modes as well as setting ttl to control.
- * redundant routes. The only remainders of fping is currently a few
- * function names.
- *
- */
+ /******************************************************************************
+*
+* Nagios check_icmp plugin
+*
+* License: GPL
+* Copyright (c) 2005-2007 nagios-plugins team
+*
+* Original Author : Andreas Ericsson <ae@op5.se>
+*
+* Last Modified: $Date$
+*
+* Description:
+*
+* This file contains the check_icmp plugin
+*
+* Relevant RFC's: 792 (ICMP), 791 (IP)
+*
+* This program was modeled somewhat after the check_icmp program,
+* which was in turn a hack of fping (www.fping.org) but has been
+* completely rewritten since to generate higher precision rta values,
+* and support several different modes as well as setting ttl to control.
+* redundant routes. The only remainders of fping is currently a few
+* function names.
+*
+* 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$
+*
+*****************************************************************************/
+
+/* progname may change */
+/* char *progname = "check_icmp"; */
+char *progname;
+const char *revision = "$Revision$";
+const char *copyright = "2005-2007";
+const char *email = "nagiosplug-devel@lists.sourceforge.net";
+
+/** nagios plugins basic includes */
+#include "common.h"
+#include "netutils.h"
+#include "utils.h"
#include <sys/time.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <signal.h>
+
/** sometimes undefined system macros (quite a few, actually) **/
#ifndef MAXTTL
# define MAXTTL 255
#endif
-/** typedefs and such **/
-enum states {
- STATE_OK = 0,
- STATE_WARNING,
- STATE_CRITICAL,
- STATE_UNKNOWN,
- STATE_DEPENDENT,
- STATE_OOB
-};
-
typedef unsigned short range_t; /* type for get_range() -- unimplemented */
typedef struct rta_host {
#define TSTATE_UNREACH 0x08
/** prototypes **/
-static void usage(unsigned char, char *);
+void print_help (void);
+void print_usage (void);
static u_int get_timevar(const char *);
static u_int get_timevaldiff(struct timeval *, struct timeval *);
static int wait_for_reply(int, u_int);
extern char **environ;
/** global variables **/
-static char *progname;
static struct rta_host **table, *cursor, *list;
static threshold crit = {80, 500000}, warn = {40, 200000};
static int mode, protocols, sockets, debug = 0, timeout = 10;
static unsigned long long max_completion_time = 0;
static unsigned char ttl = 0; /* outgoing ttl */
static unsigned int warn_down = 1, crit_down = 1; /* host down threshold values */
+static int min_hosts_alive = -1;
float pkt_backoff_factor = 1.5;
float target_backoff_factor = 1.5;
environ = NULL;
/* use the pid to mark packets as ours */
- pid = getpid();
+ /* Some systems have 32-bit pid_t so mask off only 16 bits */
+ pid = getpid() & 0xffff;
/* printf("pid = %u\n", pid); */
/* get calling name the old-fashioned way for portability instead
/* parse the arguments */
for(i = 1; i < argc; i++) {
- while((arg = getopt(argc, argv, "vhVw:c:n:p:t:H:i:b:I:l:")) != EOF) {
+ while((arg = getopt(argc, argv, "vhVw:c:n:p:t:H:i:b:I:l:m:")) != EOF) {
switch(arg) {
case 'v':
debug++;
case 'l':
ttl = (unsigned char)strtoul(optarg, NULL, 0);
break;
+ case 'm':
+ min_hosts_alive = (int)strtoul(optarg, NULL, 0);
+ break;
case 'd': /* implement later, for cluster checks */
warn_down = (unsigned char)strtoul(optarg, &ptr, 0);
if(ptr) {
crit_down = (unsigned char)strtoul(ptr + 1, NULL, 0);
}
break;
- case 'h': case 'V': default:
- usage(arg, NULL);
- break;
+ case 'V': /* version */
+ /*print_revision (progname, revision);*/ /* FIXME: Why? */
+ exit (STATE_OK);
+ case 'h': /* help */
+ print_help ();
+ exit (STATE_OK);
}
}
}
crash("packets is > 20 (%d)", packets);
}
+ if(min_hosts_alive < -1) {
+ errno = 0;
+ crash("minimum alive hosts is negative (%i)", min_hosts_alive);
+ }
+
host = list;
table = malloc(sizeof(struct rta_host **) * (argc - 1));
i = 0;
struct rta_host *host;
char *status_string[] =
{"OK", "WARNING", "CRITICAL", "UNKNOWN", "DEPENDENT"};
+ int hosts_ok = 0;
+ int hosts_warn = 0;
alarm(0);
if(debug > 1) printf("finish(%d) called\n", sig);
}
host->pl = pl;
host->rta = rta;
- if(!status && (pl >= warn.pl || rta >= warn.rta)) status = STATE_WARNING;
- if(pl >= crit.pl || rta >= crit.rta) status = STATE_CRITICAL;
+ if(pl >= crit.pl || rta >= crit.rta) {
+ status = STATE_CRITICAL;
+ }
+ else if(!status && (pl >= warn.pl || rta >= warn.rta)) {
+ status = STATE_WARNING;
+ hosts_warn++;
+ }
+ else {
+ hosts_ok++;
+ }
host = host->next;
}
/* this is inevitable */
if(!targets_alive) status = STATE_CRITICAL;
+ if(min_hosts_alive > -1) {
+ if(hosts_ok >= min_hosts_alive) status = STATE_OK;
+ else if((hosts_ok + hosts_warn) >= min_hosts_alive) status = STATE_WARNING;
+ }
printf("%s - ", status_string[status]);
host = list;
host = host->next;
}
+ if(min_hosts_alive > -1) {
+ if(hosts_ok >= min_hosts_alive) status = STATE_OK;
+ else if((hosts_ok + hosts_warn) >= min_hosts_alive) status = STATE_WARNING;
+ }
+
/* finish with an empty line */
puts("");
- if(debug) printf("targets: %u, targets_alive: %u\n",
- targets, targets_alive);
+ if(debug) printf("targets: %u, targets_alive: %u, hosts_ok: %u, hosts_warn: %u, min_hosts_alive: %i\n",
+ targets, targets_alive, hosts_ok, hosts_warn, min_hosts_alive);
exit(status);
}
return cksum;
}
-/* make core plugin developers happy (silly, really) */
-static void
-usage(unsigned char arg, char *msg)
+void
+print_help(void)
{
- if(msg) printf("%s: %s\n", progname, msg);
- if(arg == 'V') {
- printf("$Id$\n");
- exit(STATE_UNKNOWN);
- }
+ /*print_revision (progname, revision);*/ /* FIXME: Why? */
+
+ printf ("Copyright (c) 2005 Andreas Ericsson <ae@op5.se>\n");
+ printf (COPYRIGHT, copyright, email);
+
+ printf ("\n\n");
+
+ print_usage ();
+
+ printf (_(UT_HELP_VRSN));
+
+ printf (" %s\n", "-H");
+ printf (" %s\n", _("specify a target"));
+ printf (" %s\n", "-w");
+ printf (" %s", _("warning threshold (currently "));
+ printf ("%0.3fms,%u%%)\n", (float)warn.rta / 1000 , warn.pl / 1000);
+ printf (" %s\n", "-c");
+ printf (" %s", _("critical threshold (currently "));
+ printf ("%0.3fms,%u%%)\n", (float)crit.rta, crit.pl);
+ printf (" %s\n", "-n");
+ printf (" %s", _("number of packets to send (currently "));
+ printf ("%u)\n",packets);
+ printf (" %s\n", "-i");
+ printf (" %s", _("max packet interval (currently "));
+ printf ("%0.3fms)\n",(float)pkt_interval / 1000);
+ printf (" %s\n", "-I");
+ printf (" %s", _("max target interval (currently "));
+ printf ("%0.3fms)\n", (float)target_interval / 1000);
+ printf (" %s\n", "-m");
+ printf (" %s",_("number of alive hosts required for success"));
+ printf ("\n");
+ printf (" %s\n", "-l");
+ printf (" %s", _("TTL on outgoing packets (currently "));
+ printf ("%u)", ttl);
+ printf (" %s\n", "-t");
+ printf (" %s",_("timeout value (seconds, currently "));
+ printf ("%u)\n", timeout);
+ printf (" %s\n", "-b");
+ printf (" %s\n", _("icmp packet size (currenly ignored)"));
+ printf (" %s\n", "-v");
+ printf (" %s\n", _("verbose"));
+
+ printf ("\n");
+ printf ("%s\n\n", _("The -H switch is optional. Naming a host (or several) to check is not."));
+ printf ("%s\n", _("Threshold format for -w and -c is 200.25,60% for 200.25 msec RTA and 60%"));
+ printf ("%s\n", _("packet loss. The default values should work well for most users."));
+ printf ("%s\n", _("You can specify different RTA factors using the standardized abbreviations"));
+ printf ("%s\n\n", _("us (microseconds), ms (milliseconds, default) or just plain s for seconds."));
+/* -d not yet implemented */
+/* printf ("%s\n", _("Threshold format for -d is warn,crit. 12,14 means WARNING if >= 12 hops"));
+ printf ("%s\n", _("are spent and CRITICAL if >= 14 hops are spent."));
+ printf ("%s\n\n", _("NOTE: Some systems decrease TTL when forming ICMP_ECHOREPLY, others do not."));*/
+ printf ("%s\n\n", _("The -v switch can be specified several times for increased verbosity."));
+
+/* printf ("%s\n", _("Long options are currently unsupported."));
+ printf ("%s\n", _("Options marked with * require an argument"));
+*/
+ printf (_(UT_SUPPORT));
+
+ printf (_(UT_NOWARRANTY));
+}
- printf("Usage: %s [options] [-H] host1 host2 hostn\n\n", progname);
-
- if(arg != 'h') exit(3);
-
- printf("Where options are any combination of:\n"
- " * -H | --host specify a target\n"
- " * -w | --warn warning threshold (currently %0.3fms,%u%%)\n"
- " * -c | --crit critical threshold (currently %0.3fms,%u%%)\n"
- " * -n | --packets number of packets to send (currently %u)\n"
- " * -i | --interval max packet interval (currently %0.3fms)\n"
- " * -I | --hostint max target interval (currently %0.3fms)\n"
- " * -l | --ttl TTL on outgoing packets (currently %u)\n"
- " * -t | --timeout timeout value (seconds, currently %u)\n"
- " * -b | --bytes icmp packet size (currenly ignored)\n"
- " -v | --verbose verbosity++\n"
- " -h | --help this cruft\n",
- (float)warn.rta / 1000, warn.pl, (float)crit.rta / 1000, crit.pl,
- packets,
- (float)pkt_interval / 1000, (float)target_interval / 1000,
- ttl, timeout);
-
- puts("\nThe -H switch is optional. Naming a host (or several) to check is not.\n\n"
- "Threshold format for -w and -c is 200.25,60% for 200.25 msec RTA and 60%\n"
- "packet loss. The default values should work well for most users.\n"
- "You can specify different RTA factors using the standardized abbreviations\n"
- "us (microseconds), ms (milliseconds, default) or just plain s for seconds.\n\n"
- "Threshold format for -d is warn,crit. 12,14 means WARNING if >= 12 hops\n"
- "are spent and CRITICAL if >= 14 hops are spent.\n"
- "NOTE: Some systems decrease TTL when forming ICMP_ECHOREPLY, others do not.\n\n"
- "The -v switch can be specified several times for increased verbosity.\n\n"
- "Long options are currently unsupported.\n\n"
- "Options marked with * require an argument\n");
-
- puts("The latest version of this plugin can be found at http://oss.op5.se/nagios\n"
- "or https://devel.op5.se/oss until the day it is included in the official\n"
- "plugin distribution.\n");
- exit(3);
+
+void
+print_usage (void)
+{
+ printf (_("Usage:"));
+ printf(" %s [options] [-H] host1 host2 hostn\n", progname);
}