summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2024-08-19 17:15:40 -0500
committerToby Vincent <tobyv@tobyvin.dev>2024-08-19 17:33:54 -0500
commit2710dae2d886fd2a9e949e2a343de5f343bb340d (patch)
treea3bced54207ac62f4b85d8eb98206d95471519c6
feat: impl basic tplink message protocol
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock93
-rw-r--r--Cargo.toml9
-rw-r--r--src/error.rs10
-rw-r--r--src/lib.rs4
-rw-r--r--src/main.rs3
-rw-r--r--src/protocol.rs63
7 files changed, 183 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..daeaedf
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,93 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "main_error"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "155db5e86c6e45ee456bf32fad5a290ee1f7151c2faca27ea27097568da67d1a"
+
+[[package]]
+name = "nrgmon"
+version = "0.1.0"
+dependencies = [
+ "main_error",
+ "serde",
+ "thiserror",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.86"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.208"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.208"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.63"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.63"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..9a2d0b0
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "nrgmon"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+main_error = "0.1.2"
+serde = { version = "1.0.208", features = ["derive"] }
+thiserror = "1.0.63"
diff --git a/src/error.rs b/src/error.rs
new file mode 100644
index 0000000..ec03758
--- /dev/null
+++ b/src/error.rs
@@ -0,0 +1,10 @@
+pub type Result<T, E = Error> = std::result::Result<T, E>;
+
+#[derive(Debug, thiserror::Error)]
+pub enum Error {
+ #[error("IO error: {0}")]
+ IO(#[from] std::io::Error),
+
+ #[error("Invalid UTF-8: {0}")]
+ Utf8(#[from] std::str::Utf8Error),
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..faceb2c
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,4 @@
+pub use error::{Error, Result};
+
+pub mod error;
+pub mod protocol;
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..05ea213
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,3 @@
+fn main() -> Result<(), main_error::MainError> {
+ Ok(())
+}
diff --git a/src/protocol.rs b/src/protocol.rs
new file mode 100644
index 0000000..9e5edbe
--- /dev/null
+++ b/src/protocol.rs
@@ -0,0 +1,63 @@
+use crate::Error;
+
+const KEY: u8 = 0xAB;
+
+pub fn encrypt(msg: &mut [u8]) {
+ let mut key = KEY;
+ msg.iter_mut().for_each(|b| {
+ key ^= *b;
+ *b = key;
+ });
+}
+
+pub fn decrypt(bytes: &mut [u8]) {
+ let mut key = KEY;
+ bytes.iter_mut().for_each(|b| {
+ let xor = *b ^ key;
+ key = *b;
+ *b = xor;
+ });
+}
+
+pub fn recv<R: std::io::Read>(r: &mut R) -> Result<String, Error> {
+ let mut buf = [0; 4];
+ r.read_exact(&mut buf)?;
+
+ let mut buf = vec![0; u32::from_be_bytes(buf) as usize];
+ r.read_exact(&mut buf)?;
+
+ decrypt(&mut buf);
+
+ let msg = std::str::from_utf8(&buf)?.to_string();
+
+ Ok(msg)
+}
+
+pub fn send<W: std::io::Write>(w: &mut W, msg: &str) -> Result<(), Error> {
+ let mut buf = msg.as_bytes().to_owned();
+ encrypt(&mut buf);
+
+ w.write_all(&(buf.len() as u32).to_be_bytes())?;
+ w.write_all(&buf)?;
+ Ok(())
+}
+
+#[cfg(test)]
+pub(crate) mod tests {
+ use super::*;
+
+ use std::net::TcpStream;
+
+ #[test]
+ fn test_get_sysinfo() -> Result<(), Error> {
+ let mut stream = TcpStream::connect("10.42.0.119:9999")?;
+ send(&mut stream, r#"{"system":{"get_sysinfo":{}}}"#)?;
+ let msg = recv(&mut stream)?;
+
+ assert!(!msg.is_empty());
+
+ println!("{msg}");
+
+ Ok(())
+ }
+}