On Wed, 31 Oct 2001, Ray Olszewski wrote:

> Sorry to be coming into this late. I find I cannot reproduce the problem
> using the version of gatping I have here (the prototype I wrote almost a
> year ago, which I believe is the same as the version Scott sort-of released).

I guess that would be as expected... :)

[...]

> Jeff Newmiller did spot what looks like an error in the source. This line --
> 
>         ping_data_size = MIN_PING_DATA ;
> 
> should be added near the top of main(), just before this line --
> 
>         ping_pkt_size =  ping_data_size + SIZE_ICMP_HDR         ;
> 
> OTOH, that shouldn't be causing a problem with free(); if it was causing a
> segfault -- I think it doesn't only because malloc() actually allocates more
> memory than you ask for, sometimes -- that should show up when trying to
> write to the out-of-bounds location, not when trying to free() the memory
> ... that is, a few lines earlier than what the debug report shows.

No, the segfault occurs when an attempt is made to access inappropriate
memory... usually the page containing logical address zero (NULL) or
program code memory.  The way malloc usually works involves a linked list
of adjacent free memory blocks, so when you write beyond the end of a
block, you are more likely to mess up the free block data structure
following the short block than access an invalid memory page.  Thus, when
you attempt to free the short block, it attempts to update the corrupted
data structure following the short block, and fails when it tries to
follow the pointers in it.

> So despite Jeff's help, I don't think we know yet the actual cause of this
> problem. Perhaps one of you who are seeing the problem could be specific
> about the Oxygen image involved, what actual command you are running, and
> whatever else you can think of that might help to pin down the problem.
>          
> In the meantime, I'm attaching the source and executable for gatping with
> the correction I mention above incorporated. 

I tried adding this line and compiling it on my glibc2.2 workstation (I
don't have a glibc2.1 dev setup), and now instead of segfaulting it
prints a bunch of "Problem with ping - returned -1" lines followed by the
ip/macs of the Linux boxen on my LAN, but sans the Winboxen.  So yes, it
does correct the problem, but there may remain some work, depending
whether the glibc2.1 vs. 2.2 is causing the ping to fail, or whether there
is a problem in the packet generation that Linux ignores but Windows
doesn't.  I don't think the "Problem" message should be there, either.

I made some other very minor changes as well, so I am including a diff for
the record.

---------------------------------------------------------------------------
Jeff Newmiller                        The     .....       .....  Go Live...
DCN:<[EMAIL PROTECTED]>        Basics: ##.#.       ##.#.  Live Go...
                                      Live:   OO#.. Dead: OO#..  Playing
Research Engineer (Solar/Batteries            O.O#.       #.O#.  with
/Software/Embedded Controllers)               .OO#.       .OO#.  rocks...2k
---------------------------------------------------------------------------
--- x/gatping.c Sun Dec  3 17:20:50 2000
+++ gatping.c   Wed Oct 31 23:10:26 2001
@@ -24,9 +24,11 @@
 /* these next two may be a problem - fping source complains about them */
 #include <netinet/ip.h>
 #include <netinet/ip_icmp.h>
+#include <arpa/inet.h>
 #include <netdb.h>
 
 #include <sys/time.h>
+#include <sys/socket.h>
 
 /* data added after ICMP header  - can this be even shorter??? */
 typedef struct ping_data
@@ -75,7 +77,7 @@
 
 /* an array for the IP addresses we will ping */
 /* default network can be overridden on command line */
-char           network[13] = "192.168.123."    ;
+char           network[20] = "192.168.123."    ;
 int            lowhost = 1                     ;
 int            highhost = 254                  ;
 
@@ -90,10 +92,10 @@
 int            arp_table       ; /* the arp pseudo file        */
 
 /* function prototypes */
-int send_ping ( )      ;
-int make_target_list ()        ;
+void send_ping ( )     ;
+void make_target_list ()       ;
 int in_cksum ( u_short *p, int n )     ;
-int search_arp ()              ;
+void search_arp ()             ;
 
 
 /*  main program */
@@ -101,20 +103,21 @@
        {
 
        
-       int             i, j, k         ; /* misc counters */
+       int             k               ; /* misc counters */
        struct protoent *proto          ;
-       char            *buf            ;
 
        ident = getpid() & 0xFFFF       ;
        proto = getprotobyname ( "icmp" )       ;
-       mysock = socket(AF_INET, SOCK_RAW, proto->p_proto )     ;
+       mysock = socket( AF_INET, SOCK_RAW, proto->p_proto )    ;
+       ping_data_size = MIN_PING_DATA ;
        ping_pkt_size =  ping_data_size + SIZE_ICMP_HDR         ;
        
        /* see if a network other than the default is specified */
        if ( argc == 2 )
                {
-               strcpy ( network, argv[1] )     ;
-               }       ;
+               strncpy ( network, argv[1], sizeof(network)-1 ) ;
+               network[ sizeof(network) - 1 ] = '\0';
+               }
 
        /* add code later to eval command-line options */
 
@@ -130,7 +133,7 @@
                send_ping ( mysock, cursor )    ;
                k++             ;
                cursor = cursor->next           ;
-               }       ; /* while */
+               }        /* while */
        
        /* give the kernel time to do things */
        /* system ( " sleep 1 " )       ; */
@@ -139,15 +142,16 @@
 
        search_arp ()   ;
        /* clean up and exit */
-
-       }       ; /* main */
+       
+       return 0;
+       }        /* main */
 
 
 /* functions specified */
 
 /* send_ping -- sends a single ping packet to a supplied address */
 /* pretty much right from fping */
-int send_ping ( int s  ,  HOST_ENTRY *h )
+void send_ping ( int s  ,  HOST_ENTRY *h )
        {
        char            *buffer         ;
        struct icmp     *icp            ;
@@ -176,23 +180,22 @@
                        ( struct sockaddr * ) &h->saddr,
                        sizeof ( struct sockaddr_in ) ) ;
        if ( n < 0 || n != ping_pkt_size )
-               printf ( "Problem with ping - returned %d\n",n )        ;       
+               printf ( "Problem with ping - returned %d\n",n )        ;
        /* release the memory before exiting */
        free ( buffer ) ;       
 
-       }       ; /* send_ping */
+       }        /* send_ping */
 
 
 /* make_target_list -- creates a list of addresses to ping */
-int make_target_list ( )
+void make_target_list ( )
        {
 
        char            addrbuf[24]     ;
-       int             buflen          ;
-       int             i, j, k, m              ;
+       int             i, k, m         ;
        HOST_ENTRY      *p              ;
        char            * testbuf       ;
-       char            hoststring[6]           ;
+       char            hoststring[6]   ;
 
        /* open the file of addreses - must be fixed length aaa.bbb.ccc.ddd */
        /* ping_file = open ("/tmp/pingfile",O_RDONLY,0644 )    ; */
@@ -200,7 +203,7 @@
        
        for ( i = lowhost ; i <= highhost ; i++ )
                {
-               sprintf (hoststring,"%d", i )   ;
+               sprintf ( hoststring, "%d", i ) ;
                strcpy ( addrbuf, network )     ;
                strcat ( addrbuf, hoststring )  ;
 
@@ -231,24 +234,22 @@
                        cursor->next = p        ;
                        cursor = p              ;
                        }       ;
-               }       ; /* exit if that was the last line of data */
+               }        /* exit if that was the last line of data */
 
-       }       ; /* make_target_list */
+       }        /* make_target_list */
 
 
 /* search_arp -- processes the arp table to find valid entries */
 /* puts them in a linked list and writes the results to a file */
-int search_arp ( )     
+void search_arp ( )    
        {
 
         char            arpbuf[100]     ;
         int             buflen          ;
-        int             i, j, k, m              ;
        VALID_HOST      *p              ;
-        char            * testbuf       ;
 
        /* open the arp pseudo-file for reading */
-       arp_table = open ("/proc/net/arp",O_RDONLY,0644 )    ;
+       arp_table = open ( "/proc/net/arp", O_RDONLY, 0644 )    ;
                /* and read and ignore the header line */
        read ( arp_table, arpbuf, 79 )  ; 
        arpbuf[87] = '\0'       ;
@@ -264,8 +265,8 @@
                        /* add the MAC and IP addresses to the list */
                        p = ( VALID_HOST * ) malloc ( sizeof ( VALID_HOST ) ) ;
                        memset ( ( char * ) p, 0, sizeof ( VALID_HOST ) )  ;
-                       strncpy ( p->ip_add, &arpbuf[0],15 )    ;
-                       strncpy ( p->mac_add, &arpbuf[41],18 )  ;
+                       strncpy ( p->ip_add, &arpbuf[0], 15 )   ;
+                       strncpy ( p->mac_add, &arpbuf[41], 18 ) ;
                        p->next = NULL  ;
                        if ( !goodlist )
                                {
@@ -280,19 +281,18 @@
                                }       ;
                        /* and print the results to STDOUT */
                        printf ( "%s %s\n",p->ip_add,p->mac_add )       ;
-                       }       ;
+                       }       
                }
        /* close the pseudo-file */
        /* print the results to STDOUT */
        
-       }       ;
+       }       
 
 /* in_cksum -- computes checksum for ICMP packet */
 /* taken directly from fping except for formatting     */
 
-int in_cksum(u_short *p, int n)
+int in_cksum( u_short *p, int n )
        {
-       register u_short answer;
        register long sum = 0;
        u_short odd_byte = 0;
 
@@ -300,11 +300,12 @@
 
        /* mop up an odd byte, if necessary */
        if( n == 1 ) 
-               {
-       *(u_char *)(&odd_byte) = *(u_char *)p;
-       sum += odd_byte;
-               }       ;
-       }       ;
+         {
+           *(u_char *)(&odd_byte) = *(u_char *)p;
+           sum += odd_byte;
+         }
+       return sum;
+       }
 
 
 

Reply via email to