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