diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | plugins-root/check_icmp.c | 79 |
2 files changed, 37 insertions, 43 deletions
@@ -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 | ||
18 | 1.4.9 4th June 2006 | 19 | 1.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) | |||
294 | static int | 294 | static int |
295 | handle_random_icmp(struct icmp *p, struct sockaddr_in *addr) | 295 | handle_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) | |||
796 | static int | 789 | static int |
797 | send_icmp_ping(int sock, struct rta_host *host) | 790 | send_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) { |