mirror of
https://github.com/Astatin3/rust-scan-mc.git
synced 2026-06-09 08:28:02 -06:00
Improve saving format
This commit is contained in:
@@ -20,18 +20,7 @@ impl ScanResult {
|
||||
pub fn to_string_row(&self) -> StringRow {
|
||||
StringRow {
|
||||
id: self.ip.to_string(),
|
||||
values: vec![join_nums(&self.open_ports, ",")],
|
||||
ports: (*self.open_ports).to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn join_nums(nums: &Vec<i32>, sep: &str) -> String {
|
||||
// 1. Convert numbers to strings
|
||||
let str_nums: Vec<String> = nums
|
||||
.iter()
|
||||
.map(|n| n.to_string()) // map every integer to a string
|
||||
.collect(); // collect the strings into the vector
|
||||
|
||||
// 2. Join the strings. There's already a function for this.
|
||||
str_nums.join(sep)
|
||||
}
|
||||
|
||||
+53
-10
@@ -6,11 +6,12 @@ use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use indicatif::ProgressBar;
|
||||
use pnet::datalink::linux::interfaces;
|
||||
use pnet::datalink::{self};
|
||||
use pnet::packet::ip::IpNextHeaderProtocols;
|
||||
use pnet::packet::tcp::{MutableTcpPacket, TcpFlags, TcpPacket};
|
||||
use pnet::packet::{Packet, tcp};
|
||||
use pnet::transport::{self, TransportChannelType};
|
||||
use pnet::packet::{tcp, Packet};
|
||||
use pnet::transport::{self, TransportChannelType, TransportSender};
|
||||
use rand::random_range;
|
||||
|
||||
use super::port_scan::ScanResult;
|
||||
@@ -22,9 +23,20 @@ fn std_to_pnet_ipv4(previous: &IpAddr) -> Ipv4Addr {
|
||||
// Main scanning function
|
||||
pub fn tcp_scan(targets: Vec<IpAddr>, ports: Vec<i32>, timeout: Duration) -> Vec<ScanResult> {
|
||||
// Find network interface
|
||||
let interface = datalink::interfaces()
|
||||
let interfaces = datalink::interfaces();
|
||||
|
||||
println!("{}", interfaces.len());
|
||||
|
||||
let interface = interfaces
|
||||
.into_iter()
|
||||
.find(|iface| iface.is_up() && !iface.is_loopback() && !iface.ips.is_empty())
|
||||
.find(|iface| {
|
||||
iface.is_up()
|
||||
&& !iface.is_loopback()
|
||||
&& !iface.ips.is_empty()
|
||||
&& !iface.is_dormant()
|
||||
&& iface.is_running()
|
||||
&& iface.is_point_to_point()
|
||||
})
|
||||
.expect("No valid network interface found");
|
||||
|
||||
// Create transport channel for sending and receiving
|
||||
@@ -52,13 +64,19 @@ pub fn tcp_scan(targets: Vec<IpAddr>, ports: Vec<i32>, timeout: Duration) -> Vec
|
||||
let start_time = std::time::Instant::now();
|
||||
|
||||
while start_time.elapsed() < timeout {
|
||||
// println!("loop");
|
||||
let mut iter = transport::tcp_packet_iter(&mut rx);
|
||||
|
||||
match iter.next() {
|
||||
Ok((packet, addr)) => {
|
||||
match iter.next_with_timeout(timeout) {
|
||||
Ok(Some((packet, addr))) => {
|
||||
if let Some(tcp) = TcpPacket::new(packet.packet()) {
|
||||
// Check for SYN+ACK flags (indicating open port)
|
||||
if tcp.get_flags() == TcpFlags::SYN | TcpFlags::ACK {
|
||||
println!(
|
||||
"Discovered open port {} on {}",
|
||||
tcp.get_source(),
|
||||
addr.to_string()
|
||||
);
|
||||
let mut results_map = receiver_results.lock().unwrap();
|
||||
if let Some(open_ports) = results_map.get_mut(&addr) {
|
||||
open_ports.push(tcp.get_source() as i32);
|
||||
@@ -66,6 +84,9 @@ pub fn tcp_scan(targets: Vec<IpAddr>, ports: Vec<i32>, timeout: Duration) -> Vec
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(None) => {
|
||||
break;
|
||||
}
|
||||
Err(_) => {
|
||||
// Just continue on errors
|
||||
thread::sleep(Duration::from_millis(1));
|
||||
@@ -76,6 +97,8 @@ pub fn tcp_scan(targets: Vec<IpAddr>, ports: Vec<i32>, timeout: Duration) -> Vec
|
||||
|
||||
let pb = ProgressBar::new((targets.len() * ports.len()) as u64);
|
||||
|
||||
println!("{:?}", interface.ips);
|
||||
|
||||
let source_ip = interface
|
||||
.ips
|
||||
.iter()
|
||||
@@ -83,6 +106,11 @@ pub fn tcp_scan(targets: Vec<IpAddr>, ports: Vec<i32>, timeout: Duration) -> Vec
|
||||
.expect("No IPv4 address found")
|
||||
.ip();
|
||||
|
||||
// let source_ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
|
||||
// let source_ip = IpAddr::V4(Ipv4Addr::new(10, 0, 70, 4));
|
||||
|
||||
println!("Using IP: {}", source_ip.to_string());
|
||||
|
||||
for target in &targets {
|
||||
for port in &ports {
|
||||
// let source_ip = Ipv4Addr::from_bits(random_range(0..=(0xffffffff)));
|
||||
@@ -111,10 +139,7 @@ pub fn tcp_scan(targets: Vec<IpAddr>, ports: Vec<i32>, timeout: Duration) -> Vec
|
||||
);
|
||||
tcp_header.set_checksum(checksum);
|
||||
|
||||
match tx.send_to(tcp_header, *target) {
|
||||
Ok(_) => {}
|
||||
Err(e) => eprintln!("Failed to send packet: {}", e),
|
||||
}
|
||||
send_tcp_packet(&mut tx, tcp_header, target);
|
||||
|
||||
pb.inc(1);
|
||||
thread::sleep(Duration::from_micros(100));
|
||||
@@ -122,6 +147,7 @@ pub fn tcp_scan(targets: Vec<IpAddr>, ports: Vec<i32>, timeout: Duration) -> Vec
|
||||
}
|
||||
|
||||
// Wait for receiver to finish
|
||||
// thread::sleep(timeout);
|
||||
receiver_handle.join().unwrap();
|
||||
|
||||
// Convert results to the return format
|
||||
@@ -131,6 +157,7 @@ pub fn tcp_scan(targets: Vec<IpAddr>, ports: Vec<i32>, timeout: Duration) -> Vec
|
||||
.map(|ip| {
|
||||
let mut open_ports = results_map.get(ip).cloned().unwrap_or_default();
|
||||
open_ports.sort();
|
||||
open_ports.dedup();
|
||||
ScanResult {
|
||||
ip: *ip,
|
||||
open_ports,
|
||||
@@ -138,3 +165,19 @@ pub fn tcp_scan(targets: Vec<IpAddr>, ports: Vec<i32>, timeout: Duration) -> Vec
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn send_tcp_packet(tx: &mut TransportSender, tcp_header: MutableTcpPacket<'_>, target: &IpAddr) {
|
||||
match tx.send_to(&tcp_header, *target) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
if let Some(code) = e.raw_os_error() {
|
||||
if code == 105 {
|
||||
thread::sleep(Duration::from_millis(500));
|
||||
send_tcp_packet(tx, tcp_header, target);
|
||||
}
|
||||
} else {
|
||||
eprintln!("Failed to send packet: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user