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