chiark / gitweb /
boot: efi - fix missing include
[elogind.git] / src / libsystemd / sd-network / sd-network.c
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
23 #include <string.h>
24 #include <errno.h>
25 #include <sys/inotify.h>
26 #include <poll.h>
27
28 #include "util.h"
29 #include "macro.h"
30 #include "strv.h"
31 #include "fileio.h"
32 #include "sd-network.h"
33
34 _public_ int sd_network_get_operational_state(char **state) {
35         _cleanup_free_ char *s = NULL;
36         int r;
37
38         assert_return(state, -EINVAL);
39
40         r = parse_env_file("/run/systemd/netif/state", NEWLINE, "OPER_STATE", &s, NULL);
41         if (r == -ENOENT)
42                 return -ENODATA;
43         if (r < 0)
44                 return r;
45         if (isempty(s))
46                 return -ENODATA;
47
48         *state = s;
49         s = NULL;
50
51         return 0;
52 }
53
54 static int network_get_strv(const char *key, char ***ret) {
55         _cleanup_strv_free_ char **a = NULL;
56         _cleanup_free_ char *s = NULL;
57         int r;
58
59         assert_return(ret, -EINVAL);
60
61         r = parse_env_file("/run/systemd/netif/state", NEWLINE, key, &s, NULL);
62         if (r == -ENOENT)
63                 return -ENODATA;
64         if (r < 0)
65                 return r;
66         if (isempty(s)) {
67                 *ret = NULL;
68                 return 0;
69         }
70
71         a = strv_split(s, " ");
72         if (!a)
73                 return -ENOMEM;
74
75         strv_uniq(a);
76         r = strv_length(a);
77
78         *ret = a;
79         a = NULL;
80
81         return r;
82 }
83
84 _public_ int sd_network_get_dns(char ***ret) {
85         return network_get_strv("DNS", ret);
86 }
87
88 _public_ int sd_network_get_ntp(char ***ret) {
89         return network_get_strv("NTP", ret);
90 }
91
92 _public_ int sd_network_get_domains(char ***ret) {
93         return network_get_strv("DOMAINS", ret);
94 }
95
96 _public_ int sd_network_link_get_setup_state(int ifindex, char **state) {
97         _cleanup_free_ char *s = NULL, *p = NULL;
98         int r;
99
100         assert_return(ifindex > 0, -EINVAL);
101         assert_return(state, -EINVAL);
102
103         if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
104                 return -ENOMEM;
105
106         r = parse_env_file(p, NEWLINE, "ADMIN_STATE", &s, NULL);
107         if (r == -ENOENT)
108                 return -ENODATA;
109         if (r < 0)
110                 return r;
111         if (isempty(s))
112                 return -ENODATA;
113
114         *state = s;
115         s = NULL;
116
117         return 0;
118 }
119
120 _public_ int sd_network_link_get_network_file(int ifindex, char **filename) {
121         _cleanup_free_ char *s = NULL, *p = NULL;
122         int r;
123
124         assert_return(ifindex > 0, -EINVAL);
125         assert_return(filename, -EINVAL);
126
127         if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
128                 return -ENOMEM;
129
130         r = parse_env_file(p, NEWLINE, "NETWORK_FILE", &s, NULL);
131         if (r == -ENOENT)
132                 return -ENODATA;
133         if (r < 0)
134                 return r;
135         if (isempty(s))
136                 return -ENODATA;
137
138         *filename = s;
139         s = NULL;
140
141         return 0;
142 }
143
144 _public_ int sd_network_link_get_operational_state(int ifindex, char **state) {
145         _cleanup_free_ char *s = NULL, *p = NULL;
146         int r;
147
148         assert_return(ifindex > 0, -EINVAL);
149         assert_return(state, -EINVAL);
150
151         if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
152                 return -ENOMEM;
153
154         r = parse_env_file(p, NEWLINE, "OPER_STATE", &s, NULL);
155         if (r == -ENOENT)
156                 return -ENODATA;
157         if (r < 0)
158                 return r;
159         if (isempty(s))
160                 return -ENODATA;
161
162         *state = s;
163         s = NULL;
164
165         return 0;
166 }
167
168 _public_ int sd_network_link_get_llmnr(int ifindex, char **llmnr) {
169         _cleanup_free_ char *s = NULL, *p = NULL;
170         int r;
171
172         assert_return(ifindex > 0, -EINVAL);
173         assert_return(llmnr, -EINVAL);
174
175         if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
176                 return -ENOMEM;
177
178         r = parse_env_file(p, NEWLINE, "LLMNR", &s, NULL);
179         if (r == -ENOENT)
180                 return -ENODATA;
181         if (r < 0)
182                 return r;
183         if (isempty(s))
184                 return -ENODATA;
185
186         *llmnr = s;
187         s = NULL;
188
189         return 0;
190 }
191
192 _public_ int sd_network_link_get_lldp(int ifindex, char **lldp) {
193         _cleanup_free_ char *s = NULL, *p = NULL;
194         size_t size;
195         int r;
196
197         assert_return(ifindex > 0, -EINVAL);
198         assert_return(lldp, -EINVAL);
199
200         if (asprintf(&p, "/run/systemd/netif/lldp/%d", ifindex) < 0)
201                 return -ENOMEM;
202
203         r = read_full_file(p, &s, &size);
204         if (r == -ENOENT)
205                 return -ENODATA;
206         if (r < 0)
207                 return r;
208         if (size <= 0)
209                 return -ENODATA;
210
211         *lldp = s;
212         s = NULL;
213
214         return 0;
215 }
216
217
218 static int network_get_link_strv(const char *key, int ifindex, char ***ret) {
219         _cleanup_free_ char *p = NULL, *s = NULL;
220         _cleanup_strv_free_ char **a = 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, key, &s, NULL);
230         if (r == -ENOENT)
231                 return -ENODATA;
232         if (r < 0)
233                 return r;
234         if (isempty(s)) {
235                 *ret = NULL;
236                 return 0;
237         }
238
239         a = strv_split(s, " ");
240         if (!a)
241                 return -ENOMEM;
242
243         strv_uniq(a);
244         r = strv_length(a);
245
246         *ret = a;
247         a = NULL;
248
249         return r;
250 }
251
252 _public_ int sd_network_link_get_dns(int ifindex, char ***ret) {
253         return network_get_link_strv("DNS", ifindex, ret);
254 }
255
256 _public_ int sd_network_link_get_ntp(int ifindex, char ***ret) {
257         return network_get_link_strv("NTP", ifindex, ret);
258 }
259
260 _public_ int sd_network_link_get_domains(int ifindex, char ***ret) {
261         return network_get_link_strv("DOMAINS", ifindex, ret);
262 }
263
264 _public_ int sd_network_link_get_wildcard_domain(int ifindex) {
265         int r;
266         _cleanup_free_ char *p = NULL, *s = NULL;
267
268         assert_return(ifindex > 0, -EINVAL);
269
270         if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
271                 return -ENOMEM;
272
273         r = parse_env_file(p, NEWLINE, "WILDCARD_DOMAIN", &s, NULL);
274         if (r == -ENOENT)
275                 return -ENODATA;
276         if (r < 0)
277                 return r;
278         if (isempty(s))
279                 return -ENODATA;
280
281         return parse_boolean(s);
282 }
283
284 static inline int MONITOR_TO_FD(sd_network_monitor *m) {
285         return (int) (unsigned long) m - 1;
286 }
287
288 static inline sd_network_monitor* FD_TO_MONITOR(int fd) {
289         return (sd_network_monitor*) (unsigned long) (fd + 1);
290 }
291
292 _public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category) {
293         int fd, k;
294         bool good = false;
295
296         assert_return(m, -EINVAL);
297
298         fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
299         if (fd < 0)
300                 return -errno;
301
302         if (!category || streq(category, "links")) {
303                 k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE);
304                 if (k < 0) {
305                         safe_close(fd);
306                         return -errno;
307                 }
308
309                 good = true;
310         }
311
312         if (!good) {
313                 close_nointr(fd);
314                 return -EINVAL;
315         }
316
317         *m = FD_TO_MONITOR(fd);
318         return 0;
319 }
320
321 _public_ sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m) {
322         int fd;
323
324         assert_return(m, NULL);
325
326         fd = MONITOR_TO_FD(m);
327         close_nointr(fd);
328
329         return NULL;
330 }
331
332 _public_ int sd_network_monitor_flush(sd_network_monitor *m) {
333
334         assert_return(m, -EINVAL);
335
336         return flush_fd(MONITOR_TO_FD(m));
337 }
338
339 _public_ int sd_network_monitor_get_fd(sd_network_monitor *m) {
340
341         assert_return(m, -EINVAL);
342
343         return MONITOR_TO_FD(m);
344 }
345
346 _public_ int sd_network_monitor_get_events(sd_network_monitor *m) {
347
348         assert_return(m, -EINVAL);
349
350         /* For now we will only return POLLIN here, since we don't
351          * need anything else ever for inotify.  However, let's have
352          * this API to keep our options open should we later on need
353          * it. */
354         return POLLIN;
355 }
356
357 _public_ int sd_network_monitor_get_timeout(sd_network_monitor *m, uint64_t *timeout_usec) {
358
359         assert_return(m, -EINVAL);
360         assert_return(timeout_usec, -EINVAL);
361
362         /* For now we will only return (uint64_t) -1, since we don't
363          * need any timeout. However, let's have this API to keep our
364          * options open should we later on need it. */
365         *timeout_usec = (uint64_t) -1;
366         return 0;
367 }