simplify android impl, to only use netlink

main
dignifiedquire 2 years ago
parent fba8877f4a
commit 64e265889a
  1. 3
      Cargo.toml
  2. 45
      src/interface/android.rs
  3. 26
      src/interface/unix.rs

@ -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"

@ -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<T>(sym: &'static str) -> Option<T> {
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::<T>(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<unsafe extern "C" fn(*mut *mut libc::ifaddrs) -> libc::c_int> {
static INSTANCE: OnceCell<
Option<unsafe extern "C" fn(*mut *mut libc::ifaddrs) -> libc::c_int>,
> = OnceCell::new();
*INSTANCE.get_or_init(|| load_symbol("getifaddrs"))
}
fn get_freeifaddrs() -> Option<unsafe extern "C" fn(*mut libc::ifaddrs)> {
static INSTANCE: OnceCell<Option<unsafe extern "C" fn(*mut libc::ifaddrs)>> = OnceCell::new();
*INSTANCE.get_or_init(|| load_symbol("freeifaddrs"))
pub fn unix_interfaces() -> Vec<Interface> {
netlink::unix_interfaces()
}
mod netlink {

@ -198,33 +198,17 @@ fn sockaddr_to_network_addr(sa: *const libc::sockaddr) -> (Option<MacAddr>, Opti
}
}
#[cfg(not(target_os = "android"))]
pub fn unix_interfaces() -> Vec<Interface> {
unix_interfaces_inner(libc::getifaddrs, libc::freeifaddrs)
}
#[cfg(target_os = "android")]
pub fn unix_interfaces() -> Vec<Interface> {
// 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<Interface> {
#[cfg(not(target_os = "android"))]
pub fn unix_interfaces() -> Vec<Interface> {
let mut ifaces: Vec<Interface> = 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();

Loading…
Cancel
Save