default_net/interface/
mod.rs

1mod shared;
2pub use self::shared::*;
3
4mod types;
5pub use self::types::*;
6
7#[cfg(any(
8    target_os = "linux",
9    target_os = "macos",
10    target_os = "openbsd",
11    target_os = "freebsd",
12    target_os = "netbsd",
13    target_os = "ios",
14    target_os = "android"
15))]
16mod unix;
17#[cfg(any(
18    target_os = "linux",
19    target_os = "macos",
20    target_os = "openbsd",
21    target_os = "freebsd",
22    target_os = "netbsd",
23    target_os = "ios",
24    target_os = "android"
25))]
26use self::unix::*;
27
28#[cfg(target_os = "windows")]
29mod windows;
30#[cfg(target_os = "windows")]
31use self::windows::*;
32
33#[cfg(feature = "serde")]
34use serde::{Deserialize, Serialize};
35
36#[cfg(any(target_os = "linux", target_os = "android"))]
37mod linux;
38
39#[cfg(target_os = "android")]
40mod android;
41
42#[cfg(any(target_os = "macos", target_os = "ios"))]
43mod macos;
44
45use crate::gateway::Gateway;
46use crate::ip::{Ipv4Net, Ipv6Net};
47use crate::mac::MacAddr;
48use crate::sys;
49use std::net::IpAddr;
50
51/// Structure of Network Interface information
52#[derive(Clone, Eq, PartialEq, Hash, Debug)]
53#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
54pub struct Interface {
55    /// Index of network interface
56    pub index: u32,
57    /// Name of network interface
58    pub name: String,
59    /// Friendly Name of network interface
60    pub friendly_name: Option<String>,
61    /// Description of the network interface
62    pub description: Option<String>,
63    /// Interface Type
64    pub if_type: InterfaceType,
65    /// MAC address of network interface
66    pub mac_addr: Option<MacAddr>,
67    /// List of Ipv4Net for the network interface
68    pub ipv4: Vec<Ipv4Net>,
69    /// List of Ipv6Net for the network interface
70    pub ipv6: Vec<Ipv6Net>,
71    /// Flags for the network interface (OS Specific)
72    pub flags: u32,
73    /// Speed in bits per second of the transmit for the network interface
74    pub transmit_speed: Option<u64>,
75    /// Speed in bits per second of the receive for the network interface
76    pub receive_speed: Option<u64>,
77    /// Default gateway for the network interface
78    pub gateway: Option<Gateway>,
79}
80
81impl Interface {
82    /// Construct a new default Interface instance
83    pub fn default() -> Result<Interface, String> {
84        let local_ip: IpAddr = match get_local_ipaddr() {
85            Some(local_ip) => local_ip,
86            None => return Err(String::from("Local IP address not found")),
87        };
88        let interfaces: Vec<Interface> = interfaces();
89        for iface in interfaces {
90            match local_ip {
91                IpAddr::V4(local_ipv4) => {
92                    if iface.ipv4.iter().any(|x| x.addr == local_ipv4) {
93                        return Ok(iface);
94                    }
95                }
96                IpAddr::V6(local_ipv6) => {
97                    if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
98                        return Ok(iface);
99                    }
100                }
101            }
102        }
103        Err(String::from("Default Interface not found"))
104    }
105    // Construct a dummy Interface instance
106    pub fn dummy() -> Interface {
107        Interface {
108            index: 0,
109            name: String::new(),
110            friendly_name: None,
111            description: None,
112            if_type: InterfaceType::Unknown,
113            mac_addr: None,
114            ipv4: Vec::new(),
115            ipv6: Vec::new(),
116            flags: 0,
117            transmit_speed: None,
118            receive_speed: None,
119            gateway: None,
120        }
121    }
122    /// Check if the network interface is up
123    pub fn is_up(&self) -> bool {
124        self.flags & (sys::IFF_UP as u32) != 0
125    }
126    /// Check if the network interface is a Loopback interface
127    pub fn is_loopback(&self) -> bool {
128        self.flags & (sys::IFF_LOOPBACK as u32) != 0
129    }
130    /// Check if the network interface is a Point-to-Point interface
131    pub fn is_point_to_point(&self) -> bool {
132        self.flags & (sys::IFF_POINTOPOINT as u32) != 0
133    }
134    /// Check if the network interface is a Multicast interface
135    pub fn is_multicast(&self) -> bool {
136        self.flags & (sys::IFF_MULTICAST as u32) != 0
137    }
138    /// Check if the network interface is a Broadcast interface
139    pub fn is_broadcast(&self) -> bool {
140        self.flags & (sys::IFF_BROADCAST as u32) != 0
141    }
142    /// Check if the network interface is a TUN interface
143    pub fn is_tun(&self) -> bool {
144        self.is_up() && self.is_point_to_point() && !self.is_broadcast() && !self.is_loopback()
145    }
146}
147
148/// Get default Network Interface
149pub fn get_default_interface() -> Result<Interface, String> {
150    let local_ip: IpAddr = match get_local_ipaddr() {
151        Some(local_ip) => local_ip,
152        None => return Err(String::from("Local IP address not found")),
153    };
154    let interfaces: Vec<Interface> = interfaces();
155    for iface in interfaces {
156        match local_ip {
157            IpAddr::V4(local_ipv4) => {
158                if iface.ipv4.iter().any(|x| x.addr == local_ipv4) {
159                    return Ok(iface);
160                }
161            }
162            IpAddr::V6(local_ipv6) => {
163                if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
164                    return Ok(iface);
165                }
166            }
167        }
168    }
169    Err(String::from("Default Interface not found"))
170}
171
172/// Get default Network Interface index
173pub fn get_default_interface_index() -> Option<u32> {
174    let local_ip: IpAddr = match get_local_ipaddr() {
175        Some(local_ip) => local_ip,
176        None => return None,
177    };
178    let interfaces = interfaces();
179    for iface in interfaces {
180        match local_ip {
181            IpAddr::V4(local_ipv4) => {
182                if iface.ipv4.iter().any(|x| x.addr == local_ipv4) {
183                    return Some(iface.index);
184                }
185            }
186            IpAddr::V6(local_ipv6) => {
187                if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
188                    return Some(iface.index);
189                }
190            }
191        }
192    }
193    None
194}
195
196/// Get default Network Interface name
197pub fn get_default_interface_name() -> Option<String> {
198    let local_ip: IpAddr = match get_local_ipaddr() {
199        Some(local_ip) => local_ip,
200        None => return None,
201    };
202    let interfaces = interfaces();
203    for iface in interfaces {
204        match local_ip {
205            IpAddr::V4(local_ipv4) => {
206                if iface.ipv4.iter().any(|x| x.addr == local_ipv4) {
207                    return Some(iface.name);
208                }
209            }
210            IpAddr::V6(local_ipv6) => {
211                if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
212                    return Some(iface.name);
213                }
214            }
215        }
216    }
217    None
218}
219
220/// Get a list of available Network Interfaces
221pub fn get_interfaces() -> Vec<Interface> {
222    interfaces()
223}
224
225#[cfg(test)]
226mod tests {
227    use super::*;
228    #[test]
229    fn test_interfaces() {
230        let interfaces = get_interfaces();
231        for interface in interfaces {
232            println!("{:#?}", interface);
233        }
234    }
235    #[test]
236    fn test_default_interface() {
237        println!("{:#?}", get_default_interface());
238    }
239    #[test]
240    fn test_default_interface_index() {
241        println!("{:?}", get_default_interface_index());
242    }
243    #[test]
244    fn test_default_interface_name() {
245        println!("{:?}", get_default_interface_name());
246    }
247}