diff --git a/src/interface/types.rs b/src/interface/types.rs index 33ecebd..3e189b8 100644 --- a/src/interface/types.rs +++ b/src/interface/types.rs @@ -63,6 +63,8 @@ pub enum InterfaceType { HighPerformanceSerialBus, /// Mobile broadband interface for WiMAX devices. Wman, + /// Wireless wide area network interface, such as a mobile broadband or cellular modem. + Wwan, /// Mobile broadband interface for GSM-based devices. Wwanpp, /// Mobile broadband interface for CDMA-based devices. @@ -208,6 +210,7 @@ impl InterfaceType { InterfaceType::HighPerformanceSerialBus => String::from("High Performance Serial Bus"), InterfaceType::Bridge => String::from("Bridge"), InterfaceType::Wman => String::from("WMAN"), + InterfaceType::Wwan => String::from("WWAN"), InterfaceType::Wwanpp => String::from("WWANPP"), InterfaceType::Wwanpp2 => String::from("WWANPP2"), InterfaceType::Can => String::from("CAN"), diff --git a/src/os/linux/sysfs.rs b/src/os/linux/sysfs.rs index 3cc06b7..a79c4c3 100644 --- a/src/os/linux/sysfs.rs +++ b/src/os/linux/sysfs.rs @@ -17,16 +17,37 @@ fn is_wifi_interface(ifname: &str) -> bool { let base = PathBuf::from("/sys/class/net").join(ifname); // 1) Check uevent file for DEVTYPE=wlan - if let Some(ue) = read_trimmed(base.join("uevent")) { - if ue.lines().any(|l| l.trim() == "DEVTYPE=wlan") { - return true; - } + if let Some(ue) = read_trimmed(base.join("uevent")) + && ue.lines().any(|l| l.trim() == "DEVTYPE=wlan") + { + return true; } // 2) Check for wireless or phy80211 directories exists(base.join("wireless")) || exists(base.join("phy80211")) } +/// Check if the interface is a WWAN/mobile broadband interface. +fn is_wwan_interface(ifname: &str) -> bool { + let base = PathBuf::from("/sys/class/net").join(ifname); + + if let Some(uevent) = read_trimmed(base.join("uevent")) + && uevent.lines().any(|line| line.trim() == "DEVTYPE=wwan") + { + return true; + } + + is_wwan_name(ifname) +} + +fn is_wwan_name(ifname: &str) -> bool { + ifname == "wwan" + || ifname.starts_with("wwan") + || ifname.starts_with("wwp") + || ifname.starts_with("rmnet") + || ifname.starts_with("ccmni") +} + /// Check if the interface is a virtual interface. pub fn is_virtual_interface(ifname: &str) -> bool { let dev_link = PathBuf::from("/sys/class/net").join(ifname).join("device"); @@ -52,6 +73,11 @@ pub fn get_interface_type(ifname: &str) -> InterfaceType { if is_wifi_interface(ifname) { return InterfaceType::Wireless80211; } + + if is_wwan_interface(ifname) { + return InterfaceType::Wwan; + } + // Read the type from sysfs let p = PathBuf::from("/sys/class/net").join(ifname).join("type"); let ty = match read_trimmed(&p).and_then(|s| s.parse::().ok()) {