index 306113b51869b355755e7c294e12eeb2c95c610e..cba7c4400eeb4ae47c6ac8b148abad08aef403da 100644 (file)
- /******************************************************************************
-*
+/*****************************************************************************
+*
* Nagios check_icmp plugin
-*
+*
* License: GPL
-* Copyright (c) 2005-2006 nagios-plugins team
-*
+* Copyright (c) 2005-2008 Nagios Plugins Development 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
+*
+* 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.
+*
+*
+* 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
+* the Free Software Foundation, either version 3 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$
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
*
*****************************************************************************/
-/* progname may be check_ldaps */
-//char *progname = "check_ldap";
-const char *revision = "$Revision$";
-const char *copyright = "2005-2006";
+/* progname may change */
+/* char *progname = "check_icmp"; */
+char *progname;
+const char *copyright = "2005-2008";
const char *email = "nagiosplug-devel@lists.sourceforge.net";
/** nagios plugins basic includes */
#include "netutils.h"
#include "utils.h"
+#if HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdio.h>
#include <ctype.h>
#include <netdb.h>
#include <sys/socket.h>
+#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <signal.h>
+#include <float.h>
/** sometimes undefined system macros (quite a few, actually) **/
# define MAXTTL 255
#endif
#ifndef INADDR_NONE
-# define INADDR_NONE 0xffffffU
+# define INADDR_NONE (in_addr_t)(-1)
#endif
#ifndef SOL_IP
# define ICMP_UNREACH_PRECEDENCE_CUTOFF 15
#endif
+#ifndef DBL_MAX
+# define DBL_MAX 9.9999999999e999
+#endif
typedef unsigned short range_t; /* type for get_range() -- unimplemented */
unsigned char icmp_type, icmp_code; /* type and code from errors */
unsigned short flags; /* control/status flags */
double rta; /* measured RTA */
+ double rtmax; /* max rtt */
+ double rtmin; /* min rtt */
unsigned char pl; /* measured packet loss */
struct rta_host *next; /* linked list */
} rta_host;
void print_usage (void);
static u_int get_timevar(const char *);
static u_int get_timevaldiff(struct timeval *, struct timeval *);
+static in_addr_t get_ip_address(const char *);
static int wait_for_reply(int, u_int);
-static int recvfrom_wto(int, char *, unsigned int, struct sockaddr *, u_int *);
+static int recvfrom_wto(int, void *, unsigned int, struct sockaddr *, u_int *);
static int send_icmp_ping(int, struct rta_host *);
static int get_threshold(char *str, threshold *th);
static void run_checks(void);
+static void set_source_ip(char *);
static int add_target(char *);
static int add_target_ip(char *, struct in_addr *);
-static int handle_random_icmp(struct icmp *, struct sockaddr_in *);
+static int handle_random_icmp(unsigned char *, struct sockaddr_in *);
static unsigned short icmp_checksum(unsigned short *, int);
static void finish(int);
static void crash(const char *, ...);
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 short icmp_pkt_size, icmp_data_size = DEFAULT_PING_DATA_SIZE;
+static unsigned short icmp_data_size = DEFAULT_PING_DATA_SIZE;
+static unsigned short icmp_pkt_size = DEFAULT_PING_DATA_SIZE + ICMP_MINLEN;
+
static unsigned int icmp_sent = 0, icmp_recv = 0, icmp_lost = 0;
#define icmp_pkts_en_route (icmp_sent - (icmp_recv + icmp_lost))
static unsigned short targets_down = 0, targets = 0, packets = 0;
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;
}
-static char *
+static const char *
get_icmp_error_msg(unsigned char icmp_type, unsigned char icmp_code)
{
- char *msg = "unreachable";
+ const char *msg = "unreachable";
if(debug > 1) printf("get_icmp_error_msg(%u, %u)\n", icmp_type, icmp_code);
switch(icmp_type) {
}
static int
-handle_random_icmp(struct icmp *p, struct sockaddr_in *addr)
+handle_random_icmp(unsigned char *packet, struct sockaddr_in *addr)
{
- struct icmp *sent_icmp = NULL;
+ struct icmp p, sent_icmp;
struct rta_host *host = NULL;
- unsigned char *ptr;
- if(p->icmp_type == ICMP_ECHO && p->icmp_id == pid) {
+ memcpy(&p, packet, sizeof(p));
+ if(p.icmp_type == ICMP_ECHO && p.icmp_id == pid) {
/* echo request from us to us (pinging localhost) */
return 0;
}
- ptr = (unsigned char *)p;
- if(debug) printf("handle_random_icmp(%p, %p)\n", (void *)p, (void *)addr);
+ if(debug) printf("handle_random_icmp(%p, %p)\n", (void *)&p, (void *)addr);
/* only handle a few types, since others can't possibly be replies to
* us in a sane network (if it is anyway, it will be counted as lost
* TIMXCEED actually sends a proper icmp response we will have passed
* too many hops to have a hope of reaching it later, in which case it
* indicates overconfidence in the network, poor routing or both. */
- if(p->icmp_type != ICMP_UNREACH && p->icmp_type != ICMP_TIMXCEED &&
- p->icmp_type != ICMP_SOURCEQUENCH && p->icmp_type != ICMP_PARAMPROB)
+ if(p.icmp_type != ICMP_UNREACH && p.icmp_type != ICMP_TIMXCEED &&
+ p.icmp_type != ICMP_SOURCEQUENCH && p.icmp_type != ICMP_PARAMPROB)
{
return 0;
}
/* might be for us. At least it holds the original package (according
* to RFC 792). If it isn't, just ignore it */
- sent_icmp = (struct icmp *)(ptr + 28);
- if(sent_icmp->icmp_type != ICMP_ECHO || sent_icmp->icmp_id != pid ||
- sent_icmp->icmp_seq >= targets)
+ memcpy(&sent_icmp, packet + 28, sizeof(sent_icmp));
+ if(sent_icmp.icmp_type != ICMP_ECHO || sent_icmp.icmp_id != pid ||
+ sent_icmp.icmp_seq >= targets)
{
if(debug) printf("Packet is no response to a packet we sent\n");
return 0;
}
/* it is indeed a response for us */
- host = table[sent_icmp->icmp_seq];
+ host = table[sent_icmp.icmp_seq];
if(debug) {
printf("Received \"%s\" from %s for ICMP ECHO sent to %s.\n",
- get_icmp_error_msg(p->icmp_type, p->icmp_code),
+ get_icmp_error_msg(p.icmp_type, p.icmp_code),
inet_ntoa(addr->sin_addr), host->name);
}
/* source quench means we're sending too fast, so increase the
* interval and mark this packet lost */
- if(p->icmp_type == ICMP_SOURCEQUENCH) {
+ if(p.icmp_type == ICMP_SOURCEQUENCH) {
pkt_interval *= pkt_backoff_factor;
target_interval *= target_backoff_factor;
}
targets_down++;
host->flags |= FLAG_LOST_CAUSE;
}
- host->icmp_type = p->icmp_type;
- host->icmp_code = p->icmp_code;
+ host->icmp_type = p.icmp_type;
+ host->icmp_code = p.icmp_code;
host->error_addr.s_addr = addr->sin_addr.s_addr;
return 0;
int icmp_sockerrno, udp_sockerrno, tcp_sockerrno;
int result;
struct rta_host *host;
-
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ /* print a helpful error message if geteuid != 0 */
+ np_warn_if_not_root();
+
/* we only need to be setsuid when we get the sockets, so do
* that before pointer magic (esp. on network data) */
icmp_sockerrno = udp_sockerrno = tcp_sockerrno = sockets = 0;
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
packets = 5;
}
+ /* Parse extra opts if any */
+ argv=np_extra_opts(&argc, argv, progname);
+
/* 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:s:i:b:I:l:m:")) != EOF) {
+ long size;
switch(arg) {
case 'v':
debug++;
break;
case 'b':
- /* silently ignored for now */
+ size = strtol(optarg,NULL,0);
+ if (size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) &&
+ size < MAX_PING_DATA) {
+ icmp_data_size = size;
+ icmp_pkt_size = size + ICMP_MINLEN;
+ } else
+ usage_va("ICMP data length must be between: %d and %d",
+ sizeof(struct icmp) + sizeof(struct icmp_ping_data),
+ MAX_PING_DATA - 1);
+
break;
case 'i':
pkt_interval = get_timevar(optarg);
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 's': /* specify source IP address */
+ set_source_ip(optarg);
+ break;
case 'V': /* version */
- //print_revision (progname, revision);
+ print_revision (progname, NP_VERSION);
exit (STATE_OK);
case 'h': /* help */
print_help ();
}
}
- icmp_pkt_size = icmp_data_size + ICMP_MINLEN;
- if(debug > 2) printf("icmp_pkt_size = %u\n", icmp_pkt_size);
- if(icmp_pkt_size < sizeof(struct icmp) + sizeof(struct icmp_ping_data)) {
- icmp_pkt_size = sizeof(struct icmp) + sizeof(struct icmp_ping_data);
- }
- if(debug > 2) printf("icmp_pkt_size = %u\n", icmp_pkt_size);
-
if(debug) {
printf("crit = {%u, %u%%}, warn = {%u, %u%%}\n",
crit.rta, crit.pl, warn.rta, warn.pl);
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;
table[t]->name);
continue;
}
-
+
/* we're still in the game, so send next packet */
(void)send_icmp_ping(icmp_sock, table[t]);
result = wait_for_reply(icmp_sock, target_interval);
wait_for_reply(int sock, u_int t)
{
int n, hlen;
- static char buf[4096];
+ static unsigned char buf[4096];
struct sockaddr_in resp_addr;
struct ip *ip;
- struct icmp *icp, *sent_icmp;
+ struct icmp icp;
struct rta_host *host;
- struct icmp_ping_data *data;
+ struct icmp_ping_data data;
struct timeval wait_start, now;
u_int tdiff, i, per_pkt_wait;
/* } */
/* check the response */
- icp = (struct icmp *)(buf + hlen);
- sent_icmp = (struct icmp *)(buf + hlen + ICMP_MINLEN);
- /* printf("buf: %p, icp: %p, distance: %u (expected %u)\n", */
- /* buf, icp, */
- /* (u_int)icp - (u_int)buf, hlen); */
- /* printf("buf: %p, sent_icmp: %p, distance: %u (expected %u)\n", */
- /* buf, sent_icmp, */
- /* (u_int)sent_icmp - (u_int)buf, hlen + ICMP_MINLEN); */
-
- if(icp->icmp_id != pid) {
- handle_random_icmp(icp, &resp_addr);
+ memcpy(&icp, buf + hlen, sizeof(icp));
+
+ if(icp.icmp_id != pid) {
+ handle_random_icmp(buf + hlen, &resp_addr);
continue;
}
- if(icp->icmp_type != ICMP_ECHOREPLY || icp->icmp_seq >= targets) {
+ if(icp.icmp_type != ICMP_ECHOREPLY || icp.icmp_seq >= targets) {
if(debug > 2) printf("not a proper ICMP_ECHOREPLY\n");
- handle_random_icmp(icp, &resp_addr);
+ handle_random_icmp(buf + hlen, &resp_addr);
continue;
}
/* this is indeed a valid response */
- data = (struct icmp_ping_data *)(icp->icmp_data);
+ memcpy(&data, icp.icmp_data, sizeof(data));
- host = table[icp->icmp_seq];
+ host = table[icp.icmp_seq];
gettimeofday(&now, &tz);
- tdiff = get_timevaldiff(&data->stime, &now);
+ tdiff = get_timevaldiff(&data.stime, &now);
host->time_waited += tdiff;
host->icmp_recv++;
icmp_recv++;
+ if (tdiff > host->rtmax)
+ host->rtmax = tdiff;
+ if (tdiff < host->rtmin)
+ host->rtmin = tdiff;
if(debug) {
- printf("%0.3f ms rtt from %s, outgoing ttl: %u, incoming ttl: %u\n",
+ printf("%0.3f ms rtt from %s, outgoing ttl: %u, incoming ttl: %u, max: %0.3f, min: %0.3f\n",
(float)tdiff / 1000, inet_ntoa(resp_addr.sin_addr),
- ttl, ip->ip_ttl);
+ ttl, ip->ip_ttl, (float)host->rtmax / 1000, (float)host->rtmin / 1000);
}
/* if we're in hostcheck mode, exit with limited printouts */
static int
send_icmp_ping(int sock, struct rta_host *host)
{
- static char *buf = NULL; /* re-use so we prevent leaks */
+ static union {
+ void *buf; /* re-use so we prevent leaks */
+ struct icmp *icp;
+ u_short *cksum_in;
+ } packet = { NULL };
long int len;
- struct icmp *icp;
- struct icmp_ping_data *data;
+ struct icmp_ping_data data;
struct timeval tv;
struct sockaddr *addr;
-
if(sock == -1) {
errno = 0;
crash("Attempt to send on bogus socket");
}
addr = (struct sockaddr *)&host->saddr_in;
- if(!buf) {
- buf = (char *)malloc(icmp_pkt_size + sizeof(struct ip));
- if(!buf) {
+ if(!packet.buf) {
+ if (!(packet.buf = malloc(icmp_pkt_size))) {
crash("send_icmp_ping(): failed to malloc %d bytes for send buffer",
icmp_pkt_size);
return -1; /* might be reached if we're in debug mode */
}
}
- memset(buf, 0, icmp_pkt_size + sizeof(struct ip));
+ memset(packet.buf, 0, icmp_pkt_size);
if((gettimeofday(&tv, &tz)) == -1) return -1;
- icp = (struct icmp *)buf;
- icp->icmp_type = ICMP_ECHO;
- icp->icmp_code = 0;
- icp->icmp_cksum = 0;
- icp->icmp_id = pid;
- icp->icmp_seq = host->id;
- data = (struct icmp_ping_data *)icp->icmp_data;
- data->ping_id = 10; /* host->icmp.icmp_sent; */
- memcpy(&data->stime, &tv, sizeof(struct timeval));
- icp->icmp_cksum = icmp_checksum((u_short *)icp, icmp_pkt_size);
-
- len = sendto(sock, buf, icmp_pkt_size, 0, (struct sockaddr *)addr,
+ data.ping_id = 10; /* host->icmp.icmp_sent; */
+ memcpy(&data.stime, &tv, sizeof(tv));
+ memcpy(&packet.icp->icmp_data, &data, sizeof(data));
+ packet.icp->icmp_type = ICMP_ECHO;
+ packet.icp->icmp_code = 0;
+ packet.icp->icmp_cksum = 0;
+ packet.icp->icmp_id = pid;
+ packet.icp->icmp_seq = host->id;
+ packet.icp->icmp_cksum = icmp_checksum(packet.cksum_in, icmp_pkt_size);
+
+ len = sendto(sock, packet.buf, icmp_pkt_size, 0, (struct sockaddr *)addr,
sizeof(struct sockaddr));
if(len < 0 || (unsigned int)len != icmp_pkt_size) {
}
static int
-recvfrom_wto(int sock, char *buf, unsigned int len, struct sockaddr *saddr,
+recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr,
u_int *timo)
{
u_int slen;
unsigned char pl;
double rta;
struct rta_host *host;
- char *status_string[] =
+ const 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 = list;
while(host) {
if(debug) puts("");
- printf("%srta=%0.3fms;%0.3f;%0.3f;0; %spl=%u%%;%u;%u;; ",
+ printf("%srta=%0.3fms;%0.3f;%0.3f;0; %spl=%u%%;%u;%u;; %srtmax=%0.3fms;;;; %srtmin=%0.3fms;;;; ",
(targets > 1) ? host->name : "",
host->rta / 1000, (float)warn.rta / 1000, (float)crit.rta / 1000,
- (targets > 1) ? host->name : "",
- host->pl, warn.pl, crit.pl);
+ (targets > 1) ? host->name : "", host->pl, warn.pl, crit.pl,
+ (targets > 1) ? host->name : "", (float)host->rtmax / 1000,
+ (targets > 1) ? host->name : "", (host->rtmin < DBL_MAX) ? (float)host->rtmin / 1000 : (float)0);
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);
}
if(!early) early = &prog_start;
/* if early > later we return 0 so as to indicate a timeout */
- if(early->tv_sec > early->tv_sec ||
+ if(early->tv_sec > later->tv_sec ||
(early->tv_sec == later->tv_sec && early->tv_usec > later->tv_usec))
{
return 0;
host->saddr_in.sin_family = AF_INET;
host->saddr_in.sin_addr.s_addr = in->s_addr;
+ host->rtmin = DBL_MAX;
+
if(!list) list = cursor = host;
else cursor->next = host;
/* this is silly, but it works */
if(mode == MODE_HOSTCHECK || mode == MODE_ALL) {
- printf("mode: %d\n", mode);
+ if(debug > 2) printf("mode: %d\n", mode);
continue;
}
break;
return 0;
}
+
+static void
+set_source_ip(char *arg)
+{
+ struct sockaddr_in src;
+
+ memset(&src, 0, sizeof(src));
+ src.sin_family = AF_INET;
+ if((src.sin_addr.s_addr = inet_addr(arg)) == INADDR_NONE)
+ src.sin_addr.s_addr = get_ip_address(arg);
+ if(bind(icmp_sock, (struct sockaddr *)&src, sizeof(src)) == -1)
+ crash("Cannot bind to IP address %s", arg);
+}
+
+/* TODO: Move this to netutils.c and also change check_dhcp to use that. */
+static in_addr_t
+get_ip_address(const char *ifname)
+{
+#if defined(SIOCGIFADDR)
+ struct ifreq ifr;
+ struct sockaddr_in ip;
+
+ strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
+ ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
+ if(ioctl(icmp_sock, SIOCGIFADDR, &ifr) == -1)
+ crash("Cannot determine IP address of interface %s", ifname);
+ memcpy(&ip, &ifr.ifr_addr, sizeof(ip));
+ return ip.sin_addr.s_addr;
+#else
+ errno = 0;
+ crash("Cannot get interface IP address on this platform.");
+#endif
+}
+
/*
* u = micro
* m = milli
return cksum;
}
-/* make core plugin developers happy (silly, really) */
void
print_help(void)
{
- //print_revision (progname, revision);
-
+ /*print_revision (progname);*/ /* 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("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);
-
- printf("\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");
-
-/* printf("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");
+ printf (_(UT_EXTRA_OPTS));
+
+ 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);
+ printf (" %s\n", "-c");
+ printf (" %s", _("critical threshold (currently "));
+ printf ("%0.3fms,%u%%)\n", (float)crit.rta / 1000, crit.pl);
+ printf (" %s\n", "-s");
+ printf (" %s\n", _("specify a source IP address or device name"));
+ 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)\n", ttl);
+ printf (" %s\n", "-t");
+ printf (" %s",_("timeout value (seconds, currently "));
+ printf ("%u)\n", timeout);
+ printf (" %s\n", "-b");
+ printf (" %s\n", _("Number of icmp data bytes to send"));
+ printf (" %s %u + %d)\n", _("Packet size will be data bytes + icmp header (currently"),icmp_data_size, ICMP_MINLEN);
+ printf (" %s\n", "-v");
+ printf (" %s\n", _("verbose"));
+
+ printf ("\n");
+ printf ("%s\n", _("Notes:"));
+ printf (" %s\n", _("The -H switch is optional. Naming a host (or several) to check is not."));
+ printf ("\n");
+ 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", _("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 ("\n");
+ printf (" %s\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"));
*/
-
+#ifdef NP_EXTRA_OPTS
+ printf ("\n");
+ printf (_(UT_EXTRA_OPTS_NOTES));
+#endif
+
printf (_(UT_SUPPORT));
-
- printf (_(UT_NOWARRANTY));
-
-// exit(3);
}
print_usage (void)
{
printf (_("Usage:"));
- printf("Usage: %s [options] [-H] host1 host2 hostn\n\n", progname);
+ printf(" %s [options] [-H] host1 host2 hostN\n", progname);
}