summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--plugins-root/check_icmp.c79
2 files changed, 37 insertions, 43 deletions
diff --git a/NEWS b/NEWS
index 7170b19..b687f6f 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ This file documents the major additions and syntax changes between releases.
14 New check_dhcp -m/--mac option which allows for specifying the MAC 14 New check_dhcp -m/--mac option which allows for specifying the MAC
15 address to use in the DHCP request 15 address to use in the DHCP request
16 The check_dhcp -r and -s options now accept host names, too 16 The check_dhcp -r and -s options now accept host names, too
17 Fix possible check_icmp bus errors on some (non-x86/AMD64) platforms
17 18
181.4.9 4th June 2006 191.4.9 4th June 2006
19 Inclusion of contrib/check_cluster2 as check_cluster with some improvements 20 Inclusion of contrib/check_cluster2 as check_cluster with some improvements
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index 7f9160c..f0ba9d0 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -294,7 +294,7 @@ get_icmp_error_msg(unsigned char icmp_type, unsigned char icmp_code)
294static int 294static int
295handle_random_icmp(struct icmp *p, struct sockaddr_in *addr) 295handle_random_icmp(struct icmp *p, struct sockaddr_in *addr)
296{ 296{
297 struct icmp *sent_icmp = NULL; 297 struct icmp sent_icmp;
298 struct rta_host *host = NULL; 298 struct rta_host *host = NULL;
299 unsigned char *ptr; 299 unsigned char *ptr;
300 300
@@ -324,16 +324,16 @@ handle_random_icmp(struct icmp *p, struct sockaddr_in *addr)
324 324
325 /* might be for us. At least it holds the original package (according 325 /* might be for us. At least it holds the original package (according
326 * to RFC 792). If it isn't, just ignore it */ 326 * to RFC 792). If it isn't, just ignore it */
327 sent_icmp = (struct icmp *)(ptr + 28); 327 memcpy(&sent_icmp, ptr + 28, sizeof(sent_icmp));
328 if(sent_icmp->icmp_type != ICMP_ECHO || sent_icmp->icmp_id != pid || 328 if(sent_icmp.icmp_type != ICMP_ECHO || sent_icmp.icmp_id != pid ||
329 sent_icmp->icmp_seq >= targets) 329 sent_icmp.icmp_seq >= targets)
330 { 330 {
331 if(debug) printf("Packet is no response to a packet we sent\n"); 331 if(debug) printf("Packet is no response to a packet we sent\n");
332 return 0; 332 return 0;
333 } 333 }
334 334
335 /* it is indeed a response for us */ 335 /* it is indeed a response for us */
336 host = table[sent_icmp->icmp_seq]; 336 host = table[sent_icmp.icmp_seq];
337 if(debug) { 337 if(debug) {
338 printf("Received \"%s\" from %s for ICMP ECHO sent to %s.\n", 338 printf("Received \"%s\" from %s for ICMP ECHO sent to %s.\n",
339 get_icmp_error_msg(p->icmp_type, p->icmp_code), 339 get_icmp_error_msg(p->icmp_type, p->icmp_code),
@@ -677,9 +677,9 @@ wait_for_reply(int sock, u_int t)
677 static char buf[4096]; 677 static char buf[4096];
678 struct sockaddr_in resp_addr; 678 struct sockaddr_in resp_addr;
679 struct ip *ip; 679 struct ip *ip;
680 struct icmp *icp, *sent_icmp; 680 struct icmp icp;
681 struct rta_host *host; 681 struct rta_host *host;
682 struct icmp_ping_data *data; 682 struct icmp_ping_data data;
683 struct timeval wait_start, now; 683 struct timeval wait_start, now;
684 u_int tdiff, i, per_pkt_wait; 684 u_int tdiff, i, per_pkt_wait;
685 685
@@ -741,32 +741,25 @@ wait_for_reply(int sock, u_int t)
741 /* } */ 741 /* } */
742 742
743 /* check the response */ 743 /* check the response */
744 icp = (struct icmp *)(buf + hlen); 744 memcpy(&icp, buf + hlen, sizeof(icp));
745 sent_icmp = (struct icmp *)(buf + hlen + ICMP_MINLEN); 745
746 /* printf("buf: %p, icp: %p, distance: %u (expected %u)\n", */ 746 if(icp.icmp_id != pid) {
747 /* buf, icp, */ 747 handle_random_icmp(&icp, &resp_addr);
748 /* (u_int)icp - (u_int)buf, hlen); */
749 /* printf("buf: %p, sent_icmp: %p, distance: %u (expected %u)\n", */
750 /* buf, sent_icmp, */
751 /* (u_int)sent_icmp - (u_int)buf, hlen + ICMP_MINLEN); */
752
753 if(icp->icmp_id != pid) {
754 handle_random_icmp(icp, &resp_addr);
755 continue; 748 continue;
756 } 749 }
757 750
758 if(icp->icmp_type != ICMP_ECHOREPLY || icp->icmp_seq >= targets) { 751 if(icp.icmp_type != ICMP_ECHOREPLY || icp.icmp_seq >= targets) {
759 if(debug > 2) printf("not a proper ICMP_ECHOREPLY\n"); 752 if(debug > 2) printf("not a proper ICMP_ECHOREPLY\n");
760 handle_random_icmp(icp, &resp_addr); 753 handle_random_icmp(&icp, &resp_addr);
761 continue; 754 continue;
762 } 755 }
763 756
764 /* this is indeed a valid response */ 757 /* this is indeed a valid response */
765 data = (struct icmp_ping_data *)(icp->icmp_data); 758 memcpy(&data, icp.icmp_data, sizeof(data));
766 759
767 host = table[icp->icmp_seq]; 760 host = table[icp.icmp_seq];
768 gettimeofday(&now, &tz); 761 gettimeofday(&now, &tz);
769 tdiff = get_timevaldiff(&data->stime, &now); 762 tdiff = get_timevaldiff(&data.stime, &now);
770 763
771 host->time_waited += tdiff; 764 host->time_waited += tdiff;
772 host->icmp_recv++; 765 host->icmp_recv++;
@@ -796,14 +789,16 @@ wait_for_reply(int sock, u_int t)
796static int 789static int
797send_icmp_ping(int sock, struct rta_host *host) 790send_icmp_ping(int sock, struct rta_host *host)
798{ 791{
799 static char *buf = NULL; /* re-use so we prevent leaks */ 792 static union {
793 char *buf; /* re-use so we prevent leaks */
794 struct icmp *icp;
795 u_short *cksum_in;
796 } packet = { NULL };
800 long int len; 797 long int len;
801 struct icmp *icp; 798 struct icmp_ping_data data;
802 struct icmp_ping_data *data;
803 struct timeval tv; 799 struct timeval tv;
804 struct sockaddr *addr; 800 struct sockaddr *addr;
805 801
806
807 if(sock == -1) { 802 if(sock == -1) {
808 errno = 0; 803 errno = 0;
809 crash("Attempt to send on bogus socket"); 804 crash("Attempt to send on bogus socket");
@@ -811,30 +806,28 @@ send_icmp_ping(int sock, struct rta_host *host)
811 } 806 }
812 addr = (struct sockaddr *)&host->saddr_in; 807 addr = (struct sockaddr *)&host->saddr_in;
813 808
814 if(!buf) { 809 if(!packet.buf) {
815 buf = (char *)malloc(icmp_pkt_size + sizeof(struct ip)); 810 if (!(packet.buf = malloc(icmp_pkt_size))) {
816 if(!buf) {
817 crash("send_icmp_ping(): failed to malloc %d bytes for send buffer", 811 crash("send_icmp_ping(): failed to malloc %d bytes for send buffer",
818 icmp_pkt_size); 812 icmp_pkt_size);
819 return -1; /* might be reached if we're in debug mode */ 813 return -1; /* might be reached if we're in debug mode */
820 } 814 }
821 } 815 }
822 memset(buf, 0, icmp_pkt_size + sizeof(struct ip)); 816 memset(packet.buf, 0, icmp_pkt_size);
823 817
824 if((gettimeofday(&tv, &tz)) == -1) return -1; 818 if((gettimeofday(&tv, &tz)) == -1) return -1;
825 819
826 icp = (struct icmp *)buf; 820 data.ping_id = 10; /* host->icmp.icmp_sent; */
827 icp->icmp_type = ICMP_ECHO; 821 memcpy(&data.stime, &tv, sizeof(tv));
828 icp->icmp_code = 0; 822 memcpy(&packet.icp->icmp_data, &data, sizeof(data));
829 icp->icmp_cksum = 0; 823 packet.icp->icmp_type = ICMP_ECHO;
830 icp->icmp_id = pid; 824 packet.icp->icmp_code = 0;
831 icp->icmp_seq = host->id; 825 packet.icp->icmp_cksum = 0;
832 data = (struct icmp_ping_data *)icp->icmp_data; 826 packet.icp->icmp_id = pid;
833 data->ping_id = 10; /* host->icmp.icmp_sent; */ 827 packet.icp->icmp_seq = host->id;
834 memcpy(&data->stime, &tv, sizeof(struct timeval)); 828 packet.icp->icmp_cksum = icmp_checksum(packet.cksum_in, icmp_pkt_size);
835 icp->icmp_cksum = icmp_checksum((u_short *)icp, icmp_pkt_size); 829
836 830 len = sendto(sock, packet.buf, icmp_pkt_size, 0, (struct sockaddr *)addr,
837 len = sendto(sock, buf, icmp_pkt_size, 0, (struct sockaddr *)addr,
838 sizeof(struct sockaddr)); 831 sizeof(struct sockaddr));
839 832
840 if(len < 0 || (unsigned int)len != icmp_pkt_size) { 833 if(len < 0 || (unsigned int)len != icmp_pkt_size) {