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, mpsc},
6    thread::JoinHandle,
7    time::Duration,
8};
9
10use crate::{
11    error::Result,
12    network::NetworkInterface,
13    targets::{ips::IPTargets, ports::PortTargets},
14    wire::{DEFAULT_PACKET_SEND_TIMING, Wire},
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    /// Wire for reading and sending packets on the wire
29    wire: Wire,
30    /// IP targets to scan for device discovery
31    targets: Arc<IPTargets>,
32    /// Port targets to scan on discovered devices
33    ports: Arc<PortTargets>,
34    /// Whether to include vendor lookups for discovered devices
35    vendor: bool,
36    /// Whether to include hostname lookups for discovered devices
37    host: bool,
38    /// Duration to wait for responses after scanning completes
39    idle_timeout: Duration,
40    /// Throttles speed at which packets are sent. Higher throttles result
41    /// in more accurate scans
42    #[builder(default = DEFAULT_PACKET_SEND_TIMING)]
43    throttle: Duration,
44    /// Channel for sending scan results and status messages
45    notifier: mpsc::Sender<ScanMessage>,
46    /// Source port for packet listener and incoming packet identification
47    source_port: u16,
48}
49
50impl FullScanner {
51    /// Returns a builder for FullScanner
52    pub fn builder() -> FullScannerBuilder {
53        FullScannerBuilder::default()
54    }
55
56    fn get_syn_targets_from_arp_scan(&self) -> Result<Vec<Device>> {
57        let (tx, rx) = mpsc::channel::<ScanMessage>();
58
59        let mut syn_targets: Vec<Device> = Vec::new();
60
61        let arp = ARPScanner::builder()
62            .interface(Arc::clone(&self.interface))
63            .wire(self.wire.clone())
64            .targets(Arc::clone(&self.targets))
65            .source_port(self.source_port)
66            .include_vendor(self.vendor)
67            .include_host_names(self.host)
68            .idle_timeout(self.idle_timeout)
69            .throttle(self.throttle)
70            .notifier(tx.clone())
71            .build()?;
72
73        arp.scan()?;
74
75        loop {
76            if let Ok(msg) = rx.recv() {
77                match msg {
78                    ScanMessage::Done => {
79                        log::debug!("arp sending complete");
80                        break;
81                    }
82                    ScanMessage::ARPScanDevice(device) => {
83                        syn_targets.push(device.to_owned());
84                    }
85                    _ => {}
86                }
87            }
88        }
89
90        Ok(syn_targets)
91    }
92}
93
94// Implements the Scanner trait for FullScanner
95impl Scanner for FullScanner {
96    fn scan(&self) -> Result<JoinHandle<Result<()>>> {
97        let syn_targets = self.get_syn_targets_from_arp_scan()?;
98
99        let syn = SYNScanner::builder()
100            .interface(Arc::clone(&self.interface))
101            .wire(self.wire.clone())
102            .targets(syn_targets)
103            .ports(Arc::clone(&self.ports))
104            .source_port(self.source_port)
105            .idle_timeout(self.idle_timeout)
106            .throttle(self.throttle)
107            .notifier(self.notifier.clone())
108            .build()?;
109
110        syn.scan()
111    }
112}
113
114#[cfg(test)]
115#[path = "./full_scanner_tests.rs"]
116mod tests;