diff --git a/src/network/mac2ip.rs b/src/network/mac2ip.rs index 3185e87..2ca991f 100644 --- a/src/network/mac2ip.rs +++ b/src/network/mac2ip.rs @@ -19,6 +19,13 @@ use serde::Deserialize; use crate::error::{Error, Result}; +/// Timeout in Sekunden für den `mac2ip`-Subprozess (dieselbe `timeout`-Coreutils-Technik wie +/// [`crate::mount::run_with_timeout`]). `mac2ip` kann intern einen `nmap`-Scan auslösen - +/// gegen ein dauerhaft nicht erreichbares/reagierendes Netz sonst ein unbegrenztes Hängen, das +/// `smart-mount watch`/`status` komplett blockieren würde, statt korrekt "nicht auflösbar" zu +/// melden. +const MAC2IP_TIMEOUT_SECS: u64 = 15; + #[derive(Deserialize)] #[serde(untagged)] enum Mac2IpOutput { @@ -31,7 +38,9 @@ enum Mac2IpOutput { /// `binary` ist der konfigurierte Binary-Name/-Pfad (`GlobalSettings::mac2ip_binary`, /// standardmäßig `"mac2ip"`, per PATH aufgelöst). pub fn resolve(mac: &str, binary: &str) -> Result { - let output = Command::new(binary) + let output = Command::new("timeout") + .arg(MAC2IP_TIMEOUT_SECS.to_string()) + .arg(binary) .args(["--json", "--auto-trust-networks", mac]) .output() .map_err(|e| Error::Mac2Ip { @@ -39,6 +48,13 @@ pub fn resolve(mac: &str, binary: &str) -> Result { reason: format!("could not run '{binary}': {e}"), })?; + if output.status.code() == Some(124) { + return Err(Error::Mac2Ip { + mac: mac.to_string(), + reason: format!("'{binary}' did not respond within {MAC2IP_TIMEOUT_SECS}s (timed out)"), + }); + } + parse_output(&output.stdout, mac) }