* 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 <david@schweikert.ch>
* Version 3.10
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.
-AM_CFLAGS = -Wall -Wextra
+AM_CFLAGS = -Wall -Wextra -Wno-sign-compare
prog =
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;
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;
/* 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 )
{
timestamp_flag = 1;
break;
+ case 'R':
+ random_data_flag = 1;
+ break;
+
case 'l':
loop_flag = 1;
backoff_flag = 0;
}/* FOR */
- ping_pkt_size = ping_data_size + SIZE_ICMP_HDR;
-
+ init_ping_buffer(ping_data_size);
+
signal( SIGINT, finish );
gettimeofday( &start_time, &tz );
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
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 );
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);
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
}
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;
}
}
+ 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)
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);
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;
}
}
+ 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)
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);