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}
26
27/// Network interface address
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
29#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
30pub enum Addr {
31    /// IPV4 Interface from the AFINET network interface family
32    V4(V4IfAddr),
33    /// IPV6 Interface from the AFINET6 network interface family
34    V6(V6IfAddr),
35}
36
37/// IPV4 Interface from the AFINET network interface family
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
39#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
40pub struct V4IfAddr {
41    /// The IP address for this network interface
42    pub ip: Ipv4Addr,
43    /// The broadcast address for this interface
44    pub broadcast: Option<Ipv4Addr>,
45    /// The netmask for this interface
46    pub netmask: Netmask<Ipv4Addr>,
47}
48
49/// IPV6 Interface from the AFINET6 network interface family
50#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
51#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
52pub struct V6IfAddr {
53    /// The IP address for this network interface
54    pub ip: Ipv6Addr,
55    /// The broadcast address for this interface
56    pub broadcast: Option<Ipv6Addr>,
57    /// The netmask for this interface
58    pub netmask: Netmask<Ipv6Addr>,
59}
60
61impl NetworkInterface {
62    pub fn new_afinet(
63        name: &str,
64        addr: Ipv4Addr,
65        netmask: Netmask<Ipv4Addr>,
66        broadcast: Option<Ipv4Addr>,
67        index: u32,
68    ) -> NetworkInterface {
69        let ifaddr_v4 = V4IfAddr {
70            ip: addr,
71            broadcast,
72            netmask,
73        };
74
75        NetworkInterface {
76            name: name.to_string(),
77            addr: vec![Addr::V4(ifaddr_v4)],
78            mac_addr: None,
79            index,
80        }
81    }
82
83    pub fn new_afinet6(
84        name: &str,
85        addr: Ipv6Addr,
86        netmask: Netmask<Ipv6Addr>,
87        broadcast: Option<Ipv6Addr>,
88        index: u32,
89    ) -> NetworkInterface {
90        let ifaddr_v6 = V6IfAddr {
91            ip: addr,
92            broadcast,
93            netmask,
94        };
95
96        NetworkInterface {
97            name: name.to_string(),
98            addr: vec![Addr::V6(ifaddr_v6)],
99            mac_addr: None,
100            index,
101        }
102    }
103
104    pub fn with_mac_addr(self, mac_addr: Option<String>) -> Self {
105        Self { mac_addr, ..self }
106    }
107}
108
109impl Addr {
110    pub fn ip(self) -> IpAddr {
111        match self {
112            Addr::V4(ifaddr_v4) => ifaddr_v4.ip.into(),
113            Addr::V6(ifaddr_v6) => ifaddr_v6.ip.into(),
114        }
115    }
116
117    pub fn broadcast(self) -> Option<IpAddr> {
118        match self {
119            Addr::V4(ifaddr_v4) => ifaddr_v4.broadcast.map(Into::into),
120            Addr::V6(ifaddr_v6) => ifaddr_v6.broadcast.map(Into::into),
121        }
122    }
123
124    pub fn netmask(self) -> Netmask<IpAddr> {
125        match self {
126            Addr::V4(ifaddr_v4) => ifaddr_v4.netmask.map(Into::into),
127            Addr::V6(ifaddr_v6) => ifaddr_v6.netmask.map(Into::into),
128        }
129    }
130}