Añadir src/main.rs
This commit is contained in:
		
							parent
							
								
									72ed05bfa7
								
							
						
					
					
						commit
						5ea643dd9a
					
				
							
								
								
									
										147
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,147 @@ | ||||
| use clap::Parser; | ||||
| use reqwest::Client; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use std::{collections::HashSet, net::Ipv4Addr, path::Path, sync::Arc}; | ||||
| use tokio::{fs, sync::{Semaphore, Mutex}}; | ||||
| 
 | ||||
| const MAX_CONCURRENT_SCANS: usize = 500; | ||||
| const PROGRESS_FILE: &str = "progress.json"; | ||||
| const IPS_UP_FILE: &str = "ips_up.json"; | ||||
| 
 | ||||
| #[derive(Parser, Debug)] | ||||
| #[command(author, version, about = "Async IP Scanner", long_about = None)] | ||||
| struct Args { | ||||
|     /// IP to start scanning from
 | ||||
|     #[arg(short, long, default_value = "0.0.0.0")] | ||||
|     start: String, | ||||
| } | ||||
| 
 | ||||
| #[derive(Serialize, Deserialize)] | ||||
| struct Progress { | ||||
|     current_ip: String, | ||||
| } | ||||
| 
 | ||||
| fn increment_ip(ip: Ipv4Addr) -> Option<Ipv4Addr> { | ||||
|     let mut octets = ip.octets(); | ||||
|     for i in (0..4).rev() { | ||||
|         if octets[i] < 255 { | ||||
|             octets[i] += 1; | ||||
|             return Some(Ipv4Addr::from(octets)); | ||||
|         } else { | ||||
|             octets[i] = 0; | ||||
|         } | ||||
|     } | ||||
|     None | ||||
| } | ||||
| 
 | ||||
| async fn load_progress() -> Option<Progress> { | ||||
|     if Path::new(PROGRESS_FILE).exists() { | ||||
|         if let Ok(data) = fs::read_to_string(PROGRESS_FILE).await { | ||||
|             if let Ok(progress) = serde_json::from_str::<Progress>(&data) { | ||||
|                 return Some(progress); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     None | ||||
| } | ||||
| 
 | ||||
| async fn save_progress_background(ip: Ipv4Addr) { | ||||
|     tokio::spawn(async move { | ||||
|         let progress = Progress { | ||||
|             current_ip: ip.to_string(), | ||||
|         }; | ||||
|         if let Ok(data) = serde_json::to_string(&progress) { | ||||
|             let _ = fs::write(PROGRESS_FILE, data).await; | ||||
|         } | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| async fn load_ips_up() -> HashSet<String> { | ||||
|     if Path::new(IPS_UP_FILE).exists() { | ||||
|         if let Ok(data) = fs::read_to_string(IPS_UP_FILE).await { | ||||
|             if let Ok(ips) = serde_json::from_str::<HashSet<String>>(&data) { | ||||
|                 return ips; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     HashSet::new() | ||||
| } | ||||
| 
 | ||||
| async fn save_ips_up_background(ips: Arc<Mutex<HashSet<String>>>) { | ||||
|     let ips_clone = ips.clone(); | ||||
|     tokio::spawn(async move { | ||||
|         let lock = ips_clone.lock().await; | ||||
|         if let Ok(data) = serde_json::to_string(&*lock) { | ||||
|             let _ = fs::write(IPS_UP_FILE, data).await; | ||||
|         } | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| async fn scan_ip(ip: String, client: Client, sem: Arc<Semaphore>, ips_up: Arc<Mutex<HashSet<String>>>) { | ||||
|     let _permit = sem.acquire().await.unwrap(); | ||||
|     let url = format!("http://{}", ip); | ||||
|     match client.get(&url).send().await { | ||||
|         Ok(response) if response.status().is_success() => { | ||||
|             println!("{} is UP", ip); | ||||
|             let mut lock = ips_up.lock().await; | ||||
|             lock.insert(ip); | ||||
|         } | ||||
|         Ok(response) => { | ||||
|             println!("{} is DOWN (status {})", ip, response.status()); | ||||
|         } | ||||
|         Err(err) => { | ||||
|             println!("{} is DOWN (error: {})", ip, err); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[tokio::main] | ||||
| async fn main() { | ||||
|     let args = Args::parse(); | ||||
| 
 | ||||
|     let starting_ip = args.start.parse::<Ipv4Addr>().unwrap_or(Ipv4Addr::new(0, 0, 0, 0)); | ||||
|     let saved_progress = load_progress().await; | ||||
|     let mut current_ip = saved_progress | ||||
|         .map(|p| p.current_ip.parse().unwrap_or(starting_ip)) | ||||
|         .unwrap_or(starting_ip); | ||||
| 
 | ||||
|     let ips_up = Arc::new(Mutex::new(load_ips_up().await)); | ||||
|     let client = Client::builder() | ||||
|         .timeout(std::time::Duration::from_secs(2)) | ||||
|         .build() | ||||
|         .unwrap(); | ||||
|     let sem = Arc::new(Semaphore::new(MAX_CONCURRENT_SCANS)); | ||||
|     let end_ip = Ipv4Addr::new(255, 255, 255, 255); | ||||
| 
 | ||||
|     while current_ip <= end_ip { | ||||
|         let mut handles = vec![]; | ||||
|         let mut ip_batch = vec![]; | ||||
| 
 | ||||
|         for _ in 0..MAX_CONCURRENT_SCANS { | ||||
|             ip_batch.push(current_ip); | ||||
|             if let Some(next_ip) = increment_ip(current_ip) { | ||||
|                 current_ip = next_ip; | ||||
|             } else { | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         for ip in &ip_batch { | ||||
|             let ip_str = ip.to_string(); | ||||
|             let client_clone = client.clone(); | ||||
|             let sem_clone = sem.clone(); | ||||
|             let ips_clone = ips_up.clone(); | ||||
| 
 | ||||
|             handles.push(tokio::spawn(scan_ip(ip_str, client_clone, sem_clone, ips_clone))); | ||||
|         } | ||||
| 
 | ||||
|         for h in handles { | ||||
|             let _ = h.await; | ||||
|         } | ||||
| 
 | ||||
|         save_progress_background(current_ip).await; | ||||
|         save_ips_up_background(ips_up.clone()).await; | ||||
|     } | ||||
| 
 | ||||
|     println!("Finished scanning."); // lol, lmao even
 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user