Do not send duplicates

This commit is contained in:
2026-07-10 19:17:57 +05:30
parent abf1d8c175
commit cc5e33c31a
4 changed files with 70 additions and 48 deletions
+1 -1
View File
@@ -47,7 +47,7 @@ impl Config {
&nick.name
)))
.map(|mac| mac.clone()),
Device::IpV4(ip_v4) => todo!(),
Device::IpV4(_) => todo!(),
}
}
+16 -15
View File
@@ -60,9 +60,21 @@ struct LinkAddress {
pub struct NetworkInterface {
pub name: String,
pub ip: Ipv4Addr,
pub netmask: Ipv4Addr,
pub _netmask: Ipv4Addr,
pub broadcast: Ipv4Addr,
pub mac: [u8; 6],
pub _mac: [u8; 6],
}
impl NetworkInterface {
fn create(name: String, ip: Ipv4Addr, netmask: Ipv4Addr, broadcast: Ipv4Addr, mac: [u8; 6]) -> Self {
Self {
name,
ip,
_netmask: netmask,
broadcast,
_mac: mac,
}
}
}
pub fn get_network_interfaces() -> Vec<NetworkInterface> {
@@ -93,11 +105,7 @@ pub fn get_network_interfaces() -> Vec<NetworkInterface> {
let netmask = read_sa_ip(sa_netmask);
let broadcast = calculate_broadcast_address(ip, netmask);
let network_address = NetworkAddress {
ip,
netmask,
broadcast,
};
let network_address = NetworkAddress { ip, netmask, broadcast };
network_addresses.insert(name, network_address);
} else if family == AF_PACKET {
@@ -120,14 +128,7 @@ pub fn get_network_interfaces() -> Vec<NetworkInterface> {
// Assume all link_addresses have unique names for now
for (n, m) in link_addresses {
if let Some(n_addr) = network_addresses.get(&n) {
let network_interface = NetworkInterface {
name: n.to_string(),
ip: n_addr.ip,
netmask: n_addr.netmask,
broadcast: n_addr.broadcast,
mac: m.mac,
};
let network_interface = NetworkInterface::create(n, n_addr.ip, n_addr.netmask, n_addr.broadcast, m.mac);
network_interfaces.push(network_interface);
};
}
+37 -13
View File
@@ -3,7 +3,7 @@ use std::net::UdpSocket;
use crate::{
config::Config,
error::{WError, WResult},
ifaddrs,
ifaddrs::{self},
};
pub struct Wolz {
@@ -22,26 +22,50 @@ impl Wolz {
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 address = format!("{}:0", i.ip);
let broadcast_address = format!("{}:9", i.broadcast);
let socket = UdpSocket::bind(&address)
.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)))?;
socket
.send_to(&magic_bytes, &broadcast_address)
.map_err(|e| WError::UdpSocketBindError(format!("couldn't send data because {}", e)))?;
println!("Magic packet sent to {} for Mac {:}", broadcast_address, mac);
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
);
}
}
}
}
if sent_addresses.len() == 0 {
println!("Did not send to any address, are you connected to local network?");
}
Ok(())
}
}
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)))?;
socket
.send_to(magic_bytes, &broadcast_addr)
.map_err(|e| WError::UdpSocketBindError(format!("couldn't send data because {}", e)))?;
Ok(())
}