Feature: Fügt eine Funktion hinzu, die schaut, ob ein Netzwerkadapter aktiv ist.
This commit is contained in:
28
src/main.rs
28
src/main.rs
@@ -1,12 +1,30 @@
|
|||||||
|
use std::process::exit;
|
||||||
|
use std::thread::sleep;
|
||||||
|
use std::time::Duration;
|
||||||
use crate::log::LogLevel;
|
use crate::log::LogLevel;
|
||||||
|
use crate::log::log;
|
||||||
|
use crate::network::network_card::is_network_card_up;
|
||||||
|
|
||||||
mod log;
|
mod log;
|
||||||
|
mod network;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
log::log("main", "========== PROGRAMM START ==========", LogLevel::Info);
|
log("main", "========== PROGRAMM START ==========", LogLevel::Info);
|
||||||
|
|
||||||
log::log("main", "Hello, world!", LogLevel::Error);
|
let mut count = 0;
|
||||||
log::log("main", "Hello, world!", LogLevel::Warn);
|
loop {
|
||||||
log::log("main", "Hello, world!", LogLevel::Info);
|
if count >= 10 {
|
||||||
log::log("main", "Hello, world!", LogLevel::Debug);
|
log("main", "Couldn't find active network card, exiting.", LogLevel::Error);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if is_network_card_up() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
log("main", "No active network card found, waiting 10 seconds.", LogLevel::Warn);
|
||||||
|
count = count+1;
|
||||||
|
sleep(Duration::from_secs(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
log("main", "========== PROGRAMM END ==========", LogLevel::Info);
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/network/mod.rs
Normal file
1
src/network/mod.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub mod network_card;
|
||||||
136
src/network/network_card.rs
Normal file
136
src/network/network_card.rs
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
use crate::log;
|
||||||
|
use crate::log::LogLevel;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
/// Prüft, ob mindestens eine verfügbare Netzwerkschnittstelle (LAN/WLAN etc.) aktiv ist
|
||||||
|
/// und nicht nur die Loopback-Schnittstelle.
|
||||||
|
///
|
||||||
|
/// Rückgabe:
|
||||||
|
/// - true: Mindestens eine NIC ist aktiv
|
||||||
|
/// - false: Keine aktive NIC gefunden oder Fehler beim Prüfen
|
||||||
|
pub fn is_network_card_up() -> bool {
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
{
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
// Prüfe Interfaces in /sys/class/net
|
||||||
|
let sysfs = Path::new("/sys/class/net");
|
||||||
|
if let Ok(entries) = fs::read_dir(sysfs) {
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
let ifname = match entry.file_name().into_string() {
|
||||||
|
Ok(n) => n,
|
||||||
|
Err(_) => continue,
|
||||||
|
};
|
||||||
|
if ifname == "lo" {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let iface_path = entry.path();
|
||||||
|
|
||||||
|
// 1) operstate == "up"
|
||||||
|
let operstate = fs::read_to_string(iface_path.join("operstate"))
|
||||||
|
.unwrap_or_default()
|
||||||
|
.trim()
|
||||||
|
.to_string();
|
||||||
|
if operstate != "up" {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) carrier == "1" (hat Link)
|
||||||
|
let carrier = fs::read_to_string(iface_path.join("carrier"))
|
||||||
|
.unwrap_or_default()
|
||||||
|
.trim()
|
||||||
|
.to_string();
|
||||||
|
if carrier != "1" {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) Virtuell ausschließen:
|
||||||
|
// /sys/class/net/<if>/device -> Symlink zu physischer HW;
|
||||||
|
// zeigt der Pfad unterhalb von ".../virtual/..." oder existiert er gar nicht,
|
||||||
|
// dann ist das i. d. R. ein virtuelles Interface.
|
||||||
|
let device_link = iface_path.join("device");
|
||||||
|
let is_virtual = match fs::read_link(&device_link) {
|
||||||
|
Ok(target) => target.as_os_str().to_string_lossy().contains("/virtual/"),
|
||||||
|
Err(_) => true, // kein device-Link -> in der Regel virtuell
|
||||||
|
};
|
||||||
|
if is_virtual {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: bekannte „logische“ Typen via Verzeichnis-Erkennung ausschließen
|
||||||
|
// (Bridges, VLANs, Macvlan etc.)
|
||||||
|
if iface_path.join("bridge").exists()
|
||||||
|
|| iface_path.join("bonding").exists()
|
||||||
|
|| iface_path.join("team").exists()
|
||||||
|
|| iface_path.join("vlan").exists()
|
||||||
|
|| iface_path.join("macvlan").exists()
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wenn wir hier sind, haben wir eine aktive physische NIC
|
||||||
|
log::log("network_status", "Found active network interface.", LogLevel::Info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let output = Command::new("ip")
|
||||||
|
.args(["-o", "link", "show", "up"])
|
||||||
|
.output();
|
||||||
|
|
||||||
|
if let Ok(out) = output {
|
||||||
|
if !out.status.success() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let stdout = String::from_utf8_lossy(&out.stdout);
|
||||||
|
for line in stdout.lines() {
|
||||||
|
if let Some(rest) = line.splitn(2, ": ").nth(1) {
|
||||||
|
if let Some(ifname) = rest.split(':').next() {
|
||||||
|
let name = ifname.trim();
|
||||||
|
if name != "lo" {
|
||||||
|
log::log("network_status", "Found active network interface.", LogLevel::Info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
{
|
||||||
|
// Windows: PowerShell verwenden, um aktive Adapter zu finden (Status = Up).
|
||||||
|
// Wir ignorieren Loopback/Pseudo-Interfaces, indem wir Physical=true filtern.
|
||||||
|
let ps_cmd = r#"
|
||||||
|
$adapters = Get-NetAdapter -Physical | Where-Object {$_.Status -eq 'Up'}
|
||||||
|
if ($adapters -and $adapters.Count -ge 1) { 'UP' } else { 'DOWN' }
|
||||||
|
"#;
|
||||||
|
let output = Command::new("powershell")
|
||||||
|
.args(["-NoProfile", "-NonInteractive", "-Command", ps_cmd])
|
||||||
|
.output();
|
||||||
|
|
||||||
|
if let Ok(out) = output {
|
||||||
|
if !out.status.success() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let stdout = String::from_utf8_lossy(&out.stdout).to_ascii_uppercase();
|
||||||
|
|
||||||
|
return if stdout.contains("UP") {
|
||||||
|
log::log("network_status", "Found active network interface.", LogLevel::Info);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(target_os = "linux", target_os = "windows")))]
|
||||||
|
{
|
||||||
|
log::log("network_status", "OS not supported.", LogLevel::Error);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user