Skip to main content

r_lanlib/scanners/
full_scanner.rs

1//! Provides Scanner implementation for Full scanning (ARP + SYN)
2
3use derive_builder::Builder;
4use std::{
5    sync::{Arc, Mutex, mpsc},
6    thread::JoinHandle,
7    time::Duration,
8};
9
10use crate::{
11    error::Result,
12    network::NetworkInterface,
13    packet::{Reader, Sender},
14    targets::{ips::IPTargets, ports::PortTargets},
15};
16
17use super::{
18    Device, ScanMessage, Scanner, arp_scanner::ARPScanner,
19    syn_scanner::SYNScanner,
20};
21
22/// Data structure representing a Full scanner (ARP + SYN)
23#[derive(Builder)]
24#[builder(setter(into))]
25pub struct FullScanner {
26    /// Network interface to use for scanning
27    interface: Arc<NetworkInterface>,
28    /// Packet reader for receiving responses
29    packet_reader: Arc<Mutex<dyn Reader>>,
30    /// Packet sender for transmitting packets
31    packet_sender: Arc<Mutex<dyn Sender>>,
32    /// IP targets to scan for device discovery
33    targets: Arc<IPTargets>,
34    /// Port targets to scan on discovered devices
35    ports: Arc<PortTargets>,
36    /// Whether to include vendor lookups for discovered devices
37    vendor: bool,
38    /// Whether to include hostname lookups for discovered devices
39    host: bool,
40    /// Duration to wait for responses after scanning completes
41    idle_timeout: Duration,
42    /// Channel for sending scan results and status messages
43    notifier: mpsc::Sender<ScanMessage>,
44    /// Source port for packet listener and incoming packet identification
45    source_port: u16,
46}
47
48impl FullScanner {
49    /// Returns a builder for FullScanner
50    pub fn builder() -> FullScannerBuilder {
51        FullScannerBuilder::default()
52    }
53
54    fn get_syn_targets_from_arp_scan(&self) -> Result<Vec<Device>> {
55        let (tx, rx) = mpsc::channel::<ScanMessage>();
56
57        let mut syn_targets: Vec<Device> = Vec::new();
58
59        let arp = ARPScanner::builder()
60            .interface(Arc::clone(&self.interface))
61            .packet_reader(Arc::clone(&self.packet_reader))
62            .packet_sender(Arc::clone(&self.packet_sender))
63            .targets(Arc::clone(&self.targets))
64            .source_port(self.source_port)
65            .include_vendor(self.vendor)
66            .include_host_names(self.host)
67            .idle_timeout(self.idle_timeout)
68            .notifier(tx.clone())
69            .build()?;
70
71        arp.scan()?;
72
73        loop {
74            if let Ok(msg) = rx.recv() {
75                match msg {
76                    ScanMessage::Done => {
77                        log::debug!("arp sending complete");
78                        break;
79                    }
80                    ScanMessage::ARPScanDevice(device) => {
81                        syn_targets.push(device.to_owned());
82                    }
83                    _ => {}
84                }
85            }
86        }
87
88        Ok(syn_targets)
89    }
90}
91
92// Implements the Scanner trait for FullScanner
93impl Scanner for FullScanner {
94    fn scan(&self) -> Result<JoinHandle<Result<()>>> {
95        let syn_targets = self.get_syn_targets_from_arp_scan()?;
96
97        let syn = SYNScanner::builder()
98            .interface(Arc::clone(&self.interface))
99            .packet_reader(Arc::clone(&self.packet_reader))
100            .packet_sender(Arc::clone(&self.packet_sender))
101            .targets(syn_targets)
102            .ports(Arc::clone(&self.ports))
103            .source_port(self.source_port)
104            .idle_timeout(self.idle_timeout)
105            .notifier(self.notifier.clone())
106            .build()?;
107
108        syn.scan()
109    }
110}
111
112#[cfg(test)]
113#[path = "./full_scanner_tests.rs"]
114mod tests;