Hello community,

here is the log from the commit of package fping for openSUSE:Factory checked 
in at 2015-11-17 14:23:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/fping (Old)
 and      /work/SRC/openSUSE:Factory/.fping.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "fping"

Changes:
--------
--- /work/SRC/openSUSE:Factory/fping/fping.changes      2014-05-06 
13:56:48.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.fping.new/fping.changes 2015-11-17 
14:23:34.000000000 +0100
@@ -1,0 +2,20 @@
+Wed Oct 21 20:35:51 UTC 2015 - [email protected]
+
+- Update to version 3.13:
+  + Bugfix: Fix ICMP errors sometimes causing crashes with
+    fping >= 3.11.
+
+-------------------------------------------------------------------
+Thu Oct 15 22:41:57 UTC 2015 - [email protected]
+
+- Update to version 3.12:
+  + Bugfix: Fix fping6 -R (#84).
+- Changes from version 3.11:
+  + Feature: 
+    - New option -R to use random bytes instead of NULLs (#72).
+    - Small documentation and performance improvements.
+  + Bugfix: Fix double entries with fping -u and unreachable hosts.
+  + Internal: Use sockaddr_storage and simplify code, so that we
+    can one day support both IPv4 and IPv6 with the same binary.
+
+-------------------------------------------------------------------

Old:
----
  fping-3.10.tar.gz

New:
----
  fping-3.13.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ fping.spec ++++++
--- /var/tmp/diff_new_pack.u0FxFY/_old  2015-11-17 14:23:35.000000000 +0100
+++ /var/tmp/diff_new_pack.u0FxFY/_new  2015-11-17 14:23:35.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package fping
 #
-# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 Name:           fping
 Url:            http://www.fping.org
-Version:        3.10
+Version:        3.13
 Release:        0
 Summary:        A program to ping multiple hosts
 License:        MIT

++++++ fping-3.10.tar.gz -> fping-3.13.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/ChangeLog new/fping-3.13/ChangeLog
--- old/fping-3.10/ChangeLog    2014-05-04 22:33:12.000000000 +0200
+++ new/fping-3.13/ChangeLog    2015-10-21 21:02:56.000000000 +0200
@@ -1,3 +1,19 @@
+2015-10-21  David Schweikert  <[email protected]>
+  * Version 3.13
+  * (bugfix) Fix ICMP errors sometimes causing crashes with fping >= 3.11
+             (fixes #85, reported by Jamie Heilman and Bill Blough)
+
+2015-10-14  David Schweikert  <[email protected]>
+  * Version 3.12
+  * (bugfix) Fix fping6 -R (fixes #84, reported by Stuart Henderson)
+
+2015-10-12  David Schweikert  <[email protected]>
+  * Version 3.11
+  * (feature)  New option -R to use random bytes instead of NULLs (#72, 
Anthony DeRobertis)
+  * (feature)  Small documentation and performance improvements (Ryan 
Underwood)
+  * (bugfix)   Fix double entries with fping -u and unreachable hosts
+  * (internal) Use sockaddr_storage and simplify code, so that we can one day 
support both IPv4 and IPv6 with the same binary
+
 2014-05-03  David Schweikert  <[email protected]>
   * Version 3.10
   * Fix confusing error message with -g and IPv6 addresses (#58, reported by 
Axel Beckert)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/configure new/fping-3.13/configure
--- old/fping-3.10/configure    2014-05-04 22:34:29.000000000 +0200
+++ new/fping-3.13/configure    2015-10-21 21:03:44.000000000 +0200
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for fping 3.10.
+# Generated by GNU Autoconf 2.69 for fping 3.13.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@
 # Identity of this package.
 PACKAGE_NAME='fping'
 PACKAGE_TARNAME='fping'
-PACKAGE_VERSION='3.10'
-PACKAGE_STRING='fping 3.10'
+PACKAGE_VERSION='3.13'
+PACKAGE_STRING='fping 3.13'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1284,7 +1284,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures fping 3.10 to adapt to many kinds of systems.
+\`configure' configures fping 3.13 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1355,7 +1355,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of fping 3.10:";;
+     short | recursive ) echo "Configuration of fping 3.13:";;
    esac
   cat <<\_ACEOF
 
@@ -1451,7 +1451,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-fping configure 3.10
+fping configure 3.13
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1816,7 +1816,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by fping $as_me 3.10, which was
+It was created by fping $as_me 3.13, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2834,7 +2834,7 @@
 
 # Define the identity of the package.
  PACKAGE='fping'
- VERSION='3.10'
+ VERSION='3.13'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -5062,7 +5062,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by fping $as_me 3.10, which was
+This file was extended by fping $as_me 3.13, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -5128,7 +5128,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; 
s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-fping config.status 3.10
+fping config.status 3.13
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/configure.ac new/fping-3.13/configure.ac
--- old/fping-3.10/configure.ac 2014-05-04 22:33:12.000000000 +0200
+++ new/fping-3.13/configure.ac 2015-10-21 21:02:56.000000000 +0200
@@ -3,7 +3,7 @@
 dnl Minimum Autoconf version required.
 AC_PREREQ(2.59)
 
-AC_INIT([fping],[3.10])
+AC_INIT([fping],[3.13])
 
 dnl make ipv4 and ipv6 options
 AC_ARG_ENABLE([ipv4],
@@ -29,7 +29,7 @@
 fi
 
 AC_CANONICAL_TARGET
-AM_INIT_AUTOMAKE([foreign])
+AM_INIT_AUTOMAKE([-Wall -Werror foreign])
 AM_MAINTAINER_MODE
 
 AC_CONFIG_HEADERS([config.h])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/doc/fping.8 new/fping-3.13/doc/fping.8
--- old/fping-3.10/doc/fping.8  2014-05-04 22:34:32.000000000 +0200
+++ new/fping-3.13/doc/fping.8  2015-10-21 21:03:47.000000000 +0200
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "FPING 8"
-.TH FPING 8 "2014-05-04" "fping" ""
+.TH FPING 8 "2015-10-21" "fping" ""
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -159,7 +159,8 @@
 Show systems that are alive.
 .IP "\fB\-A\fR" 5
 .IX Item "-A"
-Display targets by address rather than \s-1DNS\s0 name.
+Display targets by address rather than \s-1DNS\s0 name. Combined with \-d, the 
output
+will be both the ip and (if available) the hostname.
 .IP "\fB\-b\fR \fIn\fR" 5
 .IX Item "-b n"
 Number of bytes of ping data to send.  The minimum size (normally 12) allows
@@ -263,6 +264,10 @@
 .IX Item "-r n"
 Retry limit (default 3). This is the number of times an attempt at pinging
 a target will be made, not including the first try.
+.IP "\fB\-R\fR" 5
+.IX Item "-R"
+Instead of using all-zeros as the packet data, generate random bytes.
+Use to defeat, e.g., link data compression.
 .IP "\fB\-s\fR" 5
 .IX Item "-s"
 Print cumulative statistics upon exit.
@@ -295,6 +300,14 @@
 .IP "\fB\-H\fR \fIn\fR" 5
 .IX Item "-H n"
 Set the \s-1IP\s0 \s-1TTL\s0 field (time to live hops).
+.SH "EXAMPLES"
+.IX Header "EXAMPLES"
+Generate ~1000 pings per second to a host until canceled, printing statistics
+on the fly at one second intervals, and printing statistics at the end:
+.PP
+# fping \-s \-l \-i 1 \-p 1 \-T 1 \-Q 1 127.0.0.1
+.PP
+Note that ping intervals less than 10ms can only be used as root.
 .SH "AUTHORS"
 .IX Header "AUTHORS"
 .IP "\(bu" 4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/doc/fping.pod new/fping-3.13/doc/fping.pod
--- old/fping-3.10/doc/fping.pod        2014-05-04 22:33:12.000000000 +0200
+++ new/fping-3.13/doc/fping.pod        2015-10-21 21:02:56.000000000 +0200
@@ -35,7 +35,8 @@
 
 =item B<-A>
 
-Display targets by address rather than DNS name. 
+Display targets by address rather than DNS name. Combined with -d, the output
+will be both the ip and (if available) the hostname.
 
 =item B<-b> I<n>
 
@@ -150,6 +151,11 @@
 Retry limit (default 3). This is the number of times an attempt at pinging
 a target will be made, not including the first try. 
 
+=item B<-R>
+
+Instead of using all-zeros as the packet data, generate random bytes.
+Use to defeat, e.g., link data compression.
+
 =item B<-s>
 
 Print cumulative statistics upon exit. 
@@ -193,6 +199,15 @@
 
 =back
 
+=head1 EXAMPLES
+
+Generate ~1000 pings per second to a host until canceled, printing statistics
+on the fly at one second intervals, and printing statistics at the end:
+
+# fping -s -l -i 1 -p 1 -T 1 -Q 1 127.0.0.1
+
+Note that ping intervals less than 10ms can only be used as root.
+
 =head1 AUTHORS
 
 =over 4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/doc/fping6.8 new/fping-3.13/doc/fping6.8
--- old/fping-3.10/doc/fping6.8 2014-05-04 22:34:32.000000000 +0200
+++ new/fping-3.13/doc/fping6.8 2015-10-21 21:03:47.000000000 +0200
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "fping6 8"
-.TH fping6 8 "2014-05-04" "fping" ""
+.TH fping6 8 "2015-10-21" "fping" ""
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -159,7 +159,8 @@
 Show systems that are alive.
 .IP "\fB\-A\fR" 5
 .IX Item "-A"
-Display targets by address rather than \s-1DNS\s0 name.
+Display targets by address rather than \s-1DNS\s0 name. Combined with \-d, the 
output
+will be both the ip and (if available) the hostname.
 .IP "\fB\-b\fR \fIn\fR" 5
 .IX Item "-b n"
 Number of bytes of ping data to send.  The minimum size (normally 12) allows
@@ -263,6 +264,10 @@
 .IX Item "-r n"
 Retry limit (default 3). This is the number of times an attempt at pinging
 a target will be made, not including the first try.
+.IP "\fB\-R\fR" 5
+.IX Item "-R"
+Instead of using all-zeros as the packet data, generate random bytes.
+Use to defeat, e.g., link data compression.
 .IP "\fB\-s\fR" 5
 .IX Item "-s"
 Print cumulative statistics upon exit.
@@ -295,6 +300,14 @@
 .IP "\fB\-H\fR \fIn\fR" 5
 .IX Item "-H n"
 Set the \s-1IP\s0 \s-1TTL\s0 field (time to live hops).
+.SH "EXAMPLES"
+.IX Header "EXAMPLES"
+Generate ~1000 pings per second to a host until canceled, printing statistics
+on the fly at one second intervals, and printing statistics at the end:
+.PP
+# fping \-s \-l \-i 1 \-p 1 \-T 1 \-Q 1 127.0.0.1
+.PP
+Note that ping intervals less than 10ms can only be used as root.
 .SH "AUTHORS"
 .IX Header "AUTHORS"
 .IP "\(bu" 4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/src/Makefile.am 
new/fping-3.13/src/Makefile.am
--- old/fping-3.10/src/Makefile.am      2014-05-04 22:33:12.000000000 +0200
+++ new/fping-3.13/src/Makefile.am      2015-10-21 21:02:56.000000000 +0200
@@ -1,3 +1,5 @@
+AM_CFLAGS = -Wall -Wextra -Wno-sign-compare
+
 prog =
 
 if IPV4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/src/Makefile.in 
new/fping-3.13/src/Makefile.in
--- old/fping-3.10/src/Makefile.in      2014-05-04 22:34:30.000000000 +0200
+++ new/fping-3.13/src/Makefile.in      2015-10-21 21:03:45.000000000 +0200
@@ -267,6 +267,7 @@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
+AM_CFLAGS = -Wall -Wextra -Wno-sign-compare
 prog = $(am__append_1) $(am__append_2)
 fping_SOURCES = fping.c seqmap.c socket.c socket4.c fping.h options.h seqmap.h
 fping_DEPENDENCIES = ../config.h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/src/fping.c new/fping-3.13/src/fping.c
--- old/fping-3.10/src/fping.c  2014-05-04 22:33:12.000000000 +0200
+++ new/fping-3.13/src/fping.c  2015-10-21 21:02:56.000000000 +0200
@@ -149,6 +149,7 @@
 #endif /* DEBUG || _DEBUG */
 
 /* Long names for ICMP packet types */
+#define ICMP_TYPE_STR_MAX 18
 char *icmp_type_str[19] =
 {
     "ICMP Echo Reply",          /* 0 */
@@ -212,7 +213,8 @@
      char                 *name;              /* name as given by user */
      char                 *host;              /* text description of host */
      char                 *pad;               /* pad to align print names */
-     FPING_SOCKADDR       saddr;              /* internet address */
+     struct sockaddr_storage saddr;             /* internet address */
+     socklen_t            saddr_len;
      int                  timeout;            /* time to wait for response */
      unsigned char        running;            /* unset when through sending */
      unsigned char        waiting;            /* waiting for response */
@@ -237,7 +239,6 @@
 
 /*** globals ***/
 
-HOST_ENTRY *rrlist = NULL;  /* linked list of hosts be pinged */
 HOST_ENTRY **table = NULL;  /* array of pointers to items in the list */
 
 /* event queue (ev): This, together with the ev_next / ev_prev elements are 
used
@@ -258,7 +259,6 @@
 unsigned int perhost_interval = DEFAULT_PERHOST_INTERVAL * 100;
 float backoff = DEFAULT_BACKOFF_FACTOR;
 unsigned int ping_data_size = DEFAULT_PING_DATA_SIZE;
-unsigned int ping_pkt_size;
 unsigned int count = 1;
 unsigned int trials;
 unsigned int report_interval = 0;
@@ -300,6 +300,7 @@
 int per_recv_flag, report_all_rtts_flag, name_flag, addr_flag, backoff_flag;
 int multif_flag;
 int timestamp_flag = 0;
+int random_data_flag = 0;
 #if defined( DEBUG ) || defined( _DEBUG )
 int randomly_lose_flag, sent_times_flag, trace_flag, print_per_system_flag;
 int lose_factor;
@@ -310,18 +311,12 @@
 /*** forward declarations ***/
 
 void add_name( char *name );
-#ifndef IPV6
-void add_addr( char *name, char *host, struct in_addr ipaddr );
-#else
-void add_addr( char *name, char *host, FPING_SOCKADDR *ipaddr );
-#endif
+void add_addr( char *name, char *host, struct sockaddr *ipaddr, socklen_t 
ipaddr_len);
 char *na_cat( char *name, struct in_addr ipaddr );
 void crash_and_burn( char *message );
 void errno_crash_and_burn( char *message );
 char *get_host_by_address( struct in_addr in );
-int in_cksum( unsigned short *p, int n );
-void u_sleep( int u_sec );
-int recvfrom_wto ( int s, char *buf, int len, FPING_SOCKADDR *saddr, long timo 
);
+int recvfrom_wto( int s, char *buf, int len, struct sockaddr *saddr, socklen_t 
*saddr_len, long timo );
 void remove_job( HOST_ENTRY *h );
 int send_ping( int s, HOST_ENTRY *h );
 long timeval_diff( struct timeval *a, struct timeval *b );
@@ -333,7 +328,7 @@
 void print_global_stats( void );
 void main_loop();
 void finish();
-int handle_random_icmp( FPING_ICMPHDR *p, int psize, FPING_SOCKADDR *addr );
+int handle_random_icmp( FPING_ICMPHDR *p, struct sockaddr *addr, socklen_t 
addr_len);
 char *sprint_tm( int t );
 void ev_enqueue(HOST_ENTRY  *h);
 HOST_ENTRY *ev_dequeue();
@@ -341,6 +336,7 @@
 void add_cidr(char *);
 void add_range(char *, char *);
 void print_warning(char *fmt, ...);
+int addr_cmp(struct sockaddr *a, struct sockaddr *b);
 
 /*** function definitions ***/
 
@@ -366,7 +362,7 @@
     int tos = 0; 
     HOST_ENTRY *cursor;
 
-    s = open_ping_socket();
+    s = open_ping_socket(ping_data_size);
 
     if((uid = getuid())) {
         /* drop privileges */
@@ -381,7 +377,7 @@
 
     /* get command line options */
 
-    while( ( c = getopt( argc, argv, 
"gedhlmnqusaAvDz:t:H:i:p:f:r:c:b:C:Q:B:S:I:T:O:" ) ) != EOF )
+    while( ( c = getopt( argc, argv, 
"gedhlmnqusaAvDRz:t:H:i:p:f:r:c:b:C:Q:B:S:I:T:O:" ) ) != EOF )
     {
         switch( c )
         {
@@ -477,6 +473,10 @@
             timestamp_flag = 1;
             break;
 
+        case 'R':
+            random_data_flag = 1;
+            break;
+
         case 'l':
             loop_flag = 1;
             backoff_flag = 0;
@@ -817,8 +817,8 @@
 
     }/* FOR */
 
-    ping_pkt_size = ping_data_size + SIZE_ICMP_HDR;
-    
+    init_ping_buffer(ping_data_size);
+
     signal( SIGINT, finish );
     
     gettimeofday( &start_time, &tz );
@@ -1394,58 +1394,28 @@
 
 int send_ping( int s, HOST_ENTRY *h )
 {
-    char *buffer;
-    FPING_ICMPHDR *icp;
     int n;
     int myseq;
     int ret = 1;
 
-    buffer = ( char* )malloc( ( size_t )ping_pkt_size );
-    if( !buffer )
-        crash_and_burn( "can't malloc ping packet" );
-    
-    memset( buffer, 0, ping_pkt_size * sizeof( char ) );
-    icp = ( FPING_ICMPHDR* )buffer;
-
     gettimeofday( &h->last_send_time, &tz );
     myseq = seqmap_add(h->i, h->num_sent, &h->last_send_time);
 
-#ifndef IPV6
-    icp->icmp_type = ICMP_ECHO;
-    icp->icmp_code = 0;
-    icp->icmp_cksum = 0;
-    icp->icmp_seq = htons(myseq);
-    icp->icmp_id = htons(ident);
-
-    icp->icmp_cksum = in_cksum( ( unsigned short* )icp, ping_pkt_size );
-#else
-    icp->icmp6_type = ICMP6_ECHO_REQUEST;
-    icp->icmp6_code = 0;
-    icp->icmp6_seq = htons(myseq);
-    icp->icmp6_id = htons(ident);
-
-    icp->icmp6_cksum = 0;   // The IPv6 stack calculates the checksum for us...
-#endif
 #if defined(DEBUG) || defined(_DEBUG)
     if( trace_flag )
         printf( "sending [%d] to %s\n", h->num_sent, h->host );
 #endif /* DEBUG || _DEBUG */
 
-    n = sendto( s, buffer, ping_pkt_size, 0,
-        ( struct sockaddr* )&h->saddr, sizeof( FPING_SOCKADDR ) );
+    n = socket_sendto_ping(s, (struct sockaddr *) &h->saddr, h->saddr_len, 
myseq, ident);
 
     if(
-        (n < 0 || n != ping_pkt_size)
+        (n < 0)
 #if defined( EHOSTDOWN )
         && errno != EHOSTDOWN
 #endif
     ) {
-        if( verbose_flag || unreachable_flag ) {
-            printf( "%s", h->host );
-            if( verbose_flag )
-                printf( " error while sending ping: %s\n", strerror( errno ) );
-            
-            printf( "\n" );
+        if( verbose_flag ) {
+            print_warning( "%s: error while sending ping: %s\n", h->host, 
strerror( errno ) );
         }
         
         if( !loop_flag )
@@ -1469,7 +1439,6 @@
     h->waiting++;
     num_pingsent++;
     last_send_time = h->last_send_time;
-    free( buffer );
 
     return(ret);
 }
@@ -1494,7 +1463,8 @@
 {
     int result;
     static char buffer[4096];
-    FPING_SOCKADDR response_addr;
+    struct sockaddr_storage response_addr;
+    socklen_t response_addr_len;
     struct ip *ip;
     int hlen = 0;
     FPING_ICMPHDR *icp;
@@ -1505,7 +1475,8 @@
     struct timeval *sent_time;
     SEQMAP_VALUE *seqmap_value;
 
-    result = recvfrom_wto( s, buffer, sizeof(buffer), &response_addr, 
wait_time );
+    response_addr_len = sizeof(struct sockaddr_storage);
+    result = recvfrom_wto( s, buffer, sizeof(buffer), (struct sockaddr *) 
&response_addr, &response_addr_len, wait_time );
 
     if( result < 0 )
         return 0;   /* timeout */
@@ -1516,10 +1487,11 @@
         if( ( random() & 0x07 ) <= lose_factor )
             return 0;
 
-    }/* IF */
-#endif /* DEBUG || _DEBUG */
+    }
+#endif
 
     ip = ( struct ip* )buffer;
+
 #ifndef IPV6
 #if defined( __alpha__ ) && __STDC__ && !defined( __GLIBC__ )
     /* The alpha headers are decidedly broken.
@@ -1537,14 +1509,9 @@
     {
         if( verbose_flag )
         {
-#ifndef IPV6
-            printf( "received packet too short for ICMP (%d bytes from %s)\n", 
result,
-                inet_ntoa( response_addr.sin_addr ) );
-#else           
             char buf[INET6_ADDRSTRLEN];
-            inet_ntop(response_addr.sin6_family, &response_addr.sin6_addr, 
buf, INET6_ADDRSTRLEN);
+            getnameinfo((struct sockaddr *)&response_addr, response_addr_len, 
buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
             printf( "received packet too short for ICMP (%d bytes from %s)\n", 
result, buf);
-#endif
         }
         return( 1 ); /* too short */ 
     }/* IF */
@@ -1559,7 +1526,7 @@
 #endif
     {
         /* handle some problem */
-        if( handle_random_icmp( icp, result, &response_addr ) )
+        if( handle_random_icmp( icp, (struct sockaddr *)&response_addr, 
response_addr_len ) )
             num_othericmprcvd++;
         return 1;
     }/* IF */
@@ -1627,18 +1594,12 @@
                 {
                     fprintf( stderr, "%s : duplicate for [%d], %d bytes, %s 
ms",
                         h->host, this_count, result, sprint_tm( this_reply ) );
-#ifndef IPV6
-                    if( response_addr.sin_addr.s_addr != 
h->saddr.sin_addr.s_addr )
-                        fprintf( stderr, " [<- %s]", inet_ntoa( 
response_addr.sin_addr ) );
-#else
-                    if(memcmp(&response_addr.sin6_addr, &h->saddr.sin6_addr, 
sizeof(response_addr.sin6_addr)))
-                    {
-                        char buf[INET6_ADDRSTRLEN];
-                        inet_ntop(response_addr.sin6_family, 
&response_addr.sin6_addr, buf, INET6_ADDRSTRLEN);
 
+                    if(addr_cmp((struct sockaddr *)&response_addr, (struct 
sockaddr *)&h->saddr)) {
+                        char buf[INET6_ADDRSTRLEN];
+                        getnameinfo((struct sockaddr *)&response_addr, 
response_addr_len, buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
                         fprintf( stderr, " [<- %s]", buf);
                     }
-#endif    
                     fprintf( stderr, "\n" );
     
                 }/* IF */
@@ -1668,17 +1629,13 @@
 
             if( elapsed_flag )
                 printf( " (%s ms)", sprint_tm( this_reply ) );
-#ifndef IPV6
-            if( response_addr.sin_addr.s_addr != h->saddr.sin_addr.s_addr )
-                printf( " [<- %s]", inet_ntoa( response_addr.sin_addr ) );
-#else
-        if(memcmp(&response_addr.sin6_addr, &h->saddr.sin6_addr, 
sizeof(response_addr.sin6_addr)))
-            {
+
+            if(addr_cmp((struct sockaddr *)&response_addr, (struct sockaddr 
*)&h->saddr)) {
                 char buf[INET6_ADDRSTRLEN];
-                inet_ntop(response_addr.sin6_family, &response_addr.sin6_addr, 
buf, INET6_ADDRSTRLEN);
+                getnameinfo((struct sockaddr *)&response_addr, 
response_addr_len, buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
                 fprintf( stderr, " [<- %s]", buf);
             }
-#endif
+
             printf( "\n" );
         
         }/* IF */
@@ -1696,29 +1653,22 @@
             h->host, h->pad, this_count, result, sprint_tm( this_reply ) );
         printf( " (%s avg, ", sprint_tm( avg ) );
     
-        if( h->num_recv <= h->num_sent )
-        {
+        if( h->num_recv <= h->num_sent ) {
             printf( "%d%% loss)",
                 ( ( h->num_sent - h->num_recv ) * 100 ) / h->num_sent );
 
-        }/* IF */
-        else
-        {
+        }
+        else {
             printf( "%d%% return)",
                 ( h->num_recv_total * 100 ) / h->num_sent );
         
-        }/* ELSE */
-#ifndef IPV6
-        if( response_addr.sin_addr.s_addr != h->saddr.sin_addr.s_addr )
-            printf( " [<- %s]", inet_ntoa( response_addr.sin_addr ) );
-#else
-    if(memcmp(&response_addr.sin6_addr, &h->saddr.sin6_addr, 
sizeof(response_addr.sin6_addr)))
-        {
+        }
+
+        if(addr_cmp((struct sockaddr *)&response_addr, (struct sockaddr 
*)&h->saddr)) {
             char buf[INET6_ADDRSTRLEN];
-            inet_ntop(response_addr.sin6_family, &response_addr.sin6_addr, 
buf, INET6_ADDRSTRLEN);
+            getnameinfo((struct sockaddr *)&response_addr, response_addr_len, 
buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
             fprintf( stderr, " [<- %s]", buf);
         }
-#endif
         
         printf( "\n" );
     
@@ -1740,127 +1690,91 @@
 
   Function: handle_random_icmp
 
-*************************************************************
-
-  Inputs:  FPING_ICMPHDR *p, int psize, FPING_SOCKADDR *addr
-
-  Returns:  int
-
-  Description:
-  
-
 ************************************************************/
 
-int handle_random_icmp( FPING_ICMPHDR *p, int psize, FPING_SOCKADDR *addr )
+int handle_random_icmp(FPING_ICMPHDR *p, struct sockaddr *addr, socklen_t 
addr_len)
 {
     FPING_ICMPHDR *sent_icmp;
     unsigned char *c;
     HOST_ENTRY *h;
     SEQMAP_VALUE *seqmap_value;
-#ifdef IPV6
     char addr_ascii[INET6_ADDRSTRLEN];
-    inet_ntop(addr->sin6_family, &addr->sin6_addr, addr_ascii, 
INET6_ADDRSTRLEN);
-#endif
+    unsigned short icmp_type;
+    unsigned short icmp_code;
+    unsigned short sent_icmp_type;
+    unsigned short sent_icmp_seq;
+    unsigned short sent_icmp_id;
+
+    getnameinfo((struct sockaddr *) addr, addr_len, addr_ascii, 
INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
 
     c = ( unsigned char* )p;
+
+    sent_icmp = ( FPING_ICMPHDR* )( c + 28 );
 #ifndef IPV6
-    switch( p->icmp_type )
-#else
-    switch( p->icmp6_type )
+    icmp_type = p->icmp_type;
+    icmp_code = p->icmp_code;
+    sent_icmp_type = sent_icmp->icmp_type;
+    sent_icmp_seq  = sent_icmp->icmp_seq;
+    sent_icmp_id   = sent_icmp->icmp_id;
+#else
+    icmp_type = p->icmp6_type;
+    icmp_code = p->icmp6_code;
+    sent_icmp_type = sent_icmp->icmp6_type;
+    sent_icmp_seq  = sent_icmp->icmp6_seq;
+    sent_icmp_id   = sent_icmp->icmp6_id;
 #endif
+
+    switch(icmp_type)
     {
     case ICMP_UNREACH:
-        sent_icmp = ( FPING_ICMPHDR* )( c + 28 );
-        
-#ifndef IPV6
-        seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp_seq), &current_time);
-        
-        if( ( sent_icmp->icmp_type == ICMP_ECHO ) &&
-            ( ntohs(sent_icmp->icmp_id) == ident ) &&
-            ( seqmap_value != NULL ) )
-        {
-            /* this is a response to a ping we sent */
-            h = table[seqmap_value->host_nr];
-            
-            if( p->icmp_code > ICMP_UNREACH_MAXTYPE )
-            {
-                print_warning("ICMP Unreachable (Invalid Code) from %s for 
ICMP Echo sent to %s",
-                    inet_ntoa( addr->sin_addr ), h->host );
-
-#else
-        seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp6_seq), 
&current_time);
+        seqmap_value = seqmap_fetch(ntohs(sent_icmp_seq), &current_time);
 
-        if( ( sent_icmp->icmp6_type == ICMP_ECHO ) &&
-            ( ntohs(sent_icmp->icmp6_id) == ident ) &&
+        if( ( sent_icmp_type == ICMP_ECHO ) &&
+            ( ntohs(sent_icmp_id) == ident ) &&
             ( seqmap_value != NULL ) )
         {
             /* this is a response to a ping we sent */
-            h = table[ntohs(sent_icmp->icmp6_seq) % num_hosts];
+            h = table[ntohs(sent_icmp_seq) % num_hosts];
             
-            if( p->icmp6_code > ICMP_UNREACH_MAXTYPE )
-            {
+            if( icmp_code > ICMP_UNREACH_MAXTYPE ) {
                 print_warning("ICMP Unreachable (Invalid Code) from %s for 
ICMP Echo sent to %s",
                     addr_ascii, h->host );
-#endif
-            }/* IF */
-            else
-            {
+            }
+            else {
                 print_warning("%s from %s for ICMP Echo sent to %s",
-#ifndef IPV6
-                    icmp_unreach_str[p->icmp_code], inet_ntoa( addr->sin_addr 
), h->host );
-#else
-                    icmp_unreach_str[p->icmp6_code], addr_ascii, h->host );
-#endif
-            
-            }/* ELSE */
+                        icmp_unreach_str[icmp_code], addr_ascii, h->host);
+            }
 
-            if( inet_addr( h->host ) == -1 )
-#ifndef IPV6
-                print_warning(" (%s)", inet_ntoa( h->saddr.sin_addr ) );
-#else
+            if( inet_addr( h->host ) == INADDR_NONE )
                 print_warning(" (%s)", addr_ascii);
-#endif
             
             print_warning("\n" );
-        
-        }/* IF */
-
+        }
         return 1;
 
     case ICMP_SOURCEQUENCH:
     case ICMP_REDIRECT:
     case ICMP_TIMXCEED:
     case ICMP_PARAMPROB:
-        sent_icmp = ( FPING_ICMPHDR* )( c + 28 );
-#ifndef IPV6
-        seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp_seq), &current_time);
+        seqmap_value = seqmap_fetch(ntohs(sent_icmp_seq), &current_time);
 
-        if( ( sent_icmp->icmp_type == ICMP_ECHO ) &&
-            ( ntohs(sent_icmp->icmp_id) == ident ) &&
+        if( ( sent_icmp_type == ICMP_ECHO ) &&
+            ( ntohs(sent_icmp_id) == ident ) &&
             ( seqmap_value != NULL ) )
         {
             /* this is a response to a ping we sent */
-            h = table[seqmap_value->host_nr];
-            fprintf( stderr, "%s from %s for ICMP Echo sent to %s",
-                icmp_type_str[p->icmp_type], inet_ntoa( addr->sin_addr ), 
h->host );
-      
-            if( inet_addr( h->host ) == -1 )
-                fprintf( stderr, " (%s)", inet_ntoa( h->saddr.sin_addr ) );
-#else
-        seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp6_seq), 
&current_time);
-
-        if( ( sent_icmp->icmp6_type == ICMP_ECHO ) &&
-            ( ntohs(sent_icmp->icmp6_id) == ident ) &&
-            ( seqmap_value != NULL ) )
-        {
-            /* this is a response to a ping we sent */
-            h = table[ntohs(sent_icmp->icmp6_seq) % num_hosts];
-            fprintf( stderr, "%s from %s for ICMP Echo sent to %s",
-                icmp_type_str[p->icmp6_type], addr_ascii, h->host );
+            h = table[ntohs(sent_icmp_seq) % num_hosts];
+            if(icmp_type <= ICMP_TYPE_STR_MAX) {
+                fprintf( stderr, "%s from %s for ICMP Echo sent to %s",
+                    icmp_type_str[icmp_type], addr_ascii, h->host );
+            }
+            else {
+                fprintf( stderr, "ICMP %d from %s for ICMP Echo sent to %s",
+                    icmp_type, addr_ascii, h->host );
+            }
       
-            if( inet_addr( h->host ) == -1 )
+            if( inet_addr( h->host ) == INADDR_NONE )
                 fprintf( stderr, " (%s)", addr_ascii );
-#endif
 
             fprintf( stderr, "\n" );
         
@@ -1886,54 +1800,6 @@
 
 /************************************************************
 
-  Function: in_cksum
-
-*************************************************************
-
-  Inputs:  unsigned short *p, int n
-
-  Returns:  int
-
-  Description:
-
-  Checksum routine for Internet Protocol family headers (C Version)
-  From ping examples in W.Richard Stevens "UNIX NETWORK PROGRAMMING" book.
-
-************************************************************/
-
-int in_cksum( unsigned short *p, int n )
-{
-    register unsigned short answer;
-    register long sum = 0;
-    unsigned short odd_byte = 0;
-
-    while( n > 1 )
-    {
-        sum += *p++;
-        n -= 2;
-    
-    }/* WHILE */
-
-
-    /* mop up an odd byte, if necessary */
-    if( n == 1 )
-    {
-        *( unsigned char* )( &odd_byte ) = *( unsigned char* )p;
-        sum += odd_byte;
-    
-    }/* IF */
-
-    sum = ( sum >> 16 ) + ( sum & 0xffff ); /* add hi 16 to low 16 */
-    sum += ( sum >> 16 );                   /* add carry */
-    answer = ~sum;                          /* ones-complement, truncate*/
-    
-    return ( answer );
-
-} /* in_cksum() */
-
-
-/************************************************************
-
   Function: add_name
 
 *************************************************************
@@ -1950,91 +1816,7 @@
 
 void add_name( char *name )
 {
-#ifndef IPV6
-    struct hostent *host_ent;
-    unsigned int ipaddress;
-    struct in_addr *ipa = ( struct in_addr* )&ipaddress;
-    struct in_addr *host_add;
-    char *nm;
-    int i = 0;
-
-    if( ( ipaddress = inet_addr( name ) ) != -1 )
-    {
-        /* input name is an IP addr, go with it */
-        if( name_flag )
-        {
-            if( addr_flag ) {
-                char namebuf[256];
-                snprintf(namebuf, 256, "%s (%s)", get_host_by_address(*ipa), 
name);
-                add_addr(name, namebuf, *ipa);
-            }
-            else
-            {
-                nm = get_host_by_address( *ipa );
-                add_addr( name, nm, *ipa );
-
-            }/* ELSE */
-        }/* IF */
-        else
-            add_addr( name, name, *ipa );
-        
-        return;
-    
-    }/* IF */
-
-    /* input name is not an IP addr, maybe it's a host name */
-    host_ent = gethostbyname( name ); 
-    if( host_ent == NULL )
-    { 
-            print_warning("%s address not found\n", name );
-            num_noaddress++;
-            return ; 
-    }
-
-    if(host_ent->h_addrtype != AF_INET) {
-        print_warning("%s: IPv6 address returned by gethostbyname (options 
inet6 in resolv.conf?)\n", name );
-        num_noaddress++;
-        return; 
-    }
-  
-    host_add = ( struct in_addr* )*( host_ent->h_addr_list ); 
-    if( host_add == NULL )
-    { 
-        print_warning("%s has no address data\n", name );
-        
-        num_noaddress++;
-        return; 
-
-    }/* IF */
-    else
-    {
-        /* it is indeed a hostname with a real address */
-        while( host_add )
-        {
-            if( name_flag && addr_flag ) {
-                char namebuf[256];
-                nm = inet_ntoa(*host_add);
-                snprintf(namebuf, 256, "%s (%s)", name, nm);
-                add_addr( name, namebuf, *host_add );
-            }
-            else if( addr_flag )
-            {
-                nm = inet_ntoa(*host_add);
-                add_addr( name, nm, *host_add );
-            }/* ELSE IF */
-            else
-                add_addr( name, name, *host_add );
-            
-            if( !multif_flag )
-                break;
-
-            host_add = ( struct in_addr* )( host_ent->h_addr_list[++i] ); 
-
-        }/* WHILE */
-    }/* ELSE */
-#else
-    FPING_SOCKADDR    dst;
-    struct addrinfo   *res, hints;
+    struct addrinfo   *res0, *res, hints;
     int               ret_ga;
     size_t            len;
     char              *printname;
@@ -2044,64 +1826,75 @@
     /* getaddrinfo */
     bzero(&hints, sizeof(struct addrinfo));
     hints.ai_flags = 0;
-    hints.ai_family = AF_INET6;
     hints.ai_socktype = SOCK_RAW;
+#ifndef IPV6
+    hints.ai_family = AF_INET;
+    hints.ai_protocol = IPPROTO_ICMP;
+#else
+    hints.ai_family = AF_INET6;
     hints.ai_protocol = IPPROTO_ICMPV6;
-    ret_ga = getaddrinfo(name, NULL, &hints, &res);
+#endif
+    ret_ga = getaddrinfo(name, NULL, &hints, &res0);
     if (ret_ga) {
         if(!quiet_flag)
             print_warning("%s: %s\n", name, gai_strerror(ret_ga));
         num_noaddress++;
         return; 
     }
-    len = res->ai_addrlen;
-    if (len > sizeof(FPING_SOCKADDR)) len = sizeof(FPING_SOCKADDR);
-    (void)memcpy(&dst, res->ai_addr, len);
-
-    /* name_flag: addr -> name lookup requested) */
-    if(!name_flag) {
-        printname = name;
-    }
-    else {
-        int ret;
-        ret = getnameinfo(res->ai_addr, res->ai_addrlen, namebuf,
-                          sizeof(namebuf)/sizeof(char), NULL, 0, 0);
-        if (ret) {
-            if(!quiet_flag) {
-                print_warning("%s: %s\n", name, gai_strerror(ret_ga));
+
+    // NOTE: we could/should loop with res on all addresses like this:
+    // for (res = res0; res; res = res->ai_next) {
+    // We don't do it yet, however, because is is an incompatible change
+    // (need to implement a separate option for this)
+
+    for (res = res0; res; res = 0) {
+        len = res->ai_addrlen;
+        /* name_flag: addr -> name lookup requested) */
+        if(!name_flag) {
+            printname = name;
+        }
+        else {
+            int ret;
+            ret = getnameinfo(res->ai_addr, res->ai_addrlen, namebuf,
+                              sizeof(namebuf)/sizeof(char), NULL, 0, 0);
+            if (ret) {
+                if(!quiet_flag) {
+                    print_warning("%s: %s\n", name, gai_strerror(ret_ga));
+                }
+                num_noaddress++;
+                return; 
             }
-            num_noaddress++;
-            return; 
+            printname = namebuf;
         }
-        printname = namebuf;
-    }
 
-    /* addr_flag: name -> addr lookup requested */
-    if(addr_flag) {
-        int ret;
-        ret = getnameinfo(res->ai_addr, res->ai_addrlen, addrbuf,
-                          sizeof(addrbuf)/sizeof(char), NULL, 0, 
NI_NUMERICHOST);
-        if (ret) {
-            if(!quiet_flag) {
-                print_warning("%s: %s\n", name, gai_strerror(ret_ga));
+        /* addr_flag: name -> addr lookup requested */
+        if(addr_flag) {
+            int ret;
+            ret = getnameinfo(res->ai_addr, res->ai_addrlen, addrbuf,
+                              sizeof(addrbuf)/sizeof(char), NULL, 0, 
NI_NUMERICHOST);
+            if (ret) {
+                if(!quiet_flag) {
+                    print_warning("%s: %s\n", name, gai_strerror(ret_ga));
+                }
+                num_noaddress++;
+                return; 
             }
-            num_noaddress++;
-            return; 
-        }
 
-        if(name_flag) {
-            char nameaddrbuf[512];
-            snprintf(nameaddrbuf, sizeof(nameaddrbuf)/sizeof(char), "%s (%s)", 
printname, addrbuf);
-            add_addr(name, nameaddrbuf, &dst);
+            if(name_flag) {
+                char nameaddrbuf[512];
+                snprintf(nameaddrbuf, sizeof(nameaddrbuf)/sizeof(char), "%s 
(%s)", printname, addrbuf);
+                add_addr(name, nameaddrbuf, res->ai_addr, res->ai_addrlen);
+            }
+            else {
+                add_addr(name, addrbuf, res->ai_addr, res->ai_addrlen);
+            }
         }
         else {
-            add_addr(name, addrbuf, &dst);
+            add_addr(name, printname, res->ai_addr, res->ai_addrlen);
         }
+
+        return;
     }
-    else {
-        add_addr(name, printname, &dst);
-    }
-#endif
 } /* add_name() */
 
 
@@ -2111,8 +1904,6 @@
 
 *************************************************************
 
-  Inputs:  char* name, char* host, struct in_addr ipaddr
-
   Description:
 
   add address to linked list of targets to be pinged
@@ -2120,11 +1911,7 @@
 
 ************************************************************/
 
-#ifndef IPV6
-void add_addr( char *name, char *host, struct in_addr ipaddr )
-#else
-void add_addr( char *name, char *host, FPING_SOCKADDR *ipaddr )
-#endif
+void add_addr( char *name, char *host, struct sockaddr *ipaddr, socklen_t 
ipaddr_len )
 {
     HOST_ENTRY *p;
     int n, *i;
@@ -2137,13 +1924,8 @@
 
     p->name = strdup(name);
     p->host = strdup(host);
-#ifndef IPV6
-    p->saddr.sin_family = AF_INET;
-    p->saddr.sin_addr = ipaddr; 
-#else
-    p->saddr.sin6_family = AF_INET6;
-    (void)memcpy(&p->saddr, ipaddr, sizeof(FPING_SOCKADDR));
-#endif
+    memcpy(&p->saddr, ipaddr, ipaddr_len);
+    p->saddr_len = ipaddr_len;
     p->timeout = timeout;
     p->running = 1;
     p->min_reply = 0;
@@ -2219,37 +2001,6 @@
 
 } /* remove_job() */
 
-
-/************************************************************
-
-  Function: get_host_by_address
-
-*************************************************************
-
-  Inputs:  struct in_addr in
-
-  Returns:  char*
-
-  Description:
-
-************************************************************/
-
-char *get_host_by_address( struct in_addr in )
-{
-    struct hostent *h;
-#ifndef IPV6
-    h = gethostbyaddr( ( char* )&in, sizeof( struct in_addr ),AF_INET );
-#else
-    h = gethostbyaddr( ( char* )&in, sizeof( FPING_SOCKADDR ),AF_INET6 );
-#endif
-    
-    if( h == NULL || h->h_name == NULL )
-        return inet_ntoa( in );
-    else
-        return ( char* )h->h_name;
-
-} /* get_host_by_address() */
-
 /************************************************************
 
   Function: crash_and_burn
@@ -2403,67 +2154,17 @@
 }
 
 /************************************************************
-
-  Function: u_sleep
-
-*************************************************************
-
-  Inputs:  int u_sec
-
-  Description:
-
-************************************************************/
-
-void u_sleep( int u_sec )
-{
-    int nfound;
-    struct timeval to;
-    fd_set readset, writeset;
-
-select_again:
-    to.tv_sec = u_sec / 1000000;
-    to.tv_usec = u_sec - ( to.tv_sec * 1000000 );
-
-    FD_ZERO( &readset );
-    FD_ZERO( &writeset );
-
-    nfound = select( 0, &readset, &writeset, NULL, &to );
-    if(nfound < 0) {
-       if(errno == EINTR) {
-           /* interrupted system call: redo the select */
-           goto select_again;
-       }
-       else {
-           errno_crash_and_burn( "select" );
-       }
-    }
-
-    return;
-
-} /* u_sleep() */
-
-
-/************************************************************
-
   Function: recvfrom_wto
-
 *************************************************************
-
-  Inputs:  int s, char* buf, int len, FPING_SOCKADDR *saddr, int timo
-
-  Returns:  int
-
   Description:
 
   receive with timeout
   returns length of data read or -1 if timeout
   crash_and_burn on any other errrors
-
 ************************************************************/
 
-int recvfrom_wto( int s, char *buf, int len, FPING_SOCKADDR *saddr, long timo )
+int recvfrom_wto( int s, char *buf, int len, struct sockaddr *saddr, socklen_t 
*saddr_len, long timo )
 {
-        unsigned int slen;
     int nfound, n;
     struct timeval to;
     fd_set readset, writeset;
@@ -2496,21 +2197,41 @@
     if( nfound == 0 )
         return -1;      /* timeout */
 
-#ifndef IPV6
-    slen = sizeof( struct sockaddr );
-#else
-    slen = sizeof( FPING_SOCKADDR );
-#endif
-    n = recvfrom( s, buf, len, 0, (struct sockaddr *)saddr, &slen );
+    // recvfrom(int socket, void *restrict buffer, size_t length, int flags, 
struct sockaddr *restrict address, socklen_t *restrict address_len);
+    n = recvfrom( s, buf, len, 0, saddr, saddr_len );
     if( n < 0 )
         errno_crash_and_burn( "recvfrom" );
-    
+
     return n;
 
 } /* recvfrom_wto() */
 
 /************************************************************
 
+  Function: addr_cmp
+
+*************************************************************/
+int addr_cmp(struct sockaddr *a, struct sockaddr *b)
+{
+    if(a->sa_family != b->sa_family) {
+        return a->sa_family - b->sa_family;
+    }
+    else {
+        if(a->sa_family == AF_INET) {
+            return ((struct sockaddr_in *) a)->sin_addr.s_addr - ((struct 
sockaddr_in *) b)->sin_addr.s_addr;
+        }
+        else if(a->sa_family == AF_INET6) {
+            return memcmp(&((struct sockaddr_in6 *) a)->sin6_addr,
+                          &((struct sockaddr_in6 *) b)->sin6_addr,
+                          sizeof(((struct sockaddr_in6 *) a)->sin6_addr));
+        }
+    }
+
+    return 0;
+}
+
+/************************************************************
+
   Function: ev_enqueue
 
   Enqueue a host that needs to be pinged, but not before the time
@@ -2666,6 +2387,7 @@
     fprintf(out, "   -q         quiet (don't show per-target/per-ping 
results)\n" );
     fprintf(out, "   -Q n       same as -q, but show summary every n 
seconds\n" );
     fprintf(out, "   -r n       number of retries (default %d)\n", 
DEFAULT_RETRY );
+    fprintf(out, "   -R         random packet data (to foil link data 
compression)\n" );
     fprintf(out, "   -s         print final stats\n" );
     fprintf(out, "   -S addr    set source address\n" );
     fprintf(out, "   -t n       individual target initial timeout (in 
millisec) (default %d)\n", timeout / 100 );
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/src/fping.h new/fping-3.13/src/fping.h
--- old/fping-3.10/src/fping.h  2014-05-04 22:33:12.000000000 +0200
+++ new/fping-3.13/src/fping.h  2015-10-21 21:02:56.000000000 +0200
@@ -8,11 +8,9 @@
 #include <netinet/in.h>
 
 #ifndef IPV6
-#define FPING_SOCKADDR struct sockaddr_in
 #define FPING_INADDR   struct in_addr
 #define FPING_ICMPHDR  struct icmp
 #else
-#define FPING_SOCKADDR struct sockaddr_in6
 #define FPING_INADDR   struct in6_addr
 #define FPING_ICMPHDR  struct icmp6_hdr
 #endif
@@ -20,9 +18,13 @@
 /* fping.c */
 void crash_and_burn( char *message );
 void errno_crash_and_burn( char *message );
+int in_cksum( unsigned short *p, int n );
+int random_data_flag;
 
 /* socket.c */
-int open_ping_socket();
+int  open_ping_socket();
+void init_ping_buffer(size_t ping_data_size);
 void socket_set_src_addr(int s, FPING_INADDR src_addr);
+int  socket_sendto_ping(int s, struct sockaddr *saddr, socklen_t saddr_len, 
uint16_t icmp_seq, uint16_t icmp_id);
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/src/seqmap.c new/fping-3.13/src/seqmap.c
--- old/fping-3.10/src/seqmap.c 2014-05-04 22:33:12.000000000 +0200
+++ new/fping-3.13/src/seqmap.c 2015-10-21 21:02:56.000000000 +0200
@@ -53,15 +53,12 @@
 
 static SEQMAP_VALUE *seqmap_map = NULL;
 static unsigned int seqmap_next_id = 0;
-static SEQMAP_VALUE *seqmap_free_list;
 
 #define SEQMAP_TIMEOUT_IN_S       10
 #define SEQMAP_UNASSIGNED_HOST_NR UINT_MAX
 
 void seqmap_init()
 {
-    unsigned int i;
-
     seqmap_map = calloc(SEQMAP_MAXSEQ, sizeof(SEQMAP_VALUE));
     if(seqmap_map == NULL) {
         perror("malloc error (can't allocate seqmap_map)");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/src/socket.c new/fping-3.13/src/socket.c
--- old/fping-3.10/src/socket.c 2014-05-04 22:33:12.000000000 +0200
+++ new/fping-3.13/src/socket.c 2015-10-21 21:02:56.000000000 +0200
@@ -35,8 +35,12 @@
 
 int open_ping_socket_ipv4();
 int open_ping_socket_ipv6();
+void init_ping_buffer_ipv4(size_t ping_data_size);
+void init_ping_buffer_ipv6(size_t ping_data_size);
 void socket_set_src_addr_ipv4(int s, FPING_INADDR src_addr);
 void socket_set_src_addr_ipv6(int s, FPING_INADDR src_addr);
+int socket_sendto_ping_ipv4(int s, struct sockaddr *saddr, socklen_t 
saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr);
+int socket_sendto_ping_ipv6(int s, struct sockaddr *saddr, socklen_t 
saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr);
 
 int open_ping_socket()
 {
@@ -47,6 +51,15 @@
 #endif
 }
 
+void init_ping_buffer(size_t ping_data_size)
+{
+#ifndef IPV6
+    return init_ping_buffer_ipv4(ping_data_size);
+#else
+    return init_ping_buffer_ipv6(ping_data_size);
+#endif
+}
+
 void socket_set_src_addr(int s, FPING_INADDR src_addr)
 {
 #ifndef IPV6
@@ -55,3 +68,12 @@
     socket_set_src_addr_ipv6(s, src_addr);
 #endif
 }
+
+int socket_sendto_ping(int s, struct sockaddr *saddr, socklen_t saddr_len, 
uint16_t icmp_seq_nr, uint16_t icmp_id_nr)
+{
+#ifndef IPV6
+    return socket_sendto_ping_ipv4(s, saddr, saddr_len, icmp_seq_nr, 
icmp_id_nr);
+#else
+    return socket_sendto_ping_ipv6(s, saddr, saddr_len, icmp_seq_nr, 
icmp_id_nr);
+#endif
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/src/socket4.c new/fping-3.13/src/socket4.c
--- old/fping-3.10/src/socket4.c        2014-05-04 22:33:12.000000000 +0200
+++ new/fping-3.13/src/socket4.c        2015-10-21 21:02:56.000000000 +0200
@@ -35,9 +35,15 @@
 
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
+
+char *ping_buffer = 0;
+size_t ping_pkt_size;
 
 int open_ping_socket_ipv4()
 {
@@ -61,6 +67,15 @@
     return s;
 }
 
+void init_ping_buffer_ipv4(size_t ping_data_size)
+{
+    /* allocate ping buffer */
+    ping_pkt_size = ping_data_size + ICMP_MINLEN;
+    ping_buffer = (char *) calloc(1, ping_pkt_size);
+    if(!ping_buffer)
+        crash_and_burn( "can't malloc ping packet" );
+}
+
 void socket_set_src_addr_ipv4(int s, FPING_INADDR src_addr)
 {
     struct sockaddr_in sa;
@@ -71,3 +86,46 @@
     if ( bind( s, (struct sockaddr *)&sa, sizeof( sa ) ) < 0 )
         errno_crash_and_burn( "cannot bind source address" );
 }
+
+unsigned short calcsum(unsigned short *buffer, int length)
+{
+    unsigned long sum;
+
+    // initialize sum to zero and loop until length (in words) is 0
+    for (sum=0; length>1; length-=2) // sizeof() returns number of bytes, 
we're interested in number of words
+       sum += *buffer++;       // add 1 word of buffer to sum and proceed to 
the next
+
+    // we may have an extra byte
+    if (length==1)
+       sum += (char)*buffer;
+
+    sum = (sum >> 16) + (sum & 0xFFFF); // add high 16 to low 16
+    sum += (sum >> 16);                        // add carry
+    return ~sum;
+}
+
+int socket_sendto_ping_ipv4(int s, struct sockaddr *saddr, socklen_t 
saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr)
+{
+    struct icmp *icp;
+    int n;
+
+    icp = (struct icmp *) ping_buffer;
+
+    icp->icmp_type = ICMP_ECHO;
+    icp->icmp_code = 0;
+    icp->icmp_cksum = 0;
+    icp->icmp_seq = htons(icmp_seq_nr);
+    icp->icmp_id = htons(icmp_id_nr);
+
+    if (random_data_flag) {
+        for (n = ((void*)&icp->icmp_data - (void *)icp); n < ping_pkt_size; 
++n) {
+            ping_buffer[n] = random() & 0xFF;
+        }
+    }
+
+    icp->icmp_cksum = calcsum((unsigned short *) icp, ping_pkt_size);
+
+    n = sendto(s, icp, ping_pkt_size, 0, saddr, saddr_len);
+
+    return n;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fping-3.10/src/socket6.c new/fping-3.13/src/socket6.c
--- old/fping-3.10/src/socket6.c        2014-05-04 22:33:12.000000000 +0200
+++ new/fping-3.13/src/socket6.c        2015-10-21 21:02:56.000000000 +0200
@@ -38,13 +38,16 @@
 #include <netdb.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 
-#include <netinet/icmp6.h>
+#include <netinet/icmp6.h>  
+
+char *ping_buffer = 0;
+size_t ping_pkt_size;
 
 int open_ping_socket_ipv6()
 {
     struct protoent *proto;
-    int opton = 1;
     int s;
 
     /* confirm that ICMP is available on this machine */
@@ -64,6 +67,15 @@
     return s;
 }
 
+void init_ping_buffer_ipv6(size_t ping_data_size)
+{
+    /* allocate ping buffer */
+    ping_pkt_size = ping_data_size + sizeof(struct icmp6_hdr);
+    ping_buffer = (char *) calloc(1, ping_pkt_size);
+    if(!ping_buffer)
+        crash_and_burn( "can't malloc ping packet" );
+}
+
 void socket_set_src_addr_ipv6(int s, FPING_INADDR src_addr)
 {
     struct sockaddr_in6 sa;
@@ -74,3 +86,27 @@
     if ( bind( s, (struct sockaddr *)&sa, sizeof( sa ) ) < 0 )
         errno_crash_and_burn( "cannot bind source address" );
 }
+
+int socket_sendto_ping_ipv6(int s, struct sockaddr *saddr, socklen_t 
saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr)
+{
+    struct icmp6_hdr *icp;
+    int n;
+
+    icp = (struct icmp6_hdr *) ping_buffer;
+    icp->icmp6_type  = ICMP6_ECHO_REQUEST;
+    icp->icmp6_code  = 0;
+    icp->icmp6_seq   = htons(icmp_seq_nr);
+    icp->icmp6_id    = htons(icmp_id_nr);
+
+    if (random_data_flag) {
+        for (n = sizeof(struct icmp6_hdr); n < ping_pkt_size; ++n) {
+            ping_buffer[n] = random() & 0xFF;
+        }
+    }
+
+    icp->icmp6_cksum = 0;   // The IPv6 stack calculates the checksum for us...
+
+    n = sendto(s, icp, ping_pkt_size, 0, saddr, saddr_len);
+
+    return n;
+}


Reply via email to