use std::{
io,
net::{IpAddr, Ipv4Addr, Ipv6Addr},
};
use iprfc::RFC6890;
use smallvec_wrapper::SmallVec;
use crate::{ipv4_filter_to_ip_filter, ipv6_filter_to_ip_filter};
use super::{os, IfNet, Ifv4Net, Ifv6Net};
pub fn public_ipv4_addrs() -> io::Result<SmallVec<Ifv4Net>> {
cfg_if::cfg_if! {
if #[cfg(windows)] {
os::interface_ipv4_addresses(None, public_ip_filter)
} else {
os::interface_ipv4_addresses(0, public_ip_filter)
}
}
}
pub fn public_ipv6_addrs() -> io::Result<SmallVec<Ifv6Net>> {
cfg_if::cfg_if! {
if #[cfg(windows)] {
os::interface_ipv6_addresses(None, public_ip_filter)
} else {
os::interface_ipv6_addresses(0, public_ip_filter)
}
}
}
pub fn public_addrs() -> io::Result<SmallVec<IfNet>> {
cfg_if::cfg_if! {
if #[cfg(windows)] {
os::interface_addresses(None, public_ip_filter)
} else {
os::interface_addresses(0, public_ip_filter)
}
}
}
pub fn public_ipv4_addrs_by_filter<F>(mut f: F) -> io::Result<SmallVec<Ifv4Net>>
where
F: FnMut(&Ipv4Addr) -> bool,
{
cfg_if::cfg_if! {
if #[cfg(windows)] {
os::interface_ipv4_addresses(None, |ip| {
public_ip_filter(ip) && ipv4_filter_to_ip_filter(&mut f)(ip)
})
} else {
os::interface_ipv4_addresses(0, |ip| {
public_ip_filter(ip) && ipv4_filter_to_ip_filter(&mut f)(ip)
})
}
}
}
pub fn public_ipv6_addrs_by_filter<F>(mut f: F) -> io::Result<SmallVec<Ifv6Net>>
where
F: FnMut(&Ipv6Addr) -> bool,
{
cfg_if::cfg_if! {
if #[cfg(windows)] {
os::interface_ipv6_addresses(None, |ip| {
public_ip_filter(ip) && ipv6_filter_to_ip_filter(&mut f)(ip)
})
} else {
os::interface_ipv6_addresses(0, |ip| {
public_ip_filter(ip) && ipv6_filter_to_ip_filter(&mut f)(ip)
})
}
}
}
pub fn public_addrs_by_filter<F>(mut f: F) -> io::Result<SmallVec<IfNet>>
where
F: FnMut(&IpAddr) -> bool,
{
cfg_if::cfg_if! {
if #[cfg(windows)] {
os::interface_addresses(None, |ip| public_ip_filter(ip) && f(ip))
} else {
os::interface_addresses(0, |ip| public_ip_filter(ip) && f(ip))
}
}
}
#[inline]
fn public_ip_filter(ip: &IpAddr) -> bool {
!RFC6890.contains(ip)
}