use std::net::Ipv4Addr;
use nix::net::if_::InterfaceFlags;
pub fn find_local_network_address() -> Option<Ipv4Addr> {
let mut addrs = nix::ifaddrs::getifaddrs().ok()?;
addrs.find_map(|addr| {
if addr.flags.contains(InterfaceFlags::IFF_LOOPBACK) {
return None;
}
let ipv4 = addr.address?.as_sockaddr_in()?.ip();
if is_docker_host_address(ipv4) {
return None;
}
Some(ipv4)
})
}
fn is_docker_host_address(ipv4: Ipv4Addr) -> bool {
matches!(ipv4.octets(), [172, 16..=31, 0, 1])
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_docker_host_address() {
assert!(is_docker_host_address(Ipv4Addr::new(172, 16, 0, 1)));
assert!(is_docker_host_address(Ipv4Addr::new(172, 17, 0, 1)));
assert!(is_docker_host_address(Ipv4Addr::new(172, 18, 0, 1)));
assert!(is_docker_host_address(Ipv4Addr::new(172, 19, 0, 1)));
assert!(is_docker_host_address(Ipv4Addr::new(172, 31, 0, 1)));
}
#[test]
fn test_is_not_docker_host_address() {
assert!(!is_docker_host_address(Ipv4Addr::new(172, 15, 0, 1)));
assert!(!is_docker_host_address(Ipv4Addr::new(172, 32, 0, 1)));
}
}