]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/sd-network.c
resolve-host: properly align long arguments in help text
[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
6dcaa6f5 110_public_ int sd_network_get_dhcp_lease(int ifindex, sd_dhcp_lease **ret) {
81d98a39 111 _cleanup_free_ char *p = NULL, *s = NULL;
68baa8fa 112 sd_dhcp_lease *lease = NULL;
fe8db0c5
TG
113 int r;
114
6dcaa6f5 115 assert_return(ifindex > 0, -EINVAL);
fe8db0c5
TG
116 assert_return(ret, -EINVAL);
117
6dcaa6f5 118 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
fe8db0c5
TG
119 return -ENOMEM;
120
121 r = parse_env_file(p, NEWLINE, "DHCP_LEASE", &s, NULL);
fe8db0c5 122
81d98a39 123 if (r < 0)
fe8db0c5 124 return r;
81d98a39 125 else if (!s)
fe8db0c5
TG
126 return -EIO;
127
128 r = dhcp_lease_load(s, &lease);
129 if (r < 0)
130 return r;
131
132 *ret = lease;
133
134 return 0;
135}
136
6f4dedb2 137static int network_get_strv(const char *key, int ifindex, char ***ret) {
7dbf94a9 138 _cleanup_free_ char *p = NULL, *s = NULL;
6f4dedb2 139 _cleanup_strv_free_ char **a = NULL;
7dbf94a9
TG
140 int r;
141
6dcaa6f5 142 assert_return(ifindex > 0, -EINVAL);
6f4dedb2 143 assert_return(ret, -EINVAL);
7dbf94a9 144
6dcaa6f5 145 if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
7dbf94a9
TG
146 return -ENOMEM;
147
bcb7a07e 148 r = parse_env_file(p, NEWLINE, key, &s, NULL);
7dbf94a9
TG
149 if (r < 0)
150 return r;
6f4dedb2
TG
151 else if (!s) {
152 *ret = NULL;
7dbf94a9 153
6f4dedb2
TG
154 return 0;
155 }
7dbf94a9 156
6f4dedb2
TG
157 a = strv_split(s, " ");
158 if (!a)
7dbf94a9
TG
159 return -ENOMEM;
160
6f4dedb2
TG
161 strv_uniq(a);
162 r = strv_length(a);
7dbf94a9 163
6f4dedb2
TG
164 *ret = a;
165 a = NULL;
7dbf94a9 166
6f4dedb2 167 return r;
7dbf94a9
TG
168}
169
6f4dedb2
TG
170_public_ int sd_network_get_dns(int ifindex, char ***ret) {
171 return network_get_strv("DNS", ifindex, ret);
bcb7a07e
TG
172}
173
6f4dedb2
TG
174_public_ int sd_network_get_ntp(int ifindex, char ***ret) {
175 return network_get_strv("NTP", ifindex, ret);
bcb7a07e
TG
176}
177
fe8db0c5
TG
178static inline int MONITOR_TO_FD(sd_network_monitor *m) {
179 return (int) (unsigned long) m - 1;
180}
181
182static inline sd_network_monitor* FD_TO_MONITOR(int fd) {
183 return (sd_network_monitor*) (unsigned long) (fd + 1);
184}
185
0014a4ad 186_public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category) {
fe8db0c5
TG
187 int fd, k;
188 bool good = false;
189
190 assert_return(m, -EINVAL);
191
192 fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
193 if (fd < 0)
194 return -errno;
195
7e141e49 196 if (!category || streq(category, "links")) {
85b5673b 197 k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE);
fe8db0c5 198 if (k < 0) {
03e334a1 199 safe_close(fd);
fe8db0c5
TG
200 return -errno;
201 }
202
203 good = true;
204 }
205
7e141e49 206 if (!category || streq(category, "leases")) {
85b5673b 207 k = inotify_add_watch(fd, "/run/systemd/netif/leases/", IN_MOVED_TO|IN_DELETE);
7e141e49
TG
208 if (k < 0) {
209 safe_close(fd);
210 return -errno;
211 }
212
213 good = true;
214 }
215
fe8db0c5
TG
216 if (!good) {
217 close_nointr(fd);
218 return -EINVAL;
219 }
220
221 *m = FD_TO_MONITOR(fd);
222 return 0;
223}
224
225_public_ sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m) {
226 int fd;
227
228 assert_return(m, NULL);
229
230 fd = MONITOR_TO_FD(m);
231 close_nointr(fd);
232
233 return NULL;
234}
235
236_public_ int sd_network_monitor_flush(sd_network_monitor *m) {
237
238 assert_return(m, -EINVAL);
239
240 return flush_fd(MONITOR_TO_FD(m));
241}
242
243_public_ int sd_network_monitor_get_fd(sd_network_monitor *m) {
244
245 assert_return(m, -EINVAL);
246
247 return MONITOR_TO_FD(m);
248}
249
250_public_ int sd_network_monitor_get_events(sd_network_monitor *m) {
251
252 assert_return(m, -EINVAL);
253
254 /* For now we will only return POLLIN here, since we don't
255 * need anything else ever for inotify. However, let's have
256 * this API to keep our options open should we later on need
257 * it. */
258 return POLLIN;
259}
260
261_public_ int sd_network_monitor_get_timeout(sd_network_monitor *m, uint64_t *timeout_usec) {
262
263 assert_return(m, -EINVAL);
264 assert_return(timeout_usec, -EINVAL);
265
266 /* For now we will only return (uint64_t) -1, since we don't
267 * need any timeout. However, let's have this API to keep our
268 * options open should we later on need it. */
269 *timeout_usec = (uint64_t) -1;
270 return 0;
271}