diff --git a/ci/test-08-options-n-q.pl b/ci/test-08-options-n-q.pl index 32630d0..277e482 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 => 36; +use Test::Command tests => 42; # -n show targets by name (-d is equivalent) # -O n set the type of service (tos) flag on the ICMP packets @@ -48,6 +48,24 @@ $cmd->stderr_is_eq(""); } +# fping -O --print-tos +{ +my $cmd = Test::Command->new(cmd => "fping -O 2 --print-tos 127.0.0.1"); +$cmd->exit_is_num(0); +$cmd->stdout_like(qr{127\.0\.0\.1 is alive \(TOS \d+\) +}); +$cmd->stderr_is_eq(""); +} + +# fping -O -A -n --print-tos +{ +my $cmd = Test::Command->new(cmd => "fping -O 2 -A -n --print-tos 127.0.0.1"); +$cmd->exit_is_num(0); +$cmd->stdout_like(qr{localhost \(127\.0\.0\.1\) is alive \(TOS \d+\) +}); +$cmd->stderr_is_eq(""); +} + # fping -q { my $cmd = Test::Command->new(cmd => "fping -q -p 100 -c 3 127.0.0.1"); diff --git a/doc/fping.pod b/doc/fping.pod index 3fd7332..9103f68 100644 --- a/doc/fping.pod +++ b/doc/fping.pod @@ -179,6 +179,10 @@ Calculate "outage time" based on the number of lost pings and the interval used Set the typ of service flag (TOS). I can be either decimal or hexadecimal (0xh) format. +Subcommand: B<--print-tos> + +Displays the tos value in the output + =item B<-p>, B<--period>=I In looping or counting modes (B<-l>, B<-c>, or B<-C>), this parameter sets diff --git a/src/fping.c b/src/fping.c index f7fe6a9..42320a0 100644 --- a/src/fping.c +++ b/src/fping.c @@ -355,6 +355,8 @@ int verbose_flag, quiet_flag, stats_flag, unreachable_flag, alive_flag; int elapsed_flag, version_flag, count_flag, loop_flag, netdata_flag; int per_recv_flag, report_all_rtts_flag, name_flag, addr_flag, backoff_flag, rdns_flag; int multif_flag, timeout_flag, fast_reachable; +int tos_flag = 0; +int print_tos_flag = 0; int outage_flag = 0; int timestamp_flag = 0; int timestamp_format_flag = 0; @@ -543,6 +545,7 @@ int main(int argc, char **argv) { "netdata", 'N', OPTPARSE_NONE }, { "outage", 'o', OPTPARSE_NONE }, { "tos", 'O', OPTPARSE_REQUIRED }, + { "print-tos", '0', OPTPARSE_NONE }, { "period", 'p', OPTPARSE_REQUIRED }, { "quiet", 'q', OPTPARSE_NONE }, { "squiet", 'Q', OPTPARSE_REQUIRED }, @@ -566,16 +569,20 @@ int main(int argc, char **argv) while ((c = optparse_long(&optparse_state, longopts, NULL)) != EOF) { switch (c) { case '0': - if(strstr(optparse_state.optlongname, "timestamp-format") != NULL) { - if(strcmp(optparse_state.optarg, "ctime") == 0) { - timestamp_format_flag = 1; - }else if(strcmp(optparse_state.optarg, "iso") == 0) { - timestamp_format_flag = 2; - }else if(strcmp(optparse_state.optarg, "rfc3339") == 0) { - timestamp_format_flag = 3; - }else{ + if (strstr(optparse_state.optlongname, "timestamp-format") != NULL) { + if(strcmp(optparse_state.optarg, "ctime") == 0) { + timestamp_format_flag = 1; + }else if(strcmp(optparse_state.optarg, "iso") == 0) { + timestamp_format_flag = 2; + }else if(strcmp(optparse_state.optarg, "rfc3339") == 0) { + timestamp_format_flag = 3; + }else{ + usage(1); + } + } else if (strstr(optparse_state.optlongname, "print-tos") != NULL) { + print_tos_flag = 1; + } else { usage(1); - } } break; case '4': @@ -879,6 +886,7 @@ int main(int argc, char **argv) } } #endif + tos_flag = 1; } else { usage(1); @@ -2153,14 +2161,16 @@ int decode_icmp_ipv4( char *reply_buf, size_t reply_buf_len, unsigned short *id, - unsigned short *seq) + unsigned short *seq, + int *ip_header_tos) { struct icmp *icp; + struct ip *ip; int hlen = 0; - if (!using_sock_dgram4) { - struct ip *ip = (struct ip *)reply_buf; + ip = (struct ip *)reply_buf; + if (!using_sock_dgram4) { #if defined(__alpha__) && __STDC__ && !defined(__GLIBC__) && !defined(__NetBSD__) && !defined(__OpenBSD__) /* The alpha headers are decidedly broken. * Using an ANSI compiler, it provides ip_vhl instead of ip_hl and @@ -2250,6 +2260,7 @@ int decode_icmp_ipv4( *id = icp->icmp_id; *seq = ntohs(icp->icmp_seq); + *ip_header_tos = ip->ip_tos; return hlen; } @@ -2360,6 +2371,7 @@ int wait_for_reply(int64_t wait_time) SEQMAP_VALUE *seqmap_value; unsigned short id; unsigned short seq; + int ip_header_tos; /* Receive packet */ result = receive_packet(wait_time, /* max. wait time, in ns */ @@ -2386,7 +2398,8 @@ int wait_for_reply(int64_t wait_time) buffer, sizeof(buffer), &id, - &seq); + &seq, + &ip_header_tos); if (ip_hlen < 0) { return 1; } @@ -2486,8 +2499,12 @@ int wait_for_reply(int64_t wait_time) if (verbose_flag || alive_flag) { printf("%s", h->host); - if (verbose_flag) + if (verbose_flag) { printf(" is alive"); + if (tos_flag && print_tos_flag) { + printf(" (TOS %d)", ip_header_tos); + } + } if (elapsed_flag) printf(" (%s ms)", sprint_tm(this_reply)); @@ -3057,5 +3074,6 @@ void usage(int is_error) fprintf(out, " -v, --version show version\n"); 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 (-O are required)"); exit(is_error); }