diff --git a/src/main.rs b/src/main.rs index bee2942..59351d9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ use crate::filesystem::mounted::{is_mounted, is_mounted_as}; use crate::log::log; use crate::log::LogLevel; use crate::network::network_interface::{get_active_network_interface, get_interface_ip_address}; -use crate::network::utils::{get_ip_from_mac, get_network_address, is_reachable}; +use crate::network::utils::{get_ip_from_mac, get_network_address, is_reachable, wake_on_land}; use crate::sudo::{is_run_as_root, run_as_root}; use std::process::exit; use std::thread; @@ -95,9 +95,12 @@ fn mount_local(network_address: String) { break; } - log("main", "Couldn't find MAC adress in local network, waiting 1 second.", LogLevel::Warn); + log("main", "Couldn't find MAC adress in local network, sending awake call...", LogLevel::Info); + wake_on_land(mac_address); + + log("main", "Waiting 30 seconds...", LogLevel::Info); count = count + 1; - sleep(Duration::from_secs(1)); + sleep(Duration::from_secs(30)); } if device_address.is_none() { diff --git a/src/network/utils.rs b/src/network/utils.rs index d62f389..d7b61e8 100644 --- a/src/network/utils.rs +++ b/src/network/utils.rs @@ -213,4 +213,62 @@ pub fn get_ip_from_mac(mac: &str, network: &str) -> Option { log::log("network_utils", "OS not supported.", LogLevel::Error); None } -} \ No newline at end of file +} + +/// Sendet ein Wake-on-LAN Magic Packet an eine MAC-Adresse +/// +/// # Parameter +/// - `mac`: MAC-Adresse im Format "xx:xx:xx:xx:xx:xx" +/// +/// # Funktionsweise +/// Sendet ein Magic Packet bestehend aus: +/// - 6 Bytes 0xFF (Synchronisierung) +/// - 16x die MAC-Adresse wiederholt +/// - Port 9 (Standard Wake-on-LAN Port) +pub fn wake_on_land(mac: &str) { + #[cfg(target_os = "linux")] + { + let output = Command::new("wakeonlan") + .arg(mac) + .output(); + + if let Ok(out) = output { + if !out.status.success() { + log("network_utils", "Failed to send WOL packet!", LogLevel::Error); + } + } else { + log("network_utils", "wakeonlan is not installed on the system!", LogLevel::Error); + } + } + + #[cfg(target_os = "windows")] + { + let ps_cmd = format!( + r#" + $mac="{}" + $macByteArray=[byte[]]::new(102) + 6..101 | %{{ $macByteArray[$_]=0xFF }} + $macAddr=[byte[]]::new(6) + $mac -split "[:-]" | %{{$macAddr[$i]=[Convert]::ToByte($_,16); $i++}} + 6..101 | %{{ $macByteArray[$_]=$macAddr[($_ - 6) % 6] }} + $UdpClient=New-Object System.Net.Sockets.UdpClient + $UdpClient.Connect(([System.Net.IPAddress]::Broadcast),9) + $UdpClient.Send($macByteArray,$macByteArray.Length) + "#, + mac + ); + + let output = Command::new("powershell") + .args(["-NoProfile", "-NonInteractive", "-Command", &ps_cmd]) + .output(); + + if let Err(_) = output { + log::log("network_utils", "Failed to send WOL packet!", LogLevel::Error); + } + } + + #[cfg(not(any(target_os = "linux", target_os = "windows")))] + { + log::log("network_utils", "OS not supported.", LogLevel::Error); + } +}