X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=plugins-root%2Fcheck_icmp.c;h=fe8fc56f81b0650600fe6bfca97d5d7a20ef54d3;hb=HEAD;hp=7e3b00f36a0a2f6b887e0433ef4868f7b453ff74;hpb=223da2af43da2ab67f175053ce29d88fdddf6c00;p=nagiosplug.git diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c index 7e3b00f..fe8fc56 100644 --- a/plugins-root/check_icmp.c +++ b/plugins-root/check_icmp.c @@ -1,52 +1,45 @@ - /****************************************************************************** -* +/***************************************************************************** +* * Nagios check_icmp plugin -* +* * License: GPL -* Copyright (c) 2005-2007 nagios-plugins team -* +* Copyright (c) 2005-2008 Nagios Plugins Development Team * Original Author : Andreas Ericsson -* -* 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 . +* * *****************************************************************************/ /* progname may change */ /* char *progname = "check_icmp"; */ char *progname; -const char *revision = "$Revision$"; -const char *copyright = "2005-2007"; +const char *copyright = "2005-2008"; const char *email = "nagiosplug-devel@lists.sourceforge.net"; /** nagios plugins basic includes */ @@ -54,6 +47,10 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; #include "netutils.h" #include "utils.h" +#if HAVE_SYS_SOCKIO_H +#include +#endif +#include #include #include #include @@ -66,12 +63,14 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; #include #include #include +#include #include #include #include #include #include #include +#include /** sometimes undefined system macros (quite a few, actually) **/ @@ -79,7 +78,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; # define MAXTTL 255 #endif #ifndef INADDR_NONE -# define INADDR_NONE 0xffffffU +# define INADDR_NONE (in_addr_t)(-1) #endif #ifndef SOL_IP @@ -104,6 +103,9 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; # 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 */ @@ -118,6 +120,8 @@ typedef struct rta_host { 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; @@ -178,14 +182,16 @@ 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 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 *, ...); @@ -199,7 +205,9 @@ extern char **environ; 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; @@ -235,10 +243,10 @@ crash(const char *fmt, ...) } -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) { @@ -292,19 +300,18 @@ get_icmp_error_msg(unsigned char icmp_type, unsigned char icmp_code) } 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 && ntohs(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 @@ -316,27 +323,27 @@ handle_random_icmp(struct icmp *p, struct sockaddr_in *addr) * 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 || ntohs(sent_icmp.icmp_id) != pid || + ntohs(sent_icmp.icmp_seq) >= targets*packets) { 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[ntohs(sent_icmp.icmp_seq)/packets]; 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); } @@ -347,7 +354,7 @@ handle_random_icmp(struct icmp *p, struct sockaddr_in *addr) /* 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; } @@ -355,8 +362,8 @@ handle_random_icmp(struct icmp *p, struct sockaddr_in *addr) 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; @@ -371,7 +378,14 @@ main(int argc, char **argv) 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; @@ -437,15 +451,28 @@ main(int argc, char **argv) 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:m:")) != 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); @@ -482,8 +509,11 @@ main(int argc, char **argv) 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);*/ /* FIXME: Why? */ + print_revision (progname, NP_VERSION); exit (STATE_OK); case 'h': /* help */ print_help (); @@ -571,13 +601,6 @@ main(int argc, char **argv) } } - 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); @@ -598,10 +621,10 @@ main(int argc, char **argv) } host = list; - table = malloc(sizeof(struct rta_host **) * (argc - 1)); + table = malloc(sizeof(struct rta_host **) * targets); i = 0; while(host) { - host->id = i; + host->id = i*packets; table[i] = host; host = host->next; i++; @@ -633,7 +656,7 @@ run_checks() 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); @@ -671,12 +694,12 @@ static int 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; @@ -738,41 +761,37 @@ wait_for_reply(int sock, u_int t) /* } */ /* 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); - continue; - } + memcpy(&icp, buf + hlen, sizeof(icp)); - if(icp->icmp_type != ICMP_ECHOREPLY || icp->icmp_seq >= targets) { + if(ntohs(icp.icmp_id) != pid || icp.icmp_type != ICMP_ECHOREPLY || + ntohs(icp.icmp_seq) >= targets*packets) { 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)); + if (debug > 2) + printf("ICMP echo-reply of len %u, id %u, seq %u, cksum 0x%X\n", + sizeof(data), ntohs(icp.icmp_id), ntohs(icp.icmp_seq), icp.icmp_cksum); - host = table[icp->icmp_seq]; + host = table[ntohs(icp.icmp_seq)/packets]; 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 */ @@ -793,14 +812,16 @@ wait_for_reply(int sock, u_int t) 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"); @@ -808,30 +829,32 @@ send_icmp_ping(int sock, struct rta_host *host) } 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 = htons(pid); + packet.icp->icmp_seq = htons(host->id++); + packet.icp->icmp_cksum = icmp_checksum(packet.cksum_in, icmp_pkt_size); + + if (debug > 2) + printf("Sending ICMP echo-request of len %u, id %u, seq %u, cksum 0x%X to host %s\n", + sizeof(data), ntohs(packet.icp->icmp_id), ntohs(packet.icp->icmp_seq), packet.icp->icmp_cksum, host->name); + + len = sendto(sock, packet.buf, icmp_pkt_size, 0, (struct sockaddr *)addr, sizeof(struct sockaddr)); if(len < 0 || (unsigned int)len != icmp_pkt_size) { @@ -847,7 +870,7 @@ send_icmp_ping(int sock, struct rta_host *host) } 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; @@ -887,7 +910,7 @@ finish(int sig) 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; @@ -979,11 +1002,12 @@ finish(int sig) 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; } @@ -1014,7 +1038,7 @@ get_timevaldiff(struct timeval *early, struct timeval *later) 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; @@ -1060,6 +1084,8 @@ add_target_ip(char *arg, struct in_addr *in) 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; @@ -1101,7 +1127,7 @@ add_target(char *arg) /* 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; @@ -1109,6 +1135,40 @@ add_target(char *arg) 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 @@ -1212,25 +1272,28 @@ void print_help(void) { - /*print_revision (progname, revision);*/ /* FIXME: Why? */ - + /*print_revision (progname);*/ /* FIXME: Why? */ + printf ("Copyright (c) 2005 Andreas Ericsson \n"); printf (COPYRIGHT, copyright, email); - + printf ("\n\n"); - + print_usage (); - - printf (_(UT_HELP_VRSN)); - + + printf (UT_HELP_VRSN); + 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 / 1000); + 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, crit.pl); + 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); @@ -1245,33 +1308,35 @@ print_help(void) printf ("\n"); printf (" %s\n", "-l"); printf (" %s", _("TTL on outgoing packets (currently ")); - printf ("%u)", ttl); + 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", _("icmp packet size (currenly ignored)")); + 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\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.")); + 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 ("%s\n\n", _("The -v switch can be specified several times for increased verbosity.")); - + 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")); */ - printf (_(UT_SUPPORT)); - - printf (_(UT_NOWARRANTY)); + + printf (UT_SUPPORT); } @@ -1279,6 +1344,6 @@ print_help(void) void print_usage (void) { - printf (_("Usage:")); - printf(" %s [options] [-H] host1 host2 hostn\n", progname); + printf ("%s\n", _("Usage:")); + printf(" %s [options] [-H] host1 host2 hostN\n", progname); }