beid_api 0.8.0

BeID common lib
Documentation
use std::net::Ipv4Addr;

use nix::net::if_::InterfaceFlags;

/// Find IPv4 address that application in container can be used to connect to process on host machine.
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) {
            // Container cannot connect to host via loopback address
            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)));
    }
}