mod shared;
pub use self::shared::*;
mod types;
pub use self::types::*;
#[cfg(any(
target_os = "linux",
target_os = "macos",
target_os = "openbsd",
target_os = "freebsd",
target_os = "netbsd",
target_os = "ios",
target_os = "android"
))]
mod unix;
#[cfg(any(
target_os = "linux",
target_os = "macos",
target_os = "openbsd",
target_os = "freebsd",
target_os = "netbsd",
target_os = "ios",
target_os = "android"
))]
use self::unix::*;
#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
use self::windows::*;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(any(target_os = "linux", target_os = "android"))]
mod linux;
#[cfg(target_os = "android")]
mod android;
#[cfg(any(target_os = "macos", target_os = "ios"))]
mod macos;
use crate::gateway::Gateway;
use crate::ip::{Ipv4Net, Ipv6Net};
use crate::mac::MacAddr;
use crate::sys;
use std::net::IpAddr;
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Interface {
pub index: u32,
pub name: String,
pub friendly_name: Option<String>,
pub description: Option<String>,
pub if_type: InterfaceType,
pub mac_addr: Option<MacAddr>,
pub ipv4: Vec<Ipv4Net>,
pub ipv6: Vec<Ipv6Net>,
pub flags: u32,
pub transmit_speed: Option<u64>,
pub receive_speed: Option<u64>,
pub gateway: Option<Gateway>,
}
impl Interface {
pub fn default() -> Result<Interface, String> {
let local_ip: IpAddr = match get_local_ipaddr() {
Some(local_ip) => local_ip,
None => return Err(String::from("Local IP address not found")),
};
let interfaces: Vec<Interface> = interfaces();
for iface in interfaces {
match local_ip {
IpAddr::V4(local_ipv4) => {
if iface.ipv4.iter().any(|x| x.addr == local_ipv4) {
return Ok(iface);
}
}
IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
return Ok(iface);
}
}
}
}
Err(String::from("Default Interface not found"))
}
pub fn dummy() -> Interface {
Interface {
index: 0,
name: String::new(),
friendly_name: None,
description: None,
if_type: InterfaceType::Unknown,
mac_addr: None,
ipv4: Vec::new(),
ipv6: Vec::new(),
flags: 0,
transmit_speed: None,
receive_speed: None,
gateway: None,
}
}
pub fn is_up(&self) -> bool {
self.flags & (sys::IFF_UP as u32) != 0
}
pub fn is_loopback(&self) -> bool {
self.flags & (sys::IFF_LOOPBACK as u32) != 0
}
pub fn is_point_to_point(&self) -> bool {
self.flags & (sys::IFF_POINTOPOINT as u32) != 0
}
pub fn is_multicast(&self) -> bool {
self.flags & (sys::IFF_MULTICAST as u32) != 0
}
pub fn is_broadcast(&self) -> bool {
self.flags & (sys::IFF_BROADCAST as u32) != 0
}
pub fn is_tun(&self) -> bool {
self.is_up() && self.is_point_to_point() && !self.is_broadcast() && !self.is_loopback()
}
}
pub fn get_default_interface() -> Result<Interface, String> {
let local_ip: IpAddr = match get_local_ipaddr() {
Some(local_ip) => local_ip,
None => return Err(String::from("Local IP address not found")),
};
let interfaces: Vec<Interface> = interfaces();
for iface in interfaces {
match local_ip {
IpAddr::V4(local_ipv4) => {
if iface.ipv4.iter().any(|x| x.addr == local_ipv4) {
return Ok(iface);
}
}
IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
return Ok(iface);
}
}
}
}
Err(String::from("Default Interface not found"))
}
pub fn get_default_interface_index() -> Option<u32> {
let local_ip: IpAddr = match get_local_ipaddr() {
Some(local_ip) => local_ip,
None => return None,
};
let interfaces = interfaces();
for iface in interfaces {
match local_ip {
IpAddr::V4(local_ipv4) => {
if iface.ipv4.iter().any(|x| x.addr == local_ipv4) {
return Some(iface.index);
}
}
IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
return Some(iface.index);
}
}
}
}
None
}
pub fn get_default_interface_name() -> Option<String> {
let local_ip: IpAddr = match get_local_ipaddr() {
Some(local_ip) => local_ip,
None => return None,
};
let interfaces = interfaces();
for iface in interfaces {
match local_ip {
IpAddr::V4(local_ipv4) => {
if iface.ipv4.iter().any(|x| x.addr == local_ipv4) {
return Some(iface.name);
}
}
IpAddr::V6(local_ipv6) => {
if iface.ipv6.iter().any(|x| x.addr == local_ipv6) {
return Some(iface.name);
}
}
}
}
None
}
pub fn get_interfaces() -> Vec<Interface> {
interfaces()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_interfaces() {
let interfaces = get_interfaces();
for interface in interfaces {
println!("{:#?}", interface);
}
}
#[test]
fn test_default_interface() {
println!("{:#?}", get_default_interface());
}
#[test]
fn test_default_interface_index() {
println!("{:?}", get_default_interface_index());
}
#[test]
fn test_default_interface_name() {
println!("{:?}", get_default_interface_name());
}
}