]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - 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
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>
28#include <net/if.h>
29
30#include "util.h"
31#include "macro.h"
32#include "strv.h"
33#include "fileio.h"
34#include "sd-network.h"
35#include "network-internal.h"
36#include "dhcp-lease-internal.h"
37
38_public_ int sd_network_get_link_state(int ifindex, char **state) {
39 _cleanup_free_ char *s = NULL, *p = NULL;
40 int r;
41
42 assert_return(ifindex > 0, -EINVAL);
43 assert_return(state, -EINVAL);
44
45 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
46 return -ENOMEM;
47
48 r = parse_env_file(p, NEWLINE, "ADMIN_STATE", &s, NULL);
49 if (r == -ENOENT)
50 return -ENODATA;
51 else if (r < 0)
52 return r;
53 else if (!s)
54 return -EIO;
55
56 if (streq(s, "initializing"))
57 return -EBUSY;
58
59 *state = s;
60 s = NULL;
61
62 return 0;
63}
64
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
71 r = parse_env_file("/run/systemd/netif/state", NEWLINE, "OPER_STATE",
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
86_public_ int sd_network_get_link_operational_state(int ifindex, char **state) {
87 _cleanup_free_ char *s = NULL, *p = NULL;
88 int r;
89
90 assert_return(ifindex > 0, -EINVAL);
91 assert_return(state, -EINVAL);
92
93 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
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;
103
104 *state = s;
105 s = NULL;
106
107 return 0;
108}
109
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
117 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
118 return -ENOMEM;
119
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;
125 else if (!s)
126 return -ENODATA;
127
128 *llmnr = s;
129 s = NULL;
130
131 return 0;
132}
133
134_public_ int sd_network_get_dhcp_lease(int ifindex, sd_dhcp_lease **ret) {
135 _cleanup_free_ char *p = NULL, *s = NULL;
136 sd_dhcp_lease *lease = NULL;
137 int r;
138
139 assert_return(ifindex > 0, -EINVAL);
140 assert_return(ret, -EINVAL);
141
142 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
143 return -ENOMEM;
144
145 r = parse_env_file(p, NEWLINE, "DHCP_LEASE", &s, NULL);
146
147 if (r < 0)
148 return r;
149 else if (!s)
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
161static int network_get_strv(const char *key, int ifindex, char ***ret) {
162 _cleanup_free_ char *p = NULL, *s = NULL;
163 _cleanup_strv_free_ char **a = NULL;
164 int r;
165
166 assert_return(ifindex > 0, -EINVAL);
167 assert_return(ret, -EINVAL);
168
169 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
170 return -ENOMEM;
171
172 r = parse_env_file(p, NEWLINE, key, &s, NULL);
173 if (r < 0)
174 return r;
175 else if (!s) {
176 *ret = NULL;
177
178 return 0;
179 }
180
181 a = strv_split(s, " ");
182 if (!a)
183 return -ENOMEM;
184
185 strv_uniq(a);
186 r = strv_length(a);
187
188 *ret = a;
189 a = NULL;
190
191 return r;
192}
193
194_public_ int sd_network_get_dns(int ifindex, char ***ret) {
195 return network_get_strv("DNS", ifindex, ret);
196}
197
198_public_ int sd_network_get_ntp(int ifindex, char ***ret) {
199 return network_get_strv("NTP", ifindex, ret);
200}
201
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
210_public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category) {
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
220 if (!category || streq(category, "links")) {
221 k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE);
222 if (k < 0) {
223 safe_close(fd);
224 return -errno;
225 }
226
227 good = true;
228 }
229
230 if (!category || streq(category, "leases")) {
231 k = inotify_add_watch(fd, "/run/systemd/netif/leases/", IN_MOVED_TO|IN_DELETE);
232 if (k < 0) {
233 safe_close(fd);
234 return -errno;
235 }
236
237 good = true;
238 }
239
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}