From f2ccc49a17fa4c9396e6fb572ed68fd5740cb5db Mon Sep 17 00:00:00 2001 From: donpat1to Date: Thu, 31 Jul 2025 14:24:24 +0200 Subject: [PATCH] added alternatives for windows net detection --- WatcherAgent/src/main.rs | 84 ++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/WatcherAgent/src/main.rs b/WatcherAgent/src/main.rs index a0a707e..03b902a 100644 --- a/WatcherAgent/src/main.rs +++ b/WatcherAgent/src/main.rs @@ -588,54 +588,70 @@ fn get_disk_info() -> (f64, f64, f64) { (size_gb, usage, 0.0) // Disk-Temp bleibt 0.0 ohne spezielle Hardware } +#[cfg(target_os = "windows")] fn get_network_traffic() -> Option<(u64, u64)> { - #[cfg(target_os = "linux")] - { - let content = fs::read_to_string("/proc/net/dev").ok()?; + use std::mem::size_of; + use std::ptr::null_mut; + use winapi::shared::ifmib::{MIB_IFROW, MIB_IFTABLE}; + use winapi::um::iphlpapi::GetIfTable; + + unsafe { + // Erste Abfrage zur Bestimmung der benötigten Puffergröße + let mut buffer_size = 0u32; + if GetIfTable(null_mut(), &mut buffer_size, 0) + != winapi::shared::winerror::ERROR_INSUFFICIENT_BUFFER + { + return None; + } + + // Puffer allozieren + let mut buffer = vec![0u8; buffer_size as usize]; + let if_table = buffer.as_mut_ptr() as *mut MIB_IFTABLE; + + // Tatsächliche Daten abrufen + if GetIfTable(if_table, &mut buffer_size, 0) != 0 { + return None; + } + + // Daten auswerten let mut rx_total = 0u64; let mut tx_total = 0u64; - for line in content.lines().skip(2) { - let parts: Vec<&str> = line.split_whitespace().collect(); - if parts.len() < 10 || parts[0].ends_with(":") { - continue; - } - if parts[0].contains("lo:") { - continue; - } - rx_total += parts[1].parse::().unwrap_or(0); - tx_total += parts[9].parse::().unwrap_or(0); + for i in 0..(*if_table).dwNumEntries { + let row = &*((*if_table).table.as_ptr().offset(i as isize)); + rx_total += row.dwInOctets as u64; + tx_total += row.dwOutOctets as u64; } + Some((rx_total, tx_total)) } +} - #[cfg(target_os = "windows")] - { - use std::process::Stdio; - let output = Command::new("netstat") - .args(&["-e"]) - .stdout(Stdio::piped()) - .output() - .ok()?; +#[cfg(target_os = "linux")] +fn get_network_traffic() -> Option<(u64, u64)> { + // Bessere Methode mit sysfs + let mut rx_total = 0u64; + let mut tx_total = 0u64; - let stdout = String::from_utf8_lossy(&output.stdout); - let mut lines = stdout.lines(); + if let Ok(dir) = fs::read_dir("/sys/class/net") { + for entry in dir.flatten() { + let iface = entry.file_name(); + let iface_name = iface.to_string_lossy(); - // Find the line with statistics - while let Some(line) = lines.next() { - if line.contains("Bytes") { - if let Some(stats_line) = lines.next() { - let parts: Vec<&str> = stats_line.split_whitespace().collect(); - if parts.len() >= 2 { - let rx = parts[0].parse::().unwrap_or(0); - let tx = parts[1].parse::().unwrap_or(0); - return Some((rx, tx)); - } + // Ignoriere virtuelle Interfaces + if !iface_name.starts_with("lo") && !iface_name.starts_with("virbr") { + if let (Ok(rx), Ok(tx)) = ( + fs::read_to_string(entry.path().join("statistics/rx_bytes")), + fs::read_to_string(entry.path().join("statistics/tx_bytes")), + ) { + rx_total += rx.trim().parse::().unwrap_or(0); + tx_total += tx.trim().parse::().unwrap_or(0); } } } - None } + + Some((rx_total, tx_total)) } #[tokio::main]