mirror of
https://github.com/rzuasti/oott.git
synced 2026-07-08 19:21:54 +02:00
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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
54211c57d7
commit
c12e700c27
@@ -208,7 +208,9 @@ pub fn seen(
|
|||||||
// device_type is only written when the stored value is empty, so a value chosen by the
|
// 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.
|
// user (via register) or previously deduced is never overwritten by a later sighting.
|
||||||
if !vendor.is_empty() {
|
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(vendor.into());
|
||||||
params.push(device_type.into());
|
params.push(device_type.into());
|
||||||
}
|
}
|
||||||
@@ -377,8 +379,17 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Filter by owner substring - "oh" matches "John" but not "Sarah"
|
// Filter by owner substring - "oh" matches "John" but not "Sarah"
|
||||||
let devices: Vec<Device> =
|
let devices: Vec<Device> = list_devices(
|
||||||
list_devices(None, None, None, Some("oh".to_string()), None, None, None, None).unwrap();
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Some("oh".to_string()),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
devices.len() >= 1,
|
devices.len() >= 1,
|
||||||
@@ -426,7 +437,8 @@ mod tests {
|
|||||||
tests_common::setup().await;
|
tests_common::setup().await;
|
||||||
|
|
||||||
// First page with 2 devices
|
// 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");
|
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)
|
// Second page with 2 devices, should have at least 1 (seed data has >= 3 devices)
|
||||||
|
|||||||
+5
-9
@@ -2,16 +2,12 @@ use crate::settings::get_settings;
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use log::{LevelFilter, info};
|
use log::{LevelFilter, info};
|
||||||
|
|
||||||
mod arp_scanner;
|
|
||||||
mod arp_scanner_status;
|
|
||||||
mod data;
|
mod data;
|
||||||
mod db;
|
mod db;
|
||||||
mod device_finders;
|
|
||||||
mod events;
|
mod events;
|
||||||
mod mdns_scanner;
|
|
||||||
mod mdns_scanner_status;
|
|
||||||
mod model;
|
mod model;
|
||||||
mod retention;
|
mod retention;
|
||||||
|
mod scanners;
|
||||||
mod settings;
|
mod settings;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod web_server;
|
mod web_server;
|
||||||
@@ -61,13 +57,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
db::init_db().await?;
|
db::init_db().await?;
|
||||||
|
|
||||||
// Initialize scanner status tracking
|
// Initialize scanner status tracking
|
||||||
arp_scanner_status::init();
|
scanners::arp::status::init();
|
||||||
mdns_scanner_status::init();
|
scanners::mdns::status::init();
|
||||||
|
|
||||||
// Start the device scanners, web server, and retention cleaner in parallel
|
// Start the device scanners, web server, and retention cleaner in parallel
|
||||||
tokio::join!(
|
tokio::join!(
|
||||||
arp_scanner::scan(),
|
scanners::arp::scanner::scan(),
|
||||||
mdns_scanner::listen(),
|
scanners::mdns::scanner::listen(),
|
||||||
web_server::serve(),
|
web_server::serve(),
|
||||||
retention::run()
|
retention::run()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
pub mod finder;
|
||||||
|
mod packet_send_receive;
|
||||||
|
pub mod scanner;
|
||||||
|
pub mod status;
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
mod packet_send_receive;
|
use super::packet_send_receive::{listen_for_packets, send_packet};
|
||||||
|
use crate::model::devices::Device;
|
||||||
use crate::device_finders::error::{
|
use crate::scanners::error::{
|
||||||
DataChannelError, InvalidDeviceError, NoIPAddressError, NoMACAddressError,
|
DataChannelError, InvalidDeviceError, NoIPAddressError, NoMACAddressError,
|
||||||
};
|
};
|
||||||
use crate::model::devices::Device;
|
|
||||||
use crate::settings::get_settings;
|
use crate::settings::get_settings;
|
||||||
use crate::utils::network::select_interface;
|
use crate::utils::network::select_interface;
|
||||||
use duration_string::DurationString;
|
use duration_string::DurationString;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use packet_send_receive::{listen_for_packets, send_packet};
|
|
||||||
use pnet::{
|
use pnet::{
|
||||||
datalink::{self, Channel, NetworkInterface},
|
datalink::{self, Channel, NetworkInterface},
|
||||||
ipnetwork::IpNetwork,
|
ipnetwork::IpNetwork,
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::arp_scanner_status;
|
use super::finder;
|
||||||
|
use super::status as arp_scanner_status;
|
||||||
use crate::db;
|
use crate::db;
|
||||||
use crate::device_finders;
|
|
||||||
use crate::events;
|
use crate::events;
|
||||||
use crate::settings::get_settings;
|
use crate::settings::get_settings;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
@@ -12,8 +12,7 @@ pub async fn scan() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
arp_scanner_status::set_running();
|
arp_scanner_status::set_running();
|
||||||
|
|
||||||
// Find online devices via ARP
|
// Find online devices via ARP
|
||||||
let devices =
|
let devices = finder::find(get_settings().networking.interface.clone()).await?;
|
||||||
device_finders::arp::find(get_settings().networking.interface.clone()).await?;
|
|
||||||
|
|
||||||
info!("Done with ARP probes");
|
info!("Done with ARP probes");
|
||||||
info!("Found {} online devices", devices.len());
|
info!("Found {} online devices", devices.len());
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
pub mod finder;
|
||||||
|
pub mod scanner;
|
||||||
|
pub mod status;
|
||||||
@@ -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()
|
let hostnames = records()
|
||||||
.filter(|record| matches!(record.rdata, RData::A(_)))
|
.filter(|record| matches!(record.rdata, RData::A(_)))
|
||||||
@@ -4,14 +4,14 @@ use std::time::Duration;
|
|||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
|
|
||||||
use crate::db;
|
use super::finder as mdns;
|
||||||
use crate::device_finders::mdns;
|
use super::status as mdns_scanner_status;
|
||||||
use crate::events;
|
|
||||||
use crate::data::mac_vendor_finder;
|
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::model::devices::Device;
|
||||||
use crate::settings::get_settings;
|
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
|
/// Passively listen for mDNS/Bonjour announcements and feed discovered devices into the same
|
||||||
/// pipeline used by the ARP scanner (devices table + events + notifications).
|
/// pipeline used by the ARP scanner (devices table + events + notifications).
|
||||||
@@ -62,13 +62,14 @@ async fn process_announcement(
|
|||||||
interface: Option<String>,
|
interface: Option<String>,
|
||||||
probe_timeout: Duration,
|
probe_timeout: Duration,
|
||||||
) {
|
) {
|
||||||
let mac = match crate::utils::network::resolve_mac_address(src_ip, interface, probe_timeout).await {
|
let mac =
|
||||||
Some(mac) => mac.to_string(),
|
match crate::utils::network::resolve_mac_address(src_ip, interface, probe_timeout).await {
|
||||||
None => {
|
Some(mac) => mac.to_string(),
|
||||||
debug!("Could not resolve MAC for mDNS device {src_ip} ({hostname}); skipping");
|
None => {
|
||||||
return;
|
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());
|
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.
|
// Privacy MACs are locally administered and have no real OUI, so the lookup above fails.
|
||||||
@@ -4,7 +4,7 @@ use log::error;
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use utoipa::ToSchema;
|
use utoipa::ToSchema;
|
||||||
|
|
||||||
use crate::arp_scanner_status;
|
use crate::scanners::arp::status as arp_scanner_status;
|
||||||
|
|
||||||
#[derive(Serialize, ToSchema)]
|
#[derive(Serialize, ToSchema)]
|
||||||
pub struct ArpScannerStatusResponse {
|
pub struct ArpScannerStatusResponse {
|
||||||
|
|||||||
@@ -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"),
|
Ok(_) => (axum::http::StatusCode::OK, "Device updated"),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Error updating device in the database: {}", err);
|
error!("Error updating device in the database: {}", err);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use log::error;
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use utoipa::ToSchema;
|
use utoipa::ToSchema;
|
||||||
|
|
||||||
use crate::mdns_scanner_status;
|
use crate::scanners::mdns::status as mdns_scanner_status;
|
||||||
|
|
||||||
#[derive(Serialize, ToSchema)]
|
#[derive(Serialize, ToSchema)]
|
||||||
pub struct MdnsScannerStatusResponse {
|
pub struct MdnsScannerStatusResponse {
|
||||||
|
|||||||
Reference in New Issue
Block a user