initial commit
This commit is contained in:
commit
5eb250212c
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
/target
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "wakey"
|
||||
version = "0.1.0"
|
||||
authors = ["Hubert Bugaj<lesny.rumcajs@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
hex = "0.3.2"
|
128
src/lib.rs
Normal file
128
src/lib.rs
Normal file
|
@ -0,0 +1,128 @@
|
|||
extern crate hex;
|
||||
|
||||
use std::iter;
|
||||
use std::net::{SocketAddr, ToSocketAddrs, UdpSocket};
|
||||
|
||||
const MAC_SIZE: usize = 6;
|
||||
const MAC_PER_MAGIC: usize = 16;
|
||||
|
||||
/// Wake-on-LAN packet
|
||||
pub struct WolPacket {
|
||||
/// WOL packet bytes
|
||||
packet: Vec<u8>,
|
||||
}
|
||||
|
||||
impl WolPacket {
|
||||
/// Creates WOL packet from byte MAC representation
|
||||
/// # Example
|
||||
/// ```
|
||||
/// extern crate wakey;
|
||||
/// let wol = wakey::WolPacket::from_bytes(&vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05]);
|
||||
/// ```
|
||||
pub fn from_bytes(mac: &[u8]) -> WolPacket {
|
||||
static HEADER: [u8; 6] = [0xFF; 6];
|
||||
let mut packet = Vec::with_capacity(HEADER.len() + MAC_SIZE * MAC_PER_MAGIC);
|
||||
|
||||
packet.extend(HEADER.iter());
|
||||
packet.extend(WolPacket::extend_mac(mac));
|
||||
|
||||
WolPacket { packet }
|
||||
}
|
||||
|
||||
/// Creates WOL packet from string MAC representation (e.x. 00:01:02:03:04:05)
|
||||
/// # Example
|
||||
/// ```
|
||||
/// extern crate wakey;
|
||||
/// let wol = wakey::WolPacket::from_string("00:01:02:03:04:05", ':');
|
||||
/// ```
|
||||
pub fn from_string(data: &str, sep: char) -> WolPacket {
|
||||
WolPacket::from_bytes(&WolPacket::mac_to_byte(data, sep))
|
||||
}
|
||||
|
||||
/// Broadcasts the magic packet from / to default address
|
||||
/// Source: 0.0.0.0:0
|
||||
/// Destination 255.255.255.255:9
|
||||
/// # Example
|
||||
/// ```
|
||||
/// extern crate wakey;
|
||||
/// let wol = wakey::WolPacket::from_bytes(&vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05]);
|
||||
/// wol.send_magic();
|
||||
/// ```
|
||||
pub fn send_magic(&self) -> std::io::Result<()> {
|
||||
self.send_magic_to(
|
||||
SocketAddr::from(([0, 0, 0, 0], 0)),
|
||||
SocketAddr::from(([255, 255, 255, 255], 9)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Broadcasts the magic packet from / to specified address.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// extern crate wakey;
|
||||
/// use std::net::SocketAddr;
|
||||
/// let wol = wakey::WolPacket::from_bytes(&vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05]);
|
||||
/// let src = SocketAddr::from(([0,0,0,0], 0));
|
||||
/// let dst = SocketAddr::from(([255,255,255,255], 9));
|
||||
/// wol.send_magic_to(src, dst);
|
||||
/// ```
|
||||
pub fn send_magic_to<A: ToSocketAddrs>(&self, src: A, dst: A) -> std::io::Result<()> {
|
||||
let udp_sock = UdpSocket::bind(src)?;
|
||||
udp_sock.set_broadcast(true)?;
|
||||
udp_sock.send_to(&self.packet, dst)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Converts string representation of MAC address (e.x. 00:01:02:03:04:05) to raw bytes.
|
||||
/// Panics when input MAC is invalid (i.e. contains non-byte characters)
|
||||
fn mac_to_byte(data: &str, sep: char) -> Vec<u8> {
|
||||
data.split(sep)
|
||||
.map(|x| hex::decode(x).expect("Invalid mac!"))
|
||||
.flatten()
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Extends the MAC address to fill the magic packet
|
||||
fn extend_mac(mac: &[u8]) -> Vec<u8> {
|
||||
iter::repeat(mac)
|
||||
.take(MAC_PER_MAGIC)
|
||||
.flatten()
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn extend_mac_test() {
|
||||
let mac = vec![0x01, 0x02, 0x03, 0x04, 0x05, 0x06];
|
||||
|
||||
let extended_mac = super::WolPacket::extend_mac(&mac);
|
||||
|
||||
assert_eq!(extended_mac.len(), super::MAC_PER_MAGIC * super::MAC_SIZE);
|
||||
assert_eq!(&extended_mac[90..], &mac[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mac_to_byte_test() {
|
||||
let mac = "01:02:03:04:05:06";
|
||||
let result = super::WolPacket::mac_to_byte(mac, ':');
|
||||
|
||||
assert_eq!(result, vec![0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn mac_to_byte_invalid_chars_test() {
|
||||
let mac = "ZZ:02:03:04:05:06";
|
||||
super::WolPacket::mac_to_byte(mac, ':');
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn mac_to_byte_invalid_separator_test() {
|
||||
let mac = "01002:03:04:05:06";
|
||||
super::WolPacket::mac_to_byte(mac, ':');
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user