inherface 0.3.1

Retrieve a system's Network Interfaces on Linux
Documentation
//! Network Interface abstraction from commonly used fields for nodes from the
//! linked list provided by system functions like `getifaddrs` and
//! `GetAdaptersAddresses`.
#[cfg(feature = "mac")]
use mac_address::MacAddress;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::fmt::{Debug, Display};
use std::net::{Ipv4Addr, Ipv6Addr};

/// A system's network interface
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct NetworkInterface {
    /// Interface's name
    pub name: String,
    /// The position of this interface in the list of interfaces
    pub index: u32,
    /// Collection of interface's Ipv4 addresses
    #[cfg(feature = "ipv4")]
    pub v4_addr: Vec<V4IfAddr>,
    /// Collection of interface's Ipv6 addresses
    #[cfg(feature = "ipv6")]
    pub v6_addr: Vec<V6IfAddr>,
    /// MAC Address
    #[cfg(feature = "mac")]
    pub mac_addr: Option<MacAddress>,
}

/// IPV4 Interface from the AFINET network interface family
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
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: Option<Ipv4Addr>,
}

/// IPV6 Interface from the AFINET6 network interface family
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
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: Option<Ipv6Addr>,
}

impl NetworkInterface {
    /// Create a NetworkInterface with default, empty values
    /// for everything except name and index.
    pub fn new(name: String, index: u32) -> Self {
        NetworkInterface {
            name,
            index,
            #[cfg(feature = "ipv4")]
            v4_addr: Vec::new(),
            #[cfg(feature = "ipv6")]
            v6_addr: Vec::new(),
            #[cfg(feature = "mac")]
            mac_addr: None,
        }
    }

    /// Add ipv4 addresses to NetworkInterface.v4_addr
    #[cfg(feature = "ipv4")]
    pub fn add_v4(&mut self, ip: Ipv4Addr, broadcast: Option<Ipv4Addr>, netmask: Option<Ipv4Addr>) {
        let v4 = V4IfAddr {
            ip,
            broadcast,
            netmask,
        };

        self.v4_addr.push(v4);
    }

    /// Add ipv6 addresses to NetworkInterface.v6_addr
    #[cfg(feature = "ipv6")]
    pub fn add_v6(&mut self, ip: Ipv6Addr, broadcast: Option<Ipv6Addr>, netmask: Option<Ipv6Addr>) {
        let v6 = V6IfAddr {
            ip,
            broadcast,
            netmask,
        };

        self.v6_addr.push(v6);
    }
}

impl Display for NetworkInterface {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        writeln!(f, "{}. {}", self.index, self.name)?;

        #[cfg(feature = "mac")]
        if let Some(mac) = self.mac_addr {
            write!(f, "    link: {mac}\n")?;
        };

        #[cfg(feature = "ipv4")]
        for v4_addr in self.v4_addr.iter() {
            write!(f, "{}", v4_addr)?
        }

        #[cfg(feature = "ipv6")]
        for v6_addr in self.v6_addr.iter() {
            write!(f, "{}", v6_addr)?
        }

        Ok(())
    }
}

/// This implementation of Display is meant to be used in conjunction with `NetworkInterface`.
impl Display for V4IfAddr {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "    ipv4: {}\n", self.ip)?;

        if let Some(netmask) = self.netmask {
            write!(f, "        netmask: {netmask}\n")?;
        };

        if let Some(broadcast) = self.broadcast {
            write!(f, "        broadcast: {broadcast}\n")?;
        };

        Ok(())
    }
}

/// This implementation of Display is meant to be used in conjunction with `NetworkInterface`.
impl Display for V6IfAddr {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "    ipv6: {}\n", self.ip)?;

        if let Some(netmask) = self.netmask {
            write!(f, "        netmask: {netmask}\n")?;
        };

        if let Some(broadcast) = self.broadcast {
            write!(f, "        broadcast: {broadcast}\n")?;
        };

        Ok(())
    }
}