diff options
| author | Holger Weiss <hweiss@users.sourceforge.net> | 2007-09-15 11:55:12 +0000 |
|---|---|---|
| committer | Holger Weiss <hweiss@users.sourceforge.net> | 2007-09-15 11:55:12 +0000 |
| commit | c11f63ff7eeb72ea220faec778e1b8bd6651b9f7 (patch) | |
| tree | d81cae251e35eb28aa019524d557841d1fb92117 | |
| parent | e91e92e163d0513c984d6b6b6d28b82310efe01b (diff) | |
| download | monitoring-plugins-c11f63ff7eeb72ea220faec778e1b8bd6651b9f7.tar.gz | |
Correct all instances of misaligned memory access. This fixes bus erros
on platforms which require alignment (such as SPARC and MIPS).
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1779 f882894a-f735-0410-b71e-b25c423dba1c
| -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 7f9160c4..f0ba9d0c 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) { |
