use std::process::Command; use std::net::Ipv4Addr; use crate::log; use crate::log::LogLevel; /// Prüft, ob eine angegebene IP-Adresse oder URL erreichbar ist /// /// # Parameter /// - `address`: Eine IP-Adresse oder vollständige HTTPS-URL /// /// # Rückgabe /// - `bool`: True wenn die Adresse erreichbar ist, False wenn nicht pub fn is_reachable(address: &str) -> bool { let addr = &*if let Some(parts) = address.split('/').nth(0) { if let Ok(ip) = parts.parse::() { let next_ip = Ipv4Addr::from(u32::from(ip) + 1); next_ip.to_string() } else { address.to_string() } } else { address.to_string() }; #[cfg(target_os = "linux")] { let output = Command::new("ping") .args(["-c", "1", "-W", "2", addr]) .output(); if let Ok(out) = output { out.status.success() } else { log::log("network_utils", &*format!("Couldn't reach address {}!", addr), LogLevel::Error); false } } #[cfg(target_os = "windows")] { let output = Command::new("ping") .args(["-n", "1", "-w", "2000", addr]) .output(); if let Ok(out) = output { out.status.success() } else { log::log("network_utils", &*format!("Couldn't reach address {}!", addr), LogLevel::Error); false } } #[cfg(not(any(target_os = "linux", target_os = "windows")))] { log::log("network_utils", "OS not supported.", LogLevel::Error); false } } /// Berechnet die Netzwerkadresse aus einer IP-Adresse mit Subnetzmaske /// /// # Parameter /// - `address`: Eine IPv4-Adresse mit Subnetzmaske im Format "xxx.xxx.xxx.xxx/yy" /// /// # Rückgabe /// - Option: Die Netzwerkadresse im gleichen Format oder None bei ungültiger Eingabe pub fn get_network_address(address: &str) -> Option { let parts: Vec<&str> = address.split('/').collect(); if parts.len() != 2 { return None; } if let Ok(ip) = parts[0].parse::() { if let Ok(mask) = parts[1].parse::() { if mask > 32 { return None; } let ip_bits: u32 = u32::from(ip); let mask_bits: u32 = !0u32 << (32 - mask); let network = Ipv4Addr::from(ip_bits & mask_bits); return Some(format!("{}/{}", network, mask)); } } None } /// Ermittelt die IP-Adresse zu einer gegebenen MAC-Adresse im lokalen Netzwerk. /// Verwendet einen nmap-Scan, um das Gerät zu finden. /// /// # Parameter /// - `mac`: MAC-Adresse im Format "xx:xx:xx:xx:xx:xx" /// /// # Rückgabe /// - Option: Die IP-Adresse des Geräts oder None wenn nicht gefunden pub fn get_ip_from_mac(mac: &str) -> Option { #[cfg(any(target_os = "linux", target_os = "windows"))] { let output = Command::new("nmap") .args(["-sn", "-n", "--system-dns", "-PR", "-PS22,80,443,445", "-PA80,443", "-PU161", mac]) .output(); match output { Ok(out) => { if !out.status.success() { return None; } let stdout = String::from_utf8_lossy(&out.stdout); for line in stdout.lines() { if line.contains("Nmap scan report for") { if let Some(ip) = line.split_whitespace().last() { return Some(ip.to_string()); } } } None } Err(e) => { if e.kind() == std::io::ErrorKind::NotFound { log::log("network_utils", "nmap is not installed on the system!", LogLevel::Error); } None } } } #[cfg(not(any(target_os = "linux", target_os = "windows")))] { log::log("network_utils", "OS not supported.", LogLevel::Error); None } }