diff --git a/.travis.yml b/.travis.yml index 2e20eda..c2b2cfa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ env: compiler: - gcc before_install: + - sudo apt-get update -qq - sudo apt-get install libcap2-bin - sudo apt-get install traceroute - traceroute google.com diff --git a/ChangeLog b/ChangeLog index b05932d..8ed21c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ UNRELEASED * (feature) Ignore network and broadcast for cidrs /31 and /32 (#102, Martin Topholm) * (feature) New option '-M' to set the "Don't Fragment" flag (#91, Don Bowman) + * (feature) New option '-o' to calculate total outage time (#90, @jgerbeck) * (bugfix) Exit code should be 2 when the hostname can't be resolved (fixes #98, reported by @green-fox) * (bugfix) Fix issue compliling on RHEL/Centos 7 (#95, @jbackman) diff --git a/ci/test-02-help.pl b/ci/test-02-help.pl index d8693f4..ca78a40 100755 --- a/ci/test-02-help.pl +++ b/ci/test-02-help.pl @@ -29,6 +29,7 @@ ${I_HELP} -l loop sending pings forever -m ping multiple interfaces on target host -M set the Don't Fragment flag -n show targets by name (-d is equivalent) + -o show the accumulated outage time (lost packets * packet interval) -O n set the type of service (tos) flag on the ICMP packets -p n interval between ping packets to one target (in millisec) (in looping and counting modes, default 1000) diff --git a/ci/test-08-options-n-q.pl b/ci/test-08-options-n-q.pl index 66630b8..c490c19 100755 --- a/ci/test-08-options-n-q.pl +++ b/ci/test-08-options-n-q.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl -w -use Test::Command tests => 9; +use Test::Command tests => 12; # -n show targets by name (-d is equivalent) # -O n set the type of service (tos) flag on the ICMP packets @@ -11,6 +11,14 @@ use Test::Command tests => 9; # fping -n -> test-14-internet-hosts +# fping -o +{ +my $cmd = Test::Command->new(cmd => "fping -t100 -p 100 -o -c 5 8.8.8.7"); +$cmd->exit_is_num(1); +$cmd->stdout_is_eq(""); +$cmd->stderr_like(qr{^\s*8\.8\.8\.7 : xmt/rcv/%loss = 5/0/100%, outage\(ms\) = 50\d\s*$}); +} + # fping -O { my $cmd = Test::Command->new(cmd => "fping -O 2 127.0.0.1"); diff --git a/doc/fping.pod b/doc/fping.pod index 86d6a71..a193383 100644 --- a/doc/fping.pod +++ b/doc/fping.pod @@ -127,10 +127,23 @@ Ctrl-C; statistics about responses for each target are then displayed. Send pings to each of a target host's multiple interfaces. +=item B<-M> + +Set the "Don't Fragment" bit in the IP header (used to determine/test the MTU). + =item B<-n> Same as -d. +=item B<-o> + +Calculate "outage time" based on the number of lost pings and the interval used (useful for network convergence tests). + +=item B<-O> I + +Set the typ of service flag (TOS). I can be either decimal or hexadecimal +(0xh) format. + =item B<-p> In looping or counting modes (B<-l>, B<-c>, or B<-C>), this parameter sets @@ -184,11 +197,6 @@ Ignored (for compatibility with fping 2.4). Show targets that are unreachable. -=item B<-O> I - -Set the typ of service flag (TOS). I can be either decimal or hexadecimal -(0xh) format. - =item B<-v> Print B version information. @@ -197,10 +205,6 @@ Print B version information. Set the IP TTL field (time to live hops). -=item B<-M> - -Set the "Don't Fragment" bit in the IP header (used to determine/test the MTU). - =back =head1 EXAMPLES diff --git a/src/fping.c b/src/fping.c index 453c530..f185a2e 100644 --- a/src/fping.c +++ b/src/fping.c @@ -298,6 +298,7 @@ int verbose_flag, quiet_flag, stats_flag, unreachable_flag, alive_flag; 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 outage_flag = 0; int timestamp_flag = 0; int random_data_flag = 0; #if defined( DEBUG ) || defined( _DEBUG ) @@ -376,7 +377,7 @@ int main( int argc, char **argv ) /* get command line options */ - while( ( c = getopt( argc, argv, "gedhlmnqusaAvDRz:t:H:i:p:f:r:c:b:C:Q:B:S:I:T:O:M" ) ) != EOF ) + while( ( c = getopt( argc, argv, "gedhlmnqusaAvDRz:t:H:i:p:f:r:c:b:C:Q:B:S:I:T:O:M:o" ) ) != EOF ) { switch( c ) { @@ -561,6 +562,11 @@ int main( int argc, char **argv ) usage(1); } break; + + case 'o': + outage_flag = 1; + break; + default: fprintf(stderr, "see 'fping -h' for usage information\n"); exit(1); @@ -703,6 +709,7 @@ int main( int argc, char **argv ) if( randomly_lose_flag ) fprintf( stderr, " randomly_lose_flag set\n" ); if( sent_times_flag ) fprintf( stderr, " sent_times_flag set\n" ); if( print_per_system_flag ) fprintf( stderr, " print_per_system_flag set\n" ); + if( outage_flag ) fprintf( stderr, " outage_flag set\n" ); }/* IF */ #endif /* DEBUG || _DEBUG */ @@ -1175,7 +1182,7 @@ void finish() void print_per_system_stats( void ) { - int i, j, avg; + int i, j, avg, outage_ms; HOST_ENTRY *h; char *buf; int bufsize; @@ -1221,6 +1228,12 @@ void print_per_system_stats( void ) h->num_sent, h->num_recv, h->num_sent > 0 ? ( ( h->num_sent - h->num_recv ) * 100 ) / h->num_sent : 0 ); + if (outage_flag) { + /* Time outage total */ + outage_ms = (h->num_sent - h->num_recv) * perhost_interval/100; + fprintf( stderr, ", outage(ms) = %d", outage_ms ); + } + }/* IF */ else { @@ -1280,7 +1293,7 @@ void print_per_system_stats( void ) void print_per_system_splits( void ) { - int i, avg; + int i, avg, outage_ms_i; HOST_ENTRY *h; char *buf; int bufsize; @@ -1313,6 +1326,11 @@ void print_per_system_splits( void ) h->num_sent_i, h->num_recv_i, h->num_sent_i > 0 ? ( ( h->num_sent_i - h->num_recv_i ) * 100 ) / h->num_sent_i : 0 ); + if (outage_flag) { + /* Time outage */ + outage_ms_i = (h->num_sent_i - h->num_recv_i) * perhost_interval/100; + fprintf( stderr, ", outage(ms) = %d", outage_ms_i ); + } }/* IF */ else { @@ -2397,6 +2415,7 @@ void usage(int is_error) fprintf(out, " -m ping multiple interfaces on target host\n" ); fprintf(out, " -M set the Don't Fragment flag\n" ); fprintf(out, " -n show targets by name (-d is equivalent)\n" ); + fprintf(out, " -o show the accumulated outage time (lost packets * packet interval)\n" ); fprintf(out, " -O n set the type of service (tos) flag on the ICMP packets\n" ); fprintf(out, " -p n interval between ping packets to one target (in millisec)\n" ); fprintf(out, " (in looping and counting modes, default %d)\n", perhost_interval / 100 );