1use std::net::IpAddr;
2use std::sync::Arc;
3
4use super::config::Ops;
5use super::validation::parse_limited_ipv4_subnet;
6use crate::error::Result;
7use crate::{
8 default_ipv4_subnet_string, default_ports, validate_ports, DiscoverEngine, Host, InspectEngine,
9 InspectResult, PortResult, PortScanner, SweepEngine, SweepEntry,
10};
11
12fn resolve_ports(ports: Option<Vec<u16>>) -> Result<Vec<u16>> {
22 match ports {
23 Some(ports) => {
24 validate_ports(&ports)?;
25 Ok(ports)
26 }
27 None => Ok(default_ports()),
28 }
29}
30
31impl Ops {
32 pub async fn discover_ipv4(
33 &self,
34 subnet: Option<String>,
35 resolve: bool,
36 ) -> Result<(String, Vec<Host>)> {
37 self.discover_ipv4_with_progress(subnet, resolve, None)
38 .await
39 }
40
41 pub async fn discover_ipv4_with_progress(
42 &self,
43 subnet: Option<String>,
44 resolve: bool,
45 progress: Option<Arc<dyn Fn(crate::discover::DiscoverProgress) + Send + Sync>>,
46 ) -> Result<(String, Vec<Host>)> {
47 let subnet_str = subnet.unwrap_or_else(default_ipv4_subnet_string);
48 let net = parse_limited_ipv4_subnet(&subnet_str)?;
49 let engine = DiscoverEngine::new_with_timeouts(
50 self.cfg.concurrency,
51 self.cfg.ping_timeout_ms,
52 self.cfg.dns_timeout_ms,
53 );
54 let hosts = engine
55 .scan_subnet_with_progress(net, resolve, progress)
56 .await?;
57 Ok((subnet_str, hosts))
58 }
59
60 pub async fn scan_ports(
61 &self,
62 host: &str,
63 ports: Option<Vec<u16>>,
64 ) -> Result<(IpAddr, Vec<PortResult>)> {
65 self.scan_ports_with_progress(host, ports, None).await
66 }
67
68 pub async fn scan_ports_with_progress(
69 &self,
70 host: &str,
71 ports: Option<Vec<u16>>,
72 progress: Option<Arc<dyn Fn(crate::scan::PortScanProgress) + Send + Sync>>,
73 ) -> Result<(IpAddr, Vec<PortResult>)> {
74 let ip = self.resolve_host_ip(host).await?;
75 let ports = resolve_ports(ports)?;
76 let scanner = PortScanner::new(self.cfg.concurrency);
77 let results = scanner
78 .scan_host_with_progress(ip, ports, self.cfg.scan_timeout_ms, progress)
79 .await?;
80 Ok((ip, results))
81 }
82
83 pub async fn inspect_host(
84 &self,
85 host: String,
86 ports: Option<Vec<u16>>,
87 ) -> Result<InspectResult> {
88 let ports = resolve_ports(ports)?;
89 let engine = InspectEngine::new_with_timeouts(
90 self.cfg.concurrency,
91 self.cfg.ping_timeout_ms,
92 self.cfg.scan_timeout_ms,
93 self.cfg.dns_timeout_ms,
94 );
95 engine.inspect(host, ports).await
96 }
97
98 pub async fn sweep_ipv4(
99 &self,
100 subnet: Option<String>,
101 ports: Option<Vec<u16>>,
102 resolve_hostnames: bool,
103 ) -> Result<(String, Vec<SweepEntry>)> {
104 self.sweep_ipv4_with_progress(subnet, ports, resolve_hostnames, None)
105 .await
106 }
107
108 pub async fn sweep_ipv4_with_progress(
109 &self,
110 subnet: Option<String>,
111 ports: Option<Vec<u16>>,
112 resolve_hostnames: bool,
113 progress: Option<Arc<dyn Fn(crate::sweep::SweepProgress) + Send + Sync>>,
114 ) -> Result<(String, Vec<SweepEntry>)> {
115 let subnet_str = subnet.unwrap_or_else(default_ipv4_subnet_string);
116 let net = parse_limited_ipv4_subnet(&subnet_str)?;
117 let ports = resolve_ports(ports)?;
118 let engine = SweepEngine::new_with_timeouts(
119 self.cfg.concurrency,
120 self.cfg.ping_timeout_ms,
121 self.cfg.scan_timeout_ms,
122 self.cfg.dns_timeout_ms,
123 );
124 let results = engine
125 .sweep_with_progress(net, ports, resolve_hostnames, progress)
126 .await?;
127 Ok((subnet_str, results))
128 }
129}