logo       
Google Custom Search
    AddThis Social Bookmark Button

SF.net SVN: nagiosplug: [1779] nagiosplug/trunk: msg#00004

Subject: SF.net SVN: nagiosplug: [1779] nagiosplug/trunk
Revision: 1779
          http://nagiosplug.svn.sourceforge.net/nagiosplug/?rev=1779&view=rev
Author:   hweiss
Date:     2007-09-15 04:55:12 -0700 (Sat, 15 Sep 2007)

Log Message:
-----------
Correct all instances of misaligned memory access.  This fixes bus erros
on platforms which require alignment (such as SPARC and MIPS).

Modified Paths:
--------------
    nagiosplug/trunk/NEWS
    nagiosplug/trunk/plugins-root/check_icmp.c

Modified: nagiosplug/trunk/NEWS
===================================================================
--- nagiosplug/trunk/NEWS       2007-09-15 11:34:48 UTC (rev 1778)
+++ nagiosplug/trunk/NEWS       2007-09-15 11:55:12 UTC (rev 1779)
@@ -14,6 +14,7 @@
        New check_dhcp -m/--mac option which allows for specifying the MAC
          address to use in the DHCP request
        The check_dhcp -r and -s options now accept host names, too
+       Fix possible check_icmp bus errors on some (non-x86/AMD64) platforms
 
 1.4.9 4th June 2006
        Inclusion of contrib/check_cluster2 as check_cluster with some 
improvements

Modified: nagiosplug/trunk/plugins-root/check_icmp.c
===================================================================
--- nagiosplug/trunk/plugins-root/check_icmp.c  2007-09-15 11:34:48 UTC (rev 
1778)
+++ nagiosplug/trunk/plugins-root/check_icmp.c  2007-09-15 11:55:12 UTC (rev 
1779)
@@ -294,7 +294,7 @@
 static int
 handle_random_icmp(struct icmp *p, struct sockaddr_in *addr)
 {
-       struct icmp *sent_icmp = NULL;
+       struct icmp sent_icmp;
        struct rta_host *host = NULL;
        unsigned char *ptr;
 
@@ -324,16 +324,16 @@
 
        /* 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, ptr + 28, sizeof(sent_icmp));
+       if(sent_icmp.icmp_type != ICMP_ECHO || sent_icmp.icmp_id != pid ||
+          sent_icmp.icmp_seq >= targets)
        {
                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[sent_icmp.icmp_seq];
        if(debug) {
                printf("Received \"%s\" from %s for ICMP ECHO sent to %s.\n",
                           get_icmp_error_msg(p->icmp_type, p->icmp_code),
@@ -677,9 +677,9 @@
        static 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;
 
@@ -741,32 +741,25 @@
                /* } */
 
                /* 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); 
*/
+               memcpy(&icp, buf + hlen, sizeof(icp));
 
-               if(icp->icmp_id != pid) {
-                       handle_random_icmp(icp, &resp_addr);
+               if(icp.icmp_id != pid) {
+                       handle_random_icmp(&icp, &resp_addr);
                        continue;
                }
 
-               if(icp->icmp_type != ICMP_ECHOREPLY || icp->icmp_seq >= 
targets) {
+               if(icp.icmp_type != ICMP_ECHOREPLY || icp.icmp_seq >= targets) {
                        if(debug > 2) printf("not a proper ICMP_ECHOREPLY\n");
-                       handle_random_icmp(icp, &resp_addr);
+                       handle_random_icmp(&icp, &resp_addr);
                        continue;
                }
 
                /* this is indeed a valid response */
-               data = (struct icmp_ping_data *)(icp->icmp_data);
+               memcpy(&data, icp.icmp_data, sizeof(data));
 
-               host = table[icp->icmp_seq];
+               host = table[icp.icmp_seq];
                gettimeofday(&now, &tz);
-               tdiff = get_timevaldiff(&data->stime, &now);
+               tdiff = get_timevaldiff(&data.stime, &now);
 
                host->time_waited += tdiff;
                host->icmp_recv++;
@@ -796,14 +789,16 @@
 static int
 send_icmp_ping(int sock, struct rta_host *host)
 {
-       static char *buf = NULL; /* re-use so we prevent leaks */
+       static union {
+               char *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");
@@ -811,30 +806,28 @@
        }
        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);
+       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 = pid;
+       packet.icp->icmp_seq = host->id;
+       packet.icp->icmp_cksum = icmp_checksum(packet.cksum_in, icmp_pkt_size);
 
-       len = sendto(sock, buf, icmp_pkt_size, 0, (struct sockaddr *)addr,
+       len = sendto(sock, packet.buf, icmp_pkt_size, 0, (struct sockaddr 
*)addr,
                                 sizeof(struct sockaddr));
 
        if(len < 0 || (unsigned int)len != icmp_pkt_size) {


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/


<Prev in Thread] Current Thread [Next in Thread>