]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-network/sd-network.c
sd-*.h: clean up exported (or to-be-exported) header files
[thirdparty/systemd.git] / src / libsystemd / sd-network / sd-network.c
CommitLineData
fe8db0c5
TG
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2011 Lennart Poettering
7 Copyright 2014 Tom Gundersen
8
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21***/
22
fe8db0c5 23#include <errno.h>
0a6f50c0 24#include <poll.h>
07630cea
LP
25#include <string.h>
26#include <sys/inotify.h>
fe8db0c5 27
07630cea
LP
28#include "sd-network.h"
29
30#include "fileio.h"
fe8db0c5 31#include "macro.h"
07630cea 32#include "string-util.h"
fe8db0c5 33#include "strv.h"
07630cea 34#include "util.h"
fe8db0c5 35
03cc0fd1
LP
36_public_ int sd_network_get_operational_state(char **state) {
37 _cleanup_free_ char *s = NULL;
deb2e523
TG
38 int r;
39
fe8db0c5
TG
40 assert_return(state, -EINVAL);
41
03cc0fd1 42 r = parse_env_file("/run/systemd/netif/state", NEWLINE, "OPER_STATE", &s, NULL);
cb6fa44c
TG
43 if (r == -ENOENT)
44 return -ENODATA;
03cc0fd1 45 if (r < 0)
fe8db0c5 46 return r;
03cc0fd1
LP
47 if (isempty(s))
48 return -ENODATA;
deb2e523
TG
49
50 *state = s;
51 s = NULL;
52
53 return 0;
54}
55
03cc0fd1
LP
56static int network_get_strv(const char *key, char ***ret) {
57 _cleanup_strv_free_ char **a = NULL;
bbf7c048
TG
58 _cleanup_free_ char *s = NULL;
59 int r;
60
03cc0fd1
LP
61 assert_return(ret, -EINVAL);
62
63 r = parse_env_file("/run/systemd/netif/state", NEWLINE, key, &s, NULL);
64 if (r == -ENOENT)
65 return -ENODATA;
66 if (r < 0)
67 return r;
68 if (isempty(s)) {
69 *ret = NULL;
70 return 0;
71 }
72
73 a = strv_split(s, " ");
74 if (!a)
75 return -ENOMEM;
76
77 strv_uniq(a);
78 r = strv_length(a);
79
80 *ret = a;
81 a = NULL;
82
83 return r;
84}
85
86_public_ int sd_network_get_dns(char ***ret) {
87 return network_get_strv("DNS", ret);
88}
89
90_public_ int sd_network_get_ntp(char ***ret) {
91 return network_get_strv("NTP", ret);
92}
93
8612e936
LP
94_public_ int sd_network_get_domains(char ***ret) {
95 return network_get_strv("DOMAINS", ret);
96}
97
438ca2bb 98_public_ int sd_network_link_get_setup_state(int ifindex, char **state) {
03cc0fd1
LP
99 _cleanup_free_ char *s = NULL, *p = NULL;
100 int r;
101
102 assert_return(ifindex > 0, -EINVAL);
bbf7c048
TG
103 assert_return(state, -EINVAL);
104
03cc0fd1
LP
105 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
106 return -ENOMEM;
107
108 r = parse_env_file(p, NEWLINE, "ADMIN_STATE", &s, NULL);
bbf7c048
TG
109 if (r == -ENOENT)
110 return -ENODATA;
03cc0fd1 111 if (r < 0)
bbf7c048 112 return r;
03cc0fd1
LP
113 if (isempty(s))
114 return -ENODATA;
bbf7c048
TG
115
116 *state = s;
117 s = NULL;
118
119 return 0;
120}
121
adc5b2e2
TG
122_public_ int sd_network_link_get_network_file(int ifindex, char **filename) {
123 _cleanup_free_ char *s = NULL, *p = NULL;
124 int r;
125
126 assert_return(ifindex > 0, -EINVAL);
127 assert_return(filename, -EINVAL);
128
129 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
130 return -ENOMEM;
131
132 r = parse_env_file(p, NEWLINE, "NETWORK_FILE", &s, NULL);
133 if (r == -ENOENT)
134 return -ENODATA;
135 if (r < 0)
136 return r;
137 if (isempty(s))
138 return -ENODATA;
139
140 *filename = s;
141 s = NULL;
142
143 return 0;
144}
145
d6731e4c 146_public_ int sd_network_link_get_operational_state(int ifindex, char **state) {
deb2e523
TG
147 _cleanup_free_ char *s = NULL, *p = NULL;
148 int r;
149
6dcaa6f5 150 assert_return(ifindex > 0, -EINVAL);
deb2e523
TG
151 assert_return(state, -EINVAL);
152
6dcaa6f5 153 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
deb2e523
TG
154 return -ENOMEM;
155
156 r = parse_env_file(p, NEWLINE, "OPER_STATE", &s, NULL);
157 if (r == -ENOENT)
158 return -ENODATA;
03cc0fd1 159 if (r < 0)
deb2e523 160 return r;
03cc0fd1
LP
161 if (isempty(s))
162 return -ENODATA;
cb6fa44c 163
fe8db0c5 164 *state = s;
cb6fa44c
TG
165 s = NULL;
166
fe8db0c5
TG
167 return 0;
168}
169
d6731e4c 170_public_ int sd_network_link_get_llmnr(int ifindex, char **llmnr) {
bd8f6538
TG
171 _cleanup_free_ char *s = NULL, *p = NULL;
172 int r;
173
174 assert_return(ifindex > 0, -EINVAL);
175 assert_return(llmnr, -EINVAL);
176
2cd666f8
LP
177 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
178 return -ENOMEM;
179
bd8f6538
TG
180 r = parse_env_file(p, NEWLINE, "LLMNR", &s, NULL);
181 if (r == -ENOENT)
182 return -ENODATA;
03cc0fd1 183 if (r < 0)
bd8f6538 184 return r;
03cc0fd1 185 if (isempty(s))
b3df0b34 186 return -ENODATA;
bd8f6538
TG
187
188 *llmnr = s;
189 s = NULL;
190
191 return 0;
192}
193
49699bac
SS
194_public_ int sd_network_link_get_lldp(int ifindex, char **lldp) {
195 _cleanup_free_ char *s = NULL, *p = NULL;
196 size_t size;
197 int r;
198
199 assert_return(ifindex > 0, -EINVAL);
200 assert_return(lldp, -EINVAL);
201
202 if (asprintf(&p, "/run/systemd/netif/lldp/%d", ifindex) < 0)
203 return -ENOMEM;
204
205 r = read_full_file(p, &s, &size);
206 if (r == -ENOENT)
207 return -ENODATA;
208 if (r < 0)
209 return r;
210 if (size <= 0)
211 return -ENODATA;
212
213 *lldp = s;
214 s = NULL;
215
216 return 0;
217}
218
8eb9058d
LP
219int sd_network_link_get_timezone(int ifindex, char **ret) {
220 _cleanup_free_ char *s = NULL, *p = NULL;
221 int r;
222
223 assert_return(ifindex > 0, -EINVAL);
224 assert_return(ret, -EINVAL);
225
226 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
227 return -ENOMEM;
228
229 r = parse_env_file(p, NEWLINE, "TIMEZONE", &s, NULL);
230 if (r == -ENOENT)
231 return -ENODATA;
232 if (r < 0)
233 return r;
234 if (isempty(s))
235 return -ENODATA;
236
237 *ret = s;
238 s = NULL;
239 return 0;
240}
49699bac 241
6436165d 242static int network_get_link_strv(const char *key, int ifindex, char ***ret) {
7dbf94a9 243 _cleanup_free_ char *p = NULL, *s = NULL;
6f4dedb2 244 _cleanup_strv_free_ char **a = NULL;
7dbf94a9
TG
245 int r;
246
6dcaa6f5 247 assert_return(ifindex > 0, -EINVAL);
6f4dedb2 248 assert_return(ret, -EINVAL);
7dbf94a9 249
6dcaa6f5 250 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
7dbf94a9
TG
251 return -ENOMEM;
252
bcb7a07e 253 r = parse_env_file(p, NEWLINE, key, &s, NULL);
03cc0fd1
LP
254 if (r == -ENOENT)
255 return -ENODATA;
7dbf94a9
TG
256 if (r < 0)
257 return r;
03cc0fd1 258 if (isempty(s)) {
6f4dedb2 259 *ret = NULL;
6f4dedb2
TG
260 return 0;
261 }
7dbf94a9 262
6f4dedb2
TG
263 a = strv_split(s, " ");
264 if (!a)
7dbf94a9
TG
265 return -ENOMEM;
266
6f4dedb2
TG
267 strv_uniq(a);
268 r = strv_length(a);
7dbf94a9 269
6f4dedb2
TG
270 *ret = a;
271 a = NULL;
7dbf94a9 272
6f4dedb2 273 return r;
7dbf94a9
TG
274}
275
d6731e4c 276_public_ int sd_network_link_get_dns(int ifindex, char ***ret) {
6436165d 277 return network_get_link_strv("DNS", ifindex, ret);
bcb7a07e
TG
278}
279
d6731e4c 280_public_ int sd_network_link_get_ntp(int ifindex, char ***ret) {
6436165d 281 return network_get_link_strv("NTP", ifindex, ret);
bcb7a07e
TG
282}
283
9b4d1882
TG
284_public_ int sd_network_link_get_domains(int ifindex, char ***ret) {
285 return network_get_link_strv("DOMAINS", ifindex, ret);
286}
287
0d4ad91d
AR
288_public_ int sd_network_link_get_carrier_bound_to(int ifindex, char ***ret) {
289 return network_get_link_strv("CARRIER_BOUND_TO", ifindex, ret);
290}
291
292_public_ int sd_network_link_get_carrier_bound_by(int ifindex, char ***ret) {
293 return network_get_link_strv("CARRIER_BOUND_BY", ifindex, ret);
294}
295
67272d15
TG
296_public_ int sd_network_link_get_wildcard_domain(int ifindex) {
297 int r;
298 _cleanup_free_ char *p = NULL, *s = NULL;
299
300 assert_return(ifindex > 0, -EINVAL);
301
302 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
303 return -ENOMEM;
304
305 r = parse_env_file(p, NEWLINE, "WILDCARD_DOMAIN", &s, NULL);
31d2e196
LP
306 if (r == -ENOENT)
307 return -ENODATA;
67272d15
TG
308 if (r < 0)
309 return r;
31d2e196
LP
310 if (isempty(s))
311 return -ENODATA;
67272d15
TG
312
313 return parse_boolean(s);
314}
315
fe8db0c5
TG
316static inline int MONITOR_TO_FD(sd_network_monitor *m) {
317 return (int) (unsigned long) m - 1;
318}
319
320static inline sd_network_monitor* FD_TO_MONITOR(int fd) {
321 return (sd_network_monitor*) (unsigned long) (fd + 1);
322}
323
870395a4
TG
324static int monitor_add_inotify_watch(int fd) {
325 int k;
326
327 k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE);
328 if (k >= 0)
329 return 0;
330 else if (errno != ENOENT)
331 return -errno;
332
333 k = inotify_add_watch(fd, "/run/systemd/netif/", IN_CREATE|IN_ISDIR);
334 if (k >= 0)
335 return 0;
336 else if (errno != ENOENT)
337 return -errno;
338
339 k = inotify_add_watch(fd, "/run/systemd/", IN_CREATE|IN_ISDIR);
340 if (k < 0)
341 return -errno;
342
343 return 0;
344}
345
0014a4ad 346_public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category) {
870395a4
TG
347 _cleanup_close_ int fd = -1;
348 int k;
fe8db0c5
TG
349 bool good = false;
350
351 assert_return(m, -EINVAL);
352
353 fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
354 if (fd < 0)
355 return -errno;
356
7e141e49 357 if (!category || streq(category, "links")) {
870395a4
TG
358 k = monitor_add_inotify_watch(fd);
359 if (k < 0)
360 return k;
fe8db0c5
TG
361
362 good = true;
363 }
364
3de1c8ce 365 if (!good)
fe8db0c5 366 return -EINVAL;
fe8db0c5
TG
367
368 *m = FD_TO_MONITOR(fd);
870395a4
TG
369 fd = -1;
370
fe8db0c5
TG
371 return 0;
372}
373
374_public_ sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m) {
375 int fd;
376
0b347626
TG
377 if (m) {
378 fd = MONITOR_TO_FD(m);
379 close_nointr(fd);
380 }
fe8db0c5
TG
381
382 return NULL;
383}
384
385_public_ int sd_network_monitor_flush(sd_network_monitor *m) {
870395a4
TG
386 union inotify_event_buffer buffer;
387 struct inotify_event *e;
388 ssize_t l;
389 int fd, k;
fe8db0c5
TG
390
391 assert_return(m, -EINVAL);
392
870395a4
TG
393 fd = MONITOR_TO_FD(m);
394
395 l = read(fd, &buffer, sizeof(buffer));
396 if (l < 0) {
397 if (errno == EAGAIN || errno == EINTR)
398 return 0;
399
400 return -errno;
401 }
402
403 FOREACH_INOTIFY_EVENT(e, buffer, l) {
404 if (e->mask & IN_ISDIR) {
405 k = monitor_add_inotify_watch(fd);
406 if (k < 0)
407 return k;
408
409 k = inotify_rm_watch(fd, e->wd);
410 if (k < 0)
411 return -errno;
412 }
413 }
414
415 return 0;
fe8db0c5
TG
416}
417
418_public_ int sd_network_monitor_get_fd(sd_network_monitor *m) {
419
420 assert_return(m, -EINVAL);
421
422 return MONITOR_TO_FD(m);
423}
424
425_public_ int sd_network_monitor_get_events(sd_network_monitor *m) {
426
427 assert_return(m, -EINVAL);
428
429 /* For now we will only return POLLIN here, since we don't
430 * need anything else ever for inotify. However, let's have
431 * this API to keep our options open should we later on need
432 * it. */
433 return POLLIN;
434}
435
436_public_ int sd_network_monitor_get_timeout(sd_network_monitor *m, uint64_t *timeout_usec) {
437
438 assert_return(m, -EINVAL);
439 assert_return(timeout_usec, -EINVAL);
440
441 /* For now we will only return (uint64_t) -1, since we don't
442 * need any timeout. However, let's have this API to keep our
443 * options open should we later on need it. */
444 *timeout_usec = (uint64_t) -1;
445 return 0;
446}