e_libscanner/async_scan/
scanner.rs

1use super::scan_target;
2use crate::data::id::{DEFAULT_HOSTS_CONCURRENCY, DEFAULT_PORTS_CONCURRENCY, DEFAULT_SRC_PORT};
3use crate::frame::result::ScanResult;
4use crate::frame::{result::ScanStatus, Destination, ScanSetting, ScanType};
5use crate::interface;
6use std::collections::HashSet;
7use std::net::{IpAddr, SocketAddr};
8use std::sync::mpsc::{channel, Receiver, Sender};
9use std::sync::{Arc, Mutex};
10use std::time::{Duration, Instant};
11
12/// Async Host Scanner
13/// # Example
14/// ```
15/// fn main() -> Result<(), String> {
16/// #[cfg(feature = "async")]
17/// {
18///     use e_libscanner::{async_scan, Opts};
19///     use std::thread;
20///     // more command information use: -h
21///     let mut scanner = Opts::new(Some(&[
22///         "e-libscanner",
23///         "--ips",
24///         "192.168.20.0/23",
25///         "192.168.28-31.1-10",
26///         "baidu.com",
27///         "--model",
28///         "async",
29///         "--scan",
30///         "icmp",
31///         "--no-gui",
32///     ]))?
33///     .init()?
34///     .downcast::<async_scan::Scanner>()
35///    .unwrap();
36///     let rx = scanner.get_progress_receiver();
37///     // Run scan
38///     let handle = thread::spawn(move || async_io::block_on(async { scanner.scan(None).await }));
39///     // Print progress
40///     while let Ok(socket_addr) = rx.lock().unwrap().recv() {
41///         println!("Check: {}", socket_addr);
42///     }
43///     let result = handle.join().unwrap();
44///     // Print results
45///     println!("Status: {:?}", result.scan_status);
46///     println!("UP Hosts:");
47///     let len = result.ips.len();
48///     for host in result.ips {
49///         println!("{:?}", host);
50///     }
51///     println!("Scan Time: {:?} count[ {} ]", result.scan_time, len);
52/// }
53/// Ok(())
54/// }
55/// ```
56#[derive(Clone, Debug)]
57pub struct Scanner {
58    /// Index of network interface
59    pub if_index: u32,
60    /// Name of network interface
61    pub if_name: String,
62    /// MAC address of network interface
63    pub src_mac: [u8; 6],
64    /// MAC address of default gateway(or scan target host)
65    pub dst_mac: [u8; 6],
66    /// Source IP address
67    pub src_ip: IpAddr,
68    /// Source port
69    pub src_port: u16,
70    /// Destinations
71    pub destinations: Vec<Destination>,
72    /// Scan Type
73    pub scan_type: ScanType,
74    /// Timeout setting for entire scan task
75    pub timeout: Duration,
76    /// Waiting time after packet sending task is completed
77    pub wait_time: Duration,
78    /// Packet sending interval(0 for unlimited)
79    pub send_rate: Duration,
80    /// Scan Result
81    pub scan_result: ScanResult,
82    /// Sender for progress messaging
83    pub tx: Arc<Mutex<Sender<SocketAddr>>>,
84    /// Receiver for progress messaging
85    pub rx: Arc<Mutex<Receiver<SocketAddr>>>,
86}
87
88impl Scanner {
89    /// Create new HostScanner with source IP address
90    /// Initialized with default value based on the specified IP address
91    pub fn new(src_ip: IpAddr) -> Result<Scanner, String> {
92        let mut if_index: u32 = 0;
93        let mut if_name: String = String::new();
94        let mut src_mac: pnet_datalink::MacAddr = pnet_datalink::MacAddr::zero();
95        for iface in pnet_datalink::interfaces() {
96            for ip in iface.ips {
97                if ip.ip() == src_ip {
98                    if_index = iface.index;
99                    if_name = iface.name;
100                    src_mac = iface.mac.unwrap_or(pnet_datalink::MacAddr::zero());
101                    break;
102                }
103            }
104        }
105        if if_index == 0 || if_name.is_empty() || src_mac == pnet_datalink::MacAddr::zero() {
106            return Err(String::from(
107                "Failed to create Scanner. Network Interface not found.",
108            ));
109        }
110        let (tx, rx) = channel();
111        let scanner = Scanner {
112            if_index,
113            if_name,
114            src_mac: src_mac.octets(),
115            dst_mac: interface::get_default_gateway_macaddr(),
116            src_ip,
117            src_port: DEFAULT_SRC_PORT,
118            destinations: vec![],
119            scan_type: ScanType::IcmpPingScan,
120            timeout: Duration::from_millis(300_000),
121            wait_time: Duration::from_millis(200),
122            send_rate: Duration::from_millis(0),
123            scan_result: ScanResult::new(),
124            tx: Arc::new(Mutex::new(tx)),
125            rx: Arc::new(Mutex::new(rx)),
126        };
127        Ok(scanner)
128    }
129    /// get scan count
130    pub fn len(&self) -> usize {
131        let mut len = 0;
132        for dst in self.destinations.iter() {
133            if dst.dst_ports.len() > 0 {
134                len += dst.dst_ports.len();
135            } else {
136                len += 1;
137            }
138        }
139        len
140    }
141    /// Set source IP address
142    pub fn set_src_ip(&mut self, src_ip: IpAddr) {
143        self.src_ip = src_ip;
144    }
145    /// Get source IP address
146    pub fn get_src_ip(&self) -> IpAddr {
147        self.src_ip.clone()
148    }
149    /// Add Destination
150    pub fn add_destination(&mut self, dst: Destination) {
151        self.destinations.push(dst);
152    }
153    /// Set Destinations
154    pub fn set_destinations(&mut self, dst: Vec<Destination>) {
155        self.destinations = dst;
156    }
157    /// Get Destinations
158    pub fn get_destinations(&self) -> Vec<Destination> {
159        self.destinations.clone()
160    }
161    /// Set ScanType
162    pub fn set_scan_type(&mut self, scan_type: ScanType) {
163        self.scan_type = scan_type;
164    }
165    /// Get ScanType
166    pub fn get_scan_type(&self) -> ScanType {
167        self.scan_type.clone()
168    }
169    /// Set timeout
170    pub fn set_timeout(&mut self, timeout: Duration) {
171        self.timeout = timeout;
172    }
173    /// Get timeout
174    pub fn get_timeout(&self) -> Duration {
175        self.timeout.clone()
176    }
177    /// Set wait time
178    pub fn set_wait_time(&mut self, wait_time: Duration) {
179        self.wait_time = wait_time;
180    }
181    /// Get wait time
182    pub fn get_wait_time(&self) -> Duration {
183        self.wait_time.clone()
184    }
185    /// Set send rate
186    pub fn set_send_rate(&mut self, send_rate: Duration) {
187        self.send_rate = send_rate;
188    }
189    /// Get send rate
190    pub fn get_send_rate(&self) -> Duration {
191        self.send_rate.clone()
192    }
193    /// Get scan result
194    pub fn get_scan_result(&self) -> ScanResult {
195        self.scan_result.clone()
196    }
197    /// Get progress receiver
198    pub fn get_progress_receiver(&self) -> Arc<Mutex<Receiver<SocketAddr>>> {
199        self.rx.clone()
200    }
201    /// Run Scan
202    pub async fn run_scan(&mut self, pstop: Option<Arc<Mutex<bool>>>) {
203        let mut ip_set: HashSet<IpAddr> = HashSet::new();
204        for dst in self.destinations.clone() {
205            ip_set.insert(dst.dst_ip);
206        }
207        let scan_setting: ScanSetting = ScanSetting {
208            if_index: self.if_index.clone(),
209            src_mac: pnet_datalink::MacAddr::from(self.src_mac),
210            dst_mac: pnet_datalink::MacAddr::from(self.dst_mac),
211            src_ip: self.src_ip.clone(),
212            src_port: self.src_port.clone(),
213            destinations: self.destinations.clone(),
214            ip_set,
215            timeout: self.timeout.clone(),
216            wait_time: self.wait_time.clone(),
217            send_rate: self.send_rate.clone(),
218            scan_type: self.scan_type.clone(),
219            hosts_concurrency: DEFAULT_HOSTS_CONCURRENCY,
220            ports_concurrency: DEFAULT_PORTS_CONCURRENCY,
221        };
222        let start_time = Instant::now();
223        let mut result: ScanResult = scan_target(scan_setting, &self.tx, pstop).await;
224        result.scan_time = Instant::now().duration_since(start_time);
225        if result.scan_time > self.timeout {
226            result.scan_status = ScanStatus::Timeout;
227        } else {
228            result.scan_status = ScanStatus::Done;
229        }
230        self.scan_result = result;
231    }
232    /// Run Sync scan and return result
233    pub async fn scan(&mut self, pstop: Option<Arc<Mutex<bool>>>) -> ScanResult {
234        self.run_scan(pstop).await;
235        self.scan_result.clone()
236    }
237}