Bug Summary

File:build-scan/../src/resolve/resolvectl.c
Warning:line 2841, column 29
Null pointer passed to 1st parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name resolvectl.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I resolvectl.p -I . -I .. -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/resolve/resolvectl.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <getopt.h>
4#include <net/if.h>
5
6#include "sd-bus.h"
7#include "sd-netlink.h"
8
9#include "af-list.h"
10#include "alloc-util.h"
11#include "bus-common-errors.h"
12#include "bus-error.h"
13#include "bus-util.h"
14#include "dns-domain.h"
15#include "escape.h"
16#include "gcrypt-util.h"
17#include "in-addr-util.h"
18#include "netlink-util.h"
19#include "pager.h"
20#include "parse-util.h"
21#include "resolvconf-compat.h"
22#include "resolvectl.h"
23#include "resolved-def.h"
24#include "resolved-dns-packet.h"
25#include "string-table.h"
26#include "strv.h"
27#include "terminal-util.h"
28#include "verbs.h"
29
30static int arg_family = AF_UNSPEC0;
31int arg_ifindex = 0;
32const char *arg_ifname = NULL((void*)0);
33static uint16_t arg_type = 0;
34static uint16_t arg_class = 0;
35static bool_Bool arg_legend = true1;
36static uint64_t arg_flags = 0;
37static bool_Bool arg_no_pager = false0;
38bool_Bool arg_ifindex_permissive = false0; /* If true, don't generate an error if the specified interface index doesn't exist */
39static const char *arg_service_family = NULL((void*)0);
40
41typedef enum RawType {
42 RAW_NONE,
43 RAW_PAYLOAD,
44 RAW_PACKET,
45} RawType;
46static RawType arg_raw = RAW_NONE;
47
48ExecutionMode arg_mode = MODE_RESOLVE_HOST;
49
50char **arg_set_dns = NULL((void*)0);
51char **arg_set_domain = NULL((void*)0);
52static const char *arg_set_llmnr = NULL((void*)0);
53static const char *arg_set_mdns = NULL((void*)0);
54static const char *arg_set_dns_over_tls = NULL((void*)0);
55static const char *arg_set_dnssec = NULL((void*)0);
56static char **arg_set_nta = NULL((void*)0);
57
58typedef enum StatusMode {
59 STATUS_ALL,
60 STATUS_DNS,
61 STATUS_DOMAIN,
62 STATUS_LLMNR,
63 STATUS_MDNS,
64 STATUS_PRIVATE,
65 STATUS_DNSSEC,
66 STATUS_NTA,
67} StatusMode;
68
69static int parse_ifindex_with_warn(const char *s) {
70 int ifi;
71
72 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/resolve/resolvectl.c", 72,
__PRETTY_FUNCTION__); } while (0)
;
73
74 if (parse_ifindex(s, &ifi) < 0) {
75 ifi = if_nametoindex(s);
76 if (ifi <= 0)
77 return log_error_errno(errno, "Unknown interface %s: %m", s)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/resolve/resolvectl.c", 77, __func__
, "Unknown interface %s: %m", s) : -abs(_e); })
;
78 }
79
80 return ifi;
81}
82
83static void print_source(uint64_t flags, usec_t rtt) {
84 char rtt_str[FORMAT_TIMESTAMP_MAX(3+1+10+1+8+1+6+1+6+1)];
85
86 if (!arg_legend)
87 return;
88
89 if (flags == 0)
90 return;
91
92 fputs("\n-- Information acquired via", stdoutstdout);
93
94 if (flags != 0)
95 printf(" protocol%s%s%s%s%s",
96 flags & SD_RESOLVED_DNS(1UL << 0) ? " DNS" :"",
97 flags & SD_RESOLVED_LLMNR_IPV4(1UL << 1) ? " LLMNR/IPv4" : "",
98 flags & SD_RESOLVED_LLMNR_IPV6(1UL << 2) ? " LLMNR/IPv6" : "",
99 flags & SD_RESOLVED_MDNS_IPV4(1UL << 3) ? " mDNS/IPv4" : "",
100 flags & SD_RESOLVED_MDNS_IPV6(1UL << 4) ? " mDNS/IPv6" : "");
101
102 assert_se(format_timespan(rtt_str, sizeof(rtt_str), rtt, 100))do { if ((__builtin_expect(!!(!(format_timespan(rtt_str, sizeof
(rtt_str), rtt, 100))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("format_timespan(rtt_str, sizeof(rtt_str), rtt, 100)"), "../src/resolve/resolvectl.c"
, 102, __PRETTY_FUNCTION__); } while (0)
;
103
104 printf(" in %s", rtt_str);
105
106 fputc('.', stdoutstdout);
107 fputc('\n', stdoutstdout);
108
109 printf("-- Data is authenticated: %s\n", yes_no(flags & SD_RESOLVED_AUTHENTICATED(1UL << 9)));
110}
111
112static int resolve_host(sd_bus *bus, const char *name) {
113 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *req = NULL((void*)0), *reply = NULL((void*)0);
114 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
115 const char *canonical = NULL((void*)0);
116 char ifname[IF_NAMESIZE16] = "";
117 unsigned c = 0;
118 int r;
119 uint64_t flags;
120 usec_t ts;
121
122 assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("name"), "../src/resolve/resolvectl.c", 122
, __PRETTY_FUNCTION__); } while (0)
;
123
124 if (arg_ifindex > 0 && !if_indextoname(arg_ifindex, ifname))
125 return log_error_errno(errno, "Failed to resolve interface name for index %i: %m", arg_ifindex)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/resolve/resolvectl.c", 125, __func__
, "Failed to resolve interface name for index %i: %m", arg_ifindex
) : -abs(_e); })
;
126
127 log_debug("Resolving %s (family %s, interface %s).", name, af_to_name(arg_family) ?: "*", isempty(ifname) ? "*" : ifname)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 127, __func__, "Resolving %s (family %s, interface %s)."
, name, af_to_name(arg_family) ?: "*", isempty(ifname) ? "*" :
ifname) : -abs(_e); })
;
128
129 r = sd_bus_message_new_method_call(
130 bus,
131 &req,
132 "org.freedesktop.resolve1",
133 "/org/freedesktop/resolve1",
134 "org.freedesktop.resolve1.Manager",
135 "ResolveHostname");
136 if (r < 0)
137 return bus_log_create_error(r);
138
139 r = sd_bus_message_append(req, "isit", arg_ifindex, name, arg_family, arg_flags);
140 if (r < 0)
141 return bus_log_create_error(r);
142
143 ts = now(CLOCK_MONOTONIC1);
144
145 r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC(120 * ((usec_t) 1000000ULL)), &error, &reply);
146 if (r < 0)
147 return log_error_errno(r, "%s: resolve call failed: %s", name, bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 147, __func__, "%s: resolve call failed: %s"
, name, bus_error_message(&error, r)) : -abs(_e); })
;
148
149 ts = now(CLOCK_MONOTONIC1) - ts;
150
151 r = sd_bus_message_enter_container(reply, 'a', "(iiay)");
152 if (r < 0)
153 return bus_log_parse_error(r);
154
155 while ((r = sd_bus_message_enter_container(reply, 'r', "iiay")) > 0) {
156 _cleanup_free___attribute__((cleanup(freep))) char *pretty = NULL((void*)0);
157 int ifindex, family;
158 const void *a;
159 size_t sz;
160
161 assert_cc(sizeof(int) == sizeof(int32_t))GCC diagnostic push ; GCC diagnostic ignored "-Wdeclaration-after-statement"
; struct _assert_struct_57 { char x[(sizeof(int) == sizeof(int32_t
)) ? 0 : -1]; }; GCC diagnostic pop
;
162
163 r = sd_bus_message_read(reply, "ii", &ifindex, &family);
164 if (r < 0)
165 return bus_log_parse_error(r);
166
167 r = sd_bus_message_read_array(reply, 'y', &a, &sz);
168 if (r < 0)
169 return bus_log_parse_error(r);
170
171 r = sd_bus_message_exit_container(reply);
172 if (r < 0)
173 return bus_log_parse_error(r);
174
175 if (!IN_SET(family, AF_INET, AF_INET6)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){2, 10})/sizeof(int)]; switch(family) { case
2: case 10: _found = 1; break; default: break; } _found; })
) {
176 log_debug("%s: skipping entry with family %d (%s)", name, family, af_to_name(family) ?: "unknown")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 176, __func__, "%s: skipping entry with family %d (%s)"
, name, family, af_to_name(family) ?: "unknown") : -abs(_e); }
)
;
177 continue;
178 }
179
180 if (sz != FAMILY_ADDRESS_SIZE(family)) {
181 log_error("%s: systemd-resolved returned address of invalid size %zu for family %s", name, sz, af_to_name(family) ?: "unknown")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 181, __func__, "%s: systemd-resolved returned address of invalid size %zu for family %s"
, name, sz, af_to_name(family) ?: "unknown") : -abs(_e); })
;
182 return -EINVAL22;
183 }
184
185 ifname[0] = 0;
186 if (ifindex > 0 && !if_indextoname(ifindex, ifname))
187 log_warning_errno(errno, "Failed to resolve interface name for index %i: %m", ifindex)({ int _level = ((4)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/resolve/resolvectl.c", 187, __func__
, "Failed to resolve interface name for index %i: %m", ifindex
) : -abs(_e); })
;
188
189 r = in_addr_ifindex_to_string(family, a, ifindex, &pretty);
190 if (r < 0)
191 return log_error_errno(r, "Failed to print address for %s: %m", name)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 191, __func__, "Failed to print address for %s: %m"
, name) : -abs(_e); })
;
192
193 printf("%*s%s %s%s%s\n",
194 (int) strlen(name), c == 0 ? name : "", c == 0 ? ":" : " ",
195 pretty,
196 isempty(ifname) ? "" : "%", ifname);
197
198 c++;
199 }
200 if (r < 0)
201 return bus_log_parse_error(r);
202
203 r = sd_bus_message_exit_container(reply);
204 if (r < 0)
205 return bus_log_parse_error(r);
206
207 r = sd_bus_message_read(reply, "st", &canonical, &flags);
208 if (r < 0)
209 return bus_log_parse_error(r);
210
211 if (!streq(name, canonical)(strcmp((name),(canonical)) == 0))
212 printf("%*s%s (%s)\n",
213 (int) strlen(name), c == 0 ? name : "", c == 0 ? ":" : " ",
214 canonical);
215
216 if (c == 0) {
217 log_error("%s: no addresses found", name)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 217, __func__, "%s: no addresses found"
, name) : -abs(_e); })
;
218 return -ESRCH3;
219 }
220
221 print_source(flags, ts);
222
223 return 0;
224}
225
226static int resolve_address(sd_bus *bus, int family, const union in_addr_union *address, int ifindex) {
227 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *req = NULL((void*)0), *reply = NULL((void*)0);
228 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
229 _cleanup_free___attribute__((cleanup(freep))) char *pretty = NULL((void*)0);
230 char ifname[IF_NAMESIZE16] = "";
231 uint64_t flags;
232 unsigned c = 0;
233 usec_t ts;
234 int r;
235
236 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 236
, __PRETTY_FUNCTION__); } while (0)
;
237 assert(IN_SET(family, AF_INET, AF_INET6))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){2, 10})/sizeof(int)]; switch(family) { case
2: case 10: _found = 1; break; default: break; } _found; }))
),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("IN_SET(family, AF_INET, AF_INET6)"
), "../src/resolve/resolvectl.c", 237, __PRETTY_FUNCTION__); }
while (0)
;
238 assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("address"), "../src/resolve/resolvectl.c"
, 238, __PRETTY_FUNCTION__); } while (0)
;
239
240 if (ifindex <= 0)
241 ifindex = arg_ifindex;
242
243 r = in_addr_ifindex_to_string(family, address, ifindex, &pretty);
244 if (r < 0)
245 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolvectl.c"
, 245, __func__)
;
246
247 if (ifindex > 0 && !if_indextoname(ifindex, ifname))
248 return log_error_errno(errno, "Failed to resolve interface name for index %i: %m", ifindex)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/resolve/resolvectl.c", 248, __func__
, "Failed to resolve interface name for index %i: %m", ifindex
) : -abs(_e); })
;
249
250 log_debug("Resolving %s%s%s.", pretty, isempty(ifname) ? "" : "%", ifname)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 250, __func__, "Resolving %s%s%s."
, pretty, isempty(ifname) ? "" : "%", ifname) : -abs(_e); })
;
251
252 r = sd_bus_message_new_method_call(
253 bus,
254 &req,
255 "org.freedesktop.resolve1",
256 "/org/freedesktop/resolve1",
257 "org.freedesktop.resolve1.Manager",
258 "ResolveAddress");
259 if (r < 0)
260 return bus_log_create_error(r);
261
262 r = sd_bus_message_append(req, "ii", ifindex, family);
263 if (r < 0)
264 return bus_log_create_error(r);
265
266 r = sd_bus_message_append_array(req, 'y', address, FAMILY_ADDRESS_SIZE(family));
267 if (r < 0)
268 return bus_log_create_error(r);
269
270 r = sd_bus_message_append(req, "t", arg_flags);
271 if (r < 0)
272 return bus_log_create_error(r);
273
274 ts = now(CLOCK_MONOTONIC1);
275
276 r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC(120 * ((usec_t) 1000000ULL)), &error, &reply);
277 if (r < 0)
278 return log_error_errno(r, "%s: resolve call failed: %s", pretty, bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 278, __func__, "%s: resolve call failed: %s"
, pretty, bus_error_message(&error, r)) : -abs(_e); })
;
279
280 ts = now(CLOCK_MONOTONIC1) - ts;
281
282 r = sd_bus_message_enter_container(reply, 'a', "(is)");
283 if (r < 0)
284 return bus_log_create_error(r);
285
286 while ((r = sd_bus_message_enter_container(reply, 'r', "is")) > 0) {
287 const char *n;
288
289 assert_cc(sizeof(int) == sizeof(int32_t))GCC diagnostic push ; GCC diagnostic ignored "-Wdeclaration-after-statement"
; struct _assert_struct_58 { char x[(sizeof(int) == sizeof(int32_t
)) ? 0 : -1]; }; GCC diagnostic pop
;
290
291 r = sd_bus_message_read(reply, "is", &ifindex, &n);
292 if (r < 0)
293 return r;
294
295 r = sd_bus_message_exit_container(reply);
296 if (r < 0)
297 return r;
298
299 ifname[0] = 0;
300 if (ifindex > 0 && !if_indextoname(ifindex, ifname))
301 log_warning_errno(errno, "Failed to resolve interface name for index %i: %m", ifindex)({ int _level = ((4)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/resolve/resolvectl.c", 301, __func__
, "Failed to resolve interface name for index %i: %m", ifindex
) : -abs(_e); })
;
302
303 printf("%*s%*s%*s%s %s\n",
304 (int) strlen(pretty), c == 0 ? pretty : "",
305 isempty(ifname) ? 0 : 1, c > 0 || isempty(ifname) ? "" : "%",
306 (int) strlen(ifname), c == 0 ? ifname : "",
307 c == 0 ? ":" : " ",
308 n);
309
310 c++;
311 }
312 if (r < 0)
313 return bus_log_parse_error(r);
314
315 r = sd_bus_message_exit_container(reply);
316 if (r < 0)
317 return bus_log_parse_error(r);
318
319 r = sd_bus_message_read(reply, "t", &flags);
320 if (r < 0)
321 return bus_log_parse_error(r);
322
323 if (c == 0) {
324 log_error("%s: no names found", pretty)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 324, __func__, "%s: no names found"
, pretty) : -abs(_e); })
;
325 return -ESRCH3;
326 }
327
328 print_source(flags, ts);
329
330 return 0;
331}
332
333static int output_rr_packet(const void *d, size_t l, int ifindex) {
334 _cleanup_(dns_resource_record_unrefp)__attribute__((cleanup(dns_resource_record_unrefp))) DnsResourceRecord *rr = NULL((void*)0);
335 _cleanup_(dns_packet_unrefp)__attribute__((cleanup(dns_packet_unrefp))) DnsPacket *p = NULL((void*)0);
336 int r;
337 char ifname[IF_NAMESIZE16] = "";
338
339 r = dns_packet_new(&p, DNS_PROTOCOL_DNS, 0, DNS_PACKET_SIZE_MAX0xFFFFu);
340 if (r < 0)
341 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolvectl.c"
, 341, __func__)
;
342
343 p->refuse_compression = true1;
344
345 r = dns_packet_append_blob(p, d, l, NULL((void*)0));
346 if (r < 0)
347 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolvectl.c"
, 347, __func__)
;
348
349 r = dns_packet_read_rr(p, &rr, NULL((void*)0), NULL((void*)0));
350 if (r < 0)
351 return log_error_errno(r, "Failed to parse RR: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 351, __func__, "Failed to parse RR: %m"
) : -abs(_e); })
;
352
353 if (arg_raw == RAW_PAYLOAD) {
354 void *data;
355 ssize_t k;
356
357 k = dns_resource_record_payload(rr, &data);
358 if (k < 0)
359 return log_error_errno(k, "Cannot dump RR: %m")({ int _level = ((3)), _e = ((k)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 359, __func__, "Cannot dump RR: %m"
) : -abs(_e); })
;
360 fwrite(data, 1, k, stdoutstdout);
361 } else {
362 const char *s;
363
364 s = dns_resource_record_to_string(rr);
365 if (!s)
366 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolvectl.c"
, 366, __func__)
;
367
368 if (ifindex > 0 && !if_indextoname(ifindex, ifname))
369 log_warning_errno(errno, "Failed to resolve interface name for index %i: %m", ifindex)({ int _level = ((4)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/resolve/resolvectl.c", 369, __func__
, "Failed to resolve interface name for index %i: %m", ifindex
) : -abs(_e); })
;
370
371 printf("%s%s%s\n", s, isempty(ifname) ? "" : " # interface ", ifname);
372 }
373
374 return 0;
375}
376
377static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_t type, bool_Bool warn_missing) {
378 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *req = NULL((void*)0), *reply = NULL((void*)0);
379 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
380 char ifname[IF_NAMESIZE16] = "";
381 unsigned n = 0;
382 uint64_t flags;
383 int r;
384 usec_t ts;
385 bool_Bool needs_authentication = false0;
386
387 assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("name"), "../src/resolve/resolvectl.c", 387
, __PRETTY_FUNCTION__); } while (0)
;
388
389 if (arg_ifindex > 0 && !if_indextoname(arg_ifindex, ifname))
390 return log_error_errno(errno, "Failed to resolve interface name for index %i: %m", arg_ifindex)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/resolve/resolvectl.c", 390, __func__
, "Failed to resolve interface name for index %i: %m", arg_ifindex
) : -abs(_e); })
;
391
392 log_debug("Resolving %s %s %s (interface %s).", name, dns_class_to_string(class), dns_type_to_string(type), isempty(ifname) ? "*" : ifname)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 392, __func__, "Resolving %s %s %s (interface %s)."
, name, dns_class_to_string(class), dns_type_to_string(type),
isempty(ifname) ? "*" : ifname) : -abs(_e); })
;
393
394 r = sd_bus_message_new_method_call(
395 bus,
396 &req,
397 "org.freedesktop.resolve1",
398 "/org/freedesktop/resolve1",
399 "org.freedesktop.resolve1.Manager",
400 "ResolveRecord");
401 if (r < 0)
402 return bus_log_create_error(r);
403
404 r = sd_bus_message_append(req, "isqqt", arg_ifindex, name, class, type, arg_flags);
405 if (r < 0)
406 return bus_log_create_error(r);
407
408 ts = now(CLOCK_MONOTONIC1);
409
410 r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC(120 * ((usec_t) 1000000ULL)), &error, &reply);
411 if (r < 0) {
412 if (warn_missing || r != -ENXIO6)
413 log_error("%s: resolve call failed: %s", name, bus_error_message(&error, r))({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 413, __func__, "%s: resolve call failed: %s"
, name, bus_error_message(&error, r)) : -abs(_e); })
;
414 return r;
415 }
416
417 ts = now(CLOCK_MONOTONIC1) - ts;
418
419 r = sd_bus_message_enter_container(reply, 'a', "(iqqay)");
420 if (r < 0)
421 return bus_log_parse_error(r);
422
423 while ((r = sd_bus_message_enter_container(reply, 'r', "iqqay")) > 0) {
424 uint16_t c, t;
425 int ifindex;
426 const void *d;
427 size_t l;
428
429 assert_cc(sizeof(int) == sizeof(int32_t))GCC diagnostic push ; GCC diagnostic ignored "-Wdeclaration-after-statement"
; struct _assert_struct_59 { char x[(sizeof(int) == sizeof(int32_t
)) ? 0 : -1]; }; GCC diagnostic pop
;
430
431 r = sd_bus_message_read(reply, "iqq", &ifindex, &c, &t);
432 if (r < 0)
433 return bus_log_parse_error(r);
434
435 r = sd_bus_message_read_array(reply, 'y', &d, &l);
436 if (r < 0)
437 return bus_log_parse_error(r);
438
439 r = sd_bus_message_exit_container(reply);
440 if (r < 0)
441 return bus_log_parse_error(r);
442
443 if (arg_raw == RAW_PACKET) {
444 uint64_t u64 = htole64(l);
445
446 fwrite(&u64, sizeof(u64), 1, stdoutstdout);
447 fwrite(d, 1, l, stdoutstdout);
448 } else {
449 r = output_rr_packet(d, l, ifindex);
450 if (r < 0)
451 return r;
452 }
453
454 if (dns_type_needs_authentication(t))
455 needs_authentication = true1;
456
457 n++;
458 }
459 if (r < 0)
460 return bus_log_parse_error(r);
461
462 r = sd_bus_message_exit_container(reply);
463 if (r < 0)
464 return bus_log_parse_error(r);
465
466 r = sd_bus_message_read(reply, "t", &flags);
467 if (r < 0)
468 return bus_log_parse_error(r);
469
470 if (n == 0) {
471 if (warn_missing)
472 log_error("%s: no records found", name)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 472, __func__, "%s: no records found"
, name) : -abs(_e); })
;
473 return -ESRCH3;
474 }
475
476 print_source(flags, ts);
477
478 if ((flags & SD_RESOLVED_AUTHENTICATED(1UL << 9)) == 0 && needs_authentication) {
479 fflush(stdoutstdout);
480
481 fprintf(stderrstderr, "\n%s"
482 "WARNING: The resources shown contain cryptographic key data which could not be\n"
483 " authenticated. It is not suitable to authenticate any communication.\n"
484 " This is usually indication that DNSSEC authentication was not enabled\n"
485 " or is not available for the selected protocol or DNS servers.%s\n",
486 ansi_highlight_red(),
487 ansi_normal());
488 }
489
490 return 0;
491}
492
493static int resolve_rfc4501(sd_bus *bus, const char *name) {
494 uint16_t type = 0, class = 0;
495 const char *p, *q, *n;
496 int r;
497
498 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 498
, __PRETTY_FUNCTION__); } while (0)
;
499 assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("name"), "../src/resolve/resolvectl.c", 499
, __PRETTY_FUNCTION__); } while (0)
;
500 assert(startswith(name, "dns:"))do { if ((__builtin_expect(!!(!(startswith(name, "dns:"))),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("startswith(name, \"dns:\")"
), "../src/resolve/resolvectl.c", 500, __PRETTY_FUNCTION__); }
while (0)
;
501
502 /* Parse RFC 4501 dns: URIs */
503
504 p = name + 4;
505
506 if (p[0] == '/') {
507 const char *e;
508
509 if (p[1] != '/')
510 goto invalid;
511
512 e = strchr(p + 2, '/');
513 if (!e)
514 goto invalid;
515
516 if (e != p + 2)
517 log_warning("DNS authority specification not supported; ignoring specified authority.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 517, __func__, "DNS authority specification not supported; ignoring specified authority."
) : -abs(_e); })
;
518
519 p = e + 1;
520 }
521
522 q = strchr(p, '?');
523 if (q) {
524 n = strndupa(p, q - p)(__extension__ ({ const char *__old = (p); size_t __len = strnlen
(__old, (q - p)); char *__new = (char *) __builtin_alloca (__len
+ 1); __new[__len] = '\0'; (char *) memcpy (__new, __old, __len
); }))
;
525 q++;
526
527 for (;;) {
528 const char *f;
529
530 f = startswith_no_case(q, "class=");
531 if (f) {
532 _cleanup_free___attribute__((cleanup(freep))) char *t = NULL((void*)0);
533 const char *e;
534
535 if (class != 0) {
536 log_error("DNS class specified twice.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 536, __func__, "DNS class specified twice."
) : -abs(_e); })
;
537 return -EINVAL22;
538 }
539
540 e = strchrnul(f, ';');
541 t = strndup(f, e - f);
542 if (!t)
543 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolvectl.c"
, 543, __func__)
;
544
545 r = dns_class_from_string(t);
546 if (r < 0) {
547 log_error("Unknown DNS class %s.", t)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 547, __func__, "Unknown DNS class %s."
, t) : -abs(_e); })
;
548 return -EINVAL22;
549 }
550
551 class = r;
552
553 if (*e == ';') {
554 q = e + 1;
555 continue;
556 }
557
558 break;
559 }
560
561 f = startswith_no_case(q, "type=");
562 if (f) {
563 _cleanup_free___attribute__((cleanup(freep))) char *t = NULL((void*)0);
564 const char *e;
565
566 if (type != 0) {
567 log_error("DNS type specified twice.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 567, __func__, "DNS type specified twice."
) : -abs(_e); })
;
568 return -EINVAL22;
569 }
570
571 e = strchrnul(f, ';');
572 t = strndup(f, e - f);
573 if (!t)
574 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolvectl.c"
, 574, __func__)
;
575
576 r = dns_type_from_string(t);
577 if (r < 0) {
578 log_error("Unknown DNS type %s.", t)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 578, __func__, "Unknown DNS type %s."
, t) : -abs(_e); })
;
579 return -EINVAL22;
580 }
581
582 type = r;
583
584 if (*e == ';') {
585 q = e + 1;
586 continue;
587 }
588
589 break;
590 }
591
592 goto invalid;
593 }
594 } else
595 n = p;
596
597 if (class == 0)
598 class = arg_class ?: DNS_CLASS_IN;
599 if (type == 0)
600 type = arg_type ?: DNS_TYPE_A;
601
602 return resolve_record(bus, n, class, type, true1);
603
604invalid:
605 log_error("Invalid DNS URI: %s", name)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 605, __func__, "Invalid DNS URI: %s"
, name) : -abs(_e); })
;
606 return -EINVAL22;
607}
608
609static int verb_query(int argc, char **argv, void *userdata) {
610 sd_bus *bus = userdata;
611 char **p;
612 int q, r = 0;
613
614 if (arg_type != 0)
615 STRV_FOREACH(p, argv + 1)for ((p) = (argv + 1); (p) && *(p); (p)++) {
616 q = resolve_record(bus, *p, arg_class, arg_type, true1);
617 if (q < 0)
618 r = q;
619 }
620
621 else
622 STRV_FOREACH(p, argv + 1)for ((p) = (argv + 1); (p) && *(p); (p)++) {
623 if (startswith(*p, "dns:"))
624 q = resolve_rfc4501(bus, *p);
625 else {
626 int family, ifindex;
627 union in_addr_union a;
628
629 q = in_addr_ifindex_from_string_auto(*p, &family, &a, &ifindex);
630 if (q >= 0)
631 q = resolve_address(bus, family, &a, ifindex);
632 else
633 q = resolve_host(bus, *p);
634 }
635 if (q < 0)
636 r = q;
637 }
638
639 return r;
640}
641
642static int resolve_service(sd_bus *bus, const char *name, const char *type, const char *domain) {
643 const char *canonical_name, *canonical_type, *canonical_domain;
644 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *req = NULL((void*)0), *reply = NULL((void*)0);
645 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
646 char ifname[IF_NAMESIZE16] = "";
647 size_t indent, sz;
648 uint64_t flags;
649 const char *p;
650 unsigned c;
651 usec_t ts;
652 int r;
653
654 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 654
, __PRETTY_FUNCTION__); } while (0)
;
655 assert(domain)do { if ((__builtin_expect(!!(!(domain)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("domain"), "../src/resolve/resolvectl.c"
, 655, __PRETTY_FUNCTION__); } while (0)
;
656
657 name = empty_to_null(name);
658 type = empty_to_null(type);
659
660 if (arg_ifindex > 0 && !if_indextoname(arg_ifindex, ifname))
661 return log_error_errno(errno, "Failed to resolve interface name for index %i: %m", arg_ifindex)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/resolve/resolvectl.c", 661, __func__
, "Failed to resolve interface name for index %i: %m", arg_ifindex
) : -abs(_e); })
;
662
663 if (name)
664 log_debug("Resolving service \"%s\" of type %s in %s (family %s, interface %s).", name, type, domain, af_to_name(arg_family) ?: "*", isempty(ifname) ? "*" : ifname)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 664, __func__, "Resolving service \"%s\" of type %s in %s (family %s, interface %s)."
, name, type, domain, af_to_name(arg_family) ?: "*", isempty(
ifname) ? "*" : ifname) : -abs(_e); })
;
665 else if (type)
666 log_debug("Resolving service type %s of %s (family %s, interface %s).", type, domain, af_to_name(arg_family) ?: "*", isempty(ifname) ? "*" : ifname)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 666, __func__, "Resolving service type %s of %s (family %s, interface %s)."
, type, domain, af_to_name(arg_family) ?: "*", isempty(ifname
) ? "*" : ifname) : -abs(_e); })
;
667 else
668 log_debug("Resolving service type %s (family %s, interface %s).", domain, af_to_name(arg_family) ?: "*", isempty(ifname) ? "*" : ifname)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 668, __func__, "Resolving service type %s (family %s, interface %s)."
, domain, af_to_name(arg_family) ?: "*", isempty(ifname) ? "*"
: ifname) : -abs(_e); })
;
669
670 r = sd_bus_message_new_method_call(
671 bus,
672 &req,
673 "org.freedesktop.resolve1",
674 "/org/freedesktop/resolve1",
675 "org.freedesktop.resolve1.Manager",
676 "ResolveService");
677 if (r < 0)
678 return bus_log_create_error(r);
679
680 r = sd_bus_message_append(req, "isssit", arg_ifindex, name, type, domain, arg_family, arg_flags);
681 if (r < 0)
682 return bus_log_create_error(r);
683
684 ts = now(CLOCK_MONOTONIC1);
685
686 r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC(120 * ((usec_t) 1000000ULL)), &error, &reply);
687 if (r < 0)
688 return log_error_errno(r, "Resolve call failed: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 688, __func__, "Resolve call failed: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
689
690 ts = now(CLOCK_MONOTONIC1) - ts;
691
692 r = sd_bus_message_enter_container(reply, 'a', "(qqqsa(iiay)s)");
693 if (r < 0)
694 return bus_log_parse_error(r);
695
696 indent =
697 (name ? strlen(name) + 1 : 0) +
698 (type ? strlen(type) + 1 : 0) +
699 strlen(domain) + 2;
700
701 c = 0;
702 while ((r = sd_bus_message_enter_container(reply, 'r', "qqqsa(iiay)s")) > 0) {
703 uint16_t priority, weight, port;
704 const char *hostname, *canonical;
705
706 r = sd_bus_message_read(reply, "qqqs", &priority, &weight, &port, &hostname);
707 if (r < 0)
708 return bus_log_parse_error(r);
709
710 if (name)
711 printf("%*s%s", (int) strlen(name), c == 0 ? name : "", c == 0 ? "/" : " ");
712 if (type)
713 printf("%*s%s", (int) strlen(type), c == 0 ? type : "", c == 0 ? "/" : " ");
714
715 printf("%*s%s %s:%u [priority=%u, weight=%u]\n",
716 (int) strlen(domain), c == 0 ? domain : "",
717 c == 0 ? ":" : " ",
718 hostname, port,
719 priority, weight);
720
721 r = sd_bus_message_enter_container(reply, 'a', "(iiay)");
722 if (r < 0)
723 return bus_log_parse_error(r);
724
725 while ((r = sd_bus_message_enter_container(reply, 'r', "iiay")) > 0) {
726 _cleanup_free___attribute__((cleanup(freep))) char *pretty = NULL((void*)0);
727 int ifindex, family;
728 const void *a;
729
730 assert_cc(sizeof(int) == sizeof(int32_t))GCC diagnostic push ; GCC diagnostic ignored "-Wdeclaration-after-statement"
; struct _assert_struct_60 { char x[(sizeof(int) == sizeof(int32_t
)) ? 0 : -1]; }; GCC diagnostic pop
;
731
732 r = sd_bus_message_read(reply, "ii", &ifindex, &family);
733 if (r < 0)
734 return bus_log_parse_error(r);
735
736 r = sd_bus_message_read_array(reply, 'y', &a, &sz);
737 if (r < 0)
738 return bus_log_parse_error(r);
739
740 r = sd_bus_message_exit_container(reply);
741 if (r < 0)
742 return bus_log_parse_error(r);
743
744 if (!IN_SET(family, AF_INET, AF_INET6)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){2, 10})/sizeof(int)]; switch(family) { case
2: case 10: _found = 1; break; default: break; } _found; })
) {
745 log_debug("%s: skipping entry with family %d (%s)", name, family, af_to_name(family) ?: "unknown")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 745, __func__, "%s: skipping entry with family %d (%s)"
, name, family, af_to_name(family) ?: "unknown") : -abs(_e); }
)
;
746 continue;
747 }
748
749 if (sz != FAMILY_ADDRESS_SIZE(family)) {
750 log_error("%s: systemd-resolved returned address of invalid size %zu for family %s", name, sz, af_to_name(family) ?: "unknown")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 750, __func__, "%s: systemd-resolved returned address of invalid size %zu for family %s"
, name, sz, af_to_name(family) ?: "unknown") : -abs(_e); })
;
751 return -EINVAL22;
752 }
753
754 ifname[0] = 0;
755 if (ifindex > 0 && !if_indextoname(ifindex, ifname))
756 log_warning_errno(errno, "Failed to resolve interface name for index %i: %m", ifindex)({ int _level = ((4)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/resolve/resolvectl.c", 756, __func__
, "Failed to resolve interface name for index %i: %m", ifindex
) : -abs(_e); })
;
757
758 r = in_addr_to_string(family, a, &pretty);
759 if (r < 0)
760 return log_error_errno(r, "Failed to print address for %s: %m", name)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 760, __func__, "Failed to print address for %s: %m"
, name) : -abs(_e); })
;
761
762 printf("%*s%s%s%s\n", (int) indent, "", pretty, isempty(ifname) ? "" : "%s", ifname);
763 }
764 if (r < 0)
765 return bus_log_parse_error(r);
766
767 r = sd_bus_message_exit_container(reply);
768 if (r < 0)
769 return bus_log_parse_error(r);
770
771 r = sd_bus_message_read(reply, "s", &canonical);
772 if (r < 0)
773 return bus_log_parse_error(r);
774
775 if (!streq(hostname, canonical)(strcmp((hostname),(canonical)) == 0))
776 printf("%*s(%s)\n", (int) indent, "", canonical);
777
778 r = sd_bus_message_exit_container(reply);
779 if (r < 0)
780 return bus_log_parse_error(r);
781
782 c++;
783 }
784 if (r < 0)
785 return bus_log_parse_error(r);
786
787 r = sd_bus_message_exit_container(reply);
788 if (r < 0)
789 return bus_log_parse_error(r);
790
791 r = sd_bus_message_enter_container(reply, 'a', "ay");
792 if (r < 0)
793 return bus_log_parse_error(r);
794
795 while ((r = sd_bus_message_read_array(reply, 'y', (const void**) &p, &sz)) > 0) {
796 _cleanup_free___attribute__((cleanup(freep))) char *escaped = NULL((void*)0);
797
798 escaped = cescape_length(p, sz);
799 if (!escaped)
800 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolvectl.c"
, 800, __func__)
;
801
802 printf("%*s%s\n", (int) indent, "", escaped);
803 }
804 if (r < 0)
805 return bus_log_parse_error(r);
806
807 r = sd_bus_message_exit_container(reply);
808 if (r < 0)
809 return bus_log_parse_error(r);
810
811 r = sd_bus_message_read(reply, "ssst", &canonical_name, &canonical_type, &canonical_domain, &flags);
812 if (r < 0)
813 return bus_log_parse_error(r);
814
815 canonical_name = empty_to_null(canonical_name);
816 canonical_type = empty_to_null(canonical_type);
817
818 if (!streq_ptr(name, canonical_name) ||
819 !streq_ptr(type, canonical_type) ||
820 !streq_ptr(domain, canonical_domain)) {
821
822 printf("%*s(", (int) indent, "");
823
824 if (canonical_name)
825 printf("%s/", canonical_name);
826 if (canonical_type)
827 printf("%s/", canonical_type);
828
829 printf("%s)\n", canonical_domain);
830 }
831
832 print_source(flags, ts);
833
834 return 0;
835}
836
837static int verb_service(int argc, char **argv, void *userdata) {
838 sd_bus *bus = userdata;
839
840 if (argc == 2)
841 return resolve_service(bus, NULL((void*)0), NULL((void*)0), argv[1]);
842 else if (argc == 3)
843 return resolve_service(bus, NULL((void*)0), argv[1], argv[2]);
844 else
845 return resolve_service(bus, argv[1], argv[2], argv[3]);
846}
847
848static int resolve_openpgp(sd_bus *bus, const char *address) {
849 const char *domain, *full;
850 int r;
851 _cleanup_free___attribute__((cleanup(freep))) char *hashed = NULL((void*)0);
852
853 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 853
, __PRETTY_FUNCTION__); } while (0)
;
854 assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("address"), "../src/resolve/resolvectl.c"
, 854, __PRETTY_FUNCTION__); } while (0)
;
855
856 domain = strrchr(address, '@');
857 if (!domain) {
858 log_error("Address does not contain '@': \"%s\"", address)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 858, __func__, "Address does not contain '@': \"%s\""
, address) : -abs(_e); })
;
859 return -EINVAL22;
860 } else if (domain == address || domain[1] == '\0') {
861 log_error("Address starts or ends with '@': \"%s\"", address)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 861, __func__, "Address starts or ends with '@': \"%s\""
, address) : -abs(_e); })
;
862 return -EINVAL22;
863 }
864 domain++;
865
866 r = string_hashsum_sha256(address, domain - 1 - address, &hashed);
867 if (r < 0)
868 return log_error_errno(r, "Hashing failed: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 868, __func__, "Hashing failed: %m"
) : -abs(_e); })
;
869
870 strshorten(hashed, 56);
871
872 full = strjoina(hashed, "._openpgpkey.", domain)({ const char *_appendees_[] = { hashed, "._openpgpkey.", domain
}; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ =
0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
873 log_debug("Looking up \"%s\".", full)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 873, __func__, "Looking up \"%s\"."
, full) : -abs(_e); })
;
874
875 r = resolve_record(bus, full,
876 arg_class ?: DNS_CLASS_IN,
877 arg_type ?: DNS_TYPE_OPENPGPKEY, false0);
878
879 if (IN_SET(r, -ENXIO, -ESRCH)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){-6, -3})/sizeof(int)]; switch(r) { case -
6: case -3: _found = 1; break; default: break; } _found; })
) { /* NXDOMAIN or NODATA? */
880 hashed = NULL((void*)0);
881 r = string_hashsum_sha224(address, domain - 1 - address, &hashed);
882 if (r < 0)
883 return log_error_errno(r, "Hashing failed: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 883, __func__, "Hashing failed: %m"
) : -abs(_e); })
;
884
885 full = strjoina(hashed, "._openpgpkey.", domain)({ const char *_appendees_[] = { hashed, "._openpgpkey.", domain
}; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ =
0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
886 log_debug("Looking up \"%s\".", full)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 886, __func__, "Looking up \"%s\"."
, full) : -abs(_e); })
;
887
888 return resolve_record(bus, full,
889 arg_class ?: DNS_CLASS_IN,
890 arg_type ?: DNS_TYPE_OPENPGPKEY, true1);
891 }
892
893 return r;
894}
895
896static int verb_openpgp(int argc, char **argv, void *userdata) {
897 sd_bus *bus = userdata;
898 char **p;
899 int q, r = 0;
900
901 STRV_FOREACH(p, argv + 1)for ((p) = (argv + 1); (p) && *(p); (p)++) {
902 q = resolve_openpgp(bus, *p);
903 if (q < 0)
904 r = q;
905 }
906
907 return r;
908}
909
910static int resolve_tlsa(sd_bus *bus, const char *family, const char *address) {
911 const char *port;
912 uint16_t port_num = 443;
913 _cleanup_free___attribute__((cleanup(freep))) char *full = NULL((void*)0);
914 int r;
915
916 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 916
, __PRETTY_FUNCTION__); } while (0)
;
917 assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("address"), "../src/resolve/resolvectl.c"
, 917, __PRETTY_FUNCTION__); } while (0)
;
918
919 port = strrchr(address, ':');
920 if (port) {
921 r = parse_ip_port(port + 1, &port_num);
922 if (r < 0)
923 return log_error_errno(r, "Invalid port \"%s\".", port + 1)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 923, __func__, "Invalid port \"%s\"."
, port + 1) : -abs(_e); })
;
924
925 address = strndupa(address, port - address)(__extension__ ({ const char *__old = (address); size_t __len
= strnlen (__old, (port - address)); char *__new = (char *) __builtin_alloca
(__len + 1); __new[__len] = '\0'; (char *) memcpy (__new, __old
, __len); }))
;
926 }
927
928 r = asprintf(&full, "_%u._%s.%s",
929 port_num,
930 family,
931 address);
932 if (r < 0)
933 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolvectl.c"
, 933, __func__)
;
934
935 log_debug("Looking up \"%s\".", full)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 935, __func__, "Looking up \"%s\"."
, full) : -abs(_e); })
;
936
937 return resolve_record(bus, full,
938 arg_class ?: DNS_CLASS_IN,
939 arg_type ?: DNS_TYPE_TLSA, true1);
940}
941
942static bool_Bool service_family_is_valid(const char *s) {
943 return STR_IN_SET(s, "tcp", "udp", "sctp")(!!strv_find((((char**) ((const char*[]) { "tcp", "udp", "sctp"
, ((void*)0) }))), (s)))
;
944}
945
946static int verb_tlsa(int argc, char **argv, void *userdata) {
947 sd_bus *bus = userdata;
948 char **p, **args = argv + 1;
949 const char *family = "tcp";
950 int q, r = 0;
951
952 if (service_family_is_valid(argv[1])) {
953 family = argv[1];
954 args++;
955 }
956
957 STRV_FOREACH(p, args)for ((p) = (args); (p) && *(p); (p)++) {
958 q = resolve_tlsa(bus, family, *p);
959 if (q < 0)
960 r = q;
961 }
962
963 return r;
964}
965
966static int show_statistics(int argc, char **argv, void *userdata) {
967 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
968 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *reply = NULL((void*)0);
969 sd_bus *bus = userdata;
970 uint64_t n_current_transactions, n_total_transactions,
971 cache_size, n_cache_hit, n_cache_miss,
972 n_dnssec_secure, n_dnssec_insecure, n_dnssec_bogus, n_dnssec_indeterminate;
973 int r, dnssec_supported;
974
975 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 975
, __PRETTY_FUNCTION__); } while (0)
;
976
977 r = sd_bus_get_property_trivial(bus,
978 "org.freedesktop.resolve1",
979 "/org/freedesktop/resolve1",
980 "org.freedesktop.resolve1.Manager",
981 "DNSSECSupported",
982 &error,
983 'b',
984 &dnssec_supported);
985 if (r < 0)
986 return log_error_errno(r, "Failed to get DNSSEC supported state: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 986, __func__, "Failed to get DNSSEC supported state: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
987
988 printf("DNSSEC supported by current servers: %s%s%s\n\n",
989 ansi_highlight(),
990 yes_no(dnssec_supported),
991 ansi_normal());
992
993 r = sd_bus_get_property(bus,
994 "org.freedesktop.resolve1",
995 "/org/freedesktop/resolve1",
996 "org.freedesktop.resolve1.Manager",
997 "TransactionStatistics",
998 &error,
999 &reply,
1000 "(tt)");
1001 if (r < 0)
1002 return log_error_errno(r, "Failed to get transaction statistics: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1002, __func__, "Failed to get transaction statistics: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
1003
1004 r = sd_bus_message_read(reply, "(tt)",
1005 &n_current_transactions,
1006 &n_total_transactions);
1007 if (r < 0)
1008 return bus_log_parse_error(r);
1009
1010 printf("%sTransactions%s\n"
1011 "Current Transactions: %" PRIu64"l" "u" "\n"
1012 " Total Transactions: %" PRIu64"l" "u" "\n",
1013 ansi_highlight(),
1014 ansi_normal(),
1015 n_current_transactions,
1016 n_total_transactions);
1017
1018 reply = sd_bus_message_unref(reply);
1019
1020 r = sd_bus_get_property(bus,
1021 "org.freedesktop.resolve1",
1022 "/org/freedesktop/resolve1",
1023 "org.freedesktop.resolve1.Manager",
1024 "CacheStatistics",
1025 &error,
1026 &reply,
1027 "(ttt)");
1028 if (r < 0)
1029 return log_error_errno(r, "Failed to get cache statistics: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1029, __func__, "Failed to get cache statistics: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
1030
1031 r = sd_bus_message_read(reply, "(ttt)",
1032 &cache_size,
1033 &n_cache_hit,
1034 &n_cache_miss);
1035 if (r < 0)
1036 return bus_log_parse_error(r);
1037
1038 printf("\n%sCache%s\n"
1039 " Current Cache Size: %" PRIu64"l" "u" "\n"
1040 " Cache Hits: %" PRIu64"l" "u" "\n"
1041 " Cache Misses: %" PRIu64"l" "u" "\n",
1042 ansi_highlight(),
1043 ansi_normal(),
1044 cache_size,
1045 n_cache_hit,
1046 n_cache_miss);
1047
1048 reply = sd_bus_message_unref(reply);
1049
1050 r = sd_bus_get_property(bus,
1051 "org.freedesktop.resolve1",
1052 "/org/freedesktop/resolve1",
1053 "org.freedesktop.resolve1.Manager",
1054 "DNSSECStatistics",
1055 &error,
1056 &reply,
1057 "(tttt)");
1058 if (r < 0)
1059 return log_error_errno(r, "Failed to get DNSSEC statistics: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1059, __func__, "Failed to get DNSSEC statistics: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
1060
1061 r = sd_bus_message_read(reply, "(tttt)",
1062 &n_dnssec_secure,
1063 &n_dnssec_insecure,
1064 &n_dnssec_bogus,
1065 &n_dnssec_indeterminate);
1066 if (r < 0)
1067 return bus_log_parse_error(r);
1068
1069 printf("\n%sDNSSEC Verdicts%s\n"
1070 " Secure: %" PRIu64"l" "u" "\n"
1071 " Insecure: %" PRIu64"l" "u" "\n"
1072 " Bogus: %" PRIu64"l" "u" "\n"
1073 " Indeterminate: %" PRIu64"l" "u" "\n",
1074 ansi_highlight(),
1075 ansi_normal(),
1076 n_dnssec_secure,
1077 n_dnssec_insecure,
1078 n_dnssec_bogus,
1079 n_dnssec_indeterminate);
1080
1081 return 0;
1082}
1083
1084static int reset_statistics(int argc, char **argv, void *userdata) {
1085 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
1086 sd_bus *bus = userdata;
1087 int r;
1088
1089 r = sd_bus_call_method(bus,
1090 "org.freedesktop.resolve1",
1091 "/org/freedesktop/resolve1",
1092 "org.freedesktop.resolve1.Manager",
1093 "ResetStatistics",
1094 &error,
1095 NULL((void*)0),
1096 NULL((void*)0));
1097 if (r < 0)
1098 return log_error_errno(r, "Failed to reset statistics: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1098, __func__, "Failed to reset statistics: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
1099
1100 return 0;
1101}
1102
1103static int flush_caches(int argc, char **argv, void *userdata) {
1104 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
1105 sd_bus *bus = userdata;
1106 int r;
1107
1108 r = sd_bus_call_method(bus,
1109 "org.freedesktop.resolve1",
1110 "/org/freedesktop/resolve1",
1111 "org.freedesktop.resolve1.Manager",
1112 "FlushCaches",
1113 &error,
1114 NULL((void*)0),
1115 NULL((void*)0));
1116 if (r < 0)
1117 return log_error_errno(r, "Failed to flush caches: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1117, __func__, "Failed to flush caches: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
1118
1119 return 0;
1120}
1121
1122static int reset_server_features(int argc, char **argv, void *userdata) {
1123 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
1124 sd_bus *bus = userdata;
1125 int r;
1126
1127 r = sd_bus_call_method(bus,
1128 "org.freedesktop.resolve1",
1129 "/org/freedesktop/resolve1",
1130 "org.freedesktop.resolve1.Manager",
1131 "ResetServerFeatures",
1132 &error,
1133 NULL((void*)0),
1134 NULL((void*)0));
1135 if (r < 0)
1136 return log_error_errno(r, "Failed to reset server features: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1136, __func__, "Failed to reset server features: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
1137
1138 return 0;
1139}
1140
1141static int read_dns_server_one(sd_bus_message *m, bool_Bool with_ifindex, char **ret) {
1142 _cleanup_free___attribute__((cleanup(freep))) char *pretty = NULL((void*)0);
1143 int ifindex, family, r;
1144 const void *a;
1145 size_t sz;
1146
1147 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/resolve/resolvectl.c", 1147
, __PRETTY_FUNCTION__); } while (0)
;
1148 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/resolve/resolvectl.c", 1148
, __PRETTY_FUNCTION__); } while (0)
;
1149
1150 r = sd_bus_message_enter_container(m, 'r', with_ifindex ? "iiay" : "iay");
1151 if (r <= 0)
1152 return r;
1153
1154 if (with_ifindex) {
1155 r = sd_bus_message_read(m, "i", &ifindex);
1156 if (r < 0)
1157 return r;
1158 }
1159
1160 r = sd_bus_message_read(m, "i", &family);
1161 if (r < 0)
1162 return r;
1163
1164 r = sd_bus_message_read_array(m, 'y', &a, &sz);
1165 if (r < 0)
1166 return r;
1167
1168 r = sd_bus_message_exit_container(m);
1169 if (r < 0)
1170 return r;
1171
1172 if (with_ifindex && ifindex != 0) {
1173 /* only show the global ones here */
1174 *ret = NULL((void*)0);
1175 return 1;
1176 }
1177
1178 if (!IN_SET(family, AF_INET, AF_INET6)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){2, 10})/sizeof(int)]; switch(family) { case
2: case 10: _found = 1; break; default: break; } _found; })
) {
1179 log_debug("Unexpected family, ignoring: %i", family)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1179, __func__, "Unexpected family, ignoring: %i"
, family) : -abs(_e); })
;
1180
1181 *ret = NULL((void*)0);
1182 return 1;
1183 }
1184
1185 if (sz != FAMILY_ADDRESS_SIZE(family)) {
1186 log_debug("Address size mismatch, ignoring.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1186, __func__, "Address size mismatch, ignoring."
) : -abs(_e); })
;
1187
1188 *ret = NULL((void*)0);
1189 return 1;
1190 }
1191
1192 r = in_addr_to_string(family, a, &pretty);
1193 if (r < 0)
1194 return r;
1195
1196 *ret = TAKE_PTR(pretty)({ typeof(pretty) _ptr_ = (pretty); (pretty) = ((void*)0); _ptr_
; })
;
1197
1198 return 1;
1199}
1200
1201static int map_link_dns_servers(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
1202 char ***l = userdata;
1203 int r;
1204
1205 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 1205
, __PRETTY_FUNCTION__); } while (0)
;
1206 assert(member)do { if ((__builtin_expect(!!(!(member)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("member"), "../src/resolve/resolvectl.c"
, 1206, __PRETTY_FUNCTION__); } while (0)
;
1207 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/resolve/resolvectl.c", 1207
, __PRETTY_FUNCTION__); } while (0)
;
1208 assert(l)do { if ((__builtin_expect(!!(!(l)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("l"), "../src/resolve/resolvectl.c", 1208
, __PRETTY_FUNCTION__); } while (0)
;
1209
1210 r = sd_bus_message_enter_container(m, 'a', "(iay)");
1211 if (r < 0)
1212 return r;
1213
1214 for (;;) {
1215 char *pretty = NULL((void*)0);
1216
1217 r = read_dns_server_one(m, false0, &pretty);
1218 if (r < 0)
1219 return r;
1220 if (r == 0)
1221 break;
1222
1223 if (isempty(pretty))
1224 continue;
1225
1226 r = strv_consume(l, pretty);
1227 if (r < 0)
1228 return r;
1229 }
1230
1231 r = sd_bus_message_exit_container(m);
1232 if (r < 0)
1233 return r;
1234
1235 return 0;
1236}
1237
1238static int map_link_current_dns_server(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
1239 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/resolve/resolvectl.c", 1239
, __PRETTY_FUNCTION__); } while (0)
;
1240 assert(userdata)do { if ((__builtin_expect(!!(!(userdata)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("userdata"), "../src/resolve/resolvectl.c"
, 1240, __PRETTY_FUNCTION__); } while (0)
;
1241
1242 return read_dns_server_one(m, false0, userdata);
1243}
1244
1245static int read_domain_one(sd_bus_message *m, bool_Bool with_ifindex, char **ret) {
1246 _cleanup_free___attribute__((cleanup(freep))) char *str = NULL((void*)0);
1247 int ifindex, route_only, r;
1248 const char *domain;
1249
1250 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/resolve/resolvectl.c", 1250
, __PRETTY_FUNCTION__); } while (0)
;
1251 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/resolve/resolvectl.c", 1251
, __PRETTY_FUNCTION__); } while (0)
;
1252
1253 if (with_ifindex)
1254 r = sd_bus_message_read(m, "(isb)", &ifindex, &domain, &route_only);
1255 else
1256 r = sd_bus_message_read(m, "(sb)", &domain, &route_only);
1257 if (r <= 0)
1258 return r;
1259
1260 if (with_ifindex && ifindex != 0) {
1261 /* only show the global ones here */
1262 *ret = NULL((void*)0);
1263 return 1;
1264 }
1265
1266 if (route_only)
1267 str = strappend("~", domain);
1268 else
1269 str = strdup(domain);
1270 if (!str)
1271 return -ENOMEM12;
1272
1273 *ret = TAKE_PTR(str)({ typeof(str) _ptr_ = (str); (str) = ((void*)0); _ptr_; });
1274
1275 return 1;
1276}
1277
1278static int map_link_domains(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
1279 char ***l = userdata;
1280 int r;
1281
1282 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 1282
, __PRETTY_FUNCTION__); } while (0)
;
1283 assert(member)do { if ((__builtin_expect(!!(!(member)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("member"), "../src/resolve/resolvectl.c"
, 1283, __PRETTY_FUNCTION__); } while (0)
;
1284 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/resolve/resolvectl.c", 1284
, __PRETTY_FUNCTION__); } while (0)
;
1285 assert(l)do { if ((__builtin_expect(!!(!(l)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("l"), "../src/resolve/resolvectl.c", 1285
, __PRETTY_FUNCTION__); } while (0)
;
1286
1287 r = sd_bus_message_enter_container(m, 'a', "(sb)");
1288 if (r < 0)
1289 return r;
1290
1291 for (;;) {
1292 char *pretty = NULL((void*)0);
1293
1294 r = read_domain_one(m, false0, &pretty);
1295 if (r < 0)
1296 return r;
1297 if (r == 0)
1298 break;
1299
1300 if (isempty(pretty))
1301 continue;
1302
1303 r = strv_consume(l, pretty);
1304 if (r < 0)
1305 return r;
1306 }
1307
1308 r = sd_bus_message_exit_container(m);
1309 if (r < 0)
1310 return r;
1311
1312 return 0;
1313}
1314
1315static int status_print_strv_ifindex(int ifindex, const char *ifname, char **p) {
1316 char **i;
1317
1318 printf("%sLink %i (%s)%s:",
1319 ansi_highlight(), ifindex, ifname, ansi_normal());
1320
1321 STRV_FOREACH(i, p)for ((i) = (p); (i) && *(i); (i)++)
1322 printf(" %s", *i);
1323
1324 printf("\n");
1325
1326 return 0;
1327}
1328
1329static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode mode, bool_Bool *empty_line) {
1330
1331 struct link_info {
1332 uint64_t scopes_mask;
1333 const char *llmnr;
1334 const char *mdns;
1335 const char *dns_over_tls;
1336 const char *dnssec;
1337 char *current_dns;
1338 char **dns;
1339 char **domains;
1340 char **ntas;
1341 bool_Bool dnssec_supported;
1342 } link_info = {};
1343
1344 static const struct bus_properties_map property_map[] = {
1345 { "ScopesMask", "t", NULL((void*)0), offsetof(struct link_info, scopes_mask)__builtin_offsetof(struct link_info, scopes_mask) },
1346 { "DNS", "a(iay)", map_link_dns_servers, offsetof(struct link_info, dns)__builtin_offsetof(struct link_info, dns) },
1347 { "CurrentDNSServer", "(iay)", map_link_current_dns_server, offsetof(struct link_info, current_dns)__builtin_offsetof(struct link_info, current_dns) },
1348 { "Domains", "a(sb)", map_link_domains, offsetof(struct link_info, domains)__builtin_offsetof(struct link_info, domains) },
1349 { "LLMNR", "s", NULL((void*)0), offsetof(struct link_info, llmnr)__builtin_offsetof(struct link_info, llmnr) },
1350 { "MulticastDNS", "s", NULL((void*)0), offsetof(struct link_info, mdns)__builtin_offsetof(struct link_info, mdns) },
1351 { "DNSOverTLS", "s", NULL((void*)0), offsetof(struct link_info, dns_over_tls)__builtin_offsetof(struct link_info, dns_over_tls) },
1352 { "DNSSEC", "s", NULL((void*)0), offsetof(struct link_info, dnssec)__builtin_offsetof(struct link_info, dnssec) },
1353 { "DNSSECNegativeTrustAnchors", "as", NULL((void*)0), offsetof(struct link_info, ntas)__builtin_offsetof(struct link_info, ntas) },
1354 { "DNSSECSupported", "b", NULL((void*)0), offsetof(struct link_info, dnssec_supported)__builtin_offsetof(struct link_info, dnssec_supported) },
1355 {}
1356 };
1357
1358 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
1359 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *m = NULL((void*)0);
1360 _cleanup_free___attribute__((cleanup(freep))) char *ifi = NULL((void*)0), *p = NULL((void*)0);
1361 char ifname[IF_NAMESIZE16] = "";
1362 char **i;
1363 int r;
1364
1365 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 1365
, __PRETTY_FUNCTION__); } while (0)
;
1366 assert(ifindex > 0)do { if ((__builtin_expect(!!(!(ifindex > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ifindex > 0"), "../src/resolve/resolvectl.c"
, 1366, __PRETTY_FUNCTION__); } while (0)
;
1367
1368 if (!name) {
1369 if (!if_indextoname(ifindex, ifname))
1370 return log_error_errno(errno, "Failed to resolve interface name for %i: %m", ifindex)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/resolve/resolvectl.c", 1370, __func__
, "Failed to resolve interface name for %i: %m", ifindex) : -
abs(_e); })
;
1371
1372 name = ifname;
1373 }
1374
1375 if (asprintf(&ifi, "%i", ifindex) < 0)
1376 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolvectl.c"
, 1376, __func__)
;
1377
1378 r = sd_bus_path_encode("/org/freedesktop/resolve1/link", ifi, &p);
1379 if (r < 0)
1380 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolvectl.c"
, 1380, __func__)
;
1381
1382 r = bus_map_all_properties(bus,
1383 "org.freedesktop.resolve1",
1384 p,
1385 property_map,
1386 BUS_MAP_BOOLEAN_AS_BOOL,
1387 &error,
1388 &m,
1389 &link_info);
1390 if (r < 0) {
1391 log_error_errno(r, "Failed to get link data for %i: %s", ifindex, bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1391, __func__, "Failed to get link data for %i: %s"
, ifindex, bus_error_message(&error, r)) : -abs(_e); })
;
1392 goto finish;
1393 }
1394
1395 (void) pager_open(arg_no_pager, false0);
1396
1397 if (mode == STATUS_DNS) {
1398 r = status_print_strv_ifindex(ifindex, name, link_info.dns);
1399 goto finish;
1400 }
1401
1402 if (mode == STATUS_DOMAIN) {
1403 r = status_print_strv_ifindex(ifindex, name, link_info.domains);
1404 goto finish;
1405 }
1406
1407 if (mode == STATUS_NTA) {
1408 r = status_print_strv_ifindex(ifindex, name, link_info.ntas);
1409 goto finish;
1410 }
1411
1412 if (mode == STATUS_LLMNR) {
1413 printf("%sLink %i (%s)%s: %s\n",
1414 ansi_highlight(), ifindex, name, ansi_normal(),
1415 strna(link_info.llmnr));
1416
1417 r = 0;
1418 goto finish;
1419 }
1420
1421 if (mode == STATUS_MDNS) {
1422 printf("%sLink %i (%s)%s: %s\n",
1423 ansi_highlight(), ifindex, name, ansi_normal(),
1424 strna(link_info.mdns));
1425
1426 r = 0;
1427 goto finish;
1428 }
1429
1430 if (mode == STATUS_PRIVATE) {
1431 printf("%sLink %i (%s)%s: %s\n",
1432 ansi_highlight(), ifindex, name, ansi_normal(),
1433 strna(link_info.dns_over_tls));
1434
1435 r = 0;
1436 goto finish;
1437 }
1438
1439 if (mode == STATUS_DNSSEC) {
1440 printf("%sLink %i (%s)%s: %s\n",
1441 ansi_highlight(), ifindex, name, ansi_normal(),
1442 strna(link_info.dnssec));
1443
1444 r = 0;
1445 goto finish;
1446 }
1447
1448 if (empty_line && *empty_line)
1449 fputc('\n', stdoutstdout);
1450
1451 printf("%sLink %i (%s)%s\n",
1452 ansi_highlight(), ifindex, name, ansi_normal());
1453
1454 if (link_info.scopes_mask == 0)
1455 printf(" Current Scopes: none\n");
1456 else
1457 printf(" Current Scopes:%s%s%s%s%s\n",
1458 link_info.scopes_mask & SD_RESOLVED_DNS(1UL << 0) ? " DNS" : "",
1459 link_info.scopes_mask & SD_RESOLVED_LLMNR_IPV4(1UL << 1) ? " LLMNR/IPv4" : "",
1460 link_info.scopes_mask & SD_RESOLVED_LLMNR_IPV6(1UL << 2) ? " LLMNR/IPv6" : "",
1461 link_info.scopes_mask & SD_RESOLVED_MDNS_IPV4(1UL << 3) ? " mDNS/IPv4" : "",
1462 link_info.scopes_mask & SD_RESOLVED_MDNS_IPV6(1UL << 4) ? " mDNS/IPv6" : "");
1463
1464 printf(" LLMNR setting: %s\n"
1465 "MulticastDNS setting: %s\n"
1466 " DNSOverTLS setting: %s\n"
1467 " DNSSEC setting: %s\n"
1468 " DNSSEC supported: %s\n",
1469 strna(link_info.llmnr),
1470 strna(link_info.mdns),
1471 strna(link_info.dns_over_tls),
1472 strna(link_info.dnssec),
1473 yes_no(link_info.dnssec_supported));
1474
1475 if (link_info.current_dns)
1476 printf(" Current DNS Server: %s\n", link_info.current_dns);
1477
1478 STRV_FOREACH(i, link_info.dns)for ((i) = (link_info.dns); (i) && *(i); (i)++) {
1479 printf(" %s %s\n",
1480 i == link_info.dns ? "DNS Servers:" : " ",
1481 *i);
1482 }
1483
1484 STRV_FOREACH(i, link_info.domains)for ((i) = (link_info.domains); (i) && *(i); (i)++) {
1485 printf(" %s %s\n",
1486 i == link_info.domains ? "DNS Domain:" : " ",
1487 *i);
1488 }
1489
1490 STRV_FOREACH(i, link_info.ntas)for ((i) = (link_info.ntas); (i) && *(i); (i)++) {
1491 printf(" %s %s\n",
1492 i == link_info.ntas ? "DNSSEC NTA:" : " ",
1493 *i);
1494 }
1495
1496 if (empty_line)
1497 *empty_line = true1;
1498
1499 r = 0;
1500
1501finish:
1502 free(link_info.current_dns);
1503 strv_free(link_info.dns);
1504 strv_free(link_info.domains);
1505 strv_free(link_info.ntas);
1506 return r;
1507}
1508
1509static int map_global_dns_servers(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
1510 char ***l = userdata;
1511 int r;
1512
1513 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 1513
, __PRETTY_FUNCTION__); } while (0)
;
1514 assert(member)do { if ((__builtin_expect(!!(!(member)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("member"), "../src/resolve/resolvectl.c"
, 1514, __PRETTY_FUNCTION__); } while (0)
;
1515 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/resolve/resolvectl.c", 1515
, __PRETTY_FUNCTION__); } while (0)
;
1516 assert(l)do { if ((__builtin_expect(!!(!(l)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("l"), "../src/resolve/resolvectl.c", 1516
, __PRETTY_FUNCTION__); } while (0)
;
1517
1518 r = sd_bus_message_enter_container(m, 'a', "(iiay)");
1519 if (r < 0)
1520 return r;
1521
1522 for (;;) {
1523 char *pretty = NULL((void*)0);
1524
1525 r = read_dns_server_one(m, true1, &pretty);
1526 if (r < 0)
1527 return r;
1528 if (r == 0)
1529 break;
1530
1531 if (isempty(pretty))
1532 continue;
1533
1534 r = strv_consume(l, pretty);
1535 if (r < 0)
1536 return r;
1537 }
1538
1539 r = sd_bus_message_exit_container(m);
1540 if (r < 0)
1541 return r;
1542
1543 return 0;
1544}
1545
1546static int map_global_current_dns_server(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
1547 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/resolve/resolvectl.c", 1547
, __PRETTY_FUNCTION__); } while (0)
;
1548 assert(userdata)do { if ((__builtin_expect(!!(!(userdata)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("userdata"), "../src/resolve/resolvectl.c"
, 1548, __PRETTY_FUNCTION__); } while (0)
;
1549
1550 return read_dns_server_one(m, true1, userdata);
1551}
1552
1553static int map_global_domains(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
1554 char ***l = userdata;
1555 int r;
1556
1557 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 1557
, __PRETTY_FUNCTION__); } while (0)
;
1558 assert(member)do { if ((__builtin_expect(!!(!(member)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("member"), "../src/resolve/resolvectl.c"
, 1558, __PRETTY_FUNCTION__); } while (0)
;
1559 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/resolve/resolvectl.c", 1559
, __PRETTY_FUNCTION__); } while (0)
;
1560 assert(l)do { if ((__builtin_expect(!!(!(l)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("l"), "../src/resolve/resolvectl.c", 1560
, __PRETTY_FUNCTION__); } while (0)
;
1561
1562 r = sd_bus_message_enter_container(m, 'a', "(isb)");
1563 if (r < 0)
1564 return r;
1565
1566 for (;;) {
1567 char *pretty = NULL((void*)0);
1568
1569 r = read_domain_one(m, true1, &pretty);
1570 if (r < 0)
1571 return r;
1572 if (r == 0)
1573 break;
1574
1575 if (isempty(pretty))
1576 continue;
1577
1578 r = strv_consume(l, pretty);
1579 if (r < 0)
1580 return r;
1581 }
1582
1583 r = sd_bus_message_exit_container(m);
1584 if (r < 0)
1585 return r;
1586
1587 return 0;
1588}
1589
1590static int status_print_strv_global(char **p) {
1591 char **i;
1592
1593 printf("%sGlobal%s:", ansi_highlight(), ansi_normal());
1594
1595 STRV_FOREACH(i, p)for ((i) = (p); (i) && *(i); (i)++)
1596 printf(" %s", *i);
1597
1598 printf("\n");
1599
1600 return 0;
1601}
1602
1603static int status_global(sd_bus *bus, StatusMode mode, bool_Bool *empty_line) {
1604
1605 struct global_info {
1606 char *current_dns;
1607 char **dns;
1608 char **fallback_dns;
1609 char **domains;
1610 char **ntas;
1611 const char *llmnr;
1612 const char *mdns;
1613 const char *dns_over_tls;
1614 const char *dnssec;
1615 bool_Bool dnssec_supported;
1616 } global_info = {};
1617
1618 static const struct bus_properties_map property_map[] = {
1619 { "DNS", "a(iiay)", map_global_dns_servers, offsetof(struct global_info, dns)__builtin_offsetof(struct global_info, dns) },
1620 { "FallbackDNS", "a(iiay)", map_global_dns_servers, offsetof(struct global_info, fallback_dns)__builtin_offsetof(struct global_info, fallback_dns) },
1621 { "CurrentDNSServer", "(iiay)", map_global_current_dns_server, offsetof(struct global_info, current_dns)__builtin_offsetof(struct global_info, current_dns) },
1622 { "Domains", "a(isb)", map_global_domains, offsetof(struct global_info, domains)__builtin_offsetof(struct global_info, domains) },
1623 { "DNSSECNegativeTrustAnchors", "as", NULL((void*)0), offsetof(struct global_info, ntas)__builtin_offsetof(struct global_info, ntas) },
1624 { "LLMNR", "s", NULL((void*)0), offsetof(struct global_info, llmnr)__builtin_offsetof(struct global_info, llmnr) },
1625 { "MulticastDNS", "s", NULL((void*)0), offsetof(struct global_info, mdns)__builtin_offsetof(struct global_info, mdns) },
1626 { "DNSOverTLS", "s", NULL((void*)0), offsetof(struct global_info, dns_over_tls)__builtin_offsetof(struct global_info, dns_over_tls) },
1627 { "DNSSEC", "s", NULL((void*)0), offsetof(struct global_info, dnssec)__builtin_offsetof(struct global_info, dnssec) },
1628 { "DNSSECSupported", "b", NULL((void*)0), offsetof(struct global_info, dnssec_supported)__builtin_offsetof(struct global_info, dnssec_supported) },
1629 {}
1630 };
1631
1632 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
1633 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *m = NULL((void*)0);
1634 char **i;
1635 int r;
1636
1637 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 1637
, __PRETTY_FUNCTION__); } while (0)
;
1638 assert(empty_line)do { if ((__builtin_expect(!!(!(empty_line)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("empty_line"), "../src/resolve/resolvectl.c"
, 1638, __PRETTY_FUNCTION__); } while (0)
;
1639
1640 r = bus_map_all_properties(bus,
1641 "org.freedesktop.resolve1",
1642 "/org/freedesktop/resolve1",
1643 property_map,
1644 BUS_MAP_BOOLEAN_AS_BOOL,
1645 &error,
1646 &m,
1647 &global_info);
1648 if (r < 0) {
1649 log_error_errno(r, "Failed to get global data: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1649, __func__, "Failed to get global data: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
1650 goto finish;
1651 }
1652
1653 (void) pager_open(arg_no_pager, false0);
1654
1655 if (mode == STATUS_DNS) {
1656 r = status_print_strv_global(global_info.dns);
1657 goto finish;
1658 }
1659
1660 if (mode == STATUS_DOMAIN) {
1661 r = status_print_strv_global(global_info.domains);
1662 goto finish;
1663 }
1664
1665 if (mode == STATUS_NTA) {
1666 r = status_print_strv_global(global_info.ntas);
1667 goto finish;
1668 }
1669
1670 if (mode == STATUS_LLMNR) {
1671 printf("%sGlobal%s: %s\n", ansi_highlight(), ansi_normal(),
1672 strna(global_info.llmnr));
1673
1674 r = 0;
1675 goto finish;
1676 }
1677
1678 if (mode == STATUS_MDNS) {
1679 printf("%sGlobal%s: %s\n", ansi_highlight(), ansi_normal(),
1680 strna(global_info.mdns));
1681
1682 r = 0;
1683 goto finish;
1684 }
1685
1686 if (mode == STATUS_PRIVATE) {
1687 printf("%sGlobal%s: %s\n", ansi_highlight(), ansi_normal(),
1688 strna(global_info.dns_over_tls));
1689
1690 r = 0;
1691 goto finish;
1692 }
1693
1694 if (mode == STATUS_DNSSEC) {
1695 printf("%sGlobal%s: %s\n", ansi_highlight(), ansi_normal(),
1696 strna(global_info.dnssec));
1697
1698 r = 0;
1699 goto finish;
1700 }
1701
1702 printf("%sGlobal%s\n", ansi_highlight(), ansi_normal());
1703
1704 printf(" LLMNR setting: %s\n"
1705 "MulticastDNS setting: %s\n"
1706 " DNSOverTLS setting: %s\n"
1707 " DNSSEC setting: %s\n"
1708 " DNSSEC supported: %s\n",
1709 strna(global_info.llmnr),
1710 strna(global_info.mdns),
1711 strna(global_info.dns_over_tls),
1712 strna(global_info.dnssec),
1713 yes_no(global_info.dnssec_supported));
1714
1715 if (global_info.current_dns)
1716 printf(" Current DNS Server: %s\n", global_info.current_dns);
1717
1718 STRV_FOREACH(i, global_info.dns)for ((i) = (global_info.dns); (i) && *(i); (i)++) {
1719 printf(" %s %s\n",
1720 i == global_info.dns ? "DNS Servers:" : " ",
1721 *i);
1722 }
1723
1724 STRV_FOREACH(i, global_info.fallback_dns)for ((i) = (global_info.fallback_dns); (i) && *(i); (
i)++)
{
1725 printf("%s %s\n",
1726 i == global_info.fallback_dns ? "Fallback DNS Servers:" : " ",
1727 *i);
1728 }
1729
1730 STRV_FOREACH(i, global_info.domains)for ((i) = (global_info.domains); (i) && *(i); (i)++) {
1731 printf(" %s %s\n",
1732 i == global_info.domains ? "DNS Domain:" : " ",
1733 *i);
1734 }
1735
1736 strv_sort(global_info.ntas);
1737 STRV_FOREACH(i, global_info.ntas)for ((i) = (global_info.ntas); (i) && *(i); (i)++) {
1738 printf(" %s %s\n",
1739 i == global_info.ntas ? "DNSSEC NTA:" : " ",
1740 *i);
1741 }
1742
1743 *empty_line = true1;
1744
1745 r = 0;
1746
1747finish:
1748 free(global_info.current_dns);
1749 strv_free(global_info.dns);
1750 strv_free(global_info.fallback_dns);
1751 strv_free(global_info.domains);
1752 strv_free(global_info.ntas);
1753
1754 return r;
1755}
1756
1757static int status_all(sd_bus *bus, StatusMode mode) {
1758 _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *req = NULL((void*)0), *reply = NULL((void*)0);
1759 _cleanup_(sd_netlink_unrefp)__attribute__((cleanup(sd_netlink_unrefp))) sd_netlink *rtnl = NULL((void*)0);
1760 sd_netlink_message *i;
1761 bool_Bool empty_line = false0;
1762 int r;
1763
1764 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 1764
, __PRETTY_FUNCTION__); } while (0)
;
1765
1766 r = status_global(bus, mode, &empty_line);
1767 if (r < 0)
1768 return r;
1769
1770 r = sd_netlink_open(&rtnl);
1771 if (r < 0)
1772 return log_error_errno(r, "Failed to connect to netlink: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1772, __func__, "Failed to connect to netlink: %m"
) : -abs(_e); })
;
1773
1774 r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINKRTM_GETLINK, 0);
1775 if (r < 0)
1776 return rtnl_log_create_error(r);
1777
1778 r = sd_netlink_message_request_dump(req, true1);
1779 if (r < 0)
1780 return rtnl_log_create_error(r);
1781
1782 r = sd_netlink_call(rtnl, req, 0, &reply);
1783 if (r < 0)
1784 return log_error_errno(r, "Failed to enumerate links: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1784, __func__, "Failed to enumerate links: %m"
) : -abs(_e); })
;
1785
1786 r = 0;
1787 for (i = reply; i; i = sd_netlink_message_next(i)) {
1788 const char *name;
1789 int ifindex, q;
1790 uint16_t type;
1791
1792 q = sd_netlink_message_get_type(i, &type);
1793 if (q < 0)
1794 return rtnl_log_parse_error(q);
1795
1796 if (type != RTM_NEWLINKRTM_NEWLINK)
1797 continue;
1798
1799 q = sd_rtnl_message_link_get_ifindex(i, &ifindex);
1800 if (q < 0)
1801 return rtnl_log_parse_error(q);
1802
1803 if (ifindex == LOOPBACK_IFINDEX1)
1804 continue;
1805
1806 q = sd_netlink_message_read_string(i, IFLA_IFNAME, &name);
1807 if (q < 0)
1808 return rtnl_log_parse_error(q);
1809
1810 q = status_ifindex(bus, ifindex, name, mode, &empty_line);
1811 if (q < 0 && r >= 0)
1812 r = q;
1813 }
1814
1815 return r;
1816}
1817
1818static int verb_status(int argc, char **argv, void *userdata) {
1819 sd_bus *bus = userdata;
1820 int q, r = 0;
1821
1822 if (argc > 1) {
1823 char **ifname;
1824 bool_Bool empty_line = false0;
1825
1826 STRV_FOREACH(ifname, argv + 1)for ((ifname) = (argv + 1); (ifname) && *(ifname); (ifname
)++)
{
1827 int ifindex;
1828
1829 ifindex = parse_ifindex_with_warn(*ifname);
1830 if (ifindex < 0)
1831 continue;
1832
1833 q = status_ifindex(bus, ifindex, NULL((void*)0), STATUS_ALL, &empty_line);
1834 if (q < 0)
1835 r = q;
1836 }
1837 } else
1838 r = status_all(bus, STATUS_ALL);
1839
1840 return r;
1841}
1842
1843static int log_interface_is_managed(int r, int ifindex) {
1844 char ifname[IFNAMSIZ16];
1845
1846 return log_error_errno(r,({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1849, __func__, "The specified interface %s is managed by systemd-networkd. Operation refused.\n"
"Please configure DNS settings for systemd-networkd managed interfaces directly in their .network files."
, strna(if_indextoname(ifindex, ifname))) : -abs(_e); })
1847 "The specified interface %s is managed by systemd-networkd. Operation refused.\n"({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1849, __func__, "The specified interface %s is managed by systemd-networkd. Operation refused.\n"
"Please configure DNS settings for systemd-networkd managed interfaces directly in their .network files."
, strna(if_indextoname(ifindex, ifname))) : -abs(_e); })
1848 "Please configure DNS settings for systemd-networkd managed interfaces directly in their .network files.",({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1849, __func__, "The specified interface %s is managed by systemd-networkd. Operation refused.\n"
"Please configure DNS settings for systemd-networkd managed interfaces directly in their .network files."
, strna(if_indextoname(ifindex, ifname))) : -abs(_e); })
1849 strna(if_indextoname(ifindex, ifname)))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1849, __func__, "The specified interface %s is managed by systemd-networkd. Operation refused.\n"
"Please configure DNS settings for systemd-networkd managed interfaces directly in their .network files."
, strna(if_indextoname(ifindex, ifname))) : -abs(_e); })
;
1850}
1851
1852static int verb_dns(int argc, char **argv, void *userdata) {
1853 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
1854 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *req = NULL((void*)0);
1855 sd_bus *bus = userdata;
1856 int ifindex, r;
1857 char **p;
1858
1859 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 1859
, __PRETTY_FUNCTION__); } while (0)
;
1860
1861 if (argc <= 1)
1862 return status_all(bus, STATUS_DNS);
1863
1864 ifindex = parse_ifindex_with_warn(argv[1]);
1865 if (ifindex < 0)
1866 return ifindex;
1867
1868 if (ifindex == LOOPBACK_IFINDEX1) {
1869 log_error("Interface can't be the loopback interface (lo). Sorry.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1869, __func__, "Interface can't be the loopback interface (lo). Sorry."
) : -abs(_e); })
;
1870 return -EINVAL22;
1871 }
1872
1873 if (argc == 2)
1874 return status_ifindex(bus, ifindex, NULL((void*)0), STATUS_DNS, NULL((void*)0));
1875
1876 r = sd_bus_message_new_method_call(
1877 bus,
1878 &req,
1879 "org.freedesktop.resolve1",
1880 "/org/freedesktop/resolve1",
1881 "org.freedesktop.resolve1.Manager",
1882 "SetLinkDNS");
1883 if (r < 0)
1884 return bus_log_create_error(r);
1885
1886 r = sd_bus_message_append(req, "i", ifindex);
1887 if (r < 0)
1888 return bus_log_create_error(r);
1889
1890 r = sd_bus_message_open_container(req, 'a', "(iay)");
1891 if (r < 0)
1892 return bus_log_create_error(r);
1893
1894 STRV_FOREACH(p, argv + 2)for ((p) = (argv + 2); (p) && *(p); (p)++) {
1895 struct in_addr_data data;
1896
1897 r = in_addr_from_string_auto(*p, &data.family, &data.address);
1898 if (r < 0)
1899 return log_error_errno(r, "Failed to parse DNS server address: %s", *p)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1899, __func__, "Failed to parse DNS server address: %s"
, *p) : -abs(_e); })
;
1900
1901 r = sd_bus_message_open_container(req, 'r', "iay");
1902 if (r < 0)
1903 return bus_log_create_error(r);
1904
1905 r = sd_bus_message_append(req, "i", data.family);
1906 if (r < 0)
1907 return bus_log_create_error(r);
1908
1909 r = sd_bus_message_append_array(req, 'y', &data.address, FAMILY_ADDRESS_SIZE(data.family));
1910 if (r < 0)
1911 return bus_log_create_error(r);
1912
1913 r = sd_bus_message_close_container(req);
1914 if (r < 0)
1915 return bus_log_create_error(r);
1916 }
1917
1918 r = sd_bus_message_close_container(req);
1919 if (r < 0)
1920 return bus_log_create_error(r);
1921
1922 r = sd_bus_call(bus, req, 0, &error, NULL((void*)0));
1923 if (r < 0) {
1924 if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY"org.freedesktop.resolve1.LinkBusy"))
1925 return log_interface_is_managed(r, ifindex);
1926
1927 if (arg_ifindex_permissive &&
1928 sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK"org.freedesktop.resolve1.NoSuchLink"))
1929 return 0;
1930
1931 return log_error_errno(r, "Failed to set DNS configuration: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1931, __func__, "Failed to set DNS configuration: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
1932 }
1933
1934 return 0;
1935}
1936
1937static int verb_domain(int argc, char **argv, void *userdata) {
1938 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
1939 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *req = NULL((void*)0);
1940 sd_bus *bus = userdata;
1941 int ifindex, r;
1942 char **p;
1943
1944 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 1944
, __PRETTY_FUNCTION__); } while (0)
;
1945
1946 if (argc <= 1)
1947 return status_all(bus, STATUS_DOMAIN);
1948
1949 ifindex = parse_ifindex_with_warn(argv[1]);
1950 if (ifindex < 0)
1951 return ifindex;
1952
1953 if (ifindex == LOOPBACK_IFINDEX1) {
1954 log_error("Interface can't be the loopback interface (lo). Sorry.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1954, __func__, "Interface can't be the loopback interface (lo). Sorry."
) : -abs(_e); })
;
1955 return -EINVAL22;
1956 }
1957
1958 if (argc == 2)
1959 return status_ifindex(bus, ifindex, NULL((void*)0), STATUS_DOMAIN, NULL((void*)0));
1960
1961 r = sd_bus_message_new_method_call(
1962 bus,
1963 &req,
1964 "org.freedesktop.resolve1",
1965 "/org/freedesktop/resolve1",
1966 "org.freedesktop.resolve1.Manager",
1967 "SetLinkDomains");
1968 if (r < 0)
1969 return bus_log_create_error(r);
1970
1971 r = sd_bus_message_append(req, "i", ifindex);
1972 if (r < 0)
1973 return bus_log_create_error(r);
1974
1975 r = sd_bus_message_open_container(req, 'a', "(sb)");
1976 if (r < 0)
1977 return bus_log_create_error(r);
1978
1979 STRV_FOREACH(p, argv + 2)for ((p) = (argv + 2); (p) && *(p); (p)++) {
1980 const char *n;
1981
1982 n = **p == '~' ? *p + 1 : *p;
1983
1984 r = dns_name_is_valid(n);
1985 if (r < 0)
1986 return log_error_errno(r, "Failed to validate specified domain %s: %m", n)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1986, __func__, "Failed to validate specified domain %s: %m"
, n) : -abs(_e); })
;
1987 if (r == 0) {
1988 log_error("Domain not valid: %s", n)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 1988, __func__, "Domain not valid: %s"
, n) : -abs(_e); })
;
1989 return -EINVAL22;
1990 }
1991
1992 r = sd_bus_message_append(req, "(sb)", n, **p == '~');
1993 if (r < 0)
1994 return bus_log_create_error(r);
1995 }
1996
1997 r = sd_bus_message_close_container(req);
1998 if (r < 0)
1999 return bus_log_create_error(r);
2000
2001 r = sd_bus_call(bus, req, 0, &error, NULL((void*)0));
2002 if (r < 0) {
2003 if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY"org.freedesktop.resolve1.LinkBusy"))
2004 return log_interface_is_managed(r, ifindex);
2005
2006 if (arg_ifindex_permissive &&
2007 sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK"org.freedesktop.resolve1.NoSuchLink"))
2008 return 0;
2009
2010 return log_error_errno(r, "Failed to set domain configuration: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2010, __func__, "Failed to set domain configuration: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
2011 }
2012
2013 return 0;
2014}
2015
2016static int verb_llmnr(int argc, char **argv, void *userdata) {
2017 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
2018 sd_bus *bus = userdata;
2019 int ifindex, r;
2020
2021 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 2021
, __PRETTY_FUNCTION__); } while (0)
;
2022
2023 if (argc <= 1)
2024 return status_all(bus, STATUS_LLMNR);
2025
2026 ifindex = parse_ifindex_with_warn(argv[1]);
2027 if (ifindex < 0)
2028 return ifindex;
2029
2030 if (ifindex == LOOPBACK_IFINDEX1) {
2031 log_error("Interface can't be the loopback interface (lo). Sorry.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2031, __func__, "Interface can't be the loopback interface (lo). Sorry."
) : -abs(_e); })
;
2032 return -EINVAL22;
2033 }
2034
2035 if (argc == 2)
2036 return status_ifindex(bus, ifindex, NULL((void*)0), STATUS_LLMNR, NULL((void*)0));
2037
2038 r = sd_bus_call_method(bus,
2039 "org.freedesktop.resolve1",
2040 "/org/freedesktop/resolve1",
2041 "org.freedesktop.resolve1.Manager",
2042 "SetLinkLLMNR",
2043 &error,
2044 NULL((void*)0),
2045 "is", ifindex, argv[2]);
2046 if (r < 0) {
2047 if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY"org.freedesktop.resolve1.LinkBusy"))
2048 return log_interface_is_managed(r, ifindex);
2049
2050 if (arg_ifindex_permissive &&
2051 sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK"org.freedesktop.resolve1.NoSuchLink"))
2052 return 0;
2053
2054 return log_error_errno(r, "Failed to set LLMNR configuration: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2054, __func__, "Failed to set LLMNR configuration: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
2055 }
2056
2057 return 0;
2058}
2059
2060static int verb_mdns(int argc, char **argv, void *userdata) {
2061 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
2062 sd_bus *bus = userdata;
2063 int ifindex, r;
2064
2065 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 2065
, __PRETTY_FUNCTION__); } while (0)
;
2066
2067 if (argc <= 1)
2068 return status_all(bus, STATUS_MDNS);
2069
2070 ifindex = parse_ifindex_with_warn(argv[1]);
2071 if (ifindex < 0)
2072 return ifindex;
2073
2074 if (ifindex == LOOPBACK_IFINDEX1) {
2075 log_error("Interface can't be the loopback interface (lo). Sorry.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2075, __func__, "Interface can't be the loopback interface (lo). Sorry."
) : -abs(_e); })
;
2076 return -EINVAL22;
2077 }
2078
2079 if (argc == 2)
2080 return status_ifindex(bus, ifindex, NULL((void*)0), STATUS_MDNS, NULL((void*)0));
2081
2082 r = sd_bus_call_method(bus,
2083 "org.freedesktop.resolve1",
2084 "/org/freedesktop/resolve1",
2085 "org.freedesktop.resolve1.Manager",
2086 "SetLinkMulticastDNS",
2087 &error,
2088 NULL((void*)0),
2089 "is", ifindex, argv[2]);
2090 if (r < 0) {
2091 if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY"org.freedesktop.resolve1.LinkBusy"))
2092 return log_interface_is_managed(r, ifindex);
2093
2094 if (arg_ifindex_permissive &&
2095 sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK"org.freedesktop.resolve1.NoSuchLink"))
2096 return 0;
2097
2098 return log_error_errno(r, "Failed to set MulticastDNS configuration: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2098, __func__, "Failed to set MulticastDNS configuration: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
2099 }
2100
2101 return 0;
2102}
2103
2104static int verb_dns_over_tls(int argc, char **argv, void *userdata) {
2105 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
2106 sd_bus *bus = userdata;
2107 int ifindex, r;
2108
2109 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 2109
, __PRETTY_FUNCTION__); } while (0)
;
2110
2111 if (argc <= 1)
2112 return status_all(bus, STATUS_PRIVATE);
2113
2114 ifindex = parse_ifindex_with_warn(argv[1]);
2115 if (ifindex < 0)
2116 return ifindex;
2117
2118 if (ifindex == LOOPBACK_IFINDEX1) {
2119 log_error("Interface can't be the loopback interface (lo). Sorry.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2119, __func__, "Interface can't be the loopback interface (lo). Sorry."
) : -abs(_e); })
;
2120 return -EINVAL22;
2121 }
2122
2123 if (argc == 2)
2124 return status_ifindex(bus, ifindex, NULL((void*)0), STATUS_PRIVATE, NULL((void*)0));
2125
2126 r = sd_bus_call_method(bus,
2127 "org.freedesktop.resolve1",
2128 "/org/freedesktop/resolve1",
2129 "org.freedesktop.resolve1.Manager",
2130 "SetLinkDNSOverTLS",
2131 &error,
2132 NULL((void*)0),
2133 "is", ifindex, argv[2]);
2134 if (r < 0) {
2135 if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY"org.freedesktop.resolve1.LinkBusy"))
2136 return log_interface_is_managed(r, ifindex);
2137
2138 if (arg_ifindex_permissive &&
2139 sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK"org.freedesktop.resolve1.NoSuchLink"))
2140 return 0;
2141
2142 return log_error_errno(r, "Failed to set DNSOverTLS configuration: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2142, __func__, "Failed to set DNSOverTLS configuration: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
2143 }
2144
2145 return 0;
2146}
2147
2148static int verb_dnssec(int argc, char **argv, void *userdata) {
2149 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
2150 sd_bus *bus = userdata;
2151 int ifindex, r;
2152
2153 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 2153
, __PRETTY_FUNCTION__); } while (0)
;
2154
2155 if (argc <= 1)
2156 return status_all(bus, STATUS_DNSSEC);
2157
2158 ifindex = parse_ifindex_with_warn(argv[1]);
2159 if (ifindex < 0)
2160 return ifindex;
2161
2162 if (ifindex == LOOPBACK_IFINDEX1) {
2163 log_error("Interface can't be the loopback interface (lo). Sorry.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2163, __func__, "Interface can't be the loopback interface (lo). Sorry."
) : -abs(_e); })
;
2164 return -EINVAL22;
2165 }
2166
2167 if (argc == 2)
2168 return status_ifindex(bus, ifindex, NULL((void*)0), STATUS_DNSSEC, NULL((void*)0));
2169
2170 r = sd_bus_call_method(bus,
2171 "org.freedesktop.resolve1",
2172 "/org/freedesktop/resolve1",
2173 "org.freedesktop.resolve1.Manager",
2174 "SetLinkDNSSEC",
2175 &error,
2176 NULL((void*)0),
2177 "is", ifindex, argv[2]);
2178 if (r < 0) {
2179 if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY"org.freedesktop.resolve1.LinkBusy"))
2180 return log_interface_is_managed(r, ifindex);
2181
2182 if (arg_ifindex_permissive &&
2183 sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK"org.freedesktop.resolve1.NoSuchLink"))
2184 return 0;
2185
2186 return log_error_errno(r, "Failed to set DNSSEC configuration: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2186, __func__, "Failed to set DNSSEC configuration: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
2187 }
2188
2189 return 0;
2190}
2191
2192static int verb_nta(int argc, char **argv, void *userdata) {
2193 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
2194 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *req = NULL((void*)0);
2195 sd_bus *bus = userdata;
2196 int ifindex, i, r;
2197
2198 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 2198
, __PRETTY_FUNCTION__); } while (0)
;
2199
2200 if (argc <= 1)
2201 return status_all(bus, STATUS_NTA);
2202
2203 ifindex = parse_ifindex_with_warn(argv[1]);
2204 if (ifindex < 0)
2205 return ifindex;
2206
2207 if (ifindex == LOOPBACK_IFINDEX1) {
2208 log_error("Interface can't be the loopback interface (lo). Sorry.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2208, __func__, "Interface can't be the loopback interface (lo). Sorry."
) : -abs(_e); })
;
2209 return -EINVAL22;
2210 }
2211
2212 if (argc == 2)
2213 return status_ifindex(bus, ifindex, NULL((void*)0), STATUS_NTA, NULL((void*)0));
2214
2215 for (i = 2; i < argc; i++) {
2216 r = dns_name_is_valid(argv[i]);
2217 if (r < 0)
2218 return log_error_errno(r, "Failed to validate specified domain %s: %m", argv[i])({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2218, __func__, "Failed to validate specified domain %s: %m"
, argv[i]) : -abs(_e); })
;
2219 if (r == 0) {
2220 log_error("Domain not valid: %s", argv[i])({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2220, __func__, "Domain not valid: %s"
, argv[i]) : -abs(_e); })
;
2221 return -EINVAL22;
2222 }
2223 }
2224
2225 r = sd_bus_message_new_method_call(
2226 bus,
2227 &req,
2228 "org.freedesktop.resolve1",
2229 "/org/freedesktop/resolve1",
2230 "org.freedesktop.resolve1.Manager",
2231 "SetLinkDNSSECNegativeTrustAnchors");
2232 if (r < 0)
2233 return bus_log_create_error(r);
2234
2235 r = sd_bus_message_append(req, "i", ifindex);
2236 if (r < 0)
2237 return bus_log_create_error(r);
2238
2239 r = sd_bus_message_append_strv(req, argv + 2);
2240 if (r < 0)
2241 return bus_log_create_error(r);
2242
2243 r = sd_bus_call(bus, req, 0, &error, NULL((void*)0));
2244 if (r < 0) {
2245 if (sd_bus_error_has_name(&error, BUS_ERROR_LINK_BUSY"org.freedesktop.resolve1.LinkBusy"))
2246 return log_interface_is_managed(r, ifindex);
2247
2248 if (arg_ifindex_permissive &&
2249 sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK"org.freedesktop.resolve1.NoSuchLink"))
2250 return 0;
2251
2252 return log_error_errno(r, "Failed to set DNSSEC NTA configuration: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2252, __func__, "Failed to set DNSSEC NTA configuration: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
2253 }
2254
2255 return 0;
2256}
2257
2258static int verb_revert_link(int argc, char **argv, void *userdata) {
2259 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
2260 sd_bus *bus = userdata;
2261 int ifindex, r;
2262
2263 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/resolve/resolvectl.c", 2263
, __PRETTY_FUNCTION__); } while (0)
;
2264
2265 ifindex = parse_ifindex_with_warn(argv[1]);
2266 if (ifindex < 0)
2267 return ifindex;
2268
2269 if (ifindex == LOOPBACK_IFINDEX1) {
2270 log_error("Interface can't be the loopback interface (lo). Sorry.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2270, __func__, "Interface can't be the loopback interface (lo). Sorry."
) : -abs(_e); })
;
2271 return -EINVAL22;
2272 }
2273
2274 r = sd_bus_call_method(bus,
2275 "org.freedesktop.resolve1",
2276 "/org/freedesktop/resolve1",
2277 "org.freedesktop.resolve1.Manager",
2278 "RevertLink",
2279 &error,
2280 NULL((void*)0),
2281 "i", ifindex);
2282 if (r < 0) {
2283 if (arg_ifindex_permissive &&
2284 sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_LINK"org.freedesktop.resolve1.NoSuchLink"))
2285 return 0;
2286
2287 return log_error_errno(r, "Failed to revert interface configuration: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2287, __func__, "Failed to revert interface configuration: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
2288 }
2289
2290 return 0;
2291}
2292
2293static void help_protocol_types(void) {
2294 if (arg_legend)
2295 puts("Known protocol types:");
2296 puts("dns\nllmnr\nllmnr-ipv4\nllmnr-ipv6\nmdns\nmdns-ipv4\nmdns-ipv6");
2297}
2298
2299static void help_dns_types(void) {
2300 if (arg_legend)
2301 puts("Known DNS RR types:");
2302
2303 DUMP_STRING_TABLE(dns_type, int, _DNS_TYPE_MAX)do { int _k; flockfile(stdout); for (_k = 0; _k < (_DNS_TYPE_MAX
); _k++) { const char *_t; _t = dns_type_to_string(_k); if (!
_t) continue; fputs_unlocked(_t, stdout); fputc_unlocked('\n'
, stdout); } funlockfile(stdout); } while(0)
;
2304}
2305
2306static void help_dns_classes(void) {
2307 if (arg_legend)
2308 puts("Known DNS RR classes:");
2309
2310 DUMP_STRING_TABLE(dns_class, int, _DNS_CLASS_MAX)do { int _k; flockfile(stdout); for (_k = 0; _k < (_DNS_CLASS_MAX
); _k++) { const char *_t; _t = dns_class_to_string(_k); if (
!_t) continue; fputs_unlocked(_t, stdout); fputc_unlocked('\n'
, stdout); } funlockfile(stdout); } while(0)
;
2311}
2312
2313static void compat_help(void) {
2314 printf("%1$s [OPTIONS...] HOSTNAME|ADDRESS...\n"
2315 "%1$s [OPTIONS...] --service [[NAME] TYPE] DOMAIN\n"
2316 "%1$s [OPTIONS...] --openpgp EMAIL@DOMAIN...\n"
2317 "%1$s [OPTIONS...] --statistics\n"
2318 "%1$s [OPTIONS...] --reset-statistics\n"
2319 "\n"
2320 "Resolve domain names, IPv4 and IPv6 addresses, DNS records, and services.\n\n"
2321 " -h --help Show this help\n"
2322 " --version Show package version\n"
2323 " --no-pager Do not pipe output into a pager\n"
2324 " -4 Resolve IPv4 addresses\n"
2325 " -6 Resolve IPv6 addresses\n"
2326 " -i --interface=INTERFACE Look on interface\n"
2327 " -p --protocol=PROTO|help Look via protocol\n"
2328 " -t --type=TYPE|help Query RR with DNS type\n"
2329 " -c --class=CLASS|help Query RR with DNS class\n"
2330 " --service Resolve service (SRV)\n"
2331 " --service-address=BOOL Resolve address for services (default: yes)\n"
2332 " --service-txt=BOOL Resolve TXT records for services (default: yes)\n"
2333 " --openpgp Query OpenPGP public key\n"
2334 " --tlsa Query TLS public key\n"
2335 " --cname=BOOL Follow CNAME redirects (default: yes)\n"
2336 " --search=BOOL Use search domains for single-label names\n"
2337 " (default: yes)\n"
2338 " --raw[=payload|packet] Dump the answer as binary data\n"
2339 " --legend=BOOL Print headers and additional info (default: yes)\n"
2340 " --statistics Show resolver statistics\n"
2341 " --reset-statistics Reset resolver statistics\n"
2342 " --status Show link and server status\n"
2343 " --flush-caches Flush all local DNS caches\n"
2344 " --reset-server-features\n"
2345 " Forget learnt DNS server feature levels\n"
2346 " --set-dns=SERVER Set per-interface DNS server address\n"
2347 " --set-domain=DOMAIN Set per-interface search domain\n"
2348 " --set-llmnr=MODE Set per-interface LLMNR mode\n"
2349 " --set-mdns=MODE Set per-interface MulticastDNS mode\n"
2350 " --set-dnsovertls=MODE Set per-interface DNS-over-TLS mode\n"
2351 " --set-dnssec=MODE Set per-interface DNSSEC mode\n"
2352 " --set-nta=DOMAIN Set per-interface DNSSEC NTA\n"
2353 " --revert Revert per-interface configuration\n"
2354 , program_invocation_short_name);
2355}
2356
2357static void native_help(void) {
2358 printf("%1$s [OPTIONS...] {COMMAND} ...\n"
2359 "\n"
2360 "Send control commands to the network name resolution manager, or\n"
2361 "resolve domain names, IPv4 and IPv6 addresses, DNS records, and services.\n"
2362 "\n"
2363 " -h --help Show this help\n"
2364 " --version Show package version\n"
2365 " --no-pager Do not pipe output into a pager\n"
2366 " -4 Resolve IPv4 addresses\n"
2367 " -6 Resolve IPv6 addresses\n"
2368 " -i --interface=INTERFACE Look on interface\n"
2369 " -p --protocol=PROTO|help Look via protocol\n"
2370 " -t --type=TYPE|help Query RR with DNS type\n"
2371 " -c --class=CLASS|help Query RR with DNS class\n"
2372 " --service-address=BOOL Resolve address for services (default: yes)\n"
2373 " --service-txt=BOOL Resolve TXT records for services (default: yes)\n"
2374 " --cname=BOOL Follow CNAME redirects (default: yes)\n"
2375 " --search=BOOL Use search domains for single-label names\n"
2376 " (default: yes)\n"
2377 " --raw[=payload|packet] Dump the answer as binary data\n"
2378 " --legend=BOOL Print headers and additional info (default: yes)\n"
2379 "\n"
2380 "Commands:\n"
2381 " query HOSTNAME|ADDRESS... Resolve domain names, IPv4 and IPv6 addresses\n"
2382 " service [[NAME] TYPE] DOMAIN Resolve service (SRV)\n"
2383 " openpgp EMAIL@DOMAIN... Query OpenPGP public key\n"
2384 " tlsa DOMAIN[:PORT]... Query TLS public key\n"
2385 " status [LINK...] Show link and server status\n"
2386 " statistics Show resolver statistics\n"
2387 " reset-statistics Reset resolver statistics\n"
2388 " flush-caches Flush all local DNS caches\n"
2389 " reset-server-features Forget learnt DNS server feature levels\n"
2390 " dns [LINK [SERVER...]] Get/set per-interface DNS server address\n"
2391 " domain [LINK [DOMAIN...]] Get/set per-interface search domain\n"
2392 " llmnr [LINK [MODE]] Get/set per-interface LLMNR mode\n"
2393 " mdns [LINK [MODE]] Get/set per-interface MulticastDNS mode\n"
2394 " dnsovertls [LINK [MODE]] Get/set per-interface DNS-over-TLS mode\n"
2395 " dnssec [LINK [MODE]] Get/set per-interface DNSSEC mode\n"
2396 " nta [LINK [DOMAIN...]] Get/set per-interface DNSSEC NTA\n"
2397 " revert LINK Revert per-interface configuration\n"
2398 , program_invocation_short_name);
2399}
2400
2401static int verb_help(int argc, char **argv, void *userdata) {
2402 native_help();
2403 return 0;
2404}
2405
2406static int compat_parse_argv(int argc, char *argv[]) {
2407 enum {
2408 ARG_VERSION = 0x100,
2409 ARG_LEGEND,
2410 ARG_SERVICE,
2411 ARG_CNAME,
2412 ARG_SERVICE_ADDRESS,
2413 ARG_SERVICE_TXT,
2414 ARG_OPENPGP,
2415 ARG_TLSA,
2416 ARG_RAW,
2417 ARG_SEARCH,
2418 ARG_STATISTICS,
2419 ARG_RESET_STATISTICS,
2420 ARG_STATUS,
2421 ARG_FLUSH_CACHES,
2422 ARG_RESET_SERVER_FEATURES,
2423 ARG_NO_PAGER,
2424 ARG_SET_DNS,
2425 ARG_SET_DOMAIN,
2426 ARG_SET_LLMNR,
2427 ARG_SET_MDNS,
2428 ARG_SET_PRIVATE,
2429 ARG_SET_DNSSEC,
2430 ARG_SET_NTA,
2431 ARG_REVERT_LINK,
2432 };
2433
2434 static const struct option options[] = {
2435 { "help", no_argument0, NULL((void*)0), 'h' },
2436 { "version", no_argument0, NULL((void*)0), ARG_VERSION },
2437 { "type", required_argument1, NULL((void*)0), 't' },
2438 { "class", required_argument1, NULL((void*)0), 'c' },
2439 { "legend", required_argument1, NULL((void*)0), ARG_LEGEND },
2440 { "interface", required_argument1, NULL((void*)0), 'i' },
2441 { "protocol", required_argument1, NULL((void*)0), 'p' },
2442 { "cname", required_argument1, NULL((void*)0), ARG_CNAME },
2443 { "service", no_argument0, NULL((void*)0), ARG_SERVICE },
2444 { "service-address", required_argument1, NULL((void*)0), ARG_SERVICE_ADDRESS },
2445 { "service-txt", required_argument1, NULL((void*)0), ARG_SERVICE_TXT },
2446 { "openpgp", no_argument0, NULL((void*)0), ARG_OPENPGP },
2447 { "tlsa", optional_argument2, NULL((void*)0), ARG_TLSA },
2448 { "raw", optional_argument2, NULL((void*)0), ARG_RAW },
2449 { "search", required_argument1, NULL((void*)0), ARG_SEARCH },
2450 { "statistics", no_argument0, NULL((void*)0), ARG_STATISTICS, },
2451 { "reset-statistics", no_argument0, NULL((void*)0), ARG_RESET_STATISTICS },
2452 { "status", no_argument0, NULL((void*)0), ARG_STATUS },
2453 { "flush-caches", no_argument0, NULL((void*)0), ARG_FLUSH_CACHES },
2454 { "reset-server-features", no_argument0, NULL((void*)0), ARG_RESET_SERVER_FEATURES },
2455 { "no-pager", no_argument0, NULL((void*)0), ARG_NO_PAGER },
2456 { "set-dns", required_argument1, NULL((void*)0), ARG_SET_DNS },
2457 { "set-domain", required_argument1, NULL((void*)0), ARG_SET_DOMAIN },
2458 { "set-llmnr", required_argument1, NULL((void*)0), ARG_SET_LLMNR },
2459 { "set-mdns", required_argument1, NULL((void*)0), ARG_SET_MDNS },
2460 { "set-dnsovertls", required_argument1, NULL((void*)0), ARG_SET_PRIVATE },
2461 { "set-dnssec", required_argument1, NULL((void*)0), ARG_SET_DNSSEC },
2462 { "set-nta", required_argument1, NULL((void*)0), ARG_SET_NTA },
2463 { "revert", no_argument0, NULL((void*)0), ARG_REVERT_LINK },
2464 {}
2465 };
2466
2467 int c, r;
2468
2469 assert(argc >= 0)do { if ((__builtin_expect(!!(!(argc >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("argc >= 0"), "../src/resolve/resolvectl.c"
, 2469, __PRETTY_FUNCTION__); } while (0)
;
2470 assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("argv"), "../src/resolve/resolvectl.c", 2470
, __PRETTY_FUNCTION__); } while (0)
;
2471
2472 while ((c = getopt_long(argc, argv, "h46i:t:c:p:", options, NULL((void*)0))) >= 0)
2473 switch(c) {
2474
2475 case 'h':
2476 compat_help();
2477 return 0; /* done */;
2478
2479 case ARG_VERSION:
2480 return version();
2481
2482 case '4':
2483 arg_family = AF_INET2;
2484 break;
2485
2486 case '6':
2487 arg_family = AF_INET610;
2488 break;
2489
2490 case 'i':
2491 r = parse_ifindex_with_warn(optarg);
2492 if (r < 0)
2493 return r;
2494
2495 arg_ifname = optarg;
2496 arg_ifindex = r;
2497 break;
2498
2499 case 't':
2500 if (streq(optarg, "help")(strcmp((optarg),("help")) == 0)) {
2501 help_dns_types();
2502 return 0;
2503 }
2504
2505 r = dns_type_from_string(optarg);
2506 if (r < 0) {
2507 log_error("Failed to parse RR record type %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2507, __func__, "Failed to parse RR record type %s"
, optarg) : -abs(_e); })
;
2508 return r;
2509 }
2510 arg_type = (uint16_t) r;
2511 assert((int) arg_type == r)do { if ((__builtin_expect(!!(!((int) arg_type == r)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("(int) arg_type == r"), "../src/resolve/resolvectl.c"
, 2511, __PRETTY_FUNCTION__); } while (0)
;
2512
2513 arg_mode = MODE_RESOLVE_RECORD;
2514 break;
2515
2516 case 'c':
2517 if (streq(optarg, "help")(strcmp((optarg),("help")) == 0)) {
2518 help_dns_classes();
2519 return 0;
2520 }
2521
2522 r = dns_class_from_string(optarg);
2523 if (r < 0) {
2524 log_error("Failed to parse RR record class %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2524, __func__, "Failed to parse RR record class %s"
, optarg) : -abs(_e); })
;
2525 return r;
2526 }
2527 arg_class = (uint16_t) r;
2528 assert((int) arg_class == r)do { if ((__builtin_expect(!!(!((int) arg_class == r)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("(int) arg_class == r"), "../src/resolve/resolvectl.c"
, 2528, __PRETTY_FUNCTION__); } while (0)
;
2529
2530 break;
2531
2532 case ARG_LEGEND:
2533 r = parse_boolean(optarg);
2534 if (r < 0)
2535 return log_error_errno(r, "Failed to parse --legend= argument")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2535, __func__, "Failed to parse --legend= argument"
) : -abs(_e); })
;
2536
2537 arg_legend = r;
2538 break;
2539
2540 case 'p':
2541 if (streq(optarg, "help")(strcmp((optarg),("help")) == 0)) {
2542 help_protocol_types();
2543 return 0;
2544 } else if (streq(optarg, "dns")(strcmp((optarg),("dns")) == 0))
2545 arg_flags |= SD_RESOLVED_DNS(1UL << 0);
2546 else if (streq(optarg, "llmnr")(strcmp((optarg),("llmnr")) == 0))
2547 arg_flags |= SD_RESOLVED_LLMNR((1UL << 1)|(1UL << 2));
2548 else if (streq(optarg, "llmnr-ipv4")(strcmp((optarg),("llmnr-ipv4")) == 0))
2549 arg_flags |= SD_RESOLVED_LLMNR_IPV4(1UL << 1);
2550 else if (streq(optarg, "llmnr-ipv6")(strcmp((optarg),("llmnr-ipv6")) == 0))
2551 arg_flags |= SD_RESOLVED_LLMNR_IPV6(1UL << 2);
2552 else if (streq(optarg, "mdns")(strcmp((optarg),("mdns")) == 0))
2553 arg_flags |= SD_RESOLVED_MDNS((1UL << 3)|(1UL << 4));
2554 else if (streq(optarg, "mdns-ipv4")(strcmp((optarg),("mdns-ipv4")) == 0))
2555 arg_flags |= SD_RESOLVED_MDNS_IPV4(1UL << 3);
2556 else if (streq(optarg, "mdns-ipv6")(strcmp((optarg),("mdns-ipv6")) == 0))
2557 arg_flags |= SD_RESOLVED_MDNS_IPV6(1UL << 4);
2558 else {
2559 log_error("Unknown protocol specifier: %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2559, __func__, "Unknown protocol specifier: %s"
, optarg) : -abs(_e); })
;
2560 return -EINVAL22;
2561 }
2562
2563 break;
2564
2565 case ARG_SERVICE:
2566 arg_mode = MODE_RESOLVE_SERVICE;
2567 break;
2568
2569 case ARG_OPENPGP:
2570 arg_mode = MODE_RESOLVE_OPENPGP;
2571 break;
2572
2573 case ARG_TLSA:
2574 arg_mode = MODE_RESOLVE_TLSA;
2575 if (!optarg || service_family_is_valid(optarg))
2576 arg_service_family = optarg;
2577 else {
2578 log_error("Unknown service family \"%s\".", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2578, __func__, "Unknown service family \"%s\"."
, optarg) : -abs(_e); })
;
2579 return -EINVAL22;
2580 }
2581 break;
2582
2583 case ARG_RAW:
2584 if (on_tty()) {
2585 log_error("Refusing to write binary data to tty.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2585, __func__, "Refusing to write binary data to tty."
) : -abs(_e); })
;
2586 return -ENOTTY25;
2587 }
2588
2589 if (optarg == NULL((void*)0) || streq(optarg, "payload")(strcmp((optarg),("payload")) == 0))
2590 arg_raw = RAW_PAYLOAD;
2591 else if (streq(optarg, "packet")(strcmp((optarg),("packet")) == 0))
2592 arg_raw = RAW_PACKET;
2593 else {
2594 log_error("Unknown --raw specifier \"%s\".", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2594, __func__, "Unknown --raw specifier \"%s\"."
, optarg) : -abs(_e); })
;
2595 return -EINVAL22;
2596 }
2597
2598 arg_legend = false0;
2599 break;
2600
2601 case ARG_CNAME:
2602 r = parse_boolean(optarg);
2603 if (r < 0)
2604 return log_error_errno(r, "Failed to parse --cname= argument.")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2604, __func__, "Failed to parse --cname= argument."
) : -abs(_e); })
;
2605 SET_FLAG(arg_flags, SD_RESOLVED_NO_CNAME, r == 0)(arg_flags) = (r == 0) ? ((arg_flags) | ((1UL << 5))) :
((arg_flags) & ~((1UL << 5)))
;
2606 break;
2607
2608 case ARG_SERVICE_ADDRESS:
2609 r = parse_boolean(optarg);
2610 if (r < 0)
2611 return log_error_errno(r, "Failed to parse --service-address= argument.")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2611, __func__, "Failed to parse --service-address= argument."
) : -abs(_e); })
;
2612 SET_FLAG(arg_flags, SD_RESOLVED_NO_ADDRESS, r == 0)(arg_flags) = (r == 0) ? ((arg_flags) | ((1UL << 7))) :
((arg_flags) & ~((1UL << 7)))
;
2613 break;
2614
2615 case ARG_SERVICE_TXT:
2616 r = parse_boolean(optarg);
2617 if (r < 0)
2618 return log_error_errno(r, "Failed to parse --service-txt= argument.")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2618, __func__, "Failed to parse --service-txt= argument."
) : -abs(_e); })
;
2619 SET_FLAG(arg_flags, SD_RESOLVED_NO_TXT, r == 0)(arg_flags) = (r == 0) ? ((arg_flags) | ((1UL << 6))) :
((arg_flags) & ~((1UL << 6)))
;
2620 break;
2621
2622 case ARG_SEARCH:
2623 r = parse_boolean(optarg);
2624 if (r < 0)
2625 return log_error_errno(r, "Failed to parse --search argument.")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2625, __func__, "Failed to parse --search argument."
) : -abs(_e); })
;
2626 SET_FLAG(arg_flags, SD_RESOLVED_NO_SEARCH, r == 0)(arg_flags) = (r == 0) ? ((arg_flags) | ((1UL << 8))) :
((arg_flags) & ~((1UL << 8)))
;
2627 break;
2628
2629 case ARG_STATISTICS:
2630 arg_mode = MODE_STATISTICS;
2631 break;
2632
2633 case ARG_RESET_STATISTICS:
2634 arg_mode = MODE_RESET_STATISTICS;
2635 break;
2636
2637 case ARG_FLUSH_CACHES:
2638 arg_mode = MODE_FLUSH_CACHES;
2639 break;
2640
2641 case ARG_RESET_SERVER_FEATURES:
2642 arg_mode = MODE_RESET_SERVER_FEATURES;
2643 break;
2644
2645 case ARG_STATUS:
2646 arg_mode = MODE_STATUS;
2647 break;
2648
2649 case ARG_NO_PAGER:
2650 arg_no_pager = true1;
2651 break;
2652
2653 case ARG_SET_DNS:
2654 r = strv_extend(&arg_set_dns, optarg);
2655 if (r < 0)
2656 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolvectl.c"
, 2656, __func__)
;
2657
2658 arg_mode = MODE_SET_LINK;
2659 break;
2660
2661 case ARG_SET_DOMAIN:
2662 r = strv_extend(&arg_set_domain, optarg);
2663 if (r < 0)
2664 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolvectl.c"
, 2664, __func__)
;
2665
2666 arg_mode = MODE_SET_LINK;
2667 break;
2668
2669 case ARG_SET_LLMNR:
2670 arg_set_llmnr = optarg;
2671 arg_mode = MODE_SET_LINK;
2672 break;
2673
2674 case ARG_SET_MDNS:
2675 arg_set_mdns = optarg;
2676 arg_mode = MODE_SET_LINK;
2677 break;
2678
2679 case ARG_SET_PRIVATE:
2680 arg_set_dns_over_tls = optarg;
2681 arg_mode = MODE_SET_LINK;
2682 break;
2683
2684 case ARG_SET_DNSSEC:
2685 arg_set_dnssec = optarg;
2686 arg_mode = MODE_SET_LINK;
2687 break;
2688
2689 case ARG_SET_NTA:
2690 r = strv_extend(&arg_set_nta, optarg);
2691 if (r < 0)
2692 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/resolve/resolvectl.c"
, 2692, __func__)
;
2693
2694 arg_mode = MODE_SET_LINK;
2695 break;
2696
2697 case ARG_REVERT_LINK:
2698 arg_mode = MODE_REVERT_LINK;
2699 break;
2700
2701 case '?':
2702 return -EINVAL22;
2703
2704 default:
2705 assert_not_reached("Unhandled option")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unhandled option"), "../src/resolve/resolvectl.c", 2705, __PRETTY_FUNCTION__
); } while (0)
;
2706 }
2707
2708 if (arg_type == 0 && arg_class != 0) {
2709 log_error("--class= may only be used in conjunction with --type=.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2709, __func__, "--class= may only be used in conjunction with --type=."
) : -abs(_e); })
;
2710 return -EINVAL22;
2711 }
2712
2713 if (arg_type != 0 && arg_mode == MODE_RESOLVE_SERVICE) {
2714 log_error("--service and --type= may not be combined.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2714, __func__, "--service and --type= may not be combined."
) : -abs(_e); })
;
2715 return -EINVAL22;
2716 }
2717
2718 if (arg_type != 0 && arg_class == 0)
2719 arg_class = DNS_CLASS_IN;
2720
2721 if (arg_class != 0 && arg_type == 0)
2722 arg_type = DNS_TYPE_A;
2723
2724 if (IN_SET(arg_mode, MODE_SET_LINK, MODE_REVERT_LINK)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){MODE_SET_LINK, MODE_REVERT_LINK})/sizeof
(int)]; switch(arg_mode) { case MODE_SET_LINK: case MODE_REVERT_LINK
: _found = 1; break; default: break; } _found; })
) {
2725
2726 if (arg_ifindex <= 0) {
2727 log_error("--set-dns=, --set-domain=, --set-llmnr=, --set-mdns=, --set-dnsovertls=, --set-dnssec=, --set-nta= and --revert require --interface=.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2727, __func__, "--set-dns=, --set-domain=, --set-llmnr=, --set-mdns=, --set-dnsovertls=, --set-dnssec=, --set-nta= and --revert require --interface=."
) : -abs(_e); })
;
2728 return -EINVAL22;
2729 }
2730
2731 if (arg_ifindex == LOOPBACK_IFINDEX1) {
2732 log_error("Interface can't be the loopback interface (lo). Sorry.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2732, __func__, "Interface can't be the loopback interface (lo). Sorry."
) : -abs(_e); })
;
2733 return -EINVAL22;
2734 }
2735 }
2736
2737 return 1 /* work to do */;
2738}
2739
2740static int native_parse_argv(int argc, char *argv[]) {
2741 enum {
2742 ARG_VERSION = 0x100,
2743 ARG_LEGEND,
2744 ARG_CNAME,
2745 ARG_SERVICE_ADDRESS,
2746 ARG_SERVICE_TXT,
2747 ARG_RAW,
2748 ARG_SEARCH,
2749 ARG_NO_PAGER,
2750 };
2751
2752 static const struct option options[] = {
2753 { "help", no_argument0, NULL((void*)0), 'h' },
2754 { "version", no_argument0, NULL((void*)0), ARG_VERSION },
2755 { "type", required_argument1, NULL((void*)0), 't' },
2756 { "class", required_argument1, NULL((void*)0), 'c' },
2757 { "legend", required_argument1, NULL((void*)0), ARG_LEGEND },
2758 { "interface", required_argument1, NULL((void*)0), 'i' },
2759 { "protocol", required_argument1, NULL((void*)0), 'p' },
2760 { "cname", required_argument1, NULL((void*)0), ARG_CNAME },
2761 { "service-address", required_argument1, NULL((void*)0), ARG_SERVICE_ADDRESS },
2762 { "service-txt", required_argument1, NULL((void*)0), ARG_SERVICE_TXT },
2763 { "raw", optional_argument2, NULL((void*)0), ARG_RAW },
2764 { "search", required_argument1, NULL((void*)0), ARG_SEARCH },
2765 { "no-pager", no_argument0, NULL((void*)0), ARG_NO_PAGER },
2766 {}
2767 };
2768
2769 int c, r;
2770
2771 assert(argc >= 0)do { if ((__builtin_expect(!!(!(argc >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("argc >= 0"), "../src/resolve/resolvectl.c"
, 2771, __PRETTY_FUNCTION__); } while (0)
;
1
Assuming 'argc' is >= 0
2
Taking false branch
3
Loop condition is false. Exiting loop
2772 assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("argv"), "../src/resolve/resolvectl.c", 2772
, __PRETTY_FUNCTION__); } while (0)
;
4
Assuming 'argv' is non-null
5
Taking false branch
6
Loop condition is false. Exiting loop
2773
2774 while ((c = getopt_long(argc, argv, "h46i:t:c:p:", options, NULL((void*)0))) >= 0)
7
Assuming the condition is true
8
Loop condition is true. Entering loop body
14
Assuming the condition is true
15
Loop condition is true. Entering loop body
2775 switch(c) {
9
Control jumps to 'case ARG_RAW:' at line 2865
16
Control jumps to 'case 112:' at line 2840
2776
2777 case 'h':
2778 native_help();
2779 return 0; /* done */;
2780
2781 case ARG_VERSION:
2782 return version();
2783
2784 case '4':
2785 arg_family = AF_INET2;
2786 break;
2787
2788 case '6':
2789 arg_family = AF_INET610;
2790 break;
2791
2792 case 'i':
2793 r = parse_ifindex_with_warn(optarg);
2794 if (r < 0)
2795 return r;
2796
2797 arg_ifindex = r;
2798 break;
2799
2800 case 't':
2801 if (streq(optarg, "help")(strcmp((optarg),("help")) == 0)) {
2802 help_dns_types();
2803 return 0;
2804 }
2805
2806 r = dns_type_from_string(optarg);
2807 if (r < 0) {
2808 log_error("Failed to parse RR record type %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2808, __func__, "Failed to parse RR record type %s"
, optarg) : -abs(_e); })
;
2809 return r;
2810 }
2811 arg_type = (uint16_t) r;
2812 assert((int) arg_type == r)do { if ((__builtin_expect(!!(!((int) arg_type == r)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("(int) arg_type == r"), "../src/resolve/resolvectl.c"
, 2812, __PRETTY_FUNCTION__); } while (0)
;
2813
2814 break;
2815
2816 case 'c':
2817 if (streq(optarg, "help")(strcmp((optarg),("help")) == 0)) {
2818 help_dns_classes();
2819 return 0;
2820 }
2821
2822 r = dns_class_from_string(optarg);
2823 if (r < 0) {
2824 log_error("Failed to parse RR record class %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2824, __func__, "Failed to parse RR record class %s"
, optarg) : -abs(_e); })
;
2825 return r;
2826 }
2827 arg_class = (uint16_t) r;
2828 assert((int) arg_class == r)do { if ((__builtin_expect(!!(!((int) arg_class == r)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("(int) arg_class == r"), "../src/resolve/resolvectl.c"
, 2828, __PRETTY_FUNCTION__); } while (0)
;
2829
2830 break;
2831
2832 case ARG_LEGEND:
2833 r = parse_boolean(optarg);
2834 if (r < 0)
2835 return log_error_errno(r, "Failed to parse --legend= argument")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2835, __func__, "Failed to parse --legend= argument"
) : -abs(_e); })
;
2836
2837 arg_legend = r;
2838 break;
2839
2840 case 'p':
2841 if (streq(optarg, "help")(strcmp((optarg),("help")) == 0)) {
17
Null pointer passed to 1st parameter expecting 'nonnull'
2842 help_protocol_types();
2843 return 0;
2844 } else if (streq(optarg, "dns")(strcmp((optarg),("dns")) == 0))
2845 arg_flags |= SD_RESOLVED_DNS(1UL << 0);
2846 else if (streq(optarg, "llmnr")(strcmp((optarg),("llmnr")) == 0))
2847 arg_flags |= SD_RESOLVED_LLMNR((1UL << 1)|(1UL << 2));
2848 else if (streq(optarg, "llmnr-ipv4")(strcmp((optarg),("llmnr-ipv4")) == 0))
2849 arg_flags |= SD_RESOLVED_LLMNR_IPV4(1UL << 1);
2850 else if (streq(optarg, "llmnr-ipv6")(strcmp((optarg),("llmnr-ipv6")) == 0))
2851 arg_flags |= SD_RESOLVED_LLMNR_IPV6(1UL << 2);
2852 else if (streq(optarg, "mdns")(strcmp((optarg),("mdns")) == 0))
2853 arg_flags |= SD_RESOLVED_MDNS((1UL << 3)|(1UL << 4));
2854 else if (streq(optarg, "mdns-ipv4")(strcmp((optarg),("mdns-ipv4")) == 0))
2855 arg_flags |= SD_RESOLVED_MDNS_IPV4(1UL << 3);
2856 else if (streq(optarg, "mdns-ipv6")(strcmp((optarg),("mdns-ipv6")) == 0))
2857 arg_flags |= SD_RESOLVED_MDNS_IPV6(1UL << 4);
2858 else {
2859 log_error("Unknown protocol specifier: %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2859, __func__, "Unknown protocol specifier: %s"
, optarg) : -abs(_e); })
;
2860 return -EINVAL22;
2861 }
2862
2863 break;
2864
2865 case ARG_RAW:
2866 if (on_tty()) {
10
Assuming the condition is false
11
Taking false branch
2867 log_error("Refusing to write binary data to tty.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2867, __func__, "Refusing to write binary data to tty."
) : -abs(_e); })
;
2868 return -ENOTTY25;
2869 }
2870
2871 if (optarg == NULL((void*)0) || streq(optarg, "payload")(strcmp((optarg),("payload")) == 0))
12
Assuming 'optarg' is equal to NULL
2872 arg_raw = RAW_PAYLOAD;
2873 else if (streq(optarg, "packet")(strcmp((optarg),("packet")) == 0))
2874 arg_raw = RAW_PACKET;
2875 else {
2876 log_error("Unknown --raw specifier \"%s\".", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2876, __func__, "Unknown --raw specifier \"%s\"."
, optarg) : -abs(_e); })
;
2877 return -EINVAL22;
2878 }
2879
2880 arg_legend = false0;
2881 break;
13
Execution continues on line 2774
2882
2883 case ARG_CNAME:
2884 r = parse_boolean(optarg);
2885 if (r < 0)
2886 return log_error_errno(r, "Failed to parse --cname= argument.")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2886, __func__, "Failed to parse --cname= argument."
) : -abs(_e); })
;
2887 SET_FLAG(arg_flags, SD_RESOLVED_NO_CNAME, r == 0)(arg_flags) = (r == 0) ? ((arg_flags) | ((1UL << 5))) :
((arg_flags) & ~((1UL << 5)))
;
2888 break;
2889
2890 case ARG_SERVICE_ADDRESS:
2891 r = parse_boolean(optarg);
2892 if (r < 0)
2893 return log_error_errno(r, "Failed to parse --service-address= argument.")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2893, __func__, "Failed to parse --service-address= argument."
) : -abs(_e); })
;
2894 SET_FLAG(arg_flags, SD_RESOLVED_NO_ADDRESS, r == 0)(arg_flags) = (r == 0) ? ((arg_flags) | ((1UL << 7))) :
((arg_flags) & ~((1UL << 7)))
;
2895 break;
2896
2897 case ARG_SERVICE_TXT:
2898 r = parse_boolean(optarg);
2899 if (r < 0)
2900 return log_error_errno(r, "Failed to parse --service-txt= argument.")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2900, __func__, "Failed to parse --service-txt= argument."
) : -abs(_e); })
;
2901 SET_FLAG(arg_flags, SD_RESOLVED_NO_TXT, r == 0)(arg_flags) = (r == 0) ? ((arg_flags) | ((1UL << 6))) :
((arg_flags) & ~((1UL << 6)))
;
2902 break;
2903
2904 case ARG_SEARCH:
2905 r = parse_boolean(optarg);
2906 if (r < 0)
2907 return log_error_errno(r, "Failed to parse --search argument.")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2907, __func__, "Failed to parse --search argument."
) : -abs(_e); })
;
2908 SET_FLAG(arg_flags, SD_RESOLVED_NO_SEARCH, r == 0)(arg_flags) = (r == 0) ? ((arg_flags) | ((1UL << 8))) :
((arg_flags) & ~((1UL << 8)))
;
2909 break;
2910
2911 case ARG_NO_PAGER:
2912 arg_no_pager = true1;
2913 break;
2914
2915 case '?':
2916 return -EINVAL22;
2917
2918 default:
2919 assert_not_reached("Unhandled option")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unhandled option"), "../src/resolve/resolvectl.c", 2919, __PRETTY_FUNCTION__
); } while (0)
;
2920 }
2921
2922 if (arg_type == 0 && arg_class != 0) {
2923 log_error("--class= may only be used in conjunction with --type=.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 2923, __func__, "--class= may only be used in conjunction with --type=."
) : -abs(_e); })
;
2924 return -EINVAL22;
2925 }
2926
2927 if (arg_type != 0 && arg_class == 0)
2928 arg_class = DNS_CLASS_IN;
2929
2930 if (arg_class != 0 && arg_type == 0)
2931 arg_type = DNS_TYPE_A;
2932
2933 return 1 /* work to do */;
2934}
2935
2936static int native_main(int argc, char *argv[], sd_bus *bus) {
2937
2938 static const Verb verbs[] = {
2939 { "help", VERB_ANY((unsigned) -1), VERB_ANY((unsigned) -1), 0, verb_help },
2940 { "status", VERB_ANY((unsigned) -1), VERB_ANY((unsigned) -1), VERB_DEFAULT, verb_status },
2941 { "query", 2, VERB_ANY((unsigned) -1), 0, verb_query },
2942 { "service", 2, 4, 0, verb_service },
2943 { "openpgp", 2, VERB_ANY((unsigned) -1), 0, verb_openpgp },
2944 { "tlsa", 2, VERB_ANY((unsigned) -1), 0, verb_tlsa },
2945 { "statistics", VERB_ANY((unsigned) -1), 1, 0, show_statistics },
2946 { "reset-statistics", VERB_ANY((unsigned) -1), 1, 0, reset_statistics },
2947 { "flush-caches", VERB_ANY((unsigned) -1), 1, 0, flush_caches },
2948 { "reset-server-features", VERB_ANY((unsigned) -1), 1, 0, reset_server_features },
2949 { "dns", VERB_ANY((unsigned) -1), VERB_ANY((unsigned) -1), 0, verb_dns },
2950 { "domain", VERB_ANY((unsigned) -1), VERB_ANY((unsigned) -1), 0, verb_domain },
2951 { "llmnr", VERB_ANY((unsigned) -1), 3, 0, verb_llmnr },
2952 { "mdns", VERB_ANY((unsigned) -1), 3, 0, verb_mdns },
2953 { "dnsovertls", VERB_ANY((unsigned) -1), 3, 0, verb_dns_over_tls },
2954 { "dnssec", VERB_ANY((unsigned) -1), 3, 0, verb_dnssec },
2955 { "nta", VERB_ANY((unsigned) -1), VERB_ANY((unsigned) -1), 0, verb_nta },
2956 { "revert", 2, 2, 0, verb_revert_link },
2957 {}
2958 };
2959
2960 return dispatch_verb(argc, argv, verbs, bus);
2961}
2962
2963static int translate(const char *verb, const char *single_arg, size_t num_args, char **args, sd_bus *bus) {
2964 char **fake, **p;
2965 size_t num, i;
2966
2967 assert(verb)do { if ((__builtin_expect(!!(!(verb)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("verb"), "../src/resolve/resolvectl.c", 2967
, __PRETTY_FUNCTION__); } while (0)
;
2968 assert(num_args == 0 || args)do { if ((__builtin_expect(!!(!(num_args == 0 || args)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("num_args == 0 || args"), "../src/resolve/resolvectl.c"
, 2968, __PRETTY_FUNCTION__); } while (0)
;
2969
2970 num = !!single_arg + num_args + 1;
2971
2972 p = fake = newa0(char *, num + 1)({ do { if ((__builtin_expect(!!(!(!size_multiply_overflow(sizeof
(char *), num + 1))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("!size_multiply_overflow(sizeof(char *), num + 1)"), "../src/resolve/resolvectl.c"
, 2972, __PRETTY_FUNCTION__); } while (0); (char **) ({ char *
_new_; size_t _len_ = sizeof(char *)*(num + 1); _new_ = __builtin_alloca
(_len_); (void *) memset(_new_, 0, _len_); }); })
;
2973 *p++ = (char *) verb;
2974 if (single_arg)
2975 *p++ = (char *) single_arg;
2976 for (i = 0; i < num_args; i++)
2977 *p++ = args[i];
2978
2979 optind = 0;
2980 return native_main((int) num, fake, bus);
2981}
2982
2983static int compat_main(int argc, char *argv[], sd_bus *bus) {
2984 int r = 0;
2985
2986 switch (arg_mode) {
2987 case MODE_RESOLVE_HOST:
2988 case MODE_RESOLVE_RECORD:
2989 return translate("query", NULL((void*)0), argc - optind, argv + optind, bus);
2990
2991 case MODE_RESOLVE_SERVICE:
2992 return translate("service", NULL((void*)0), argc - optind, argv + optind, bus);
2993
2994 case MODE_RESOLVE_OPENPGP:
2995 return translate("openpgp", NULL((void*)0), argc - optind, argv + optind, bus);
2996
2997 case MODE_RESOLVE_TLSA:
2998 return translate("tlsa", arg_service_family, argc - optind, argv + optind, bus);
2999
3000 case MODE_STATISTICS:
3001 return translate("statistics", NULL((void*)0), 0, NULL((void*)0), bus);
3002
3003 case MODE_RESET_STATISTICS:
3004 return translate("reset-statistics", NULL((void*)0), 0, NULL((void*)0), bus);
3005
3006 case MODE_FLUSH_CACHES:
3007 return translate("flush-caches", NULL((void*)0), 0, NULL((void*)0), bus);
3008
3009 case MODE_RESET_SERVER_FEATURES:
3010 return translate("reset-server-features", NULL((void*)0), 0, NULL((void*)0), bus);
3011
3012 case MODE_STATUS:
3013 return translate("status", NULL((void*)0), argc - optind, argv + optind, bus);
3014
3015 case MODE_SET_LINK:
3016 if (arg_set_dns) {
3017 r = translate("dns", arg_ifname, strv_length(arg_set_dns), arg_set_dns, bus);
3018 if (r < 0)
3019 return r;
3020 }
3021
3022 if (arg_set_domain) {
3023 r = translate("domain", arg_ifname, strv_length(arg_set_domain), arg_set_domain, bus);
3024 if (r < 0)
3025 return r;
3026 }
3027
3028 if (arg_set_nta) {
3029 r = translate("nta", arg_ifname, strv_length(arg_set_nta), arg_set_nta, bus);
3030 if (r < 0)
3031 return r;
3032 }
3033
3034 if (arg_set_llmnr) {
3035 r = translate("llmnr", arg_ifname, 1, (char **) &arg_set_llmnr, bus);
3036 if (r < 0)
3037 return r;
3038 }
3039
3040 if (arg_set_mdns) {
3041 r = translate("mdns", arg_ifname, 1, (char **) &arg_set_mdns, bus);
3042 if (r < 0)
3043 return r;
3044 }
3045
3046 if (arg_set_dns_over_tls) {
3047 r = translate("dnsovertls", arg_ifname, 1, (char **) &arg_set_dns_over_tls, bus);
3048 if (r < 0)
3049 return r;
3050 }
3051
3052 if (arg_set_dnssec) {
3053 r = translate("dnssec", arg_ifname, 1, (char **) &arg_set_dnssec, bus);
3054 if (r < 0)
3055 return r;
3056 }
3057
3058 return r;
3059
3060 case MODE_REVERT_LINK:
3061 return translate("revert", arg_ifname, 0, NULL((void*)0), bus);
3062
3063 case _MODE_INVALID:
3064 assert_not_reached("invalid mode")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"invalid mode"), "../src/resolve/resolvectl.c", 3064, __PRETTY_FUNCTION__
); } while (0)
;
3065 }
3066
3067 return 0;
3068}
3069
3070int main(int argc, char **argv) {
3071 sd_bus *bus = NULL((void*)0);
3072 int r;
3073
3074 setlocale(LC_ALL6, "");
3075 log_parse_environment()log_parse_environment_realm(LOG_REALM_SYSTEMD);
3076 log_open();
3077
3078 if (streq(program_invocation_short_name, "resolvconf")(strcmp((program_invocation_short_name),("resolvconf")) == 0))
3079 r = resolvconf_parse_argv(argc, argv);
3080 else if (streq(program_invocation_short_name, "systemd-resolve")(strcmp((program_invocation_short_name),("systemd-resolve")) ==
0)
)
3081 r = compat_parse_argv(argc, argv);
3082 else
3083 r = native_parse_argv(argc, argv);
3084 if (r <= 0)
3085 goto finish;
3086
3087 r = sd_bus_open_system(&bus);
3088 if (r < 0) {
3089 log_error_errno(r, "sd_bus_open_system: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/resolve/resolvectl.c", 3089, __func__, "sd_bus_open_system: %m"
) : -abs(_e); })
;
3090 goto finish;
3091 }
3092
3093 if (STR_IN_SET(program_invocation_short_name, "systemd-resolve", "resolvconf")(!!strv_find((((char**) ((const char*[]) { "systemd-resolve",
"resolvconf", ((void*)0) }))), (program_invocation_short_name
)))
)
3094 r = compat_main(argc, argv, bus);
3095 else
3096 r = native_main(argc, argv, bus);
3097
3098finish:
3099 /* make sure we terminate the bus connection first, and then close the
3100 * pager, see issue #3543 for the details. */
3101 sd_bus_flush_close_unref(bus);
3102 pager_close();
3103
3104 strv_free(arg_set_dns);
3105 strv_free(arg_set_domain);
3106 strv_free(arg_set_nta);
3107
3108 return r < 0 ? EXIT_FAILURE1 : EXIT_SUCCESS0;
3109}