r_lanlib/scanners/
full_scanner.rs1use 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 packet::wire::Wire,
14 targets::{ips::IPTargets, ports::PortTargets},
15};
16
17use super::{
18 Device, ScanMessage, Scanner, arp_scanner::ARPScanner,
19 syn_scanner::SYNScanner,
20};
21
22#[derive(Builder)]
24#[builder(setter(into))]
25pub struct FullScanner {
26 interface: Arc<NetworkInterface>,
28 wire: Wire,
30 targets: Arc<IPTargets>,
32 ports: Arc<PortTargets>,
34 vendor: bool,
36 host: bool,
38 idle_timeout: Duration,
40 notifier: mpsc::Sender<ScanMessage>,
42 source_port: u16,
44}
45
46impl FullScanner {
47 pub fn builder() -> FullScannerBuilder {
49 FullScannerBuilder::default()
50 }
51
52 fn get_syn_targets_from_arp_scan(&self) -> Result<Vec<Device>> {
53 let (tx, rx) = mpsc::channel::<ScanMessage>();
54
55 let mut syn_targets: Vec<Device> = Vec::new();
56
57 let arp = ARPScanner::builder()
58 .interface(Arc::clone(&self.interface))
59 .wire(self.wire.clone())
60 .targets(Arc::clone(&self.targets))
61 .source_port(self.source_port)
62 .include_vendor(self.vendor)
63 .include_host_names(self.host)
64 .idle_timeout(self.idle_timeout)
65 .notifier(tx.clone())
66 .build()?;
67
68 arp.scan()?;
69
70 loop {
71 if let Ok(msg) = rx.recv() {
72 match msg {
73 ScanMessage::Done => {
74 log::debug!("arp sending complete");
75 break;
76 }
77 ScanMessage::ARPScanDevice(device) => {
78 syn_targets.push(device.to_owned());
79 }
80 _ => {}
81 }
82 }
83 }
84
85 Ok(syn_targets)
86 }
87}
88
89impl Scanner for FullScanner {
91 fn scan(&self) -> Result<JoinHandle<Result<()>>> {
92 let syn_targets = self.get_syn_targets_from_arp_scan()?;
93
94 let syn = SYNScanner::builder()
95 .interface(Arc::clone(&self.interface))
96 .wire(self.wire.clone())
97 .targets(syn_targets)
98 .ports(Arc::clone(&self.ports))
99 .source_port(self.source_port)
100 .idle_timeout(self.idle_timeout)
101 .notifier(self.notifier.clone())
102 .build()?;
103
104 syn.scan()
105 }
106}
107
108#[cfg(test)]
109#[path = "./full_scanner_tests.rs"]
110mod tests;