]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-network/sd-network.c
TODO
[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
23#include <unistd.h>
24#include <string.h>
25#include <errno.h>
26#include <sys/inotify.h>
27#include <sys/poll.h>
deb2e523 28#include <net/if.h>
fe8db0c5
TG
29
30#include "util.h"
31#include "macro.h"
32#include "strv.h"
33#include "fileio.h"
34#include "sd-network.h"
7dbf94a9 35#include "network-internal.h"
fe8db0c5 36
03cc0fd1
LP
37_public_ int sd_network_get_operational_state(char **state) {
38 _cleanup_free_ char *s = NULL;
deb2e523
TG
39 int r;
40
fe8db0c5
TG
41 assert_return(state, -EINVAL);
42
03cc0fd1 43 r = parse_env_file("/run/systemd/netif/state", NEWLINE, "OPER_STATE", &s, NULL);
cb6fa44c
TG
44 if (r == -ENOENT)
45 return -ENODATA;
03cc0fd1 46 if (r < 0)
fe8db0c5 47 return r;
03cc0fd1
LP
48 if (isempty(s))
49 return -ENODATA;
deb2e523
TG
50
51 *state = s;
52 s = NULL;
53
54 return 0;
55}
56
03cc0fd1
LP
57static int network_get_strv(const char *key, char ***ret) {
58 _cleanup_strv_free_ char **a = NULL;
bbf7c048
TG
59 _cleanup_free_ char *s = NULL;
60 int r;
61
03cc0fd1
LP
62 assert_return(ret, -EINVAL);
63
64 r = parse_env_file("/run/systemd/netif/state", NEWLINE, key, &s, NULL);
65 if (r == -ENOENT)
66 return -ENODATA;
67 if (r < 0)
68 return r;
69 if (isempty(s)) {
70 *ret = NULL;
71 return 0;
72 }
73
74 a = strv_split(s, " ");
75 if (!a)
76 return -ENOMEM;
77
78 strv_uniq(a);
79 r = strv_length(a);
80
81 *ret = a;
82 a = NULL;
83
84 return r;
85}
86
87_public_ int sd_network_get_dns(char ***ret) {
88 return network_get_strv("DNS", ret);
89}
90
91_public_ int sd_network_get_ntp(char ***ret) {
92 return network_get_strv("NTP", ret);
93}
94
8612e936
LP
95_public_ int sd_network_get_domains(char ***ret) {
96 return network_get_strv("DOMAINS", ret);
97}
98
438ca2bb 99_public_ int sd_network_link_get_setup_state(int ifindex, char **state) {
03cc0fd1
LP
100 _cleanup_free_ char *s = NULL, *p = NULL;
101 int r;
102
103 assert_return(ifindex > 0, -EINVAL);
bbf7c048
TG
104 assert_return(state, -EINVAL);
105
03cc0fd1
LP
106 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
107 return -ENOMEM;
108
109 r = parse_env_file(p, NEWLINE, "ADMIN_STATE", &s, NULL);
bbf7c048
TG
110 if (r == -ENOENT)
111 return -ENODATA;
03cc0fd1 112 if (r < 0)
bbf7c048 113 return r;
03cc0fd1
LP
114 if (isempty(s))
115 return -ENODATA;
bbf7c048
TG
116
117 *state = s;
118 s = NULL;
119
120 return 0;
121}
122
d6731e4c 123_public_ int sd_network_link_get_operational_state(int ifindex, char **state) {
deb2e523
TG
124 _cleanup_free_ char *s = NULL, *p = NULL;
125 int r;
126
6dcaa6f5 127 assert_return(ifindex > 0, -EINVAL);
deb2e523
TG
128 assert_return(state, -EINVAL);
129
6dcaa6f5 130 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
deb2e523
TG
131 return -ENOMEM;
132
133 r = parse_env_file(p, NEWLINE, "OPER_STATE", &s, NULL);
134 if (r == -ENOENT)
135 return -ENODATA;
03cc0fd1 136 if (r < 0)
deb2e523 137 return r;
03cc0fd1
LP
138 if (isempty(s))
139 return -ENODATA;
cb6fa44c 140
fe8db0c5 141 *state = s;
cb6fa44c
TG
142 s = NULL;
143
fe8db0c5
TG
144 return 0;
145}
146
d6731e4c 147_public_ int sd_network_link_get_llmnr(int ifindex, char **llmnr) {
bd8f6538
TG
148 _cleanup_free_ char *s = NULL, *p = NULL;
149 int r;
150
151 assert_return(ifindex > 0, -EINVAL);
152 assert_return(llmnr, -EINVAL);
153
2cd666f8
LP
154 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
155 return -ENOMEM;
156
bd8f6538
TG
157 r = parse_env_file(p, NEWLINE, "LLMNR", &s, NULL);
158 if (r == -ENOENT)
159 return -ENODATA;
03cc0fd1 160 if (r < 0)
bd8f6538 161 return r;
03cc0fd1 162 if (isempty(s))
b3df0b34 163 return -ENODATA;
bd8f6538
TG
164
165 *llmnr = s;
166 s = NULL;
167
168 return 0;
169}
170
6436165d 171static int network_get_link_strv(const char *key, int ifindex, char ***ret) {
7dbf94a9 172 _cleanup_free_ char *p = NULL, *s = NULL;
6f4dedb2 173 _cleanup_strv_free_ char **a = NULL;
7dbf94a9
TG
174 int r;
175
6dcaa6f5 176 assert_return(ifindex > 0, -EINVAL);
6f4dedb2 177 assert_return(ret, -EINVAL);
7dbf94a9 178
6dcaa6f5 179 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
7dbf94a9
TG
180 return -ENOMEM;
181
bcb7a07e 182 r = parse_env_file(p, NEWLINE, key, &s, NULL);
03cc0fd1
LP
183 if (r == -ENOENT)
184 return -ENODATA;
7dbf94a9
TG
185 if (r < 0)
186 return r;
03cc0fd1 187 if (isempty(s)) {
6f4dedb2 188 *ret = NULL;
6f4dedb2
TG
189 return 0;
190 }
7dbf94a9 191
6f4dedb2
TG
192 a = strv_split(s, " ");
193 if (!a)
7dbf94a9
TG
194 return -ENOMEM;
195
6f4dedb2
TG
196 strv_uniq(a);
197 r = strv_length(a);
7dbf94a9 198
6f4dedb2
TG
199 *ret = a;
200 a = NULL;
7dbf94a9 201
6f4dedb2 202 return r;
7dbf94a9
TG
203}
204
d6731e4c 205_public_ int sd_network_link_get_dns(int ifindex, char ***ret) {
6436165d 206 return network_get_link_strv("DNS", ifindex, ret);
bcb7a07e
TG
207}
208
d6731e4c 209_public_ int sd_network_link_get_ntp(int ifindex, char ***ret) {
6436165d 210 return network_get_link_strv("NTP", ifindex, ret);
bcb7a07e
TG
211}
212
9b4d1882
TG
213_public_ int sd_network_link_get_domains(int ifindex, char ***ret) {
214 return network_get_link_strv("DOMAINS", ifindex, ret);
215}
216
67272d15
TG
217_public_ int sd_network_link_get_wildcard_domain(int ifindex) {
218 int r;
219 _cleanup_free_ char *p = NULL, *s = NULL;
220
221 assert_return(ifindex > 0, -EINVAL);
222
223 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
224 return -ENOMEM;
225
226 r = parse_env_file(p, NEWLINE, "WILDCARD_DOMAIN", &s, NULL);
31d2e196
LP
227 if (r == -ENOENT)
228 return -ENODATA;
67272d15
TG
229 if (r < 0)
230 return r;
31d2e196
LP
231 if (isempty(s))
232 return -ENODATA;
67272d15
TG
233
234 return parse_boolean(s);
235}
236
fe8db0c5
TG
237static inline int MONITOR_TO_FD(sd_network_monitor *m) {
238 return (int) (unsigned long) m - 1;
239}
240
241static inline sd_network_monitor* FD_TO_MONITOR(int fd) {
242 return (sd_network_monitor*) (unsigned long) (fd + 1);
243}
244
0014a4ad 245_public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category) {
fe8db0c5
TG
246 int fd, k;
247 bool good = false;
248
249 assert_return(m, -EINVAL);
250
251 fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
252 if (fd < 0)
253 return -errno;
254
7e141e49 255 if (!category || streq(category, "links")) {
85b5673b 256 k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE);
fe8db0c5 257 if (k < 0) {
03e334a1 258 safe_close(fd);
fe8db0c5
TG
259 return -errno;
260 }
261
262 good = true;
263 }
264
265 if (!good) {
266 close_nointr(fd);
267 return -EINVAL;
268 }
269
270 *m = FD_TO_MONITOR(fd);
271 return 0;
272}
273
274_public_ sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m) {
275 int fd;
276
277 assert_return(m, NULL);
278
279 fd = MONITOR_TO_FD(m);
280 close_nointr(fd);
281
282 return NULL;
283}
284
285_public_ int sd_network_monitor_flush(sd_network_monitor *m) {
286
287 assert_return(m, -EINVAL);
288
289 return flush_fd(MONITOR_TO_FD(m));
290}
291
292_public_ int sd_network_monitor_get_fd(sd_network_monitor *m) {
293
294 assert_return(m, -EINVAL);
295
296 return MONITOR_TO_FD(m);
297}
298
299_public_ int sd_network_monitor_get_events(sd_network_monitor *m) {
300
301 assert_return(m, -EINVAL);
302
303 /* For now we will only return POLLIN here, since we don't
304 * need anything else ever for inotify. However, let's have
305 * this API to keep our options open should we later on need
306 * it. */
307 return POLLIN;
308}
309
310_public_ int sd_network_monitor_get_timeout(sd_network_monitor *m, uint64_t *timeout_usec) {
311
312 assert_return(m, -EINVAL);
313 assert_return(timeout_usec, -EINVAL);
314
315 /* For now we will only return (uint64_t) -1, since we don't
316 * need any timeout. However, let's have this API to keep our
317 * options open should we later on need it. */
318 *timeout_usec = (uint64_t) -1;
319 return 0;
320}