network_interface/
interface.rs

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