]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/libsystemd/sd-network/sd-network.c
sd-network: rename operstates 'down' -> 'off' and 'up' -> 'no-carrier'
[thirdparty/systemd.git] / src / libsystemd / sd-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
37_public_ int sd_network_get_operational_state(char **state) {
38 _cleanup_free_ char *s = NULL;
39 int r;
40
41 assert_return(state, -EINVAL);
42
43 r = parse_env_file("/run/systemd/netif/state", NEWLINE, "OPER_STATE", &s, NULL);
44 if (r == -ENOENT)
45 return -ENODATA;
46 if (r < 0)
47 return r;
48 if (isempty(s))
49 return -ENODATA;
50
51 *state = s;
52 s = NULL;
53
54 return 0;
55}
56
57static int network_get_strv(const char *key, char ***ret) {
58 _cleanup_strv_free_ char **a = NULL;
59 _cleanup_free_ char *s = NULL;
60 int r;
61
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
95_public_ int sd_network_link_get_state(int ifindex, char **state) {
96 _cleanup_free_ char *s = NULL, *p = NULL;
97 int r;
98
99 assert_return(ifindex > 0, -EINVAL);
100 assert_return(state, -EINVAL);
101
102 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
103 return -ENOMEM;
104
105 r = parse_env_file(p, NEWLINE, "ADMIN_STATE", &s, NULL);
106 if (r == -ENOENT)
107 return -ENODATA;
108 if (r < 0)
109 return r;
110 if (isempty(s))
111 return -ENODATA;
112
113 *state = s;
114 s = NULL;
115
116 return 0;
117}
118
119_public_ int sd_network_link_get_operational_state(int ifindex, char **state) {
120 _cleanup_free_ char *s = NULL, *p = NULL;
121 int r;
122
123 assert_return(ifindex > 0, -EINVAL);
124 assert_return(state, -EINVAL);
125
126 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
127 return -ENOMEM;
128
129 r = parse_env_file(p, NEWLINE, "OPER_STATE", &s, NULL);
130 if (r == -ENOENT)
131 return -ENODATA;
132 if (r < 0)
133 return r;
134 if (isempty(s))
135 return -ENODATA;
136
137 *state = s;
138 s = NULL;
139
140 return 0;
141}
142
143_public_ int sd_network_link_get_llmnr(int ifindex, char **llmnr) {
144 _cleanup_free_ char *s = NULL, *p = NULL;
145 int r;
146
147 assert_return(ifindex > 0, -EINVAL);
148 assert_return(llmnr, -EINVAL);
149
150 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
151 return -ENOMEM;
152
153 r = parse_env_file(p, NEWLINE, "LLMNR", &s, NULL);
154 if (r == -ENOENT)
155 return -ENODATA;
156 if (r < 0)
157 return r;
158 if (isempty(s))
159 return -ENODATA;
160
161 *llmnr = s;
162 s = NULL;
163
164 return 0;
165}
166
167static int network_get_link_strv(const char *key, int ifindex, char ***ret) {
168 _cleanup_free_ char *p = NULL, *s = NULL;
169 _cleanup_strv_free_ char **a = NULL;
170 int r;
171
172 assert_return(ifindex > 0, -EINVAL);
173 assert_return(ret, -EINVAL);
174
175 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
176 return -ENOMEM;
177
178 r = parse_env_file(p, NEWLINE, key, &s, NULL);
179 if (r == -ENOENT)
180 return -ENODATA;
181 if (r < 0)
182 return r;
183 if (isempty(s)) {
184 *ret = NULL;
185 return 0;
186 }
187
188 a = strv_split(s, " ");
189 if (!a)
190 return -ENOMEM;
191
192 strv_uniq(a);
193 r = strv_length(a);
194
195 *ret = a;
196 a = NULL;
197
198 return r;
199}
200
201_public_ int sd_network_link_get_dns(int ifindex, char ***ret) {
202 return network_get_link_strv("DNS", ifindex, ret);
203}
204
205_public_ int sd_network_link_get_ntp(int ifindex, char ***ret) {
206 return network_get_link_strv("NTP", ifindex, ret);
207}
208
209static inline int MONITOR_TO_FD(sd_network_monitor *m) {
210 return (int) (unsigned long) m - 1;
211}
212
213static inline sd_network_monitor* FD_TO_MONITOR(int fd) {
214 return (sd_network_monitor*) (unsigned long) (fd + 1);
215}
216
217_public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category) {
218 int fd, k;
219 bool good = false;
220
221 assert_return(m, -EINVAL);
222
223 fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
224 if (fd < 0)
225 return -errno;
226
227 if (!category || streq(category, "links")) {
228 k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE);
229 if (k < 0) {
230 safe_close(fd);
231 return -errno;
232 }
233
234 good = true;
235 }
236
237 if (!good) {
238 close_nointr(fd);
239 return -EINVAL;
240 }
241
242 *m = FD_TO_MONITOR(fd);
243 return 0;
244}
245
246_public_ sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m) {
247 int fd;
248
249 assert_return(m, NULL);
250
251 fd = MONITOR_TO_FD(m);
252 close_nointr(fd);
253
254 return NULL;
255}
256
257_public_ int sd_network_monitor_flush(sd_network_monitor *m) {
258
259 assert_return(m, -EINVAL);
260
261 return flush_fd(MONITOR_TO_FD(m));
262}
263
264_public_ int sd_network_monitor_get_fd(sd_network_monitor *m) {
265
266 assert_return(m, -EINVAL);
267
268 return MONITOR_TO_FD(m);
269}
270
271_public_ int sd_network_monitor_get_events(sd_network_monitor *m) {
272
273 assert_return(m, -EINVAL);
274
275 /* For now we will only return POLLIN here, since we don't
276 * need anything else ever for inotify. However, let's have
277 * this API to keep our options open should we later on need
278 * it. */
279 return POLLIN;
280}
281
282_public_ int sd_network_monitor_get_timeout(sd_network_monitor *m, uint64_t *timeout_usec) {
283
284 assert_return(m, -EINVAL);
285 assert_return(timeout_usec, -EINVAL);
286
287 /* For now we will only return (uint64_t) -1, since we don't
288 * need any timeout. However, let's have this API to keep our
289 * options open should we later on need it. */
290 *timeout_usec = (uint64_t) -1;
291 return 0;
292}