From c12e700c275425cc5aa53521a38c444fcf5da601 Mon Sep 17 00:00:00 2001 From: rzuasti Date: Sat, 30 May 2026 09:48:29 -0400 Subject: [PATCH] Consolidate ARP/mDNS modules under scanners::{arp,mdns}::{finder,scanner,status} Group each discovery protocol's primitive (finder), orchestration loop (scanner), and status state under one module tree instead of splitting them between device_finders/ and crate-root *_scanner / *_scanner_status files. Also includes incidental rustfmt fixes to a few pre-existing long lines. Co-Authored-By: Claude Opus 4.7 --- backend/src/db/devices.rs | 20 ++++++++++++--- backend/src/main.rs | 14 ++++------- .../src/{device_finders.rs => scanners.rs} | 0 backend/src/scanners/arp.rs | 4 +++ .../arp.rs => scanners/arp/finder.rs} | 8 +++--- .../arp/packet_send_receive.rs | 0 .../arp/scanner.rs} | 7 +++--- .../arp/status.rs} | 0 .../src/{device_finders => scanners}/error.rs | 0 backend/src/scanners/mdns.rs | 3 +++ .../mdns.rs => scanners/mdns/finder.rs} | 7 +++++- .../mdns/scanner.rs} | 25 ++++++++++--------- .../mdns/status.rs} | 0 backend/src/web_server/arp_scanner.rs | 2 +- backend/src/web_server/devices.rs | 7 +++++- backend/src/web_server/mdns_scanner.rs | 2 +- 16 files changed, 61 insertions(+), 38 deletions(-) rename backend/src/{device_finders.rs => scanners.rs} (100%) create mode 100644 backend/src/scanners/arp.rs rename backend/src/{device_finders/arp.rs => scanners/arp/finder.rs} (96%) rename backend/src/{device_finders => scanners}/arp/packet_send_receive.rs (100%) rename backend/src/{arp_scanner.rs => scanners/arp/scanner.rs} (93%) rename backend/src/{arp_scanner_status.rs => scanners/arp/status.rs} (100%) rename backend/src/{device_finders => scanners}/error.rs (100%) create mode 100644 backend/src/scanners/mdns.rs rename backend/src/{device_finders/mdns.rs => scanners/mdns/finder.rs} (97%) rename backend/src/{mdns_scanner.rs => scanners/mdns/scanner.rs} (90%) rename backend/src/{mdns_scanner_status.rs => scanners/mdns/status.rs} (100%) diff --git a/backend/src/db/devices.rs b/backend/src/db/devices.rs index a1a3727..a7d0459 100644 --- a/backend/src/db/devices.rs +++ b/backend/src/db/devices.rs @@ -208,7 +208,9 @@ pub fn seen( // device_type is only written when the stored value is empty, so a value chosen by the // user (via register) or previously deduced is never overwritten by a later sighting. if !vendor.is_empty() { - sql.push_str(", vendor=?, device_type=CASE WHEN device_type='' THEN ? ELSE device_type END"); + sql.push_str( + ", vendor=?, device_type=CASE WHEN device_type='' THEN ? ELSE device_type END", + ); params.push(vendor.into()); params.push(device_type.into()); } @@ -377,8 +379,17 @@ mod tests { ); // Filter by owner substring - "oh" matches "John" but not "Sarah" - let devices: Vec = - list_devices(None, None, None, Some("oh".to_string()), None, None, None, None).unwrap(); + let devices: Vec = list_devices( + None, + None, + None, + Some("oh".to_string()), + None, + None, + None, + None, + ) + .unwrap(); assert!( devices.len() >= 1, @@ -426,7 +437,8 @@ mod tests { tests_common::setup().await; // First page with 2 devices - let first_page = list_devices(None, None, None, None, None, None, Some(0), Some(2)).unwrap(); + let first_page = + list_devices(None, None, None, None, None, None, Some(0), Some(2)).unwrap(); assert_eq!(first_page.len(), 2, "First page should have 2 devices"); // Second page with 2 devices, should have at least 1 (seed data has >= 3 devices) diff --git a/backend/src/main.rs b/backend/src/main.rs index 3618b18..2d2a066 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -2,16 +2,12 @@ use crate::settings::get_settings; use clap::Parser; use log::{LevelFilter, info}; -mod arp_scanner; -mod arp_scanner_status; mod data; mod db; -mod device_finders; mod events; -mod mdns_scanner; -mod mdns_scanner_status; mod model; mod retention; +mod scanners; mod settings; mod utils; mod web_server; @@ -61,13 +57,13 @@ async fn main() -> Result<(), Box> { db::init_db().await?; // Initialize scanner status tracking - arp_scanner_status::init(); - mdns_scanner_status::init(); + scanners::arp::status::init(); + scanners::mdns::status::init(); // Start the device scanners, web server, and retention cleaner in parallel tokio::join!( - arp_scanner::scan(), - mdns_scanner::listen(), + scanners::arp::scanner::scan(), + scanners::mdns::scanner::listen(), web_server::serve(), retention::run() ) diff --git a/backend/src/device_finders.rs b/backend/src/scanners.rs similarity index 100% rename from backend/src/device_finders.rs rename to backend/src/scanners.rs diff --git a/backend/src/scanners/arp.rs b/backend/src/scanners/arp.rs new file mode 100644 index 0000000..aab1cf8 --- /dev/null +++ b/backend/src/scanners/arp.rs @@ -0,0 +1,4 @@ +pub mod finder; +mod packet_send_receive; +pub mod scanner; +pub mod status; diff --git a/backend/src/device_finders/arp.rs b/backend/src/scanners/arp/finder.rs similarity index 96% rename from backend/src/device_finders/arp.rs rename to backend/src/scanners/arp/finder.rs index e86ab82..0ac66e5 100644 --- a/backend/src/device_finders/arp.rs +++ b/backend/src/scanners/arp/finder.rs @@ -1,14 +1,12 @@ -mod packet_send_receive; - -use crate::device_finders::error::{ +use super::packet_send_receive::{listen_for_packets, send_packet}; +use crate::model::devices::Device; +use crate::scanners::error::{ DataChannelError, InvalidDeviceError, NoIPAddressError, NoMACAddressError, }; -use crate::model::devices::Device; use crate::settings::get_settings; use crate::utils::network::select_interface; use duration_string::DurationString; use log::{debug, error, info, warn}; -use packet_send_receive::{listen_for_packets, send_packet}; use pnet::{ datalink::{self, Channel, NetworkInterface}, ipnetwork::IpNetwork, diff --git a/backend/src/device_finders/arp/packet_send_receive.rs b/backend/src/scanners/arp/packet_send_receive.rs similarity index 100% rename from backend/src/device_finders/arp/packet_send_receive.rs rename to backend/src/scanners/arp/packet_send_receive.rs diff --git a/backend/src/arp_scanner.rs b/backend/src/scanners/arp/scanner.rs similarity index 93% rename from backend/src/arp_scanner.rs rename to backend/src/scanners/arp/scanner.rs index d725eea..430efaf 100644 --- a/backend/src/arp_scanner.rs +++ b/backend/src/scanners/arp/scanner.rs @@ -1,6 +1,6 @@ -use crate::arp_scanner_status; +use super::finder; +use super::status as arp_scanner_status; use crate::db; -use crate::device_finders; use crate::events; use crate::settings::get_settings; use chrono::Utc; @@ -12,8 +12,7 @@ pub async fn scan() -> Result<(), Box> { arp_scanner_status::set_running(); // Find online devices via ARP - let devices = - device_finders::arp::find(get_settings().networking.interface.clone()).await?; + let devices = finder::find(get_settings().networking.interface.clone()).await?; info!("Done with ARP probes"); info!("Found {} online devices", devices.len()); diff --git a/backend/src/arp_scanner_status.rs b/backend/src/scanners/arp/status.rs similarity index 100% rename from backend/src/arp_scanner_status.rs rename to backend/src/scanners/arp/status.rs diff --git a/backend/src/device_finders/error.rs b/backend/src/scanners/error.rs similarity index 100% rename from backend/src/device_finders/error.rs rename to backend/src/scanners/error.rs diff --git a/backend/src/scanners/mdns.rs b/backend/src/scanners/mdns.rs new file mode 100644 index 0000000..aefcb6d --- /dev/null +++ b/backend/src/scanners/mdns.rs @@ -0,0 +1,3 @@ +pub mod finder; +pub mod scanner; +pub mod status; diff --git a/backend/src/device_finders/mdns.rs b/backend/src/scanners/mdns/finder.rs similarity index 97% rename from backend/src/device_finders/mdns.rs rename to backend/src/scanners/mdns/finder.rs index 710d510..5adf2f3 100644 --- a/backend/src/device_finders/mdns.rs +++ b/backend/src/scanners/mdns/finder.rs @@ -67,7 +67,12 @@ pub fn parse_announcement(buf: &[u8]) -> Announcement { } }; - let records = || packet.answers.iter().chain(packet.additional_records.iter()); + let records = || { + packet + .answers + .iter() + .chain(packet.additional_records.iter()) + }; let hostnames = records() .filter(|record| matches!(record.rdata, RData::A(_))) diff --git a/backend/src/mdns_scanner.rs b/backend/src/scanners/mdns/scanner.rs similarity index 90% rename from backend/src/mdns_scanner.rs rename to backend/src/scanners/mdns/scanner.rs index bc0a89b..d5450a8 100644 --- a/backend/src/mdns_scanner.rs +++ b/backend/src/scanners/mdns/scanner.rs @@ -4,14 +4,14 @@ use std::time::Duration; use chrono::Local; use log::{debug, error, info, warn}; -use crate::db; -use crate::device_finders::mdns; -use crate::events; +use super::finder as mdns; +use super::status as mdns_scanner_status; use crate::data::mac_vendor_finder; -use crate::mdns_scanner_status; +use crate::data::vendor_device_type_finder; +use crate::db; +use crate::events; use crate::model::devices::Device; use crate::settings::get_settings; -use crate::data::vendor_device_type_finder; /// Passively listen for mDNS/Bonjour announcements and feed discovered devices into the same /// pipeline used by the ARP scanner (devices table + events + notifications). @@ -62,13 +62,14 @@ async fn process_announcement( interface: Option, probe_timeout: Duration, ) { - let mac = match crate::utils::network::resolve_mac_address(src_ip, interface, probe_timeout).await { - Some(mac) => mac.to_string(), - None => { - debug!("Could not resolve MAC for mDNS device {src_ip} ({hostname}); skipping"); - return; - } - }; + let mac = + match crate::utils::network::resolve_mac_address(src_ip, interface, probe_timeout).await { + Some(mac) => mac.to_string(), + None => { + debug!("Could not resolve MAC for mDNS device {src_ip} ({hostname}); skipping"); + return; + } + }; let mut vendor = mac_vendor_finder::find(mac.get(0..8).unwrap_or("").to_string()); // Privacy MACs are locally administered and have no real OUI, so the lookup above fails. diff --git a/backend/src/mdns_scanner_status.rs b/backend/src/scanners/mdns/status.rs similarity index 100% rename from backend/src/mdns_scanner_status.rs rename to backend/src/scanners/mdns/status.rs diff --git a/backend/src/web_server/arp_scanner.rs b/backend/src/web_server/arp_scanner.rs index 02a1650..1dcb92e 100644 --- a/backend/src/web_server/arp_scanner.rs +++ b/backend/src/web_server/arp_scanner.rs @@ -4,7 +4,7 @@ use log::error; use serde::Serialize; use utoipa::ToSchema; -use crate::arp_scanner_status; +use crate::scanners::arp::status as arp_scanner_status; #[derive(Serialize, ToSchema)] pub struct ArpScannerStatusResponse { diff --git a/backend/src/web_server/devices.rs b/backend/src/web_server/devices.rs index 91dc474..69833cc 100644 --- a/backend/src/web_server/devices.rs +++ b/backend/src/web_server/devices.rs @@ -176,7 +176,12 @@ pub async fn update( ); } - match db::devices::update(mac_address, payload.owner, payload.device_type, payload.vendor) { + match db::devices::update( + mac_address, + payload.owner, + payload.device_type, + payload.vendor, + ) { Ok(_) => (axum::http::StatusCode::OK, "Device updated"), Err(err) => { error!("Error updating device in the database: {}", err); diff --git a/backend/src/web_server/mdns_scanner.rs b/backend/src/web_server/mdns_scanner.rs index 4dfc8ef..9d55e22 100644 --- a/backend/src/web_server/mdns_scanner.rs +++ b/backend/src/web_server/mdns_scanner.rs @@ -4,7 +4,7 @@ use log::error; use serde::Serialize; use utoipa::ToSchema; -use crate::mdns_scanner_status; +use crate::scanners::mdns::status as mdns_scanner_status; #[derive(Serialize, ToSchema)] pub struct MdnsScannerStatusResponse {