From 58fcce95471c25944290c4f01cd803f765ee9b7b Mon Sep 17 00:00:00 2001 From: Anthony DeRobertis Date: Wed, 17 Dec 2014 13:50:53 -0500 Subject: [PATCH] New option -R to use random bytes instead of NULLs (#72, Anthony DeRobertis) --- ChangeLog | 1 + doc/fping.pod | 5 +++++ src/Makefile.am | 2 +- src/fping.c | 15 ++++++++++----- src/fping.h | 4 +++- src/socket.c | 17 ++++++++++++++--- src/socket4.c | 17 +++++++++++++---- src/socket6.c | 17 +++++++++++++---- 8 files changed, 60 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 62dab00..06b8e74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ UNRELEASED * Use sockaddr_storage and simplify code, so that we can one day support both IPv4 and IPv6 with the same binary * Fix double entries with fping -u and unreachable hosts + * New option -R to use random bytes instead of NULLs (#72, Anthony DeRobertis) 2014-05-03 David Schweikert * Version 3.10 diff --git a/doc/fping.pod b/doc/fping.pod index a21e2ed..f1e8d55 100644 --- a/doc/fping.pod +++ b/doc/fping.pod @@ -151,6 +151,11 @@ Like B<-q>, but show summary results every n seconds. 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. diff --git a/src/Makefile.am b/src/Makefile.am index dfdcac7..4dcfae8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ -AM_CFLAGS = -Wall -Wextra +AM_CFLAGS = -Wall -Wextra -Wno-sign-compare prog = diff --git a/src/fping.c b/src/fping.c index f0551b7..4a6b5d9 100644 --- a/src/fping.c +++ b/src/fping.c @@ -259,7 +259,6 @@ unsigned int interval = DEFAULT_INTERVAL * 100; 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; @@ -301,6 +300,7 @@ int elapsed_flag, version_flag, count_flag, loop_flag; 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; @@ -379,7 +379,7 @@ int main( int argc, char **argv ) /* 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 ) { @@ -475,6 +475,10 @@ int main( int argc, char **argv ) timestamp_flag = 1; break; + case 'R': + random_data_flag = 1; + break; + case 'l': loop_flag = 1; backoff_flag = 0; @@ -815,8 +819,8 @@ int main( int argc, char **argv ) }/* FOR */ - ping_pkt_size = ping_data_size + SIZE_ICMP_HDR; - + init_ping_buffer(ping_data_size); + signal( SIGINT, finish ); gettimeofday( &start_time, &tz ); @@ -1407,7 +1411,7 @@ int send_ping( int s, HOST_ENTRY *h ) 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 @@ -2473,6 +2477,7 @@ void usage(int is_error) 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 --git a/src/fping.h b/src/fping.h index 29c183c..2066173 100644 --- a/src/fping.h +++ b/src/fping.h @@ -19,9 +19,11 @@ 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(size_t ping_data_size); +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); diff --git a/src/socket.c b/src/socket.c index 988afdb..782f041 100644 --- a/src/socket.c +++ b/src/socket.c @@ -35,17 +35,28 @@ 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(size_t ping_data_size) +int open_ping_socket() { #ifndef IPV6 - return open_ping_socket_ipv4(ping_data_size); + return open_ping_socket_ipv4(); #else - return open_ping_socket_ipv6(ping_data_size); + return open_ping_socket_ipv6(); +#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 } diff --git a/src/socket4.c b/src/socket4.c index 318f7fe..f1bdf5e 100644 --- a/src/socket4.c +++ b/src/socket4.c @@ -45,7 +45,7 @@ char *ping_buffer = 0; size_t ping_pkt_size; -int open_ping_socket_ipv4(size_t ping_data_size) +int open_ping_socket_ipv4() { struct protoent *proto; int s; @@ -64,13 +64,16 @@ int open_ping_socket_ipv4(size_t ping_data_size) } } + 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" ); - - return s; } void socket_set_src_addr_ipv4(int s, FPING_INADDR src_addr) @@ -93,9 +96,15 @@ int socket_sendto_ping_ipv4(int s, struct sockaddr *saddr, socklen_t saddr_len, 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 = in_cksum((unsigned short*) icp, ping_pkt_size ); n = sendto(s, icp, ping_pkt_size, 0, saddr, saddr_len); diff --git a/src/socket6.c b/src/socket6.c index 08e0afc..e4dd6db 100644 --- a/src/socket6.c +++ b/src/socket6.c @@ -45,7 +45,7 @@ char *ping_buffer = 0; size_t ping_pkt_size; -int open_ping_socket_ipv6(size_t ping_data_size) +int open_ping_socket_ipv6() { struct protoent *proto; int s; @@ -64,13 +64,16 @@ int open_ping_socket_ipv6(size_t ping_data_size) } } + 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" ); - - return s; } void socket_set_src_addr_ipv6(int s, FPING_INADDR src_addr) @@ -89,12 +92,18 @@ int socket_sendto_ping_ipv6(int s, struct sockaddr *saddr, socklen_t saddr_len, struct icmp6_hdr *icp; int n; - // FIXME: randomization 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 = ((void*)&icp->icmp6_data8 - (void *)icp); 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);