134 lines
4.0 KiB
Rust
134 lines
4.0 KiB
Rust
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::<Ipv4Addr>() {
|
|
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<String>: Die Netzwerkadresse im gleichen Format oder None bei ungültiger Eingabe
|
|
pub fn get_network_address(address: &str) -> Option<String> {
|
|
let parts: Vec<&str> = address.split('/').collect();
|
|
if parts.len() != 2 {
|
|
return None;
|
|
}
|
|
|
|
if let Ok(ip) = parts[0].parse::<Ipv4Addr>() {
|
|
if let Ok(mask) = parts[1].parse::<u8>() {
|
|
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<String>: Die IP-Adresse des Geräts oder None wenn nicht gefunden
|
|
pub fn get_ip_from_mac(mac: &str) -> Option<String> {
|
|
#[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
|
|
}
|
|
} |