hardware_query/
network.rs

1use crate::Result;
2use serde::{Deserialize, Serialize};
3use sysinfo::Networks;
4
5/// Network interface type
6#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7pub enum NetworkType {
8    Ethernet,
9    WiFi,
10    Bluetooth,
11    Cellular,
12    VPN,
13    Loopback,
14    Unknown,
15}
16
17impl std::fmt::Display for NetworkType {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        match self {
20            NetworkType::Ethernet => write!(f, "Ethernet"),
21            NetworkType::WiFi => write!(f, "WiFi"),
22            NetworkType::Bluetooth => write!(f, "Bluetooth"),
23            NetworkType::Cellular => write!(f, "Cellular"),
24            NetworkType::VPN => write!(f, "VPN"),
25            NetworkType::Loopback => write!(f, "Loopback"),
26            NetworkType::Unknown => write!(f, "Unknown"),
27        }
28    }
29}
30
31/// Network interface information
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct NetworkInfo {
34    /// Interface name
35    pub name: String,
36    /// Network type
37    pub network_type: NetworkType,
38    /// MAC address
39    pub mac_address: String,
40    /// IP addresses
41    pub ip_addresses: Vec<String>,
42    /// Interface speed in Mbps (if available)
43    pub speed_mbps: Option<u32>,
44    /// Is interface up/active
45    pub is_up: bool,
46    /// Bytes received
47    pub bytes_received: u64,
48    /// Bytes transmitted
49    pub bytes_transmitted: u64,
50    /// Packets received
51    pub packets_received: u64,
52    /// Packets transmitted
53    pub packets_transmitted: u64,
54    /// Receive errors
55    pub receive_errors: u64,
56    /// Transmit errors
57    pub transmit_errors: u64,
58}
59
60impl NetworkInfo {
61    /// Query all network interfaces
62    pub fn query_all() -> Result<Vec<Self>> {
63        let networks = Networks::new_with_refreshed_list();
64
65        let mut network_interfaces = Vec::new();
66
67        for (interface_name, network_data) in &networks {
68            let network_info = Self {
69                name: interface_name.clone(),
70                network_type: Self::detect_network_type(interface_name),
71                mac_address: Self::get_mac_address(interface_name),
72                ip_addresses: Self::get_ip_addresses(interface_name),
73                speed_mbps: None, // Would need platform-specific implementation
74                is_up: network_data.received() > 0 || network_data.transmitted() > 0,
75                bytes_received: network_data.received(),
76                bytes_transmitted: network_data.transmitted(),
77                packets_received: network_data.packets_received(),
78                packets_transmitted: network_data.packets_transmitted(),
79                receive_errors: network_data.errors_on_received(),
80                transmit_errors: network_data.errors_on_transmitted(),
81            };
82
83            network_interfaces.push(network_info);
84        }
85
86        Ok(network_interfaces)
87    }
88
89    /// Get interface name
90    pub fn name(&self) -> &str {
91        &self.name
92    }
93
94    /// Get network type
95    pub fn network_type(&self) -> &NetworkType {
96        &self.network_type
97    }
98
99    /// Get MAC address
100    pub fn mac_address(&self) -> &str {
101        &self.mac_address
102    }
103
104    /// Get IP addresses
105    pub fn ip_addresses(&self) -> &[String] {
106        &self.ip_addresses
107    }
108
109    /// Check if interface is active
110    pub fn is_active(&self) -> bool {
111        self.is_up
112    }
113
114    /// Get total bytes transferred
115    pub fn total_bytes(&self) -> u64 {
116        self.bytes_received + self.bytes_transmitted
117    }
118
119    /// Get total packets transferred
120    pub fn total_packets(&self) -> u64 {
121        self.packets_received + self.packets_transmitted
122    }
123
124    /// Get total errors
125    pub fn total_errors(&self) -> u64 {
126        self.receive_errors + self.transmit_errors
127    }
128
129    fn detect_network_type(name: &str) -> NetworkType {
130        let name_lower = name.to_lowercase();
131
132        if name_lower.contains("lo") || name_lower.contains("loopback") {
133            NetworkType::Loopback
134        } else if name_lower.contains("eth") || name_lower.contains("ethernet") {
135            NetworkType::Ethernet
136        } else if name_lower.contains("wlan")
137            || name_lower.contains("wifi")
138            || name_lower.contains("wi-fi")
139        {
140            NetworkType::WiFi
141        } else if name_lower.contains("bluetooth") || name_lower.contains("bt") {
142            NetworkType::Bluetooth
143        } else if name_lower.contains("cellular") || name_lower.contains("mobile") {
144            NetworkType::Cellular
145        } else if name_lower.contains("vpn") || name_lower.contains("tunnel") {
146            NetworkType::VPN
147        } else {
148            NetworkType::Unknown
149        }
150    }
151
152    fn get_mac_address(_interface_name: &str) -> String {
153        // Platform-specific implementation would go here
154        "00:00:00:00:00:00".to_string()
155    }
156
157    fn get_ip_addresses(_interface_name: &str) -> Vec<String> {
158        // Platform-specific implementation would go here
159        vec![]
160    }
161}