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), ¤t_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), ¤t_time); + seqmap_value = seqmap_fetch(ntohs(sent_icmp_seq), ¤t_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), ¤t_time); + seqmap_value = seqmap_fetch(ntohs(sent_icmp_seq), ¤t_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), ¤t_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; +}
