Fix: Überarbeitet get_ip_from_mac, verbessert MAC-Normalisierung und IP-Erkennung.

This commit is contained in:
2025-08-21 12:49:14 +02:00
parent ad4e9e0055
commit 663307be63

View File

@@ -113,18 +113,66 @@ pub fn get_ip_from_mac(mac: &str, network: &str) -> Option<String> {
let stdout = String::from_utf8_lossy(&out.stdout); let stdout = String::from_utf8_lossy(&out.stdout);
log("network_utils", &*stdout, LogLevel::Debug); log("network_utils", &*stdout, LogLevel::Debug);
for line in stdout.lines() { // MAC normalisieren: nur Hex-Zeichen, klein, ohne Trennzeichen
if line.contains("Nmap scan report for") { let normalize_mac = |m: &str| -> String {
let ip_line = line; m.chars()
log("network_utils", &*ip_line, LogLevel::Debug); .filter(|c| c.is_ascii_hexdigit())
if let Some(next_line) = stdout.lines().find(|l| l.to_lowercase().contains(mac)) { .flat_map(|c| c.to_lowercase())
log("network_utils", &*next_line, LogLevel::Debug); .collect::<String>()
if let Some(ip) = ip_line.split_whitespace().last() { };
return Some(ip.to_string()); let target_mac = normalize_mac(mac);
// Beispielausgaben:
// Nmap scan report for 192.168.0.10
// Nmap scan report for printer.lan (192.168.0.10)
// MAC Address: 00:11:22:33:44:55 (Vendor)
//
// Strategie:
// - Merke die zuletzt gesehene IP aus "Nmap scan report for ..."
// - Wenn danach eine "MAC Address:"-Zeile folgt und MAC passt -> gib IP zurück
let mut current_ip: Option<String> = None;
for raw_line in stdout.lines() {
let line = raw_line.trim();
if line.starts_with("Nmap scan report for") {
// Versuche IP zu extrahieren:
// 1) Klammerform: ... (x.x.x.x)
// 2) Sonst letztes Token als IP
let ip = if let Some(start) = line.rfind('(') {
if let Some(end) = line.rfind(')') {
let in_parens = &line[start + 1..end];
Some(in_parens.to_string())
} else {
None
}
} else {
line.split_whitespace()
.last()
.map(|s| s.to_string())
};
// Grobe Validierung IPv4
if let Some(ip_str) = ip {
let maybe_ip = ip_str.parse::<Ipv4Addr>().ok().map(|ip| ip.to_string());
current_ip = maybe_ip;
} else {
current_ip = None;
}
} else if line.starts_with("MAC Address:") {
// Format: "MAC Address: XX:XX:XX:XX:XX:XX (Vendor)"
let mac_part = line.strip_prefix("MAC Address:").unwrap().trim();
let mac_token = mac_part.split_whitespace().next().unwrap_or("");
let seen_mac = normalize_mac(mac_token);
if !seen_mac.is_empty() && seen_mac == target_mac {
if let Some(ip) = current_ip.clone() {
return Some(ip);
} }
} }
} }
} }
None None
} }
Err(e) => { Err(e) => {