Cleanup, polish and version bumping
This commit is contained in:
parent
44e63e679e
commit
d70e57ea90
8 changed files with 86 additions and 389 deletions
197
Cargo.lock
generated
197
Cargo.lock
generated
|
@ -22,12 +22,6 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "0.1.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
|
@ -55,15 +49,6 @@ dependencies = [
|
||||||
"vec_map",
|
"vec_map",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cloudabi"
|
|
||||||
version = "0.0.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "3.0.2"
|
version = "3.0.2"
|
||||||
|
@ -84,21 +69,6 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "eff-wordlist"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "226cc2588a6b769f444d06dedd29a366ea92469edea1cef7873fbd76e5b34c24"
|
|
||||||
dependencies = [
|
|
||||||
"rand 0.6.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fuchsia-cprng"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
@ -133,15 +103,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.97"
|
version = "0.2.98"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
|
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ppv-lite86"
|
|
||||||
version = "0.2.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
|
@ -161,161 +125,6 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.6.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"libc",
|
|
||||||
"rand_chacha 0.1.1",
|
|
||||||
"rand_core 0.4.2",
|
|
||||||
"rand_hc 0.1.0",
|
|
||||||
"rand_isaac",
|
|
||||||
"rand_jitter",
|
|
||||||
"rand_os",
|
|
||||||
"rand_pcg",
|
|
||||||
"rand_xorshift",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.8.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"rand_chacha 0.3.1",
|
|
||||||
"rand_core 0.6.3",
|
|
||||||
"rand_hc 0.3.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_chacha"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"rand_core 0.3.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_chacha"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
|
||||||
dependencies = [
|
|
||||||
"ppv-lite86",
|
|
||||||
"rand_core 0.6.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.4.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.6.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_hc"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.3.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_hc"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.6.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_isaac"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.3.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_jitter"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"rand_core 0.4.2",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_os"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
|
||||||
dependencies = [
|
|
||||||
"cloudabi",
|
|
||||||
"fuchsia-cprng",
|
|
||||||
"libc",
|
|
||||||
"rand_core 0.4.2",
|
|
||||||
"rdrand",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_pcg"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"rand_core 0.4.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_xorshift"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.3.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rdrand"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.3.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.2.9"
|
version = "0.2.9"
|
||||||
|
@ -422,9 +231,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"dirs",
|
"dirs",
|
||||||
"eff-wordlist",
|
|
||||||
"hex",
|
"hex",
|
||||||
"rand 0.8.4",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
|
@ -11,5 +11,5 @@ serde = { version = "*", features = ["derive"] }
|
||||||
serde_json = "*"
|
serde_json = "*"
|
||||||
dirs = "*"
|
dirs = "*"
|
||||||
clap = "*"
|
clap = "*"
|
||||||
eff-wordlist = "*"
|
# eff-wordlist = "*"
|
||||||
rand = "*"
|
# rand = "*"
|
||||||
|
|
83
README.md
83
README.md
|
@ -1,61 +1,36 @@
|
||||||
TODO: Review parsing methods
|
# Waker
|
||||||
Add confirm for wake all
|
**An intelligent wake on lan utility to keep track of your machines**
|
||||||
|
|
||||||
Hosts should be pinged on listing
|
The output from program help flag should provide a clear idea of its use:
|
||||||
|
```
|
||||||
|
Waker 0.1.0
|
||||||
|
Imbus64
|
||||||
|
Utility for sending magic packets to configured machines.
|
||||||
|
|
||||||
Structs defined:
|
USAGE:
|
||||||
Host
|
waker [FLAGS] [OPTIONS] [MAC ADDRESSES]...
|
||||||
- Implement methods to retrieve as macbytes/ipv4addr
|
|
||||||
- Field containing MagicPacket?
|
|
||||||
Machines
|
|
||||||
- WakeAll method
|
|
||||||
- PingAll method
|
|
||||||
MagicPacket
|
|
||||||
- Finalze parsers
|
|
||||||
|
|
||||||
The format of a Wake-on-LAN (WOL) magic packet is defined
|
FLAGS:
|
||||||
as a byte array with 6 bytes of value 255 (0xFF) and
|
-a, --add Add a new host
|
||||||
16 repetitions of the target machine’s 48-bit (6-byte) MAC address.
|
--all Wake all configured hosts
|
||||||
|
-e, --edit Enter edit mode
|
||||||
|
-h, --help Prints help information
|
||||||
|
-l, --list List all configured entries
|
||||||
|
-p, --print-config Print contents of configuration file to stdout
|
||||||
|
-V, --version Prints version information
|
||||||
|
|
||||||
102 bytes
|
OPTIONS:
|
||||||
|
--backup <File> Backup configuration file
|
||||||
|
|
||||||
several macs per name
|
ARGS:
|
||||||
|
<MAC ADDRESSES>...
|
||||||
|
|
||||||
edit, delete, add
|
```
|
||||||
|
This project is currently in beta. Many features are implemented, but some may not work as expected.
|
||||||
|
|
||||||
wakemode::all
|
## Future plans:
|
||||||
|
- Further testing and polish in general.
|
||||||
wake(bytes) method
|
- [ ] Include pinging functionality, so the user gets feedback on what machines are already awake (Top priority)
|
||||||
async ping method(ip)?
|
- [ ] Enable users to import an existing config, appending selected hosts to current config. (Second priority)
|
||||||
|
- [ ] Perhaps wrap run_mode in an Option, with None being the default when the program is invoked without CLI parameters
|
||||||
const MAGIC_BYTES_HEADER: [u8; 6] = [0xFF; 6];
|
- [ ] Rewrite all input/blocking related code into a struct of some sort
|
||||||
vec<u8> bytes = FFFFFFFFFFFF .reserve(enough) 102?
|
|
||||||
|
|
||||||
match run_mode {
|
|
||||||
Some() => Do according to some
|
|
||||||
None => Figure out what to do(set run_mode)
|
|
||||||
}
|
|
||||||
|
|
||||||
add 8 char string -> to bytes ask for name and add
|
|
||||||
add 11 char string -> if mac[2,5,8] is same char -> split by it and ask for name -> add
|
|
||||||
|
|
||||||
store json in ~/.config/waker.conf
|
|
||||||
dump-json method
|
|
||||||
export/import? append?
|
|
||||||
|
|
||||||
struct mechine {
|
|
||||||
vec of all macs
|
|
||||||
ip of machine? so we can ping it?
|
|
||||||
name
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mac_list {
|
|
||||||
Vec
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ask what do:
|
|
||||||
1. Wake
|
|
||||||
2. Wake all
|
|
||||||
3. Add
|
|
||||||
4. Edit
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
|
|
||||||
/// Python like input method with prompt message
|
/// Python like input function with prompt message
|
||||||
pub fn input(prompt: &str) -> String {
|
pub fn input(prompt: &str) -> String {
|
||||||
print!("{}", prompt);
|
print!("{}", prompt);
|
||||||
let _ = io::stdout().flush();
|
let _ = io::stdout().flush();
|
||||||
|
@ -15,11 +15,14 @@ pub fn input(prompt: &str) -> String {
|
||||||
input.trim().to_string()
|
input.trim().to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Simple confirm dialogue
|
/// Simple confirm dialogue. Appends " [y/N]: " to your message, and prints feedback on your
|
||||||
|
/// choice.
|
||||||
pub fn confirm(message: &str) -> bool {
|
pub fn confirm(message: &str) -> bool {
|
||||||
let answer = input(format!("{} [y/N]: ", message).as_str()).to_uppercase();
|
let answer = input(format!("{} [y/N]: ", message).as_str()).to_uppercase();
|
||||||
if answer == "YES" || answer == "Y" {
|
if answer == "YES" || answer == "Y" {
|
||||||
|
println!("Yes");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
println!("No");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,9 @@ impl Machines {
|
||||||
Ok(machines)
|
Ok(machines)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_skeleton_config(file: &PathBuf) -> Result<(), Box<dyn Error>> {
|
/// Creates file and dumps a skeleton config into it
|
||||||
|
pub fn create_skeleton_config(file: &PathBuf) -> Result<(), Box<dyn Error>> {
|
||||||
|
std::fs::File::create(&file)?;
|
||||||
let skel_machines = Machines::new();
|
let skel_machines = Machines::new();
|
||||||
skel_machines.dump(file)?;
|
skel_machines.dump(file)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
56
src/main.rs
56
src/main.rs
|
@ -16,7 +16,6 @@ mod host; // The actual Host struct
|
||||||
mod input; // Gives us a python-like input function, as well as a simple confirm function
|
mod input; // Gives us a python-like input function, as well as a simple confirm function
|
||||||
mod machines; // Struct that holds a vec of Hosts, as well as operations on those
|
mod machines; // Struct that holds a vec of Hosts, as well as operations on those
|
||||||
mod packet; // The actual magic packet struct, with wake methods e.t.c.
|
mod packet; // The actual magic packet struct, with wake methods e.t.c.
|
||||||
// mod random_machine; // Exposes a function that generates a random Host, with random mac, ip and name // The actual host struct.
|
|
||||||
mod sanitizers; // Functions that sanitizes MAC and IP addresses
|
mod sanitizers; // Functions that sanitizes MAC and IP addresses
|
||||||
|
|
||||||
// use crate::packet::*;
|
// use crate::packet::*;
|
||||||
|
@ -76,20 +75,17 @@ fn prompt_file_creation(config_path: &PathBuf) -> Option<File> {
|
||||||
config_path.to_str().unwrap()
|
config_path.to_str().unwrap()
|
||||||
);
|
);
|
||||||
if input::confirm(&msg) {
|
if input::confirm(&msg) {
|
||||||
|
|
||||||
let newfile = std::fs::File::create(&config_path).expect(&format!(
|
let newfile = std::fs::File::create(&config_path).expect(&format!(
|
||||||
"Could not create file: {}",
|
"Could not create file: {}",
|
||||||
config_path.to_str().unwrap()
|
config_path.to_str().unwrap()
|
||||||
));
|
));
|
||||||
|
|
||||||
// Deserialize an empty Machines struct into the new config file.
|
// Deserialize an empty Machines struct into the new config file.
|
||||||
// The parser is not equipped to handle empty or malformatted files...
|
match Machines::create_skeleton_config(config_path) {
|
||||||
// This could potentially be moved into a static method in Machines, like
|
Ok(()) => { return Some(newfile); }
|
||||||
// Machines::init_config_file(), which does this for us.
|
Err(_) => return None,
|
||||||
//
|
}
|
||||||
// For now, this will do.
|
|
||||||
let skeleton_machines = Machines::new();
|
|
||||||
skeleton_machines.dump(&config_path).unwrap();
|
|
||||||
return Some(newfile);
|
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +165,7 @@ fn edit_host(host: &mut Host, editmode: HostEditMode) {
|
||||||
let newip = input("New IP: ");
|
let newip = input("New IP: ");
|
||||||
match sanitizers::sanitize(&newip, sanitizers::AddrType::IPv4) {
|
match sanitizers::sanitize(&newip, sanitizers::AddrType::IPv4) {
|
||||||
Some(ip) => {
|
Some(ip) => {
|
||||||
host.ips[index as usize] = newip;
|
host.ips[index as usize] = ip;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
println!("Could not parse IP");
|
println!("Could not parse IP");
|
||||||
|
@ -226,7 +222,7 @@ fn edit_host(host: &mut Host, editmode: HostEditMode) {
|
||||||
let newmac = input("New MAC: ");
|
let newmac = input("New MAC: ");
|
||||||
match sanitizers::sanitize(&newmac, sanitizers::AddrType::MAC) {
|
match sanitizers::sanitize(&newmac, sanitizers::AddrType::MAC) {
|
||||||
Some(mac_addr) => {
|
Some(mac_addr) => {
|
||||||
host.macs[index as usize] = newmac;
|
host.macs[index as usize] = mac_addr;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
println!("Could not parse MAC");
|
println!("Could not parse MAC");
|
||||||
|
@ -345,8 +341,11 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let file = prompt_file_creation(&config_path);
|
let file = prompt_file_creation(&config_path);
|
||||||
if file.is_none() {
|
if file.is_none() {
|
||||||
println!("Exiting...");
|
println!("Exiting...");
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
println!("Config file created.");
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: More sophisticated error checking and logging
|
// TODO: More sophisticated error checking and logging
|
||||||
|
@ -362,22 +361,29 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
RunMode::Wake(wake_mode) => {
|
RunMode::Wake(wake_mode) => {
|
||||||
match wake_mode {
|
match wake_mode {
|
||||||
WakeMode::WakeAll => {
|
WakeMode::WakeAll => {
|
||||||
machines.wakeall();
|
if confirm("You are about to wake all configured machines.\nContinue?") {
|
||||||
for host in &machines.list {
|
machines.wakeall();
|
||||||
println!("Woke {}", host.name)
|
for host in &machines.list {
|
||||||
|
println!("Woke {}", host.name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WakeMode::WakeSome => {
|
WakeMode::WakeSome => {
|
||||||
println!("{}", machines);
|
if ! machines.list.is_empty() {
|
||||||
let indexes = which_indexes(
|
println!("{}", machines);
|
||||||
"Select which hosts to wake up (Comma separated integers): ",
|
let indexes = which_indexes(
|
||||||
&machines,
|
"Select which hosts to wake up (Comma separated integers): ",
|
||||||
);
|
&machines,
|
||||||
for index in indexes {
|
);
|
||||||
// TODO: Bounds checking
|
for index in indexes {
|
||||||
let host = &machines.list[index as usize];
|
// TODO: Bounds checking
|
||||||
host.wake();
|
let host = &machines.list[index as usize];
|
||||||
println!("Woke {}", host.name)
|
host.wake();
|
||||||
|
println!("Woke {}", host.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println!("No machines configured yet... Try \"waker --help\" for information about usage");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => println!("undefined"),
|
_ => println!("undefined"),
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use std::{
|
use std::{convert::TryInto, error::Error, net::{Ipv4Addr, ToSocketAddrs, UdpSocket}};
|
||||||
error::Error,
|
use crate::sanitizers::{self, sanitize};
|
||||||
net::{Ipv4Addr, ToSocketAddrs, UdpSocket},
|
|
||||||
};
|
|
||||||
|
|
||||||
// The format of a Wake-on-LAN (WOL) magic packet is defined
|
// The format of a Wake-on-LAN (WOL) magic packet is defined
|
||||||
// as a byte array with 6 bytes of value 255 (0xFF) followed by
|
// as a byte array with 6 bytes of value 255 (0xFF) followed by
|
||||||
|
@ -34,73 +32,22 @@ impl MagicPacket {
|
||||||
return MagicPacket { bytes: magic_bytes };
|
return MagicPacket { bytes: magic_bytes };
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is horrible code
|
|
||||||
/// Parse a MAC-string into a packet.
|
/// Parse a MAC-string into a packet.
|
||||||
/// Takes both separated and unseparated
|
/// The MAC-string should be 17 characters long, separated by colons (i.e. XX:XX:XX:XX:XX:XX)
|
||||||
pub fn from_str(mac_str: &str) -> Result<MagicPacket, Box<dyn Error>> {
|
pub fn from_str(mac_str: &str) -> Result<MagicPacket, Box<dyn Error>> {
|
||||||
use hex::FromHex;
|
let mac_bytes = MagicPacket::parse_macstr(mac_str, ':')?;
|
||||||
let mut mac_string = mac_str.trim().to_string();
|
return Ok(MagicPacket::new(&mac_bytes));
|
||||||
|
|
||||||
if mac_string.len() == 17 {
|
|
||||||
for i in 0..5 {
|
|
||||||
mac_string.remove(14 - (i * 3)); // Deal with it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut mac_arr: [u8; 6];
|
|
||||||
let hex_vec = Vec::from_hex(mac_string)?;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
mac_arr = std::mem::MaybeUninit::uninit().assume_init();
|
|
||||||
let src: *const u8 = &hex_vec[0];
|
|
||||||
let dst: *mut u8 = &mut mac_arr[0];
|
|
||||||
dst.copy_from_nonoverlapping(src, 6);
|
|
||||||
}
|
|
||||||
return Ok(MagicPacket::new(&mac_arr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_str2(mac_str: &str) -> Result<MagicPacket, Box<dyn Error>> {
|
// This method is a bit allocation heavy.
|
||||||
return Ok(MagicPacket::new(&MagicPacket::parse(mac_str).unwrap()));
|
pub fn parse_macstr<S: AsRef<str>>(mac_str: S, sep: char) -> Result<Box<[u8; 6]>, Box<dyn Error>> {
|
||||||
}
|
let sanitized_macstr = sanitize(mac_str.as_ref(), sanitizers::AddrType::MAC).unwrap();
|
||||||
|
let bytes_split: Vec<u8> = sanitized_macstr.split(sep)
|
||||||
// Stolen
|
|
||||||
fn mac_to_byte(data: &str, sep: char) -> Vec<u8> {
|
|
||||||
data.split(sep)
|
|
||||||
.flat_map(|x| hex::decode(x).expect("Invalid mac!"))
|
.flat_map(|x| hex::decode(x).expect("Invalid mac!"))
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parses string by position if string is 12+5 characters long (delimited by : for example)
|
|
||||||
pub fn parse<S: AsRef<str>>(mac_str: S) -> Result<Box<[u8; 6]>, Box<dyn Error>> {
|
|
||||||
use hex::FromHex;
|
|
||||||
let mut mstr: &str = mac_str.as_ref();
|
|
||||||
mstr = mstr.trim();
|
|
||||||
let mut bytes: [u8; 6] = [0, 0, 0, 0, 0, 0];
|
|
||||||
|
|
||||||
for (index, byte) in bytes.iter_mut().enumerate() {
|
|
||||||
// 0,3,6,9...
|
|
||||||
let substr = &mstr[3 * index..3 * index + 2];
|
|
||||||
*byte = <[u8; 1]>::from_hex(substr).unwrap()[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(Box::new(bytes));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loops the string and parses any valid hex
|
|
||||||
pub fn parse_harder<S: Into<String>>(mac_str: S) -> Result<Box<[u8; 6]>, Box<dyn Error>> {
|
|
||||||
let mstr: String = mac_str.into();
|
|
||||||
let mut hexdigits: String = mstr
|
|
||||||
.chars()
|
|
||||||
.filter(|c| char::is_ascii_hexdigit(c))
|
|
||||||
.collect();
|
.collect();
|
||||||
let mut bytes: [u8; 6] = [0; 6];
|
|
||||||
|
|
||||||
if hexdigits.len() >= 12 {
|
let arr: [u8; 6] = bytes_split.try_into().unwrap();
|
||||||
hexdigits.truncate(12); // May not be needed, since bytes is only 6 bytes, and from_hex might be smart enough to realize...
|
Ok(Box::new(arr))
|
||||||
//let bytes: [u8; 6] = hex::FromHex::from_hex(hexdigits)?;
|
|
||||||
bytes = hex::FromHex::from_hex(hexdigits)?;
|
|
||||||
}
|
|
||||||
return Ok(Box::new(bytes));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send packet to/from specific address/interface
|
/// Send packet to/from specific address/interface
|
||||||
|
@ -118,11 +65,6 @@ impl MagicPacket {
|
||||||
(Ipv4Addr::new(0x0, 0x0, 0x0, 0x0), 0),
|
(Ipv4Addr::new(0x0, 0x0, 0x0, 0x0), 0),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return raw bytes, ready to be broadcasted
|
|
||||||
pub fn get_bytes(&self) -> &[u8; 102] {
|
|
||||||
&self.bytes
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -142,7 +84,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn magic_packet_from_new() {
|
fn magic_packet_from_new() {
|
||||||
let packet3 = MagicPacket::from_str2("10:10:10:10:10:10").unwrap();
|
let packet3 = MagicPacket::from_str("10:10:10:10:10:10").unwrap();
|
||||||
//let vec: [u8; 102] = [0xFF; 102];
|
//let vec: [u8; 102] = [0xFF; 102];
|
||||||
let slice = &packet3.bytes[packet3.bytes.len() - 6..];
|
let slice = &packet3.bytes[packet3.bytes.len() - 6..];
|
||||||
for a in slice {
|
for a in slice {
|
||||||
|
@ -155,15 +97,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse() {
|
fn test_parse() {
|
||||||
let mp = MagicPacket::parse("ff:ff:ff:ff:ff:ff").unwrap();
|
let mp = MagicPacket::parse_macstr("ff:ff:ff:ff:ff:ff", ':').unwrap();
|
||||||
assert_eq!([0xFF; 6], *mp);
|
assert_eq!([0xFF; 6], *mp);
|
||||||
let mp2 = MagicPacket::parse("10:10:10:10:10:10").unwrap();
|
let mp2 = MagicPacket::parse_macstr("10:10:10:10:10:10", ':').unwrap();
|
||||||
assert_eq!([0x10; 6], *mp2);
|
assert_eq!([0x10; 6], *mp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_harder_test() {
|
|
||||||
let mac = MagicPacket::parse_harder("10:10:10:10:10:10").unwrap();
|
|
||||||
assert_eq!([0x10; 6], *mac);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
32
waker.json
32
waker.json
|
@ -1,32 +0,0 @@
|
||||||
{
|
|
||||||
"list": [
|
|
||||||
{
|
|
||||||
"name": "Name",
|
|
||||||
"macs": [
|
|
||||||
"E9:A3:29:73:FE:D2"
|
|
||||||
],
|
|
||||||
"ips": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "i",
|
|
||||||
"macs": [
|
|
||||||
"7D:E1:AC:94:29:79"
|
|
||||||
],
|
|
||||||
"ips": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "PartyMaskinen",
|
|
||||||
"macs": [
|
|
||||||
"96:F8:FF:30:4C:EE"
|
|
||||||
],
|
|
||||||
"ips": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Kalle",
|
|
||||||
"macs": [
|
|
||||||
"FF:FF:FF:FF:FF:FF"
|
|
||||||
],
|
|
||||||
"ips": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
Loading…
Reference in a new issue