Files
SmartMount/src/network/utils.rs

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
}
}