This commit is contained in:
cool-mist
2026-07-11 09:53:24 +05:30
parent 4b52bdce76
commit d1ff5c0b10
4 changed files with 88 additions and 51 deletions
+31 -37
View File
@@ -1,7 +1,11 @@
use std::net::UdpSocket;
use crate::{
config::Config, daemon, error::{WError, WResult}, ifaddrs::{self},
arp,
config::Config,
error::{WError, WResult},
mac::Mac,
netif::{self, LocalNetwork},
};
pub struct Wolz {
@@ -38,55 +42,45 @@ impl Wolz {
let mut magic_bytes = [0u8; 102];
mac.copy_magic_bytes(&mut magic_bytes);
let interfaces = ifaddrs::get_network_interfaces();
let mut sent_addresses = Vec::new();
for i in &interfaces {
if sent_addresses.contains(&i.broadcast) {
continue;
}
// man systemd.net-naming-scheme
// Only broadcast to local network
let iname = &i.name;
if iname.starts_with("en") || iname.starts_with("wl") || iname.starts_with("eth") {
let send_addr = format!("{}:0", i.ip);
let broadcast_addr = format!("{}:9", i.broadcast);
match try_send_magic_bytes(&magic_bytes, &send_addr, &broadcast_addr) {
Ok(()) => {
println!("Sent magic pkt {} -> {} for Mac {}", send_addr, broadcast_addr, mac);
sent_addresses.push(i.broadcast);
}
Err(e) => {
println!(
"Unable to send magic pkt {} -> {} for Mac {}, because {}",
send_addr, broadcast_addr, mac, e
);
}
}
}
let networks = netif::get_local_networks()?;
if networks.len() == 0 {
println!("Refusing to send WoL packets. Are you connected to any network?");
return Ok(());
}
if sent_addresses.len() == 0 {
println!("Did not send to any address, are you connected to local network?");
for n in &networks {
try_send_magic_bytes(&magic_bytes, &mac, n);
}
Ok(())
}
pub fn shut_down(&self, mac_or_nick: &str) -> WResult<()> {
let mac = self.config.get_mac(mac_or_nick)?;
let ip_from_arp = netif::find_local_networks_with_mac(mac)?;
todo!()
}
}
fn try_send_magic_bytes(magic_bytes: &[u8; 102], send_addr: &str, broadcast_addr: &str) -> WResult<()> {
let socket = UdpSocket::bind(&send_addr)
.map_err(|e| WError::UdpSocketBindError(format!("couldn't bind to socket because {}", e)))?;
socket
.set_broadcast(true)
.map_err(|e| WError::UdpSocketBindError(format!("couldn't set broadcast because {}", e)))?;
fn try_send_magic_bytes(magic_bytes: &[u8; 102], mac: &Mac, local_network: &LocalNetwork) {
let send_addr = format!("{}:0", local_network.source_ip_hint);
let broadcast_addr = format!("{}:9", local_network.subnet_broadcast);
match send_magic_bytes(&magic_bytes, &send_addr, &broadcast_addr) {
Ok(()) => {
println!("Sent magic pkt {} -> {} for Mac {}", send_addr, broadcast_addr, mac);
}
Err(e) => println!(
"Unable to send magic pkt {} -> {} for Mac {}, because {}",
send_addr, broadcast_addr, mac, e
),
}
}
fn send_magic_bytes(magic_bytes: &[u8; 102], send_addr: &str, broadcast_addr: &str) -> WResult<()> {
let socket = UdpSocket::bind(&send_addr).map_err(WError::UdpSocketBindError)?;
socket.set_broadcast(true).map_err(WError::UdpSocketBindError)?;
socket
.send_to(magic_bytes, &broadcast_addr)
.map_err(|e| WError::UdpSocketBindError(format!("couldn't send data because {}", e)))?;
.map_err(WError::UdpSocketBindError)?;
Ok(())
}