]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/nss-myhostname/netlink.c
resolved: properly free network monitor
[thirdparty/systemd.git] / src / nss-myhostname / netlink.c
CommitLineData
8041b5ba
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
cbc06dcd 4 This file is part of systemd.
8041b5ba
LP
5
6 Copyright 2008-2011 Lennart Poettering
d1ca51b1 7 Copyright 2014 Tom Gundersen
8041b5ba 8
cbc06dcd
TG
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.
8041b5ba 13
cbc06dcd
TG
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
8041b5ba
LP
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
cbc06dcd
TG
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/>.
8041b5ba
LP
21***/
22
d1ca51b1
TG
23#include "sd-rtnl.h"
24#include "rtnl-util.h"
25#include "macro.h"
8041b5ba 26
1df2a0fc 27#include "ifconf.h"
8041b5ba 28
d1ca51b1
TG
29int ifconf_acquire_addresses(struct address **_list, unsigned *_n_list) {
30 _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
31 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
32 sd_rtnl_message *m;
33 _cleanup_free_ struct address *list = NULL;
34 struct address *new_list = NULL;
35 unsigned n_list = 0;
36 int r;
d73c3269 37
d1ca51b1
TG
38 r = sd_rtnl_open(&rtnl, 0);
39 if (r < 0)
40 return r;
8041b5ba 41
d1ca51b1
TG
42 r = sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
43 if (r < 0)
44 return r;
8041b5ba 45
d1ca51b1
TG
46 r = sd_rtnl_call(rtnl, req, 0, &reply);
47 if (r < 0)
48 return r;
49 m = reply;
50
51 do {
52 uint16_t type;
53 unsigned char scope;
54 unsigned char flags;
55 unsigned char family;
56 int ifindex;
57 union {
58 struct in_addr in;
59 struct in6_addr in6;
60 } address;
61
62 r = sd_rtnl_message_get_errno(m);
63 if (r < 0)
64 return r;
65
66 r = sd_rtnl_message_get_type(m, &type);
67 if (r < 0)
68 return r;
69
70 if (type != RTM_NEWADDR)
8041b5ba
LP
71 continue;
72
d1ca51b1
TG
73 r = sd_rtnl_message_addr_get_scope(m, &scope);
74 if (r < 0)
75 return r;
8041b5ba 76
d1ca51b1 77 if (scope == RT_SCOPE_HOST || scope == RT_SCOPE_NOWHERE)
d73c3269 78 continue;
8041b5ba 79
d1ca51b1
TG
80 r = sd_rtnl_message_addr_get_flags(m, &flags);
81 if (r < 0)
82 return r;
8041b5ba 83
d1ca51b1 84 if (flags & IFA_F_DEPRECATED)
d73c3269 85 continue;
8041b5ba 86
d1ca51b1
TG
87 r = sd_rtnl_message_addr_get_family(m, &family);
88 if (r < 0)
89 return r;
90
91 switch (family) {
92 case AF_INET:
93 r = sd_rtnl_message_read_in_addr(m, IFA_LOCAL, &address.in);
94 if (r < 0) {
95 r = sd_rtnl_message_read_in_addr(m, IFA_ADDRESS, &address.in);
96 if (r < 0)
97 continue;
98 }
99 break;
100 case AF_INET6:
101 r = sd_rtnl_message_read_in6_addr(m, IFA_LOCAL, &address.in6);
102 if (r < 0) {
103 r = sd_rtnl_message_read_in6_addr(m, IFA_ADDRESS, &address.in6);
104 if (r < 0)
105 continue;
106 }
107 break;
108 default:
d73c3269 109 continue;
d73c3269 110 }
8041b5ba 111
d1ca51b1
TG
112 r = sd_rtnl_message_addr_get_ifindex(m, &ifindex);
113 if (r < 0)
114 return r;
8041b5ba 115
d1ca51b1
TG
116 new_list = realloc(list, (n_list+1) * sizeof(struct address));
117 if (!new_list)
118 return -ENOMEM;
119 else
120 list = new_list;
8041b5ba 121
d1ca51b1 122 assert_cc(sizeof(address) <= 16);
8041b5ba 123
d1ca51b1
TG
124 list[n_list].family = family;
125 list[n_list].scope = scope;
126 memcpy(list[n_list].address, &address, sizeof(address));
127 list[n_list].ifindex = ifindex;
8041b5ba 128
d1ca51b1 129 n_list++;
7464b33d 130
d1ca51b1 131 } while ((m = sd_rtnl_message_next(m)));
8041b5ba 132
7ff7394d
ZJS
133 if (n_list)
134 qsort(list, n_list, sizeof(struct address), address_compare);
d73c3269 135
d73c3269 136 *_n_list = n_list;
d1ca51b1
TG
137 *_list = list;
138 list = NULL;
d73c3269
ZJS
139
140 return 0;
8041b5ba 141}