diff --git a/src/network/utils.rs b/src/network/utils.rs index d7b61e8..40356e6 100644 --- a/src/network/utils.rs +++ b/src/network/utils.rs @@ -215,6 +215,71 @@ pub fn get_ip_from_mac(mac: &str, network: &str) -> Option { } } +/// Ermittelt die MAC-Adresse zu einer gegebenen IP-Adresse im lokalen Netzwerk +/// durch Auslesen der ARP-Tabelle. +/// +/// # Parameter +/// - `ip`: IP-Adresse für die die MAC-Adresse ermittelt werden soll +/// +/// # Rückgabe +/// - Option: Die MAC-Adresse des Geräts oder None wenn nicht gefunden +pub fn get_mac_from_ip(ip: &str) -> Option { + #[cfg(target_os = "linux")] + { + let output = Command::new("ip") + .args(["neigh", "show", ip]) + .output(); + + match output { + Ok(out) => { + if !out.status.success() { + return None; + } + let stdout = String::from_utf8_lossy(&out.stdout); + // Format: 192.168.1.1 dev eth0 lladdr 00:11:22:33:44:55 REACHABLE + for line in stdout.lines() { + let parts: Vec<&str> = line.split_whitespace().collect(); + if parts.len() >= 4 && parts[0] == ip && parts[2] == "lladdr" { + return Some(parts[3].to_string()); + } + } + None + } + Err(_) => None + } + } + + #[cfg(target_os = "windows")] + { + let output = Command::new("arp") + .args(["-a", ip]) + .output(); + + match output { + Ok(out) => { + if !out.status.success() { + return None; + } + let stdout = String::from_utf8_lossy(&out.stdout); + for line in stdout.lines() { + let parts: Vec<&str> = line.split_whitespace().collect(); + // Format: 192.168.1.1 00-11-22-33-44-55 dynamic + if parts.len() >= 2 && parts[0] == ip { + return Some(parts[1].replace('-', ":")); + } + } + None + } + Err(_) => None + } + } + + #[cfg(not(any(target_os = "linux", target_os = "windows")))] + { + log::log("network_utils", "OS not supported.", LogLevel::Error); + None + } +} /// Sendet ein Wake-on-LAN Magic Packet an eine MAC-Adresse /// /// # Parameter