Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion src/interface/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ use std::net::IpAddr;

const PATH_RESOLV_CONF: &str = "/etc/resolv.conf";

fn is_wifi_interface(interface_name: &str) -> bool {
let wireless_path = format!("/sys/class/net/{}/wireless", interface_name);
let phy80211_path = format!("/sys/class/net/{}/phy80211", interface_name);
std::path::Path::new(&wireless_path).exists() || std::path::Path::new(&phy80211_path).exists()
}

pub fn get_interface_type(if_name: String) -> InterfaceType {
let if_type_path: String = format!("/sys/class/net/{}/type", if_name);
let r = read_to_string(if_type_path);
Expand All @@ -13,7 +19,17 @@ pub fn get_interface_type(if_name: String) -> InterfaceType {
let if_type_string = content.trim().to_string();
match if_type_string.parse::<u32>() {
Ok(if_type) => {
return InterfaceType::try_from(if_type).unwrap_or(InterfaceType::Unknown);
if if_type == crate::sys::if_arp::ARPHRD_ETHER {
// Since some Wi-Fi interfaces may also be reported as Ethernet,
// further check if the interface is actually Wi-Fi.
if is_wifi_interface(&if_name) {
return InterfaceType::Wireless80211;
} else {
return InterfaceType::Ethernet;
}
} else {
return InterfaceType::try_from(if_type).unwrap_or(InterfaceType::Unknown);
}
}
Err(_) => {
return InterfaceType::Unknown;
Expand Down
23 changes: 13 additions & 10 deletions src/interface/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,17 +106,20 @@ impl InterfaceType {
/// Returns OS-specific value of InterfaceType
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn value(&self) -> u32 {
use crate::sys;
match *self {
InterfaceType::Ethernet => 1,
InterfaceType::TokenRing => 4,
InterfaceType::Fddi => 774,
InterfaceType::Ppp => 512,
InterfaceType::Loopback => 772,
InterfaceType::Ethernet3Megabit => 2,
InterfaceType::Slip => 256,
InterfaceType::Atm => 19,
InterfaceType::Wireless80211 => 801,
InterfaceType::Tunnel => 768,
InterfaceType::Ethernet => sys::if_arp::ARPHRD_ETHER,
InterfaceType::TokenRing => sys::if_arp::ARPHRD_IEEE802,
InterfaceType::Fddi => sys::if_arp::ARPHRD_FDDI,
InterfaceType::Ppp => sys::if_arp::ARPHRD_PPP,
InterfaceType::Loopback => sys::if_arp::ARPHRD_LOOPBACK,
InterfaceType::Ethernet3Megabit => sys::if_arp::ARPHRD_EETHER,
InterfaceType::Slip => sys::if_arp::ARPHRD_SLIP,
InterfaceType::Atm => sys::if_arp::ARPHRD_ATM,
InterfaceType::Wireless80211 => sys::if_arp::ARPHRD_IEEE80211,
InterfaceType::Tunnel => sys::if_arp::ARPHRD_TUNNEL,
InterfaceType::Isdn => sys::if_arp::ARPHRD_X25,
InterfaceType::HighPerformanceSerialBus => sys::if_arp::ARPHRD_IEEE1394,
_ => u32::MAX,
}
}
Expand Down
15 changes: 15 additions & 0 deletions src/sys/linux.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// ARP protocol HARDWARE identifiers
pub mod if_arp {
pub const ARPHRD_ETHER: u32 = libc::ARPHRD_ETHER as u32;
pub const ARPHRD_IEEE802: u32 = libc::ARPHRD_IEEE802 as u32;
pub const ARPHRD_FDDI: u32 = libc::ARPHRD_FDDI as u32;
pub const ARPHRD_PPP: u32 = libc::ARPHRD_PPP as u32;
pub const ARPHRD_LOOPBACK: u32 = libc::ARPHRD_LOOPBACK as u32;
pub const ARPHRD_EETHER: u32 = libc::ARPHRD_EETHER as u32;
pub const ARPHRD_SLIP: u32 = libc::ARPHRD_SLIP as u32;
pub const ARPHRD_ATM: u32 = libc::ARPHRD_ATM as u32;
pub const ARPHRD_IEEE80211: u32 = libc::ARPHRD_IEEE80211 as u32;
pub const ARPHRD_TUNNEL: u32 = libc::ARPHRD_TUNNEL as u32;
pub const ARPHRD_X25: u32 = libc::ARPHRD_X25 as u32;
pub const ARPHRD_IEEE1394: u32 = libc::ARPHRD_IEEE1394 as u32;
}
5 changes: 5 additions & 0 deletions src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ pub use self::unix::*;
mod windows;
#[cfg(target_os = "windows")]
pub use self::windows::*;

#[cfg(any(target_os = "linux", target_os = "android"))]
mod linux;
#[cfg(any(target_os = "linux", target_os = "android"))]
pub use self::linux::*;