From c6ee82e3380a267183b7db5a9ec7ea85f46e9335 Mon Sep 17 00:00:00 2001 From: mattbk Date: Tue, 30 Sep 2025 21:42:57 -0500 Subject: [PATCH 1/7] Update readme. --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c173bde..f0eb9b5 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,7 @@ (working name) Experimental server to catch UDP packets from a -[modified mwtchahrd](https://gitea.farpn.net/w1cdn/mwtchahrd) and do something with them. \ No newline at end of file +[modified mwtchahrd](https://gitea.farpn.net/w1cdn/mwtchahrd) and do something with them. + +Initially based on the example here: +[Building UDP Clients and Servers](https://notes.kodekloud.com/docs/Rust-Programming/Network-Programming-and-File-Handling/Building-UDP-Clients-and-Servers) \ No newline at end of file -- 2.39.5 From 0420e9994b97efe6974e3c9f7136a2a3010e32d2 Mon Sep 17 00:00:00 2001 From: mattbk Date: Wed, 1 Oct 2025 14:18:44 -0500 Subject: [PATCH 2/7] Change suggested by cargo build. --- src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index ee922ef..ef24ca0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use std::net::UdpSocket; fn main() -> std::io::Result<()> { let socket_result: Result = UdpSocket::bind("127.0.0.1:7878"); - let mut socket: UdpSocket = match socket_result { + let socket: UdpSocket = match socket_result { Ok(s) => s, Err(e) => { println!("Failed to bind socket: {}", e); @@ -28,7 +28,6 @@ fn main() -> std::io::Result<()> { String::from_utf8_lossy(&buffer[..bytes_received]) ); - // Echo the data back to the client socket.send_to(&buffer[..bytes_received], src_addr)?; } -- 2.39.5 From 0261369e7b02d78624e0169550ee778974fef58d Mon Sep 17 00:00:00 2001 From: mattbk Date: Wed, 1 Oct 2025 14:42:52 -0500 Subject: [PATCH 3/7] Rough out db basics. --- .gitignore | 1 + Cargo.lock | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 48 +++++++++++++++++++++++++++-- 4 files changed, 134 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 87f1765..70d5dc5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock +*.db diff --git a/Cargo.lock b/Cargo.lock index 1bf7e66..41fd5f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,93 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "bitflags" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "133c182a6a2c87864fe97778797e46c7e999672690dc9fa3ee8e241aa4a9c13f" +dependencies = [ + "pkg-config", + "vcpkg", +] + [[package]] name = "my_udp_server" version = "0.1.0" +dependencies = [ + "rusqlite", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "rusqlite" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" +dependencies = [ + "bitflags", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" diff --git a/Cargo.toml b/Cargo.toml index 2733c35..5961110 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" edition = "2024" [dependencies] +rusqlite = "0.37.0" diff --git a/src/main.rs b/src/main.rs index ef24ca0..cfba167 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,13 @@ -// UDP server -use std::net::UdpSocket; +use std::net::UdpSocket; // UDP server +use rusqlite::{params, Connection, Result}; // Database operations and result handling +use std::time::{SystemTime, UNIX_EPOCH}; fn main() -> std::io::Result<()> { + + let _ = create_database(); + let _ = insert_packet("foo", 1); + let socket_result: Result = UdpSocket::bind("127.0.0.1:7878"); let socket: UdpSocket = match socket_result { Ok(s) => s, @@ -17,7 +22,6 @@ fn main() -> std::io::Result<()> { // Buffer for incoming data (512 bytes) let mut buffer: [u8; 512] = [0; 512]; - loop { // Receive data from the client let (bytes_received, src_addr) = socket.recv_from(&mut buffer)?; @@ -32,3 +36,41 @@ fn main() -> std::io::Result<()> { socket.send_to(&buffer[..bytes_received], src_addr)?; } } + + +// Database functions +fn create_database() -> Result<()> { + // Connect to SQLite database (creates the file if it doesn't exist) + let conn = Connection::open("pkt_database.db")?; + + // Create a table + conn.execute( + "CREATE TABLE IF NOT EXISTS packets ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + raw TEXT NOT NULL, + age INTEGER NOT NULL, + date INTEGER NOT NULL + )", + [], // No parameters needed + )?; + + println!("Database and table created successfully."); + Ok(()) +} + +fn insert_packet(raw: &str, age: i32) -> Result<()> { + let conn = Connection::open("pkt_database.db")?; + + let ds = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); + + // Insert + conn.execute( + "INSERT INTO packets (raw, age, date) VALUES (?1, ?2, ?3)", + params![raw, age, ds], // Bind parameters + )?; + + println!("Row inserted successfully."); + Ok(()) +} + + -- 2.39.5 From c228129e21c7d681dc1c41c513aea40743a6a7c9 Mon Sep 17 00:00:00 2001 From: mattbk Date: Wed, 1 Oct 2025 19:41:10 -0500 Subject: [PATCH 4/7] Store raw packet in db. --- src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.rs b/src/main.rs index cfba167..5801044 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,6 +31,8 @@ fn main() -> std::io::Result<()> { src_addr, String::from_utf8_lossy(&buffer[..bytes_received]) ); + + let _ = insert_packet(&String::from_utf8_lossy(&buffer[..bytes_received]), 1); // Echo the data back to the client socket.send_to(&buffer[..bytes_received], src_addr)?; -- 2.39.5 From 97f6a4bdb96c38589d201a7d83b6c80faae34bbb Mon Sep 17 00:00:00 2001 From: mattbk Date: Sat, 4 Oct 2025 22:46:44 -0500 Subject: [PATCH 5/7] Clean up db more. --- src/main.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main.rs b/src/main.rs index 5801044..2986add 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,9 @@ use std::time::{SystemTime, UNIX_EPOCH}; fn main() -> std::io::Result<()> { + // Set up db and make sure it works let _ = create_database(); - let _ = insert_packet("foo", 1); + let _ = insert_packet("foo"); let socket_result: Result = UdpSocket::bind("127.0.0.1:7878"); let socket: UdpSocket = match socket_result { @@ -32,7 +33,7 @@ fn main() -> std::io::Result<()> { String::from_utf8_lossy(&buffer[..bytes_received]) ); - let _ = insert_packet(&String::from_utf8_lossy(&buffer[..bytes_received]), 1); + let _ = insert_packet(&String::from_utf8_lossy(&buffer[..bytes_received])); // Echo the data back to the client socket.send_to(&buffer[..bytes_received], src_addr)?; @@ -50,7 +51,6 @@ fn create_database() -> Result<()> { "CREATE TABLE IF NOT EXISTS packets ( id INTEGER PRIMARY KEY AUTOINCREMENT, raw TEXT NOT NULL, - age INTEGER NOT NULL, date INTEGER NOT NULL )", [], // No parameters needed @@ -60,18 +60,18 @@ fn create_database() -> Result<()> { Ok(()) } -fn insert_packet(raw: &str, age: i32) -> Result<()> { +fn insert_packet(raw: &str) -> Result<()> { let conn = Connection::open("pkt_database.db")?; let ds = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); // Insert conn.execute( - "INSERT INTO packets (raw, age, date) VALUES (?1, ?2, ?3)", - params![raw, age, ds], // Bind parameters + "INSERT INTO packets (raw, date) VALUES (?1, ?2)", + params![raw, ds], // Bind parameters )?; - println!("Row inserted successfully."); + //println!("Row inserted successfully."); Ok(()) } -- 2.39.5 From 0698deee418e8883b5f81f92b08a0c450db0e394 Mon Sep 17 00:00:00 2001 From: mattbk Date: Sun, 5 Oct 2025 20:37:22 -0500 Subject: [PATCH 6/7] Accept JSON from mwtchahrd. --- Cargo.lock | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 12 +++++-- 3 files changed, 107 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 41fd5f5..bbbb450 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,6 +44,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + [[package]] name = "libsqlite3-sys" version = "0.35.0" @@ -54,11 +60,18 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + [[package]] name = "my_udp_server" version = "0.1.0" dependencies = [ "rusqlite", + "serde_json", ] [[package]] @@ -67,6 +80,24 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + [[package]] name = "rusqlite" version = "0.37.0" @@ -81,12 +112,77 @@ dependencies = [ "smallvec", ] +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + [[package]] name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + [[package]] name = "vcpkg" version = "0.2.15" diff --git a/Cargo.toml b/Cargo.toml index 5961110..212eaf7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,3 +5,4 @@ edition = "2024" [dependencies] rusqlite = "0.37.0" +serde_json = "1.0.145" diff --git a/src/main.rs b/src/main.rs index 2986add..fc9add0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,14 @@ use std::net::UdpSocket; // UDP server use rusqlite::{params, Connection, Result}; // Database operations and result handling use std::time::{SystemTime, UNIX_EPOCH}; +use serde_json::{Value}; fn main() -> std::io::Result<()> { // Set up db and make sure it works let _ = create_database(); - let _ = insert_packet("foo"); + //let _ = insert_packet("foo"); let socket_result: Result = UdpSocket::bind("127.0.0.1:7878"); let socket: UdpSocket = match socket_result { @@ -33,7 +34,14 @@ fn main() -> std::io::Result<()> { String::from_utf8_lossy(&buffer[..bytes_received]) ); - let _ = insert_packet(&String::from_utf8_lossy(&buffer[..bytes_received])); + let p_raw = &String::from_utf8_lossy(&buffer[..bytes_received]); + + // look for type code in JSON here, only insert if data + let p: Value = serde_json::from_str(p_raw)?; + + if p["type"] != "status" { + let _ = insert_packet(p_raw); + } // Echo the data back to the client socket.send_to(&buffer[..bytes_received], src_addr)?; -- 2.39.5 From d8cdcfeb122b666e48bedb5af4204beb2557037a Mon Sep 17 00:00:00 2001 From: mattbk Date: Sun, 12 Oct 2025 20:59:51 -0500 Subject: [PATCH 7/7] Pass JSON into the database as fields. --- Cargo.lock | 1 + Cargo.toml | 2 +- src/main.rs | 35 +++++++++++++++++++++++++++-------- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bbbb450..9df4904 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,6 +109,7 @@ dependencies = [ "fallible-streaming-iterator", "hashlink", "libsqlite3-sys", + "serde_json", "smallvec", ] diff --git a/Cargo.toml b/Cargo.toml index 212eaf7..59bf953 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,5 +4,5 @@ version = "0.1.0" edition = "2024" [dependencies] -rusqlite = "0.37.0" +rusqlite = {version = "0.37.0", features = ["serde_json"]} serde_json = "1.0.145" diff --git a/src/main.rs b/src/main.rs index fc9add0..f34c54a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,6 @@ use rusqlite::{params, Connection, Result}; // Database operations and result ha use std::time::{SystemTime, UNIX_EPOCH}; use serde_json::{Value}; - fn main() -> std::io::Result<()> { // Set up db and make sure it works @@ -39,8 +38,12 @@ fn main() -> std::io::Result<()> { // look for type code in JSON here, only insert if data let p: Value = serde_json::from_str(p_raw)?; + //p.what_is_this; + + //println!("{}",p["type"]); + if p["type"] != "status" { - let _ = insert_packet(p_raw); + let _ = insert_packet(p); } // Echo the data back to the client @@ -58,8 +61,11 @@ fn create_database() -> Result<()> { conn.execute( "CREATE TABLE IF NOT EXISTS packets ( id INTEGER PRIMARY KEY AUTOINCREMENT, - raw TEXT NOT NULL, - date INTEGER NOT NULL + date INTEGER NOT NULL, + source TEXT, + summary TEXT, + final_destination TEXT, + text TEXT )", [], // No parameters needed )?; @@ -68,16 +74,29 @@ fn create_database() -> Result<()> { Ok(()) } -fn insert_packet(raw: &str) -> Result<()> { +fn insert_packet(p_json: serde_json::Value) -> Result<()> { let conn = Connection::open("pkt_database.db")?; let ds = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); + //println!{"{}", p_json["type"]} + + //println!("{}", p_json); + //println!("{}", &p_json["source"]); + // Insert conn.execute( - "INSERT INTO packets (raw, date) VALUES (?1, ?2)", - params![raw, ds], // Bind parameters - )?; + "INSERT INTO packets (date, + source, + summary, + final_destination, + text) VALUES (?1, ?2, ?3, ?4, ?5)", + params![ds, + &p_json["source"], + &p_json["summary"], + &p_json["final_destination"], + &p_json["text"]], // Bind parameters + )?; //println!("Row inserted successfully."); Ok(()) -- 2.39.5