Added build script

This commit is contained in:
2026-10-09 09:46:32 -04:00
parent fd8bb16d40
commit cf2cc9f8ed
13 changed files with 50 additions and 35 deletions
Executable
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
cd src-tauri && cargo clean
cargo clippy --fix --all-targets --allow-dirty
cargo fmt
cargo tauri build
cargo tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc
+1 -1
View File
@@ -16,4 +16,4 @@ pub async fn check_privileges() -> Result<bool, String> {
// On Windows, check if running as administrator // On Windows, check if running as administrator
Ok(is_elevated::is_elevated()) Ok(is_elevated::is_elevated())
} }
} }
+4 -5
View File
@@ -1,16 +1,15 @@
use pulldown_cmark::{Options, Parser, html}; use pulldown_cmark::{html, Options, Parser};
const CHANGELOG_MD: &str = include_str!("../../../CHANGELOG.md"); const CHANGELOG_MD: &str = include_str!("../../../CHANGELOG.md");
#[tauri::command] #[tauri::command]
pub async fn get_changelog() -> Result<String, String> { pub async fn get_changelog() -> Result<String, String> {
let options = Options::ENABLE_HEADING_ATTRIBUTES let options =
| Options::ENABLE_STRIKETHROUGH Options::ENABLE_HEADING_ATTRIBUTES | Options::ENABLE_STRIKETHROUGH | Options::ENABLE_TABLES;
| Options::ENABLE_TABLES;
let parser = Parser::new_ext(CHANGELOG_MD, options); let parser = Parser::new_ext(CHANGELOG_MD, options);
let mut html_output = String::new(); let mut html_output = String::new();
html::push_html(&mut html_output, parser); html::push_html(&mut html_output, parser);
Ok(html_output) Ok(html_output)
} }
+2 -3
View File
@@ -11,8 +11,7 @@ pub struct ExportRequest {
#[tauri::command] #[tauri::command]
pub async fn export_csv(request: ExportRequest) -> Result<(), String> { pub async fn export_csv(request: ExportRequest) -> Result<(), String> {
let file = File::create(&request.path) let file = File::create(&request.path).map_err(|e| format!("Failed to create file: {}", e))?;
.map_err(|e| format!("Failed to create file: {}", e))?;
let mut writer = csv::Writer::from_writer(file); let mut writer = csv::Writer::from_writer(file);
@@ -43,4 +42,4 @@ pub async fn export_csv(request: ExportRequest) -> Result<(), String> {
tracing::info!("Exported {} hosts to {}", request.hosts.len(), request.path); tracing::info!("Exported {} hosts to {}", request.hosts.len(), request.path);
Ok(()) Ok(())
} }
+10 -1
View File
@@ -40,7 +40,16 @@ pub async fn start_scan(app: AppHandle, config: ScanConfig) -> Result<(), String
let port_timeout_ms = config.port_timeout_ms.unwrap_or(1000); let port_timeout_ms = config.port_timeout_ms.unwrap_or(1000);
tokio::spawn(async move { tokio::spawn(async move {
ping_sweep(&app, &ips, timeout_ms, cancel, port_scan, ports, port_timeout_ms).await; ping_sweep(
&app,
&ips,
timeout_ms,
cancel,
port_scan,
ports,
port_timeout_ms,
)
.await;
}); });
Ok(()) Ok(())
} }
+4 -4
View File
@@ -6,7 +6,7 @@ pub enum HostStatus {
Up, Up,
Down, Down,
Filtered, Filtered,
Unknown Unknown,
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -42,7 +42,7 @@ pub struct PortResult {
pub struct NetbiosInfo { pub struct NetbiosInfo {
pub computer_name: Option<String>, pub computer_name: Option<String>,
pub workgroup: Option<String>, pub workgroup: Option<String>,
pub mac_from_netbios: Option<String> pub mac_from_netbios: Option<String>,
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -79,7 +79,7 @@ impl HostResult {
updated_at: now_ms(), updated_at: now_ms(),
} }
} }
pub fn down(ip: IpAddr) -> Self { pub fn down(ip: IpAddr) -> Self {
Self { Self {
ip, ip,
@@ -93,4 +93,4 @@ impl HostResult {
updated_at: now_ms(), updated_at: now_ms(),
} }
} }
} }
+1 -1
View File
@@ -1,2 +1,2 @@
pub mod host; pub mod host;
pub mod monitor; pub mod monitor;
+2 -4
View File
@@ -3,9 +3,7 @@ use std::net::IpAddr;
/// Perform reverse DNS lookup on a single IP. /// Perform reverse DNS lookup on a single IP.
/// Returns the hostname if found, None otherwise. /// Returns the hostname if found, None otherwise.
pub async fn reverse_lookup(ip: IpAddr) -> Option<String> { pub async fn reverse_lookup(ip: IpAddr) -> Option<String> {
let result = tokio::task::spawn_blocking(move || { let result = tokio::task::spawn_blocking(move || dns_lookup::lookup_addr(&ip)).await;
dns_lookup::lookup_addr(&ip)
}).await;
match result { match result {
Ok(Ok(hostname)) => { Ok(Ok(hostname)) => {
@@ -17,4 +15,4 @@ pub async fn reverse_lookup(ip: IpAddr) -> Option<String> {
} }
_ => None, _ => None,
} }
} }
+1 -1
View File
@@ -1,2 +1,2 @@
pub mod dns;
pub mod range; pub mod range;
pub mod dns;
+1 -1
View File
@@ -140,4 +140,4 @@ mod tests {
fn test_reversed_range() { fn test_reversed_range() {
assert!(parse_ip_range("192.168.1.10-192.168.1.1").is_err()); assert!(parse_ip_range("192.168.1.10-192.168.1.1").is_err());
} }
} }
+1 -1
View File
@@ -1,3 +1,3 @@
pub mod netbios;
pub mod ping; pub mod ping;
pub mod ports; pub mod ports;
pub mod netbios;
+1 -2
View File
@@ -91,8 +91,7 @@ pub async fn ping_sweep(
let nb_fut = query_netbios(enriched.ip, 500); let nb_fut = query_netbios(enriched.ip, 500);
if port_scan { if port_scan {
let scan_ports = ports2 let scan_ports = ports2.unwrap_or_else(|| DEFAULT_PORTS.to_vec());
.unwrap_or_else(|| DEFAULT_PORTS.to_vec());
let (nb_result, port_results) = tokio::join!( let (nb_result, port_results) = tokio::join!(
nb_fut, nb_fut,
scan_host_ports(enriched.ip, &scan_ports, port_timeout_ms) scan_host_ports(enriched.ip, &scan_ports, port_timeout_ms)
+16 -11
View File
@@ -42,8 +42,7 @@ fn service_name(port: u16) -> Option<String> {
} }
pub const DEFAULT_PORTS: &[u16] = &[ pub const DEFAULT_PORTS: &[u16] = &[
21, 22, 23, 25, 53, 80, 110, 111, 135, 139, 143, 21, 22, 23, 25, 53, 80, 110, 111, 135, 139, 143, 443, 445, 993, 995, 1433, 1521, 3306, 3389,
443, 445, 993, 995, 1433, 1521, 3306, 3389,
5432, 5900, 5985, 5986, 8080, 8088, 8443, 5432, 5900, 5985, 5986, 8080, 8088, 8443,
]; ];
@@ -96,7 +95,10 @@ async fn grab_banner(mut stream: TcpStream, port: u16) -> Option<String> {
}; };
if let Some(data) = probe { if let Some(data) = probe {
if timeout(banner_timeout, stream.write_all(data)).await.is_err() { if timeout(banner_timeout, stream.write_all(data))
.await
.is_err()
{
return None; return None;
} }
} }
@@ -107,8 +109,15 @@ async fn grab_banner(mut stream: TcpStream, port: u16) -> Option<String> {
Ok(Ok(n)) if n > 0 => { Ok(Ok(n)) if n > 0 => {
buf.truncate(n); buf.truncate(n);
// Strip to printable ASCII, replace control chars // Strip to printable ASCII, replace control chars
let banner: String = buf.iter() let banner: String = buf
.map(|&b| if b >= 0x20 && b < 0x7f { b as char } else { ' ' }) .iter()
.map(|&b| {
if (0x20..0x7f).contains(&b) {
b as char
} else {
' '
}
})
.collect(); .collect();
let banner = banner.trim().to_string(); let banner = banner.trim().to_string();
if banner.is_empty() { if banner.is_empty() {
@@ -124,11 +133,7 @@ async fn grab_banner(mut stream: TcpStream, port: u16) -> Option<String> {
const MAX_PORT_CONCURRENT: usize = 64; const MAX_PORT_CONCURRENT: usize = 64;
pub async fn scan_host_ports( pub async fn scan_host_ports(ip: IpAddr, ports: &[u16], timeout_ms: u64) -> Vec<PortResult> {
ip: IpAddr,
ports: &[u16],
timeout_ms: u64,
) -> Vec<PortResult> {
let mut results = Vec::with_capacity(ports.len()); let mut results = Vec::with_capacity(ports.len());
for chunk in ports.chunks(MAX_PORT_CONCURRENT) { for chunk in ports.chunks(MAX_PORT_CONCURRENT) {
@@ -148,4 +153,4 @@ pub async fn scan_host_ports(
results.sort_by_key(|p| p.port); results.sort_by_key(|p| p.port);
results results
} }