use std::net::Ipv6Addr;
#[cfg(feature = "gateway")]
use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
fn try_ipv4() -> Option<IpAddr> {
let socket = match UdpSocket::bind(SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0)) {
Ok(s) => s,
Err(_) => return None,
};
match socket.connect(SocketAddr::new(
IpAddr::V4(Ipv4Addr::new(10, 254, 254, 254)),
1,
)) {
Ok(()) => (),
Err(_) => return None,
};
match socket.local_addr() {
Ok(addr) => return Some(addr.ip()),
Err(_) => return None,
};
}
fn try_ipv6() -> Option<IpAddr> {
let socket = match UdpSocket::bind(SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 0)) {
Ok(s) => s,
Err(_) => return None,
};
match socket.connect(SocketAddr::new(
IpAddr::V6(Ipv6Addr::new(
0xfdff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
)),
1,
)) {
Ok(()) => (),
Err(_) => return None,
};
match socket.local_addr() {
Ok(addr) => return Some(addr.ip()),
Err(_) => return None,
};
}
#[cfg(feature = "gateway")]
pub fn get_local_ipaddr() -> Option<IpAddr> {
if let Some(addr) = try_ipv4() {
Some(addr)
} else {
try_ipv6()
}
}