chiark / gitweb /
pam_elogind compiling
[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_carrier_bound_to(int ifindex, char ***ret) {
265         return network_get_link_strv("CARRIER_BOUND_TO", ifindex, ret);
266 }
267
268 _public_ int sd_network_link_get_carrier_bound_by(int ifindex, char ***ret) {
269         return network_get_link_strv("CARRIER_BOUND_BY", ifindex, ret);
270 }
271
272 _public_ int sd_network_link_get_wildcard_domain(int ifindex) {
273         int r;
274         _cleanup_free_ char *p = NULL, *s = NULL;
275
276         assert_return(ifindex > 0, -EINVAL);
277
278         if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
279                 return -ENOMEM;
280
281         r = parse_env_file(p, NEWLINE, "WILDCARD_DOMAIN", &s, NULL);
282         if (r == -ENOENT)
283                 return -ENODATA;
284         if (r < 0)
285                 return r;
286         if (isempty(s))
287                 return -ENODATA;
288
289         return parse_boolean(s);
290 }
291
292 static inline int MONITOR_TO_FD(sd_network_monitor *m) {
293         return (int) (unsigned long) m - 1;
294 }
295
296 static inline sd_network_monitor* FD_TO_MONITOR(int fd) {
297         return (sd_network_monitor*) (unsigned long) (fd + 1);
298 }
299
300 _public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category) {
301         int fd, k;
302         bool good = false;
303
304         assert_return(m, -EINVAL);
305
306         fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
307         if (fd < 0)
308                 return -errno;
309
310         if (!category || streq(category, "links")) {
311                 k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE);
312                 if (k < 0) {
313                         safe_close(fd);
314                         return -errno;
315                 }
316
317                 good = true;
318         }
319
320         if (!good) {
321                 close_nointr(fd);
322                 return -EINVAL;
323         }
324
325         *m = FD_TO_MONITOR(fd);
326         return 0;
327 }
328
329 _public_ sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m) {
330         int fd;
331
332         assert_return(m, NULL);
333
334         fd = MONITOR_TO_FD(m);
335         close_nointr(fd);
336
337         return NULL;
338 }
339
340 _public_ int sd_network_monitor_flush(sd_network_monitor *m) {
341
342         assert_return(m, -EINVAL);
343
344         return flush_fd(MONITOR_TO_FD(m));
345 }
346
347 _public_ int sd_network_monitor_get_fd(sd_network_monitor *m) {
348
349         assert_return(m, -EINVAL);
350
351         return MONITOR_TO_FD(m);
352 }
353
354 _public_ int sd_network_monitor_get_events(sd_network_monitor *m) {
355
356         assert_return(m, -EINVAL);
357
358         /* For now we will only return POLLIN here, since we don't
359          * need anything else ever for inotify.  However, let's have
360          * this API to keep our options open should we later on need
361          * it. */
362         return POLLIN;
363 }
364
365 _public_ int sd_network_monitor_get_timeout(sd_network_monitor *m, uint64_t *timeout_usec) {
366
367         assert_return(m, -EINVAL);
368         assert_return(timeout_usec, -EINVAL);
369
370         /* For now we will only return (uint64_t) -1, since we don't
371          * need any timeout. However, let's have this API to keep our
372          * options open should we later on need it. */
373         *timeout_usec = (uint64_t) -1;
374         return 0;
375 }