From ddf417eac36644640e6b5c714e1fe8cd8f5d7e3f Mon Sep 17 00:00:00 2001 From: Nuno Alves Date: Wed, 21 Aug 2024 23:07:28 +0100 Subject: [PATCH] Print returned TTL value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Luís Fonseca --- ci/test-04-options-a-b.pl | 29 ++++++++++++++++++++++++++++- ci/test-11-unpriv.pl | 8 +++++++- doc/fping.pod | 6 ++++++ src/fping.c | 22 ++++++++++++++++++++-- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/ci/test-04-options-a-b.pl b/ci/test-04-options-a-b.pl index dc5435cc..1e16ee3d 100755 --- a/ci/test-04-options-a-b.pl +++ b/ci/test-04-options-a-b.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl -w -use Test::Command tests => 32; +use Test::Command tests => 41; use Test::More; use Time::HiRes qw(gettimeofday tv_interval); @@ -68,6 +68,33 @@ $cmd->stderr_is_eq(""); } +# fping -a --print-ttl +{ +my $cmd = Test::Command->new(cmd => "fping -a --print-ttl 127.0.0.1 127.0.0.2"); +$cmd->exit_is_num(0); +$cmd->stdout_like(qr{127\.0\.0\.1 \(TTL \d+\)\n127\.0\.0\.2 \(TTL \d+\)\n}); +$cmd->stderr_is_eq(""); +} + +# fping --print-ttl +{ +my $cmd = Test::Command->new(cmd => "fping --print-ttl 127.0.0.1"); +$cmd->exit_is_num(0); +$cmd->stdout_like(qr{127\.0\.0\.1 is alive \(TTL \d+\)}); +$cmd->stderr_is_eq(""); +} + +# fping --print-ttl with IPv6 +SKIP: { + if($ENV{SKIP_IPV6}) { + skip 'Skip IPv6 tests', 3; + } + my $cmd = Test::Command->new(cmd => "fping --print-ttl ::1"); + $cmd->exit_is_num(0); + $cmd->stdout_like(qr{::1 is alive \(TTL unknown\)\n}); + $cmd->stderr_is_eq(""); +} + # fping -A { my $cmd = Test::Command->new(cmd => "fping -4 -A localhost"); diff --git a/ci/test-11-unpriv.pl b/ci/test-11-unpriv.pl index 74deb6a4..debf2afb 100755 --- a/ci/test-11-unpriv.pl +++ b/ci/test-11-unpriv.pl @@ -40,7 +40,7 @@ sub get_ping_gid_range { } sub test_unprivileged_works { - plan tests => 12; + plan tests => 15; { my $cmd = Test::Command->new(cmd => "$fping_copy 127.0.0.1"); @@ -54,6 +54,12 @@ sub test_unprivileged_works { $cmd->stdout_is_eq("127.0.0.1 is alive (TOS unknown)\n"); $cmd->stderr_is_eq(""); } + { + my $cmd = Test::Command->new(cmd => "$fping_copy --print-ttl 127.0.0.1"); + $cmd->exit_is_num(0); + $cmd->stdout_is_eq("127.0.0.1 is alive (TTL unknown)\n"); + $cmd->stderr_is_eq(""); + } SKIP: { if($^O ne 'linux') { skip '-k option is only supported on Linux', 3; diff --git a/doc/fping.pod b/doc/fping.pod index 4bc15762..af4fae30 100644 --- a/doc/fping.pod +++ b/doc/fping.pod @@ -140,6 +140,12 @@ Print usage message. Set the IP TTL field (time to live hops). +=item B<--print-ttl> + +Displays the IPv4 TTL value from the IP Header in the output. +If B cannot read the TTL value, "(TTL unknown)" is returned. +IPv4 only, requires root privileges or cap_net_raw. + =item B<-i>, B<--interval>=I The minimum amount of time (in milliseconds) between sending a ping packet diff --git a/src/fping.c b/src/fping.c index 696a017b..09224261 100644 --- a/src/fping.c +++ b/src/fping.c @@ -362,6 +362,7 @@ int random_data_flag = 0; int cumulative_stats_flag = 0; int check_source_flag = 0; int print_tos_flag = 0; +int print_ttl_flag = 0; #if defined(DEBUG) || defined(_DEBUG) int randomly_lose_flag, trace_flag, print_per_system_flag; int lose_factor; @@ -560,6 +561,7 @@ int main(int argc, char **argv) { "fast-reachable", 'X', OPTPARSE_REQUIRED }, { "check-source", '0', OPTPARSE_NONE }, { "print-tos", '0', OPTPARSE_NONE }, + { "print-ttl", '0', OPTPARSE_NONE }, #if defined(DEBUG) || defined(_DEBUG) { NULL, 'z', OPTPARSE_REQUIRED }, #endif @@ -584,6 +586,8 @@ int main(int argc, char **argv) check_source_flag = 1; } else if (strstr(optparse_state.optlongname, "print-tos") != NULL) { print_tos_flag = 1; + } else if (strstr(optparse_state.optlongname, "print-ttl") != NULL) { + print_ttl_flag = 1; } else { usage(1); } @@ -2164,7 +2168,8 @@ int decode_icmp_ipv4( size_t reply_buf_len, unsigned short *id, unsigned short *seq, - int *ip_header_tos) + int *ip_header_tos, + int *ip_header_ttl) { struct icmp *icp; int hlen = 0; @@ -2172,6 +2177,7 @@ int decode_icmp_ipv4( if (!using_sock_dgram4) { struct ip *ip = (struct ip *)reply_buf; *ip_header_tos = ip->ip_tos; + *ip_header_ttl = ip->ip_ttl; #if defined(__alpha__) && __STDC__ && !defined(__GLIBC__) && !defined(__NetBSD__) && !defined(__OpenBSD__) /* The alpha headers are decidedly broken. @@ -2373,6 +2379,7 @@ int wait_for_reply(int64_t wait_time) unsigned short id; unsigned short seq; int ip_header_tos = -1; + int ip_header_ttl = -1; /* Receive packet */ result = receive_packet(wait_time, /* max. wait time, in ns */ @@ -2400,7 +2407,8 @@ int wait_for_reply(int64_t wait_time) sizeof(buffer), &id, &seq, - &ip_header_tos); + &ip_header_tos, + &ip_header_ttl); if (ip_hlen < 0) { return 1; } @@ -2518,6 +2526,15 @@ int wait_for_reply(int64_t wait_time) } } + if (print_ttl_flag) { + if(ip_header_ttl != -1) { + printf(" (TTL %d)", ip_header_ttl); + } + else { + printf(" (TTL unknown)"); + } + } + if (elapsed_flag) printf(" (%s ms)", sprint_tm(this_reply)); @@ -3088,5 +3105,6 @@ void usage(int is_error) fprintf(out, " -x, --reachable=N shows if >=N hosts are reachable or not\n"); fprintf(out, " -X, --fast-reachable=N exits true immediately when N hosts are found\n"); fprintf(out, " --print-tos show tos value\n"); + fprintf(out, " --print-ttl show IP TTL value\n"); exit(is_error); }