diff --git a/Cargo.toml b/Cargo.toml index 13f4421..0fffd3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,9 +14,6 @@ license = "MIT" libc = "0.2" [target.'cfg(target_os = "android")'.dependencies] -# DL Open -dlopen = "0.1.8" -once_cell = "1.17.1" # netlink netlink-packet-core = "0.5" netlink-packet-route = "0.15" diff --git a/src/interface/android.rs b/src/interface/android.rs index b8addde..ab2084a 100644 --- a/src/interface/android.rs +++ b/src/interface/android.rs @@ -1,46 +1,7 @@ -use once_cell::sync::OnceCell; +use crate::interface::Interface; -pub fn get_libc_ifaddrs() -> Option<( - unsafe extern "C" fn(*mut *mut libc::ifaddrs) -> libc::c_int, - unsafe extern "C" fn(*mut libc::ifaddrs), -)> { - match (get_getifaddrs(), get_freeifaddrs()) { - (Some(a), Some(b)) => Some((a, b)), - _ => None, - } -} - -fn load_symbol(sym: &'static str) -> Option { - const LIB_NAME: &str = "libc.so"; - - println!("loading symbol: {} from {}", sym, LIB_NAME); - match dlopen::raw::Library::open(LIB_NAME) { - Ok(lib) => match unsafe { lib.symbol::(sym) } { - Ok(val) => Some(val), - Err(err) => { - eprintln!("failed to load symbol {} from {}: {:?}", sym, LIB_NAME, err); - None - } - }, - Err(err) => { - eprintln!("failed to load {}: {:?}", LIB_NAME, err); - None - } - } -} - -fn get_getifaddrs() -> Option libc::c_int> { - static INSTANCE: OnceCell< - Option libc::c_int>, - > = OnceCell::new(); - - *INSTANCE.get_or_init(|| load_symbol("getifaddrs")) -} - -fn get_freeifaddrs() -> Option { - static INSTANCE: OnceCell> = OnceCell::new(); - - *INSTANCE.get_or_init(|| load_symbol("freeifaddrs")) +pub fn unix_interfaces() -> Vec { + netlink::unix_interfaces() } mod netlink { diff --git a/src/interface/unix.rs b/src/interface/unix.rs index f615d27..b91dcbe 100644 --- a/src/interface/unix.rs +++ b/src/interface/unix.rs @@ -198,33 +198,17 @@ fn sockaddr_to_network_addr(sa: *const libc::sockaddr) -> (Option, Opti } } -#[cfg(not(target_os = "android"))] -pub fn unix_interfaces() -> Vec { - unix_interfaces_inner(libc::getifaddrs, libc::freeifaddrs) -} #[cfg(target_os = "android")] pub fn unix_interfaces() -> Vec { - // Android is complicated - - // API 24+ contains the getifaddrs and freeifaddrs functions but the NDK doesn't - // expose those functions in ifaddrs.h when the minimum supported SDK is lower than 24 - // and therefore we need to load them manually. - if let Some((getifaddrs, freeeifaddrs)) = android::get_libc_ifaddrs() { - return unix_interfaces_inner(getifaddrs, freeifaddrs); - } - - // If API < 24 (or we can't load libc for some other reason), we fallback to using netlink - android::netlink::unix_interfaces() + super::android::unix_interfaces() } -pub fn unix_interfaces_inner( - getifaddrs: unsafe extern "C" fn(ifap: *mut *mut libc::ifaddrs) -> libc::c_int, - freeifaddrs: unsafe extern "C" fn(ifa: *mut libc::ifaddrs), -) -> Vec { +#[cfg(not(target_os = "android"))] +pub fn unix_interfaces() -> Vec { let mut ifaces: Vec = vec![]; let mut addrs: MaybeUninit<*mut libc::ifaddrs> = MaybeUninit::uninit(); - if unsafe { getifaddrs(addrs.as_mut_ptr()) } != 0 { + if unsafe { libc::getifaddrs(addrs.as_mut_ptr()) } != 0 { return ifaces; } let addrs = unsafe { addrs.assume_init() }; @@ -320,7 +304,7 @@ pub fn unix_interfaces_inner( addr = addr_ref.ifa_next; } unsafe { - freeifaddrs(addrs); + libc::freeifaddrs(addrs); } for iface in &mut ifaces { let name = CString::new(iface.name.as_bytes()).unwrap();