use std::{io, net::IpAddr};
pub const DEFAULT_NET_IF_NAME: &str = "eth0";
#[derive(Debug, thiserror::Error)]
pub enum NetInterfaceError {
#[error("failed to read OS interfaces: {0}")]
Io(io::Error),
#[error("interface not found: {0}, found other interfaces: {1:?}")]
IFNotFound(String, Vec<String>),
}
pub fn resolve_net_if_ip(if_name: &str) -> Result<IpAddr, NetInterfaceError> {
match if_addrs::get_if_addrs() {
Ok(ifs) => {
let ip = ifs.iter().find(|i| i.name == if_name).map(|i| i.ip());
match ip {
Some(ip) => Ok(ip),
None => {
let ifs = ifs.into_iter().map(|i| i.name.as_str().into()).collect();
Err(NetInterfaceError::IFNotFound(if_name.into(), ifs))
}
}
}
Err(err) => Err(NetInterfaceError::Io(err)),
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::net::Ipv4Addr;
#[test]
fn read_docker_if_addr() {
const LOCALHOST_IF: [&str; 2] = ["lo0", "lo"];
let ip = resolve_net_if_ip(LOCALHOST_IF[0])
.unwrap_or_else(|_| resolve_net_if_ip(LOCALHOST_IF[1]).unwrap());
assert_eq!(ip, Ipv4Addr::LOCALHOST);
}
}