X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=plugins-root%2Fcheck_icmp.c;h=6d8ba09980a141848e2c21d6441ec4c9aa1617ce;hb=654086f1117ee22d9f7e8270330daff6c463c9ad;hp=cc3f3d593dffe7ae27b814011ce2f24b89fc12a2;hpb=caa8bd6423e2d0d1b4e72c150e80b9c6a9e1b7fe;p=nagiosplug.git diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c index cc3f3d5..6d8ba09 100644 --- a/plugins-root/check_icmp.c +++ b/plugins-root/check_icmp.c @@ -6,8 +6,6 @@ * Copyright (c) 2005-2008 Nagios Plugins Development Team * Original Author : Andreas Ericsson * -* Last Modified: $Date$ -* * Description: * * This file contains the check_icmp plugin @@ -35,14 +33,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * -* $Id$ * *****************************************************************************/ /* progname may change */ /* char *progname = "check_icmp"; */ char *progname; -const char *revision = "$Revision$"; const char *copyright = "2005-2008"; const char *email = "nagiosplug-devel@lists.sourceforge.net"; @@ -74,6 +70,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; #include #include #include +#include /** sometimes undefined system macros (quite a few, actually) **/ @@ -187,14 +184,14 @@ 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(char *, 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 *, ...); @@ -303,13 +300,13 @@ get_icmp_error_msg(unsigned char icmp_type, unsigned char icmp_code) } static int -handle_random_icmp(char *packet, struct sockaddr_in *addr) +handle_random_icmp(unsigned char *packet, struct sockaddr_in *addr) { struct icmp p, sent_icmp; struct rta_host *host = NULL; memcpy(&p, packet, sizeof(p)); - if(p.icmp_type == ICMP_ECHO && p.icmp_id == pid) { + if(p.icmp_type == ICMP_ECHO && ntohs(p.icmp_id) == pid) { /* echo request from us to us (pinging localhost) */ return 0; } @@ -335,15 +332,15 @@ handle_random_icmp(char *packet, struct sockaddr_in *addr) /* might be for us. At least it holds the original package (according * to RFC 792). If it isn't, just ignore it */ 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(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), @@ -516,7 +513,7 @@ main(int argc, char **argv) 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 (); @@ -627,7 +624,7 @@ main(int argc, char **argv) table = malloc(sizeof(struct rta_host **) * (argc - 1)); i = 0; while(host) { - host->id = i; + host->id = i*packets; table[i] = host; host = host->next; i++; @@ -697,7 +694,7 @@ 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; @@ -766,12 +763,8 @@ wait_for_reply(int sock, u_int t) /* check the response */ 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(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(buf + hlen, &resp_addr); continue; @@ -779,8 +772,11 @@ wait_for_reply(int sock, u_int t) /* this is indeed a valid response */ 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); @@ -817,7 +813,7 @@ static int send_icmp_ping(int sock, struct rta_host *host) { static union { - char *buf; /* re-use so we prevent leaks */ + void *buf; /* re-use so we prevent leaks */ struct icmp *icp; u_short *cksum_in; } packet = { NULL }; @@ -850,10 +846,14 @@ send_icmp_ping(int sock, struct rta_host *host) 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_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)); @@ -870,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; @@ -1038,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; @@ -1272,7 +1272,7 @@ 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); @@ -1281,17 +1281,17 @@ print_help(void) print_usage (); - printf (_(UT_HELP_VRSN)); - printf (_(UT_EXTRA_OPTS)); + 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"); @@ -1335,12 +1335,8 @@ print_help(void) /* 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_SUPPORT); } @@ -1348,6 +1344,6 @@ print_help(void) void print_usage (void) { - printf (_("Usage:")); + printf ("%s\n", _("Usage:")); printf(" %s [options] [-H] host1 host2 hostN\n", progname); }