mirror of
https://github.com/rzuasti/oott.git
synced 2026-07-08 19:21:54 +02:00
Parallel execution and timeouts working. Receiver returning found
devices properly.
This commit is contained in:
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
[env]
|
[env]
|
||||||
RUST_LOG="info"
|
RUST_LOG="debug"
|
||||||
OOTT_ARP_SENDER_TIMEOUT="180"
|
OOTT_ARP_SENDER_TIMEOUT="30"
|
||||||
OOTT_ARP_RECEIVER_TIMEOUT="300"
|
OOTT_ARP_SCAN_DURATION="60"
|
||||||
|
|||||||
+27
-46
@@ -10,7 +10,7 @@ use pnet::{
|
|||||||
use tokio::time::{Duration, Instant, timeout};
|
use tokio::time::{Duration, Instant, timeout};
|
||||||
|
|
||||||
const DEFAULT_SENDER_TIMEOUT: u64 = 60; // 1 minute to send all packets - good for a class C network
|
const DEFAULT_SENDER_TIMEOUT: u64 = 60; // 1 minute to send all packets - good for a class C network
|
||||||
const DEFAULT_RECEIVER_TIMEOUT: u64 = 300; // 5 minutes to wait per round to receive responses
|
const DEFAULT_SCAN_DURATION: u64 = 300; // 5 minutes to wait per round to receive responses
|
||||||
|
|
||||||
pub async fn find(interface: &str) -> Vec<Device> {
|
pub async fn find(interface: &str) -> Vec<Device> {
|
||||||
debug!("Looking up devices via ARP using interface {}", interface);
|
debug!("Looking up devices via ARP using interface {}", interface);
|
||||||
@@ -57,55 +57,36 @@ pub async fn find(interface: &str) -> Vec<Device> {
|
|||||||
|
|
||||||
let send_interface = network_interface.clone();
|
let send_interface = network_interface.clone();
|
||||||
|
|
||||||
// Spawn sender thread
|
// Get timeouts
|
||||||
info!("Starting ARP sender");
|
|
||||||
let sender_start = Instant::now();
|
|
||||||
let sender_timeout =
|
let sender_timeout =
|
||||||
config::parse_env("OOTT_ARP_SENDER_TIMEOUT").unwrap_or(DEFAULT_SENDER_TIMEOUT);
|
config::parse_env("OOTT_ARP_SENDER_TIMEOUT").unwrap_or(DEFAULT_SENDER_TIMEOUT);
|
||||||
debug!("Sender timeout set to {} seconds", sender_timeout);
|
info!("Sender timeout set to {} seconds", sender_timeout);
|
||||||
let sender_thread = timeout(
|
let scan_duration =
|
||||||
Duration::from_secs(sender_timeout),
|
config::parse_env("OOTT_ARP_SCAN_DURATION").unwrap_or(DEFAULT_SCAN_DURATION);
|
||||||
send_packet(sender, send_interface, ipv4_net, mac),
|
let receiver_timeout = scan_duration * 2;
|
||||||
|
info!("Scan duration set to {} seconds", scan_duration);
|
||||||
|
info!("Receiver timeout set to {} seconds", receiver_timeout);
|
||||||
|
|
||||||
|
if sender_timeout >= scan_duration {
|
||||||
|
panic!("OOTT_ARP_SENDER_TIMEOUT needs to be smaller than OOTT_ARP_SCAN_DURATION");
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = tokio::join!(
|
||||||
|
timeout(
|
||||||
|
Duration::from_secs(sender_timeout),
|
||||||
|
send_packet(sender, send_interface, ipv4_net, mac),
|
||||||
|
),
|
||||||
|
timeout(
|
||||||
|
Duration::from_secs(receiver_timeout),
|
||||||
|
listen_for_packets(receiver, ipv4_net, scan_duration),
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Spawn receiver thread
|
match result {
|
||||||
info!("Starting ARP receiver");
|
(Ok(_), Ok(_)) => info!("ARP sender and receiver done"),
|
||||||
let receiver_start = Instant::now();
|
(Err(_), _) => warn!("ARP sender timed out"),
|
||||||
let receiver_timeout =
|
(_, Err(_)) => info!("ARP receiver timed out"),
|
||||||
config::parse_env("OOTT_ARP_RECEIVER_TIMEOUT").unwrap_or(DEFAULT_RECEIVER_TIMEOUT);
|
|
||||||
debug!("Receiver timeout set to {} seconds", receiver_timeout);
|
|
||||||
let receiver_thread = timeout(
|
|
||||||
Duration::from_secs(receiver_timeout),
|
|
||||||
listen_for_packets(receiver, ipv4_net),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Now we wait
|
|
||||||
// Joining sender thread - It should have a shorter timeout than the receiver thread
|
|
||||||
let sender_result = sender_thread.await;
|
|
||||||
match sender_result {
|
|
||||||
Ok(_) => info!("ARP sender done"),
|
|
||||||
Err(_) => warn!("ARP sender timed out"),
|
|
||||||
};
|
};
|
||||||
info!(
|
|
||||||
"ARP sender took {} secs",
|
|
||||||
(Instant::now() - sender_start).as_secs()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Joining receiver thread
|
result.1.unwrap_or(Vec::new())
|
||||||
let receiver_result = receiver_thread.await;
|
|
||||||
match receiver_result {
|
|
||||||
Ok(_) => info!("ARP receiver done"),
|
|
||||||
Err(_) => warn!("ARP receiver timed out"),
|
|
||||||
};
|
|
||||||
info!(
|
|
||||||
"ARP receiver took {} secs",
|
|
||||||
(Instant::now() - receiver_start).as_secs()
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut devices = Vec::new();
|
|
||||||
devices.push(Device {
|
|
||||||
mac_address: String::from("mac"),
|
|
||||||
ipv4_address: String::from("ip"),
|
|
||||||
});
|
|
||||||
devices
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::device_finders::Device;
|
||||||
use log::{debug, info, warn};
|
use log::{debug, info, warn};
|
||||||
use pnet::datalink::{DataLinkReceiver, DataLinkSender, NetworkInterface};
|
use pnet::datalink::{DataLinkReceiver, DataLinkSender, NetworkInterface};
|
||||||
use pnet::ipnetwork::Ipv4Network;
|
use pnet::ipnetwork::Ipv4Network;
|
||||||
@@ -5,7 +6,7 @@ use pnet::packet::arp::{ArpHardwareTypes, ArpOperations, ArpPacket, MutableArpPa
|
|||||||
use pnet::packet::ethernet::{EtherTypes, EthernetPacket, MutableEthernetPacket};
|
use pnet::packet::ethernet::{EtherTypes, EthernetPacket, MutableEthernetPacket};
|
||||||
use pnet::packet::{MutablePacket, Packet};
|
use pnet::packet::{MutablePacket, Packet};
|
||||||
use pnet::util::MacAddr;
|
use pnet::util::MacAddr;
|
||||||
use tokio::time::{Duration, sleep, timeout};
|
use tokio::time::{Duration, Instant, sleep};
|
||||||
|
|
||||||
pub async fn send_packet(
|
pub async fn send_packet(
|
||||||
mut tx: Box<dyn DataLinkSender>,
|
mut tx: Box<dyn DataLinkSender>,
|
||||||
@@ -13,7 +14,9 @@ pub async fn send_packet(
|
|||||||
sender_ip: Ipv4Network,
|
sender_ip: Ipv4Network,
|
||||||
sender_macaddr: MacAddr,
|
sender_macaddr: MacAddr,
|
||||||
) {
|
) {
|
||||||
info!("Starting ARP sender loop");
|
info!("Starting ARP sender");
|
||||||
|
let sender_start = Instant::now();
|
||||||
|
|
||||||
for target_ip in sender_ip.iter() {
|
for target_ip in sender_ip.iter() {
|
||||||
if target_ip == sender_ip.ip() {
|
if target_ip == sender_ip.ip() {
|
||||||
continue;
|
continue;
|
||||||
@@ -51,11 +54,24 @@ pub async fn send_packet(
|
|||||||
// Sleep 1 millisecond between IPs
|
// Sleep 1 millisecond between IPs
|
||||||
sleep(Duration::from_millis(1)).await;
|
sleep(Duration::from_millis(1)).await;
|
||||||
}
|
}
|
||||||
|
info!(
|
||||||
|
"ARP sender took {} secs",
|
||||||
|
(Instant::now() - sender_start).as_secs()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn listen_for_packets(mut rx: Box<dyn DataLinkReceiver>, ipv4_net: Ipv4Network) {
|
pub async fn listen_for_packets(
|
||||||
info!("Starting ARP receiver loop");
|
mut rx: Box<dyn DataLinkReceiver>,
|
||||||
loop {
|
ipv4_net: Ipv4Network,
|
||||||
|
run_for_secs: u64,
|
||||||
|
) -> Vec<Device> {
|
||||||
|
info!("Starting ARP receiver for {} secs", run_for_secs);
|
||||||
|
let start_time = Instant::now();
|
||||||
|
|
||||||
|
let mut devices = Vec::new();
|
||||||
|
|
||||||
|
// Run while still under the time window
|
||||||
|
while (Instant::now() - start_time).as_secs() <= run_for_secs {
|
||||||
let arp_buffer = match rx.next() {
|
let arp_buffer = match rx.next() {
|
||||||
Ok(buffer) => buffer,
|
Ok(buffer) => buffer,
|
||||||
Err(_) => continue,
|
Err(_) => continue,
|
||||||
@@ -68,15 +84,25 @@ pub async fn listen_for_packets(mut rx: Box<dyn DataLinkReceiver>, ipv4_net: Ipv
|
|||||||
if arp_packet.get_operation() == ArpOperations::Reply {
|
if arp_packet.get_operation() == ArpOperations::Reply {
|
||||||
debug!("It is an ARP reply packet");
|
debug!("It is an ARP reply packet");
|
||||||
if arp_packet.get_target_proto_addr() == ipv4_net.ip() {
|
if arp_packet.get_target_proto_addr() == ipv4_net.ip() {
|
||||||
info!(
|
debug!(
|
||||||
"Found online device - IP addr={} - MAC addr={}",
|
"Found online device - IP addr={} - MAC addr={}",
|
||||||
arp_packet.get_sender_proto_addr(),
|
arp_packet.get_sender_proto_addr(),
|
||||||
arp_packet.get_sender_hw_addr()
|
arp_packet.get_sender_hw_addr()
|
||||||
);
|
);
|
||||||
|
devices.push(Device {
|
||||||
|
mac_address: arp_packet.get_sender_hw_addr().to_string(),
|
||||||
|
ipv4_address: arp_packet.get_sender_proto_addr().to_string(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Sleep 1 millisecond between IPs
|
// Sleep 1 millisecond between IPs
|
||||||
sleep(Duration::from_millis(1)).await;
|
sleep(Duration::from_millis(1)).await;
|
||||||
}
|
}
|
||||||
|
info!(
|
||||||
|
"ARP receiver run for {} secs",
|
||||||
|
(Instant::now() - start_time).as_secs()
|
||||||
|
);
|
||||||
|
|
||||||
|
devices
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -7,11 +7,12 @@ async fn main() {
|
|||||||
env_logger::init();
|
env_logger::init();
|
||||||
info!("Starting up oott");
|
info!("Starting up oott");
|
||||||
|
|
||||||
let devices = device_finders::arp::find("eno1").await;
|
let devices = device_finders::arp::find("wlp1s0").await;
|
||||||
|
|
||||||
info!("Done with ARP probes");
|
info!("Done with ARP probes");
|
||||||
|
info!("Found {} online devices", devices.iter().count());
|
||||||
for device in devices.iter() {
|
for device in devices.iter() {
|
||||||
debug!("Device found {}", device);
|
info!("Device found {}", device);
|
||||||
}
|
}
|
||||||
info!("Exiting");
|
info!("Exiting");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user