@@ -24,8 +24,8 @@ use system_configuration::{
24
24
network_configuration:: SCNetworkSet ,
25
25
preferences:: SCPreferences ,
26
26
sys:: schema_definitions:: {
27
- kSCDynamicStorePropNetPrimaryInterface, kSCPropInterfaceName, kSCPropNetIPv4Addresses ,
28
- kSCPropNetIPv4Router , kSCPropNetIPv6Addresses , kSCPropNetIPv6Router,
27
+ kSCDynamicStorePropNetPrimaryInterface, kSCPropInterfaceName, kSCPropNetIPv4Router ,
28
+ kSCPropNetIPv6Router,
29
29
} ,
30
30
} ;
31
31
@@ -168,19 +168,15 @@ impl PrimaryInterfaceMonitor {
168
168
let ( iface, index) = ifaces
169
169
. into_iter ( )
170
170
. filter_map ( |iface| {
171
- let index = if_nametoindex ( iface. name . as_str ( ) ) . map_err ( |error| {
172
- log:: error!( "Failed to retrieve interface index for \" {}\" : {error}" , iface. name) ;
173
- error
174
- } ) . ok ( ) ?;
175
-
176
- let active = is_active_interface ( & iface. name , family) . unwrap_or_else ( |error| {
177
- log:: error!( "is_active_interface() returned an error for interface \" {}\" , assuming active. Error: {error}" , iface. name) ;
178
- true
179
- } ) ;
180
- if !active {
181
- log:: debug!( "Skipping inactive interface {}, router IP {}" , iface. name, iface. router_ip) ;
182
- return None ;
183
- }
171
+ let index = if_nametoindex ( iface. name . as_str ( ) )
172
+ . map_err ( |error| {
173
+ log:: error!(
174
+ "Failed to retrieve interface index for \" {}\" : {error}" ,
175
+ iface. name
176
+ ) ;
177
+ error
178
+ } )
179
+ . ok ( ) ?;
184
180
Some ( ( iface, index) )
185
181
} )
186
182
. next ( ) ?;
@@ -232,10 +228,11 @@ impl PrimaryInterfaceMonitor {
232
228
log:: debug!( "Missing router IP for primary interface ({name}, {family})" ) ;
233
229
None
234
230
} ) ?;
235
- let first_ip = get_service_first_ip ( & ip_dict , family) . or_else ( || {
231
+ let first_ip = find_first_ip ( & name , family) . or_else ( || {
236
232
log:: debug!( "Missing IP for primary interface ({name}, {family})" ) ;
237
233
None
238
234
} ) ?;
235
+
239
236
Some ( NetworkServiceDetails {
240
237
name,
241
238
router_ip,
@@ -267,7 +264,7 @@ impl PrimaryInterfaceMonitor {
267
264
log:: debug!( "Missing router IP for {service_key} ({name}, {family})" ) ;
268
265
None
269
266
} ) ?;
270
- let first_ip = get_service_first_ip ( & ip_dict , family) . or_else ( || {
267
+ let first_ip = find_first_ip ( & name , family) . or_else ( || {
271
268
log:: debug!( "Missing IP for \" {service_key}\" ({name}, {family})" ) ;
272
269
None
273
270
} ) ?;
@@ -307,26 +304,30 @@ pub fn get_interface_link_addresses() -> io::Result<BTreeMap<String, SockaddrSto
307
304
Ok ( gateway_link_addrs)
308
305
}
309
306
310
- /// Return whether the given interface has an assigned (unicast) IP address.
311
- fn is_active_interface ( interface_name : & str , family : Family ) -> io :: Result < bool > {
307
+ /// Return the first assigned (unicast) IP address for the given interface
308
+ fn find_first_ip ( interface_name : & str , family : Family ) -> Option < IpAddr > {
312
309
let required_link_flags: InterfaceFlags = InterfaceFlags :: IFF_UP | InterfaceFlags :: IFF_RUNNING ;
313
- let has_ip_addr = nix:: ifaddrs:: getifaddrs ( ) ?
310
+ nix:: ifaddrs:: getifaddrs ( )
311
+ . ok ( ) ?
314
312
. filter ( |addr| ( addr. flags & required_link_flags) == required_link_flags)
315
313
. filter ( |addr| addr. interface_name == interface_name)
316
- . any ( |addr| {
317
- if let Some ( addr) = addr. address {
318
- // Check if family matches; ignore if link-local address
319
- match family {
320
- Family :: V4 => matches ! ( addr. as_sockaddr_in( ) , Some ( addr_in) if is_routable_v4( & addr_in. ip( ) ) ) ,
321
- Family :: V6 => {
322
- matches ! ( addr. as_sockaddr_in6( ) , Some ( addr_in) if is_routable_v6( & addr_in. ip( ) ) )
323
- }
324
- }
325
- } else {
326
- false
327
- }
328
- } ) ;
329
- Ok ( has_ip_addr)
314
+ . filter_map ( |addr| addr. address )
315
+ . find_map ( |addr| match family {
316
+ Family :: V4 => addr
317
+ . as_sockaddr_in ( )
318
+ . map ( |addr_in| IpAddr :: from ( addr_in. ip ( ) ) ) ,
319
+ Family :: V6 => addr
320
+ . as_sockaddr_in6 ( )
321
+ . map ( |addr_in| IpAddr :: from ( addr_in. ip ( ) ) ) ,
322
+ } )
323
+ . filter ( is_routable)
324
+ }
325
+
326
+ fn is_routable ( addr : & IpAddr ) -> bool {
327
+ match addr {
328
+ IpAddr :: V4 ( ip) => is_routable_v4 ( ip) ,
329
+ IpAddr :: V6 ( ip) => is_routable_v6 ( ip) ,
330
+ }
330
331
}
331
332
332
333
fn is_routable_v4 ( addr : & Ipv4Addr ) -> bool {
@@ -350,25 +351,6 @@ fn get_service_router_ip(ip_dict: &CFDictionary, family: Family) -> Option<IpAdd
350
351
get_dict_elem_as_string ( ip_dict, router_key) . and_then ( |ip| ip. parse ( ) . ok ( ) )
351
352
}
352
353
353
- fn get_service_first_ip ( ip_dict : & CFDictionary , family : Family ) -> Option < IpAddr > {
354
- let ip_key = if family == Family :: V4 {
355
- unsafe { kSCPropNetIPv4Addresses }
356
- } else {
357
- unsafe { kSCPropNetIPv6Addresses }
358
- } ;
359
- ip_dict
360
- . find ( ip_key. to_void ( ) )
361
- . map ( |s| unsafe { CFType :: wrap_under_get_rule ( * s) } )
362
- . and_then ( |s| s. downcast :: < CFArray > ( ) )
363
- . and_then ( |ips| {
364
- ips. get ( 0 )
365
- . map ( |ip| unsafe { CFType :: wrap_under_get_rule ( * ip) } )
366
- } )
367
- . and_then ( |s| s. downcast :: < CFString > ( ) )
368
- . map ( |s| s. to_string ( ) )
369
- . and_then ( |ip| ip. parse ( ) . ok ( ) )
370
- }
371
-
372
354
fn get_dict_elem_as_string ( dict : & CFDictionary , key : CFStringRef ) -> Option < String > {
373
355
dict. find ( key. to_void ( ) )
374
356
. map ( |s| unsafe { CFType :: wrap_under_get_rule ( * s) } )
0 commit comments