diff options
Diffstat (limited to 'src/resolve-host')
-rw-r--r-- | src/resolve-host/resolve-host.c | 138 |
1 files changed, 98 insertions, 40 deletions
diff --git a/src/resolve-host/resolve-host.c b/src/resolve-host/resolve-host.c index 3709268dd2..c39b582373 100644 --- a/src/resolve-host/resolve-host.c +++ b/src/resolve-host/resolve-host.c @@ -32,6 +32,7 @@ #include "build.h" #include "resolved-dns-packet.h" +#include "resolved-def.h" #define DNS_CALL_TIMEOUT_USEC (45*USEC_PER_SEC) @@ -40,6 +41,32 @@ static int arg_ifindex = 0; static int arg_type = 0; static uint16_t arg_class = 0; static bool arg_legend = true; +static uint64_t arg_flags = 0; + +static void print_source(int ifindex, uint64_t flags) { + + if (!arg_legend) + return; + + if (ifindex <= 0 && flags == 0) + return; + + fputs("\n-- Information acquired via", stdout); + + if (flags != 0) + printf(" protocol%s%s%s", + flags & SD_RESOLVED_DNS ? " DNS" :"", + flags & SD_RESOLVED_LLMNR_IPV4 ? " LLMNR/IPv4" : "", + flags & SD_RESOLVED_LLMNR_IPV6 ? " LLMNR/IPv6" : ""); + + if (ifindex > 0) { + char ifname[IF_NAMESIZE] = ""; + printf(" interface %s", strna(if_indextoname(ifindex, ifname))); + } + + fputc('.', stdout); + fputc('\n', stdout); +} static int resolve_host(sd_bus *bus, const char *name) { @@ -47,7 +74,8 @@ static int resolve_host(sd_bus *bus, const char *name) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; const char *canonical = NULL; unsigned c = 0; - int r; + int r, ifindex; + uint64_t flags; assert(name); @@ -67,7 +95,7 @@ static int resolve_host(sd_bus *bus, const char *name) { if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_append(req, "si", name, arg_family); + r = sd_bus_message_append(req, "isit", arg_ifindex, name, arg_family, arg_flags); if (r < 0) return bus_log_create_error(r); @@ -77,13 +105,17 @@ static int resolve_host(sd_bus *bus, const char *name) { return r; } - r = sd_bus_message_enter_container(reply, 'a', "(iayi)"); + r = sd_bus_message_read(reply, "i", &ifindex); if (r < 0) return bus_log_parse_error(r); - while ((r = sd_bus_message_enter_container(reply, 'r', "iayi")) > 0) { + r = sd_bus_message_enter_container(reply, 'a', "(iay)"); + if (r < 0) + return bus_log_parse_error(r); + + while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) { const void *a; - int family, ifindex; + int family; size_t sz; _cleanup_free_ char *pretty = NULL; char ifname[IF_NAMESIZE] = ""; @@ -96,10 +128,6 @@ static int resolve_host(sd_bus *bus, const char *name) { if (r < 0) return bus_log_parse_error(r); - r = sd_bus_message_read(reply, "i", &ifindex); - if (r < 0) - return bus_log_parse_error(r); - r = sd_bus_message_exit_container(reply); if (r < 0) return bus_log_parse_error(r); @@ -115,12 +143,6 @@ static int resolve_host(sd_bus *bus, const char *name) { continue; } - if (ifindex < 0) { - log_error("%s: systemd-resolved returned invalid interface index %i", - name, ifindex); - continue; - } - if (ifindex > 0) { char *t; @@ -131,12 +153,6 @@ static int resolve_host(sd_bus *bus, const char *name) { } } - if (arg_ifindex > 0 && ifindex > 0 && ifindex != arg_ifindex) { - log_debug("%s: skipping entry with ifindex %i (%s)", - name, ifindex, ifname); - continue; - } - r = in_addr_to_string(family, a, &pretty); if (r < 0) { log_error("%s: failed to print address: %s", name, strerror(-r)); @@ -157,7 +173,7 @@ static int resolve_host(sd_bus *bus, const char *name) { if (r < 0) return bus_log_parse_error(r); - r = sd_bus_message_read(reply, "s", &canonical); + r = sd_bus_message_read(reply, "st", &canonical, &flags); if (r < 0) return bus_log_parse_error(r); @@ -172,6 +188,8 @@ static int resolve_host(sd_bus *bus, const char *name) { return -ESRCH; } + print_source(ifindex, flags); + return 0; } @@ -180,6 +198,7 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_free_ char *pretty = NULL; char ifname[IF_NAMESIZE] = ""; + uint64_t flags; unsigned c = 0; const char *n; int r; @@ -218,7 +237,7 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_append(req, "i", family); + r = sd_bus_message_append(req, "ii", ifindex, family); if (r < 0) return bus_log_create_error(r); @@ -226,7 +245,7 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_append(req, "i", ifindex); + r = sd_bus_message_append(req, "t", arg_flags); if (r < 0) return bus_log_create_error(r); @@ -236,6 +255,10 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a return r; } + r = sd_bus_message_read(reply, "i", &ifindex); + if (r < 0) + return bus_log_parse_error(r); + r = sd_bus_message_enter_container(reply, 'a', "s"); if (r < 0) return bus_log_create_error(r); @@ -257,11 +280,17 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a if (r < 0) return bus_log_parse_error(r); + r = sd_bus_message_read(reply, "t", &flags); + if (r < 0) + return bus_log_parse_error(r); + if (c == 0) { log_error("%s: no names found", pretty); return -ESRCH; } + print_source(ifindex, flags); + return 0; } @@ -296,7 +325,8 @@ static int resolve_record(sd_bus *bus, const char *name) { _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; unsigned n = 0; - int r; + uint64_t flags; + int r, ifindex; assert(name); @@ -317,7 +347,7 @@ static int resolve_record(sd_bus *bus, const char *name) { return bus_log_create_error(r); assert((uint16_t) arg_type == arg_type); - r = sd_bus_message_append(req, "sqq", name, arg_class, arg_type); + r = sd_bus_message_append(req, "isqqt", arg_ifindex, name, arg_class, arg_type, arg_flags); if (r < 0) return bus_log_create_error(r); @@ -327,6 +357,10 @@ static int resolve_record(sd_bus *bus, const char *name) { return r; } + r = sd_bus_message_read(reply, "i", &ifindex); + if (r < 0) + return bus_log_parse_error(r); + r = sd_bus_message_enter_container(reply, 'a', "(qqay)"); if (r < 0) return bus_log_parse_error(r); @@ -381,11 +415,17 @@ static int resolve_record(sd_bus *bus, const char *name) { if (r < 0) return bus_log_parse_error(r); + r = sd_bus_message_read(reply, "t", &flags); + if (r < 0) + return bus_log_parse_error(r); + if (n == 0) { log_error("%s: no records found", name); return -ESRCH; } + print_source(ifindex, flags); + return 0; } @@ -418,14 +458,15 @@ static void help_dns_classes(void) { static void help(void) { printf("%s [OPTIONS...]\n\n" "Resolve IPv4 or IPv6 addresses.\n\n" - " -h --help Show this help\n" - " --version Show package version\n" - " -4 Resolve IPv4 addresses\n" - " -6 Resolve IPv6 addresses\n" - " -i INTERFACE Filter by interface\n" - " -t --type=TYPE Query RR with DNS type\n" - " -c --class=CLASS Query RR with DNS class\n" - " --no-legend Do not print column headers\n" + " -h --help Show this help\n" + " --version Show package version\n" + " -4 Resolve IPv4 addresses\n" + " -6 Resolve IPv6 addresses\n" + " -i INTERFACE Look on interface\n" + " -p --protocol=PROTOCOL Look via protocol\n" + " -t --type=TYPE Query RR with DNS type\n" + " -c --class=CLASS Query RR with DNS class\n" + " --no-legend Do not print column headers\n" , program_invocation_short_name); } @@ -436,11 +477,12 @@ static int parse_argv(int argc, char *argv[]) { }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "type", no_argument, NULL, 't' }, - { "class", no_argument, NULL, 'c' }, - { "no-legend", no_argument, NULL, ARG_NO_LEGEND }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "type", required_argument, NULL, 't' }, + { "class", required_argument, NULL, 'c' }, + { "no-legend", no_argument, NULL, ARG_NO_LEGEND }, + { "protocol", required_argument, NULL, 'p' }, {} }; @@ -449,7 +491,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "h46i:t:c:", options, NULL)) >= 0) + while ((c = getopt_long(argc, argv, "h46i:t:c:p:", options, NULL)) >= 0) switch(c) { case 'h': @@ -510,6 +552,22 @@ static int parse_argv(int argc, char *argv[]) { arg_legend = false; break; + case 'p': + if (streq(optarg, "dns")) + arg_flags |= SD_RESOLVED_DNS; + else if (streq(optarg, "llmnr")) + arg_flags |= SD_RESOLVED_LLMNR; + else if (streq(optarg, "llmnr-ipv4")) + arg_flags |= SD_RESOLVED_LLMNR_IPV4; + else if (streq(optarg, "llmnr-ipv6")) + arg_flags |= SD_RESOLVED_LLMNR_IPV6; + else { + log_error("Unknown protocol specifier: %s", optarg); + return -EINVAL; + } + + break; + case '?': return -EINVAL; |