1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
7 Copyright 2014 Tom Gundersen
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.
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.
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/>.
26 #include <sys/inotify.h>
34 #include "sd-network.h"
35 #include "network-internal.h"
36 #include "dhcp-lease-internal.h"
38 static int link_get_flags(unsigned index, unsigned *flags) {
39 _cleanup_free_ char *s = NULL, *p = NULL;
45 if (asprintf(&p, "/run/systemd/network/links/%u", index) < 0)
48 r = parse_env_file(p, NEWLINE, "FLAGS", &s, NULL);
56 return safe_atou(s, flags);
59 _public_ int sd_network_link_is_loopback(unsigned index) {
63 r = link_get_flags(index, &flags);
67 return flags & IFF_LOOPBACK;
70 _public_ int sd_network_get_link_state(unsigned index, char **state) {
71 _cleanup_free_ char *s = NULL, *p = NULL;
74 assert_return(index, -EINVAL);
75 assert_return(state, -EINVAL);
77 if (asprintf(&p, "/run/systemd/network/links/%u", index) < 0)
80 r = parse_env_file(p, NEWLINE, "ADMIN_STATE", &s, NULL);
88 if (streq(s, "unmanaged"))
90 else if (streq(s, "initializing"))
99 _public_ int sd_network_get_operational_state(char **state) {
100 _cleanup_free_ char *s = NULL;
103 assert_return(state, -EINVAL);
105 r = parse_env_file("/run/systemd/network/state", NEWLINE, "OPER_STATE",
120 _public_ int sd_network_get_link_operational_state(unsigned index, char **state) {
121 _cleanup_free_ char *s = NULL, *p = NULL;
124 assert_return(index, -EINVAL);
125 assert_return(state, -EINVAL);
127 if (asprintf(&p, "/run/systemd/network/links/%u", index) < 0)
130 r = parse_env_file(p, NEWLINE, "OPER_STATE", &s, NULL);
144 _public_ int sd_network_get_dhcp_lease(unsigned index, sd_dhcp_lease **ret) {
145 _cleanup_free_ char *p = NULL, *s = NULL;
146 sd_dhcp_lease *lease;
149 assert_return(index, -EINVAL);
150 assert_return(ret, -EINVAL);
152 if (asprintf(&p, "/run/systemd/network/links/%u", index) < 0)
155 r = parse_env_file(p, NEWLINE, "DHCP_LEASE", &s, NULL);
162 r = dhcp_lease_load(s, &lease);
171 _public_ int sd_network_get_dns(unsigned index, struct in_addr **addr, size_t *addr_size) {
172 _cleanup_free_ char *p = NULL, *s = NULL;
175 assert_return(index, -EINVAL);
176 assert_return(addr, -EINVAL);
177 assert_return(addr_size, -EINVAL);
179 if (asprintf(&p, "/run/systemd/network/links/%u", index) < 0)
182 r = parse_env_file(p, NEWLINE, "DNS", &s, NULL);
188 return deserialize_in_addrs(addr, addr_size, s);
191 _public_ int sd_network_get_dns6(unsigned index, struct in6_addr **addr, size_t *addr_size) {
192 _cleanup_free_ char *p = NULL, *s = NULL;
195 assert_return(index, -EINVAL);
196 assert_return(addr, -EINVAL);
197 assert_return(addr_size, -EINVAL);
199 if (asprintf(&p, "/run/systemd/network/links/%u", index) < 0)
202 r = parse_env_file(p, NEWLINE, "DNS", &s, NULL);
208 return deserialize_in6_addrs(addr, addr_size, s);
211 _public_ int sd_network_dhcp_use_dns(unsigned index) {
212 _cleanup_free_ char *p = NULL, *s = NULL;
215 assert_return(index, -EINVAL);
217 if (asprintf(&p, "/run/systemd/network/links/%u", index) < 0)
220 r = parse_env_file(p, NEWLINE, "DHCP_USE_DNS", &s, NULL);
226 return parse_boolean(s);
229 _public_ int sd_network_get_ifindices(unsigned **indices) {
230 _cleanup_closedir_ DIR *d;
233 _cleanup_free_ uid_t *l = NULL;
235 d = opendir("/run/systemd/network/links/");
246 if (!de && errno != 0)
252 dirent_ensure_type(d, de);
254 if (!dirent_is_file(de))
257 k = safe_atou(de->d_name, &index);
262 if ((unsigned) r >= n) {
266 t = realloc(l, sizeof(unsigned) * n);
273 assert((unsigned) r < n);
287 static inline int MONITOR_TO_FD(sd_network_monitor *m) {
288 return (int) (unsigned long) m - 1;
291 static inline sd_network_monitor* FD_TO_MONITOR(int fd) {
292 return (sd_network_monitor*) (unsigned long) (fd + 1);
295 _public_ int sd_network_monitor_new(const char *category, sd_network_monitor **m) {
299 assert_return(m, -EINVAL);
301 fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
305 if (!category || streq(category, "links")) {
306 k = inotify_add_watch(fd, "/run/systemd/network/links/", IN_MOVED_TO|IN_DELETE);
315 if (!category || streq(category, "leases")) {
316 k = inotify_add_watch(fd, "/run/systemd/network/leases/", IN_MOVED_TO|IN_DELETE);
330 *m = FD_TO_MONITOR(fd);
334 _public_ sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m) {
337 assert_return(m, NULL);
339 fd = MONITOR_TO_FD(m);
345 _public_ int sd_network_monitor_flush(sd_network_monitor *m) {
347 assert_return(m, -EINVAL);
349 return flush_fd(MONITOR_TO_FD(m));
352 _public_ int sd_network_monitor_get_fd(sd_network_monitor *m) {
354 assert_return(m, -EINVAL);
356 return MONITOR_TO_FD(m);
359 _public_ int sd_network_monitor_get_events(sd_network_monitor *m) {
361 assert_return(m, -EINVAL);
363 /* For now we will only return POLLIN here, since we don't
364 * need anything else ever for inotify. However, let's have
365 * this API to keep our options open should we later on need
370 _public_ int sd_network_monitor_get_timeout(sd_network_monitor *m, uint64_t *timeout_usec) {
372 assert_return(m, -EINVAL);
373 assert_return(timeout_usec, -EINVAL);
375 /* For now we will only return (uint64_t) -1, since we don't
376 * need any timeout. However, let's have this API to keep our
377 * options open should we later on need it. */
378 *timeout_usec = (uint64_t) -1;