resolve-host.c revision dad29dff1925a114e20d4eb7b47fca23c4f25fd7
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen This file is part of systemd.
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen Copyright 2014 Zbigniew Jędrzejewski-Szmek
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen systemd is free software; you can redistribute it and/or modify it
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen under the terms of the GNU Lesser General Public License as published by
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen (at your option) any later version.
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen systemd is distributed in the hope that it will be useful, but
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen Lesser General Public License for more details.
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen You should have received a copy of the GNU Lesser General Public License
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen#define DNS_CALL_TIMEOUT_USEC (45*USEC_PER_SEC)
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersenstatic int arg_ifindex = 0;
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersenstatic int arg_type = 0;
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersenstatic bool arg_legend = true;
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersenstatic void print_source(int ifindex, uint64_t flags) {
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen fputs("\n-- Information acquired via", stdout);
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen flags & SD_RESOLVED_LLMNR_IPV4 ? " LLMNR/IPv4" : "",
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen flags & SD_RESOLVED_LLMNR_IPV6 ? " LLMNR/IPv6" : "");
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen printf(" interface %s", strna(if_indextoname(ifindex, ifname)));
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersenstatic int resolve_host(sd_bus *bus, const char *name) {
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL;
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen unsigned c = 0;
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen log_debug("Resolving %s (family %s, ifindex %i).", name, af_to_name(arg_family) ?: "*", arg_ifindex);
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen "org.freedesktop.resolve1",
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen "org.freedesktop.resolve1.Manager",
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen "ResolveHostname");
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen r = sd_bus_message_set_auto_start(req, false);
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen r = sd_bus_message_append(req, "isit", arg_ifindex, name, arg_family, arg_flags);
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen log_error("%s: resolve call failed: %s", name, bus_error_message(&error, r));
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen r = sd_bus_message_read(reply, "i", &ifindex);
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen r = sd_bus_message_enter_container(reply, 'a', "(iay)");
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen const void *a;
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen r = sd_bus_message_read_array(reply, 'y', &a, &sz);
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen log_debug("%s: skipping entry with family %d (%s)", name, family, af_to_name(family) ?: "unknown");
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen log_error("%s: systemd-resolved returned address of invalid size %zu for family %s",
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen log_error("Failed to resolve interface name for index %i", ifindex);
7a695d8e1fda59857c4c23bcb50cd1e0aaf4a854Tom Gundersen log_error("%s: failed to print address: %s", name, strerror(-r));
7a695d8e1fda59857c4c23bcb50cd1e0aaf4a854Tom Gundersen (int) strlen(name), c == 0 ? name : "", c == 0 ? ":" : " ",
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen r = sd_bus_message_read(reply, "st", &canonical, &flags);
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen (int) strlen(name), c == 0 ? name : "", c == 0 ? ":" : " ",
3b015d40c19d9338b66bf916d84dec601019c811Tom Gundersen if (c == 0) {
7a695d8e1fda59857c4c23bcb50cd1e0aaf4a854Tom Gundersenstatic int resolve_address(sd_bus *bus, int family, const union in_addr_union *address, int ifindex) {
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL;
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen unsigned c = 0;
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen const char *n;
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen r = in_addr_to_string(family, address, &pretty);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen log_error("Failed to resolve interface name for index %i", ifindex);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen log_debug("Resolving %s%s%s.", pretty, isempty(ifname) ? "" : "%", ifname);
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen "org.freedesktop.resolve1",
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen "org.freedesktop.resolve1.Manager",
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen "ResolveAddress");
a13c50e7a33e2b8e0481f725c6272142e6f71751Tom Gundersen r = sd_bus_message_set_auto_start(req, false);
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen r = sd_bus_message_append(req, "ii", ifindex, family);
9d96e6c3efbe5ef52b2855612d51db52c469beb2Tom Gundersen r = sd_bus_message_append_array(req, 'y', address, FAMILY_ADDRESS_SIZE(family));
return bus_log_create_error(r);
return bus_log_parse_error(r);
return bus_log_create_error(r);
return bus_log_parse_error(r);
return bus_log_parse_error(r);
return bus_log_parse_error(r);
return -ESRCH;
const char *percent, *a;
int ifi = 0;
if (percent) {
if (r < 0 || ifi <= 0) {
if (ifi <= 0)
return -EINVAL;
int r, ifindex;
log_debug("Resolving %s %s %s.", name, dns_class_to_string(arg_class), dns_type_to_string(arg_type));
bus,
&req,
"/org/freedesktop/resolve1",
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_parse_error(r);
return bus_log_parse_error(r);
uint16_t c, t;
size_t l;
return bus_log_parse_error(r);
return bus_log_parse_error(r);
return bus_log_parse_error(r);
return log_oom();
return log_oom();
return bus_log_parse_error(r);
return bus_log_parse_error(r);
return bus_log_parse_error(r);
return -ESRCH;
static void help_dns_types(void) {
if (arg_legend)
for (i = 0; i < _DNS_TYPE_MAX; i++) {
t = dns_type_to_string(i);
puts(t);
static void help_dns_classes(void) {
if (arg_legend)
for (i = 0; i < _DNS_CLASS_MAX; i++) {
t = dns_class_to_string(i);
puts(t);
static void help(void) {
help();
case ARG_VERSION:
if (arg_ifindex <= 0) {
return -errno;
if (arg_type < 0) {
return arg_type;
case ARG_LEGEND:
if (optarg) {
arg_legend = !!r;
arg_legend = false;
return -EINVAL;
return -EINVAL;
return -EINVAL;
log_open();
goto finish;
r = -EINVAL;
goto finish;
goto finish;
union in_addr_union a;
if (arg_type != 0)
optind++;