From 020e964b1303ff272bbd76b36739b5882a6bb676 Mon Sep 17 00:00:00 2001 From: DragonSlayer_14 Date: Mon, 18 Aug 2025 15:11:47 +0200 Subject: [PATCH] =?UTF-8?q?Feat:=20F=C3=BCgt=20Funktionen=20hinzu,=20um=20?= =?UTF-8?q?zu=20testen,=20ob=20eine=20Adresse=20erreichbar=20ist.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.rs | 21 ++++++++++- src/network/mod.rs | 4 +- src/network/utils.rs | 89 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 src/network/utils.rs diff --git a/src/main.rs b/src/main.rs index 24c3fef..41515e2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use std::time::Duration; use crate::log::LogLevel; use crate::log::log; use crate::network::network_interface::{get_active_network_interface, get_interface_ip_address}; +use crate::network::utils::{get_network_address, is_reachable}; mod log; mod network; @@ -29,12 +30,28 @@ fn main() { count = count+1; sleep(Duration::from_secs(1)); } - log("main", &*format!("Active network interface found: {}", network_interface), LogLevel::Info); let interface_address = get_interface_ip_address(network_interface.as_str()).unwrap().trim().to_string(); - log("main", &*format!("Interface address: {}", interface_address), LogLevel::Info); + let network_address = get_network_address(interface_address.as_str()).unwrap().trim().to_string(); + log("main", &*format!("Network address: {}", network_address), LogLevel::Info); + + count = 0; + loop { + if is_reachable(network_address.as_str()) { + break; + } else if count >= 10 { + log("main", "Couldn't reach network address, exiting.", LogLevel::Error); + exit(1); + } + + log("main", "Network address not reachable, waiting 1 second.", LogLevel::Warn); + count = count+1; + sleep(Duration::from_secs(1)); + } + log("main", "Network address is reachable.", LogLevel::Info); + log("main", "========== PROGRAMM END ==========", LogLevel::Info); } diff --git a/src/network/mod.rs b/src/network/mod.rs index 74704a5..401a650 100644 --- a/src/network/mod.rs +++ b/src/network/mod.rs @@ -1,2 +1,2 @@ -pub mod network_card; -pub mod network_interface; \ No newline at end of file +pub mod network_interface; +pub mod utils; \ No newline at end of file diff --git a/src/network/utils.rs b/src/network/utils.rs new file mode 100644 index 0000000..2f8b9de --- /dev/null +++ b/src/network/utils.rs @@ -0,0 +1,89 @@ +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 +} +