20
20
#define DEBUG_LEVEL 5
21
21
#include <re_dbg.h>
22
22
23
+ enum { BUFSZ = 8192 , MAXIF = 255 };
24
+
23
25
24
26
static void parse_rtattr (struct rtattr * tb [], struct rtattr * rta , int len )
25
27
{
@@ -42,8 +44,38 @@ static bool is_ipv6_deprecated(uint32_t flags)
42
44
return false;
43
45
}
44
46
45
- static bool parse_msg (struct nlmsghdr * msg , int len , net_ifaddr_h * ifh ,
46
- void * arg )
47
+
48
+ static bool parse_msg_link (struct nlmsghdr * msg , size_t len , int * iff_up )
49
+ {
50
+ struct nlmsghdr * nlh ;
51
+ struct ifinfomsg * ifi ;
52
+
53
+ for (nlh = msg ; NLMSG_OK (nlh , len ); nlh = NLMSG_NEXT (nlh , len )) {
54
+ if (nlh -> nlmsg_type == NLMSG_DONE ) {
55
+ return true;
56
+ }
57
+ if (nlh -> nlmsg_type == NLMSG_ERROR ) {
58
+ DEBUG_WARNING ("netlink recv error\n" );
59
+ return true;
60
+ }
61
+
62
+ ifi = NLMSG_DATA (nlh );
63
+
64
+ if (ifi -> ifi_index >= MAXIF ) {
65
+ DEBUG_WARNING ("Max interface index [%d] reached!\n" ,
66
+ MAXIF );
67
+ return false;
68
+ }
69
+
70
+ iff_up [ifi -> ifi_index ] = ifi -> ifi_flags & IFF_UP ;
71
+ }
72
+
73
+ return false;
74
+ }
75
+
76
+
77
+ static bool parse_msg_addr (struct nlmsghdr * msg , size_t len , net_ifaddr_h * ifh ,
78
+ int * iff_up , void * arg )
47
79
{
48
80
struct nlmsghdr * nlh ;
49
81
for (nlh = msg ; NLMSG_OK (nlh , len ); nlh = NLMSG_NEXT (nlh , len )) {
@@ -56,7 +88,7 @@ static bool parse_msg(struct nlmsghdr *msg, int len, net_ifaddr_h *ifh,
56
88
}
57
89
if (nlh -> nlmsg_type == NLMSG_ERROR ) {
58
90
DEBUG_WARNING ("netlink recv error\n" );
59
- return false ;
91
+ return true ;
60
92
}
61
93
62
94
struct ifaddrmsg * ifa = NLMSG_DATA (nlh );
@@ -68,6 +100,9 @@ static bool parse_msg(struct nlmsghdr *msg, int len, net_ifaddr_h *ifh,
68
100
if (!rta_tb [IFA_ADDRESS ])
69
101
continue ;
70
102
103
+ if (ifa -> ifa_index < MAXIF && !iff_up [ifa -> ifa_index ])
104
+ continue ;
105
+
71
106
if (rta_tb [IFA_FLAGS ] && ifa -> ifa_family == AF_INET6 ) {
72
107
flags = * (uint32_t * )RTA_DATA (rta_tb [IFA_FLAGS ]);
73
108
if (is_ipv6_deprecated (flags ))
@@ -100,9 +135,10 @@ static bool parse_msg(struct nlmsghdr *msg, int len, net_ifaddr_h *ifh,
100
135
int net_netlink_addrs (net_ifaddr_h * ifh , void * arg )
101
136
{
102
137
int err = 0 ;
103
- char buffer [8192 ];
138
+ char buffer [BUFSZ ];
104
139
re_sock_t sock ;
105
140
int len ;
141
+ int iff_up [MAXIF ] = {0 };
106
142
107
143
struct {
108
144
struct nlmsghdr nlh ;
@@ -121,6 +157,25 @@ int net_netlink_addrs(net_ifaddr_h *ifh, void *arg)
121
157
struct timeval timeout = {5 , 0 };
122
158
setsockopt (sock , SOL_SOCKET , SO_RCVTIMEO , & timeout , sizeof (timeout ));
123
159
160
+ /* GETLINK */
161
+ memset (& req , 0 , sizeof (req ));
162
+ req .nlh .nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg ));
163
+ req .nlh .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP ;
164
+ req .nlh .nlmsg_type = RTM_GETLINK ;
165
+
166
+ if (send (sock , & req , req .nlh .nlmsg_len , 0 ) < 0 ) {
167
+ err = errno ;
168
+ DEBUG_WARNING ("sendto failed %m\n" , err );
169
+ goto out ;
170
+ }
171
+
172
+ while ((len = (int )recv (sock , buffer , sizeof (buffer ), 0 )) > 0 ) {
173
+ if (parse_msg_link ((struct nlmsghdr * )buffer , (size_t )len ,
174
+ iff_up ))
175
+ break ;
176
+ }
177
+
178
+ /* GETADDR */
124
179
memset (& req , 0 , sizeof (req ));
125
180
req .nlh .nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg ));
126
181
req .nlh .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP ;
@@ -133,7 +188,8 @@ int net_netlink_addrs(net_ifaddr_h *ifh, void *arg)
133
188
}
134
189
135
190
while ((len = (int )recv (sock , buffer , sizeof (buffer ), 0 )) > 0 ) {
136
- if (parse_msg ((struct nlmsghdr * )buffer , len , ifh , arg ))
191
+ if (parse_msg_addr ((struct nlmsghdr * )buffer , (size_t )len , ifh ,
192
+ iff_up , arg ))
137
193
break ;
138
194
}
139
195
0 commit comments