1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
//! Network Interface abstraction from commonly used fields for nodes from the
//! linked list provided by system functions like `getifaddrs` and
//! `GetAdaptersAddresses`.
use std::fmt::Debug;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
/// An alias for an `Option` that wraps either a `Ipv4Addr` or a `Ipv6Addr`
/// representing the IP for a Network Interface netmask
pub type Netmask<T> = Option<T>;
/// A system's network interface
#[derive(Debug, Clone)]
pub struct NetworkInterface {
/// Interface's name
pub name: String,
/// Interface's address
pub addr: Vec<Addr>,
/// MAC Address
pub mac_addr: Option<String>,
/// Interface's index
pub index: u32,
}
/// Network interface address
#[derive(Debug, Clone, Copy)]
pub enum Addr {
/// IPV4 Interface from the AFINET network interface family
V4(V4IfAddr),
/// IPV6 Interface from the AFINET6 network interface family
V6(V6IfAddr),
}
/// IPV4 Interface from the AFINET network interface family
#[derive(Debug, Clone, Copy)]
pub struct V4IfAddr {
/// The IP address for this network interface
pub ip: Ipv4Addr,
/// The broadcast address for this interface
pub broadcast: Option<Ipv4Addr>,
/// The netmask for this interface
pub netmask: Netmask<Ipv4Addr>,
}
/// IPV6 Interface from the AFINET6 network interface family
#[derive(Debug, Clone, Copy)]
pub struct V6IfAddr {
/// The IP address for this network interface
pub ip: Ipv6Addr,
/// The broadcast address for this interface
pub broadcast: Option<Ipv6Addr>,
/// The netmask for this interface
pub netmask: Netmask<Ipv6Addr>,
}
impl NetworkInterface {
pub fn new_afinet(
name: &str,
addr: Ipv4Addr,
netmask: Netmask<Ipv4Addr>,
broadcast: Option<Ipv4Addr>,
index: u32,
) -> NetworkInterface {
let ifaddr_v4 = V4IfAddr {
ip: addr,
broadcast,
netmask,
};
NetworkInterface {
name: name.to_string(),
addr: vec![Addr::V4(ifaddr_v4)],
mac_addr: None,
index,
}
}
pub fn new_afinet6(
name: &str,
addr: Ipv6Addr,
netmask: Netmask<Ipv6Addr>,
broadcast: Option<Ipv6Addr>,
index: u32,
) -> NetworkInterface {
let ifaddr_v6 = V6IfAddr {
ip: addr,
broadcast,
netmask,
};
NetworkInterface {
name: name.to_string(),
addr: vec![Addr::V6(ifaddr_v6)],
mac_addr: None,
index,
}
}
pub fn with_mac_addr(self, mac_addr: Option<String>) -> Self {
Self { mac_addr, ..self }
}
}
impl Addr {
pub fn ip(self) -> IpAddr {
match self {
Addr::V4(ifaddr_v4) => ifaddr_v4.ip.into(),
Addr::V6(ifaddr_v6) => ifaddr_v6.ip.into(),
}
}
pub fn broadcast(self) -> Option<IpAddr> {
match self {
Addr::V4(ifaddr_v4) => ifaddr_v4.broadcast.map(Into::into),
Addr::V6(ifaddr_v6) => ifaddr_v6.broadcast.map(Into::into),
}
}
pub fn netmask(self) -> Netmask<IpAddr> {
match self {
Addr::V4(ifaddr_v4) => ifaddr_v4.netmask.map(Into::into),
Addr::V6(ifaddr_v6) => ifaddr_v6.netmask.map(Into::into),
}
}
}