use std::net::{IpAddr, Ipv6Addr};
use xenet::net::interface::Interface;
use xenet::net::mac::MacAddr;
fn is_global_ipv6(ipv6_addr: &Ipv6Addr) -> bool {
!(ipv6_addr.is_unspecified()
|| ipv6_addr.is_loopback()
|| matches!(ipv6_addr.segments(), [0, 0, 0, 0, 0, 0xffff, _, _])
|| matches!(ipv6_addr.segments(), [0x64, 0xff9b, 1, _, _, _, _, _])
|| matches!(ipv6_addr.segments(), [0x100, 0, 0, 0, _, _, _, _])
|| (matches!(ipv6_addr.segments(), [0x2001, b, _, _, _, _, _, _] if b < 0x200)
&& !(
u128::from_be_bytes(ipv6_addr.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0001
|| u128::from_be_bytes(ipv6_addr.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0002
|| matches!(ipv6_addr.segments(), [0x2001, 3, _, _, _, _, _, _])
|| matches!(ipv6_addr.segments(), [0x2001, 4, 0x112, _, _, _, _, _])
|| matches!(ipv6_addr.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x2F)
))
|| ((ipv6_addr.segments()[0] == 0x2001) && (ipv6_addr.segments()[1] == 0x2) && (ipv6_addr.segments()[2] == 0))
|| ((ipv6_addr.segments()[0] & 0xfe00) == 0xfc00)
|| ((ipv6_addr.segments()[0] & 0xffc0) == 0xfe80))
}
pub(crate) fn get_interface_by_ip(ip_addr: IpAddr) -> Option<Interface> {
for iface in xenet::net::interface::get_interfaces() {
for ip in iface.ipv4.clone() {
if ip.addr == ip_addr {
return Some(iface);
}
}
for ip in iface.ipv6.clone() {
if ip.addr == ip_addr {
return Some(iface);
}
}
}
return None;
}
pub(crate) fn get_interface_by_index(index: u32) -> Option<Interface> {
for iface in xenet::net::interface::get_interfaces() {
if iface.index == index {
return Some(iface);
}
}
return None;
}
pub(crate) fn get_interface_by_name(name: String) -> Option<Interface> {
for iface in xenet::net::interface::get_interfaces() {
if iface.name == name {
return Some(iface);
}
}
return None;
}
pub(crate) fn get_interface_ipv4(iface: &Interface) -> Option<IpAddr> {
for ip in iface.ipv4.clone() {
return Some(IpAddr::V4(ip.addr));
}
return None;
}
pub(crate) fn get_interface_ipv6(iface: &Interface) -> Option<IpAddr> {
for ip in iface.ipv6.clone() {
if is_global_ipv6(&ip.addr) {
return Some(IpAddr::V6(ip.addr));
}
}
return None;
}
pub fn get_interface_macaddr(iface: &Interface) -> MacAddr {
match &iface.mac_addr {
Some(mac_addr) => mac_addr.clone(),
None => MacAddr::zero(),
}
}
pub fn get_gateway_macaddr(iface: &Interface) -> MacAddr {
match &iface.gateway {
Some(gateway) => gateway.mac_addr.clone(),
None => MacAddr::zero(),
}
}