]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-link-bus.c
resolved: expose bus objects for each Link
[thirdparty/systemd.git] / src / resolve / resolved-link-bus.c
CommitLineData
3abaabda
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2016 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include "alloc-util.h"
23#include "bus-util.h"
24#include "parse-util.h"
25#include "resolve-util.h"
26#include "resolved-bus.h"
27#include "resolved-link-bus.h"
28#include "strv.h"
29
30static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_resolve_support, resolve_support, ResolveSupport);
31static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_dnssec_mode, dnssec_mode, DnssecMode);
32
33static int property_get_dns(
34 sd_bus *bus,
35 const char *path,
36 const char *interface,
37 const char *property,
38 sd_bus_message *reply,
39 void *userdata,
40 sd_bus_error *error) {
41
42 Link *l = userdata;
43 DnsServer *s;
44 int r;
45
46 assert(reply);
47 assert(l);
48
49 r = sd_bus_message_open_container(reply, 'a', "(iay)");
50 if (r < 0)
51 return r;
52
53 LIST_FOREACH(servers, s, l->dns_servers) {
54 r = bus_dns_server_append(reply, s, false);
55 if (r < 0)
56 return r;
57 }
58
59 return sd_bus_message_close_container(reply);
60}
61
62static int property_get_domains(
63 sd_bus *bus,
64 const char *path,
65 const char *interface,
66 const char *property,
67 sd_bus_message *reply,
68 void *userdata,
69 sd_bus_error *error) {
70
71 Link *l = userdata;
72 DnsSearchDomain *d;
73 int r;
74
75 assert(reply);
76 assert(l);
77
78 r = sd_bus_message_open_container(reply, 'a', "s");
79 if (r < 0)
80 return r;
81
82 LIST_FOREACH(domains, d, l->search_domains) {
83 r = sd_bus_message_append(reply, "s", d->name);
84 if (r < 0)
85 return r;
86 }
87
88 return sd_bus_message_close_container(reply);
89}
90
91static int property_get_scopes_mask(
92 sd_bus *bus,
93 const char *path,
94 const char *interface,
95 const char *property,
96 sd_bus_message *reply,
97 void *userdata,
98 sd_bus_error *error) {
99
100 Link *l = userdata;
101 uint64_t mask;
102
103 assert(reply);
104 assert(l);
105
106 mask = (l->unicast_scope ? SD_RESOLVED_DNS : 0) |
107 (l->llmnr_ipv4_scope ? SD_RESOLVED_LLMNR_IPV4 : 0) |
108 (l->llmnr_ipv6_scope ? SD_RESOLVED_LLMNR_IPV6 : 0) |
109 (l->mdns_ipv4_scope ? SD_RESOLVED_MDNS_IPV4 : 0) |
110 (l->mdns_ipv6_scope ? SD_RESOLVED_MDNS_IPV6 : 0);
111
112 return sd_bus_message_append(reply, "t", mask);
113}
114
115static int property_get_ntas(
116 sd_bus *bus,
117 const char *path,
118 const char *interface,
119 const char *property,
120 sd_bus_message *reply,
121 void *userdata,
122 sd_bus_error *error) {
123
124 Link *l = userdata;
125 const char *name;
126 Iterator i;
127 int r;
128
129 assert(reply);
130 assert(l);
131
132 r = sd_bus_message_open_container(reply, 'a', "s");
133 if (r < 0)
134 return r;
135
136 SET_FOREACH(name, l->dnssec_negative_trust_anchors, i) {
137 r = sd_bus_message_append(reply, "s", name);
138 if (r < 0)
139 return r;
140 }
141
142 return sd_bus_message_close_container(reply);
143}
144
145const sd_bus_vtable link_vtable[] = {
146 SD_BUS_VTABLE_START(0),
147
148 SD_BUS_PROPERTY("ScopesMask", "t", property_get_scopes_mask, 0, 0),
149 SD_BUS_PROPERTY("DNS", "a(iay)", property_get_dns, 0, 0),
150 SD_BUS_PROPERTY("Domains", "as", property_get_domains, 0, 0),
151 SD_BUS_PROPERTY("LLMNR", "s", property_get_resolve_support, offsetof(Link, llmnr_support), 0),
152 SD_BUS_PROPERTY("MulticastDNS", "s", property_get_resolve_support, offsetof(Link, mdns_support), 0),
153 SD_BUS_PROPERTY("DNSSEC", "s", property_get_dnssec_mode, offsetof(Link, dnssec_mode), 0),
154 SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", property_get_ntas, 0, 0),
155
156 SD_BUS_VTABLE_END
157};
158
159int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
160 _cleanup_free_ char *e = NULL;
161 Manager *m = userdata;
162 int ifindex;
163 Link *link;
164 int r;
165
166 assert(bus);
167 assert(path);
168 assert(interface);
169 assert(found);
170 assert(m);
171
172 r = sd_bus_path_decode(path, "/org/freedesktop/resolve1/link", &e);
173 if (r <= 0)
174 return 0;
175
176 r = parse_ifindex(e, &ifindex);
177 if (r < 0)
178 return 0;
179
180 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
181 if (!link)
182 return 0;
183
184 *found = link;
185 return 1;
186}
187
188char *link_bus_path(Link *link) {
189 _cleanup_free_ char *ifindex = NULL;
190 char *p;
191 int r;
192
193 assert(link);
194
195 if (asprintf(&ifindex, "%i", link->ifindex) < 0)
196 return NULL;
197
198 r = sd_bus_path_encode("/org/freedesktop/resolve1/link", ifindex, &p);
199 if (r < 0)
200 return NULL;
201
202 return p;
203}
204
205int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
206 _cleanup_strv_free_ char **l = NULL;
207 Manager *m = userdata;
208 Link *link;
209 Iterator i;
210 unsigned c = 0;
211
212 assert(bus);
213 assert(path);
214 assert(m);
215 assert(nodes);
216
217 l = new0(char*, hashmap_size(m->links) + 1);
218 if (!l)
219 return -ENOMEM;
220
221 HASHMAP_FOREACH(link, m->links, i) {
222 char *p;
223
224 p = link_bus_path(link);
225 if (!p)
226 return -ENOMEM;
227
228 l[c++] = p;
229 }
230
231 l[c] = NULL;
232 *nodes = l;
233 l = NULL;
234
235 return 1;
236}