From bab585e9fa0761c953592a8c33e3b784d0b87ba9 Mon Sep 17 00:00:00 2001 From: David Schweikert Date: Fri, 10 Feb 2017 17:56:53 +0100 Subject: [PATCH] new option --rdns --- ChangeLog | 9 ++- ci/test-14-ping-internet-hosts.pl | 18 ++++- src/fping.c | 107 ++++++++++++++++-------------- 3 files changed, 82 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4fc17a4..24972b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,9 +15,14 @@ Unreleased * Version 4.0 * (feature) Unified 'fping' and 'fping6' into one binary (#80) + * (feature) Long option names for all options * (feature) --enable-ipv6 is now default - * (feature) New option '-4' to force IPv4 - * (feature) New option '-6' to force IPv6 + * (feature) New option -4 to force IPv4 + * (feature) New option -6 to force IPv6 + * (feature) Keep original name if a hostname is given with -n/--name + * (feature) New option -X/--rdns, similar to -n/--name, but which always + does a rdns-lookup, even for names (name->IP->name), as '-n' + was doing until now * (bugfix) Fix compatibility issue with GNU Hurd * (other) A C99 compiler is now required * (other) Option parsing with optparse (https://github.com/skeeto/optparse) diff --git a/ci/test-14-ping-internet-hosts.pl b/ci/test-14-ping-internet-hosts.pl index ed6cfcd..f2b63ed 100755 --- a/ci/test-14-ping-internet-hosts.pl +++ b/ci/test-14-ping-internet-hosts.pl @@ -9,7 +9,7 @@ if(!gethostbyname("www.google.com")) { exit 0; } -plan tests => 21; +plan tests => 27; my $re_num = qr{\d+(?:\.\d+)?}; @@ -41,6 +41,22 @@ $cmd->stdout_is_eq("google-public-dns-a.google.com (8.8.8.8) is alive\n"); $cmd->stderr_is_eq(""); } +# fping -4 --addr --rdns +{ +my $cmd = Test::Command->new(cmd => "fping -4 --addr --rdns www.google.com"); +$cmd->exit_is_num(0); +$cmd->stdout_like(qr{^\S+\.1e100\.net \(\d+\.\d+\.\d+\.\d+\) is alive\n$}); +$cmd->stderr_is_eq(""); +} + +# fping -4 --addr --name +{ +my $cmd = Test::Command->new(cmd => "fping -4 --addr --name www.google.com"); +$cmd->exit_is_num(0); +$cmd->stdout_like(qr{^www\.google\.com \(\d+\.\d+\.\d+\.\d+\) is alive\n$}); +$cmd->stderr_is_eq(""); +} + # fping -A -n (IPv6) SKIP: { if(system("/sbin/ifconfig | grep inet6.*Scope:Global") != 0) { diff --git a/src/fping.c b/src/fping.c index ff81208..922213a 100644 --- a/src/fping.c +++ b/src/fping.c @@ -281,7 +281,7 @@ struct timezone tz; int generate_flag = 0; /* flag for IP list generation */ 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; +int per_recv_flag, report_all_rtts_flag, name_flag, addr_flag, backoff_flag, rdns_flag; int multif_flag; int outage_flag = 0; int timestamp_flag = 0; @@ -368,42 +368,42 @@ int main(int argc, char** argv) /* get command line options */ struct optparse_long longopts[] = { - { NULL, '4', OPTPARSE_NONE }, - { NULL, '6', OPTPARSE_NONE }, - { "alive", 'a', OPTPARSE_NONE }, - { "addr", 'A', OPTPARSE_NONE }, - { "size", 'b', OPTPARSE_REQUIRED }, - { "backoff", 'B', OPTPARSE_REQUIRED }, - { "count", 'c', OPTPARSE_REQUIRED }, - { "vcount", 'C', OPTPARSE_REQUIRED }, - { NULL, 'd', OPTPARSE_NONE }, // same as '--names' + { NULL, '4', OPTPARSE_NONE }, + { NULL, '6', OPTPARSE_NONE }, + { "alive", 'a', OPTPARSE_NONE }, + { "addr", 'A', OPTPARSE_NONE }, + { "size", 'b', OPTPARSE_REQUIRED }, + { "backoff", 'B', OPTPARSE_REQUIRED }, + { "count", 'c', OPTPARSE_REQUIRED }, + { "vcount", 'C', OPTPARSE_REQUIRED }, + { NULL, 'd', OPTPARSE_NONE }, // same as '--name' { "timestamp", 'D', OPTPARSE_NONE }, - { "elapsed", 'e', OPTPARSE_NONE }, - { "file", 'f', OPTPARSE_REQUIRED }, - { "generate", 'g', OPTPARSE_NONE }, - { "help", 'h', OPTPARSE_NONE }, - { "ttl", 'H', OPTPARSE_REQUIRED }, - { "interval", 'i', OPTPARSE_REQUIRED }, - { "iface", 'I', OPTPARSE_REQUIRED }, - { "loop", 'l', OPTPARSE_NONE }, - { "all", 'm', OPTPARSE_NONE }, - { "dontfrag", 'M', OPTPARSE_NONE }, - { "names", 'n', OPTPARSE_NONE }, - { "netdata", 'N', OPTPARSE_NONE }, - { "outage", 'o', OPTPARSE_NONE }, - { "tos", 'O', OPTPARSE_REQUIRED }, - { "period", 'p', OPTPARSE_REQUIRED }, - { "quiet", 'q', OPTPARSE_NONE }, - { "squiet", 'Q', OPTPARSE_REQUIRED }, - { "retry", 'r', OPTPARSE_REQUIRED }, - { "random", 'R', OPTPARSE_NONE }, - { "stats", 's', OPTPARSE_NONE }, - { "src", 'S', OPTPARSE_REQUIRED }, - { "timeout", 't', OPTPARSE_REQUIRED }, - { NULL, 'T', OPTPARSE_REQUIRED }, - { "unreach", 'u', OPTPARSE_NONE }, - { "version", 'v', OPTPARSE_NONE }, - { "rdns", 'X', OPTPARSE_NONE }, // FIXME: similar to --names, but do name->IP->name if a name is provided + { "elapsed", 'e', OPTPARSE_NONE }, + { "file", 'f', OPTPARSE_REQUIRED }, + { "generate", 'g', OPTPARSE_NONE }, + { "help", 'h', OPTPARSE_NONE }, + { "ttl", 'H', OPTPARSE_REQUIRED }, + { "interval", 'i', OPTPARSE_REQUIRED }, + { "iface", 'I', OPTPARSE_REQUIRED }, + { "loop", 'l', OPTPARSE_NONE }, + { "all", 'm', OPTPARSE_NONE }, + { "dontfrag", 'M', OPTPARSE_NONE }, + { "name", 'n', OPTPARSE_NONE }, + { "netdata", 'N', OPTPARSE_NONE }, + { "outage", 'o', OPTPARSE_NONE }, + { "tos", 'O', OPTPARSE_REQUIRED }, + { "period", 'p', OPTPARSE_REQUIRED }, + { "quiet", 'q', OPTPARSE_NONE }, + { "squiet", 'Q', OPTPARSE_REQUIRED }, + { "retry", 'r', OPTPARSE_REQUIRED }, + { "random", 'R', OPTPARSE_NONE }, + { "stats", 's', OPTPARSE_NONE }, + { "src", 'S', OPTPARSE_REQUIRED }, + { "timeout", 't', OPTPARSE_REQUIRED }, + { NULL, 'T', OPTPARSE_REQUIRED }, + { "unreach", 'u', OPTPARSE_NONE }, + { "version", 'v', OPTPARSE_NONE }, + { "rdns", 'X', OPTPARSE_NONE }, // FIXME: similar to --name, but do name->IP->name if a name is provided { 0, 0, 0 } }; @@ -529,6 +529,10 @@ int main(int argc, char** argv) name_flag = 1; break; + case 'X': + rdns_flag = 1; + break; + case 'A': addr_flag = 1; break; @@ -2215,22 +2219,27 @@ void add_name(char* name) */ for (res = res0; res; res = res->ai_next) { /* name_flag: addr -> name lookup requested) */ - if (!name_flag) { - printname = name; - } - else { - int ret; - ret = getnameinfo(res->ai_addr, res->ai_addrlen, namebuf, - sizeof(namebuf) / sizeof(char), NULL, 0, 0); - if (ret) { - if (!quiet_flag) { - print_warning("%s: can't reverse-lookup (%s)\n", name, gai_strerror(ret)); + if (name_flag || rdns_flag) { + int do_rdns = rdns_flag ? 1 : 0; + if (name_flag) { + /* Was it a numerical address? Only then do a rdns-query */ + struct addrinfo* nres; + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(name, NULL, &hints, &nres) == 0) { + do_rdns = 1; + freeaddrinfo(nres); } - printname = name; } - else { + + if (do_rdns && getnameinfo(res->ai_addr, res->ai_addrlen, namebuf, sizeof(namebuf) / sizeof(char), NULL, 0, 0) == 0) { printname = namebuf; } + else { + printname = name; + } + } + else { + printname = name; } /* addr_flag: name -> addr lookup requested */ @@ -2245,7 +2254,7 @@ void add_name(char* name) continue; } - if (name_flag) { + if (name_flag || rdns_flag) { char nameaddrbuf[512]; snprintf(nameaddrbuf, sizeof(nameaddrbuf) / sizeof(char), "%s (%s)", printname, addrbuf); add_addr(name, nameaddrbuf, res->ai_addr, res->ai_addrlen);