holy shi
This commit is contained in:
Generated
+75
@@ -162,6 +162,21 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.31"
|
||||
@@ -169,6 +184,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -177,6 +193,40 @@ version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.31"
|
||||
@@ -189,10 +239,16 @@ version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -325,6 +381,12 @@ version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
|
||||
[[package]]
|
||||
name = "macaddr"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baee0bbc17ce759db233beb01648088061bf678383130602a298e6998eedb2d8"
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.8.4"
|
||||
@@ -501,6 +563,15 @@ dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.11"
|
||||
@@ -556,10 +627,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"io-uring",
|
||||
"libc",
|
||||
"mio",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"slab",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
@@ -665,6 +738,8 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"color-eyre",
|
||||
"futures",
|
||||
"macaddr",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
||||
+3
-1
@@ -7,4 +7,6 @@ publish = ["gitea"]
|
||||
[dependencies]
|
||||
axum = "0.8.4"
|
||||
color-eyre = "0.6.5"
|
||||
tokio = "1.47.1"
|
||||
futures = "0.3.31"
|
||||
macaddr = "1.0.1"
|
||||
tokio = { version = "1.47.1", features = ["fs", "process"] }
|
||||
|
||||
@@ -11,6 +11,6 @@ cross build --release --target armv7-unknown-linux-musleabihf # my machine
|
||||
```
|
||||
|
||||
cross works with a random windows machine.
|
||||
it works; those toolchains they tried to install: add them forcefully by hand.
|
||||
it works; those toolchains they tried to install: add them forcefully by hand.
|
||||
|
||||
it works. uses docker.
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// struct arp;
|
||||
|
||||
// async fn read_arp() -> io::Result<()> {
|
||||
// let arp_file = tokio::fs::File::open("/proc/net/arp").await?;
|
||||
// let arp_read = BufReader::new(arp_file);
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
+71
-8
@@ -1,41 +1,104 @@
|
||||
use axum::{Router, response::Html, routing::get};
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use axum::{
|
||||
Router,
|
||||
response::Html,
|
||||
routing::get,
|
||||
};
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
mod arpparse;
|
||||
mod utils;
|
||||
use utils::*;
|
||||
const MACHINE_NAME: &str = "lda.lan";
|
||||
async fn home() -> Html<String> {
|
||||
Html(format!(
|
||||
r#"
|
||||
<html>
|
||||
<body>
|
||||
<p>the machine is {}!</p>
|
||||
<p>the machine is {}! <a href="/status">Status</a></p>
|
||||
<form method="POST" action="/wake">
|
||||
<button type="submit">Wake LDA</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
"#,
|
||||
if ping_ip("192.168.100.94:22").await {
|
||||
"on"
|
||||
} else {
|
||||
"off"
|
||||
match get_ips(MACHINE_NAME).await {
|
||||
Ok(ips) => {
|
||||
let addrs: Vec<SocketAddr> = ips.into_iter().map(|ip|(ip, 22).into()).collect();
|
||||
if ping_ip(&*addrs).await { "on" } else { "off" }
|
||||
}
|
||||
Err(_) => "off",
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
async fn wake_handler() -> &'static str {
|
||||
match wake("lda.lan").await {
|
||||
match wake(MACHINE_NAME).await {
|
||||
Err(_) => "Wake failed",
|
||||
Ok(_) => "Packet sent!",
|
||||
}
|
||||
}
|
||||
|
||||
async fn status() -> Html<String> {
|
||||
let formatted_ips = match get_ips(MACHINE_NAME).await {
|
||||
Ok(ips) => {
|
||||
let string: String = ips
|
||||
.iter()
|
||||
.map(|ip| format!("<tr><td>{ip}</td></tr>"))
|
||||
.collect();
|
||||
format!(
|
||||
"<p>the ips of {m} are:</p>
|
||||
<table>
|
||||
<tr><th>IP</th></tr>
|
||||
{string}
|
||||
</table>",
|
||||
m = MACHINE_NAME )
|
||||
}
|
||||
Err(e) => format!("<p>error getting ips: {e}</p>"),
|
||||
};
|
||||
let formatted_macs = match get_macs(MACHINE_NAME).await {
|
||||
Ok(table) => {
|
||||
let the: String = table
|
||||
.iter()
|
||||
.map(|(ip, mac)| {
|
||||
let mac_str = if let Some(mac) = mac {
|
||||
back_to_str(mac)
|
||||
} else {
|
||||
"None".into()
|
||||
};
|
||||
format!("<tr><td>{ip}</td><td>{mac_str}</td></tr>")
|
||||
})
|
||||
.collect();
|
||||
format!(
|
||||
"<p>the macs here:</p>
|
||||
<table>
|
||||
<tr><th>IP</th><th>MAC</th></tr>
|
||||
{the}
|
||||
</table>"
|
||||
)
|
||||
}
|
||||
Err(e) => format!("<p>cant get macs either: {e}</p>"),
|
||||
};
|
||||
|
||||
Html(format!(
|
||||
r#"
|
||||
<html>
|
||||
<body>
|
||||
{formatted_ips}
|
||||
{formatted_macs}
|
||||
</body>
|
||||
</html>
|
||||
"#,
|
||||
))
|
||||
}
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> color_eyre::Result<()> {
|
||||
color_eyre::install()?;
|
||||
let app = Router::new()
|
||||
.route("/", get(home))
|
||||
.route("/wake", axum::routing::post(wake_handler));
|
||||
.route("/wake", axum::routing::post(wake_handler))
|
||||
.route("/status", get(status));
|
||||
|
||||
let port = TcpListener::bind("0.0.0.0:12012").await?;
|
||||
axum::serve(port, app.into_make_service()).await?;
|
||||
|
||||
+68
-14
@@ -1,13 +1,15 @@
|
||||
pub const LDA_MACS: [[u8; 6]; 2] = [
|
||||
[0x04, 0x7c, 0x16, 0x79, 0x6d, 0xee],
|
||||
[0xbc, 0x09, 0x1b, 0xec, 0x65, 0xd0],
|
||||
];
|
||||
]; // is it time to lookup host lda.lan for this...
|
||||
|
||||
|
||||
pub async fn wake(_machine_name: &str) -> io::Result<()> {
|
||||
pub async fn wake(machine_name: &str) -> io::Result<()> {
|
||||
let suh = UdpSocket::bind("0.0.0.0:0").await?;
|
||||
suh.set_broadcast(true)?;
|
||||
for mac in LDA_MACS {
|
||||
for (_, mac) in get_macs(machine_name).await? {
|
||||
let Some(mac) = mac else {
|
||||
continue;
|
||||
};
|
||||
let pac: Vec<u8> = iter::once([0xff; 6])
|
||||
.chain(iter::repeat_n(mac, 16))
|
||||
.flatten()
|
||||
@@ -16,8 +18,9 @@ pub async fn wake(_machine_name: &str) -> io::Result<()> {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
use std::{iter, time::Duration};
|
||||
use std::{collections::HashSet, iter, net::IpAddr, time::Duration};
|
||||
|
||||
use macaddr::MacAddr;
|
||||
use tokio::{
|
||||
io,
|
||||
net::{TcpStream, ToSocketAddrs, UdpSocket},
|
||||
@@ -32,14 +35,65 @@ pub async fn ping_ip<T: ToSocketAddrs>(addr: T) -> bool {
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub async fn get_ips(machine_name: &str) -> io::Result<Vec<IpAddr>> {
|
||||
Ok(tokio::net::lookup_host((machine_name, 0))
|
||||
.await?
|
||||
.map(|c| c.ip())
|
||||
.collect())
|
||||
}
|
||||
|
||||
// pub async fn get_ips(macs: &[&[u8;6]]) -> Vec<IpAddr> {
|
||||
// /*
|
||||
// root@AP-AX3000CV2-0A55:~# ip neigh show 192.168.100.94
|
||||
// 192.168.100.94 dev eth1.6 FAILED
|
||||
// 192.168.100.94 dev br-lan lladdr 04:7c:16:79:6d:ee REACHABLE
|
||||
// 192.168.100.94 dev eth1.7 FAILED
|
||||
// 192.168.100.94 dev eth1.5 FAILED
|
||||
// */
|
||||
pub async fn get_macs(machine_name: &str) -> io::Result<Vec<(IpAddr, Option<[u8; 6]>)>> {
|
||||
let ips = get_ips(machine_name).await?;
|
||||
let futures = ips
|
||||
.iter()
|
||||
// .filter(|f| f.is_ipv4())
|
||||
.map(|ip| {
|
||||
let ip = ip.to_canonical();
|
||||
async move {
|
||||
let mut u = tokio::process::Command::new("ip");
|
||||
u.args(["neigh", "show", "to", &ip.to_string()]);
|
||||
let o = u.output().await.ok()?;
|
||||
let mac = o.status.success().then(|| {
|
||||
let stdout = String::from_utf8_lossy(&o.stdout);
|
||||
stdout
|
||||
.lines()
|
||||
.filter_map(|line| {
|
||||
let mut parts = line.split_whitespace();
|
||||
parts.find(|&x| x == "lladdr")?;
|
||||
let macstr = parts.next()?;
|
||||
to_arr(macstr)
|
||||
})
|
||||
.next()
|
||||
})?;
|
||||
Some((ip, mac))
|
||||
}
|
||||
});
|
||||
let results = futures::future::join_all(futures).await;
|
||||
Ok(results.into_iter().flatten().collect())
|
||||
}
|
||||
|
||||
// }
|
||||
pub async fn get_macs_2(machine_name: &str) -> io::Result<HashSet<MacAddr>> {
|
||||
Ok(get_macs(machine_name)
|
||||
.await?
|
||||
.into_iter()
|
||||
.filter_map(|(_, m)| m.map(MacAddr::from))
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub fn to_arr(macstr: &str) -> Option<[u8; 6]> {
|
||||
let mut this = [0u8; 6];
|
||||
(macstr.split(':').count() == 6).then(|| {
|
||||
for (n, h) in this.iter_mut().zip(macstr.split(':')) {
|
||||
*n = u8::from_str_radix(h, 16).ok()?;
|
||||
}
|
||||
Some(this)
|
||||
})?
|
||||
}
|
||||
|
||||
pub fn back_to_str(thing: &[u8; 6]) -> String {
|
||||
thing
|
||||
.iter()
|
||||
.map(|n| format!("{n:02x}"))
|
||||
.collect::<Vec<String>>()
|
||||
.join(":")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user