From 0738307f87c78141328a10224572e71aa687409c Mon Sep 17 00:00:00 2001 From: rzuasti Date: Tue, 13 Jan 2026 15:48:17 -0500 Subject: [PATCH] Trying to add timeouts to send and receive --- Cargo.lock | 242 ++++++++++++++++++ Cargo.toml | 1 + src/device_finders/arp.rs | 107 +++++++- src/device_finders/arp/packet_send_receive.rs | 77 ++++++ src/main.rs | 5 +- 5 files changed, 426 insertions(+), 6 deletions(-) create mode 100644 src/device_finders/arp/packet_send_receive.rs diff --git a/Cargo.lock b/Cargo.lock index bcafa81..d0a015a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,34 @@ dependencies = [ "memchr", ] +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "bytes" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "glob" version = "0.3.3" @@ -32,12 +60,32 @@ version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + [[package]] name = "memchr" version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + [[package]] name = "no-std-net" version = "0.6.0" @@ -49,8 +97,38 @@ name = "oott" version = "0.1.0" dependencies = [ "pnet", + "tokio", ] +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + [[package]] name = "pnet" version = "0.35.0" @@ -160,6 +238,15 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.12.2" @@ -189,6 +276,12 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "serde" version = "1.0.228" @@ -218,6 +311,32 @@ dependencies = [ "syn", ] +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + [[package]] name = "syn" version = "2.0.114" @@ -229,12 +348,46 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tokio" +version = "1.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "unicode-ident" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + [[package]] name = "winapi" version = "0.3.9" @@ -256,3 +409,92 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" diff --git a/Cargo.toml b/Cargo.toml index f35e8b4..5dede73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,3 +5,4 @@ edition = "2024" [dependencies] pnet = "0.35.0" +tokio = { version = "1.0", features = ["full"] } diff --git a/src/device_finders/arp.rs b/src/device_finders/arp.rs index 3f39e41..9ed6b71 100644 --- a/src/device_finders/arp.rs +++ b/src/device_finders/arp.rs @@ -1,9 +1,108 @@ -use crate::device_finders::Device; +use crate::device_finders::{ + Device, + arp::packet_send_receive::{listen_for_packets, send_packet}, +}; +use pnet::{ + datalink::{self, Channel, NetworkInterface}, + ipnetwork::IpNetwork, +}; +use tokio::task; +use tokio::time::{Duration, timeout}; -pub fn find() -> Vec { - //let devices = helper_async_arp::execute_probe(&String::from("eno1")); +mod packet_send_receive; + +pub async fn find(interface: &str) -> Vec { + // Get the network device to use + let network_interface: NetworkInterface = datalink::interfaces() + .iter() + .filter(|el| el.is_up()) + .filter(|el| el.name == interface) + .next() + .expect("Selected interface not found") + .clone(); + + // Get the IPV4 network to use + let ipv4_net = network_interface + .ips + .iter() + .filter_map(|el| match el { + IpNetwork::V4(v4) => Some(*v4), + _ => None, + }) + .next() + .expect("No local ip address found"); + + // Get the local MAC address + let mac = match network_interface.mac { + Some(mac) => mac, + None => { + panic!("No local MAC address found"); + } + }; + + println!("Local MAC: {}", mac); + println!("Local IP: {}", ipv4_net); + + // Data channel + println!("Creating data channel"); + let tunnel = datalink::channel(&network_interface, datalink::Config::default()) + .expect("Failed to create datalink channel"); + let (sender, receiver) = match tunnel { + Channel::Ethernet(tx, rx) => (tx, rx), + _ => panic!("Unsupported data channel type"), + }; + + let send_interface = network_interface.clone(); + + println!("Starting sender"); + + let send_result = timeout( + Duration::from_secs(2), + send_packet(sender, send_interface, ipv4_net, mac), + ) + .await; + match send_result { + Ok(_) => println!("Sender done"), + Err(_) => println!("Sender timed out"), + }; + + let receive_result = timeout( + Duration::from_secs(5), + listen_for_packets(receiver, ipv4_net), + ) + .await; + match receive_result { + Ok(_) => println!("Receiver done"), + Err(_) => println!("Receiver timed out"), + }; + + // println!("Spawning receiver threads"); + // let reciever_thread = thread::spawn(move || { + // listen_for_packets(receiver, ipv4_net); + // }); + + // println!("Spawning sender thread"); + // let sender_thread = thread::spawn(move || { + // send_packet(sender, send_interface, ipv4_net, mac); + // }); + + // match sender_thread.join() { + // Ok(it) => println!("Sender thread done"), + // Err(err) => panic!("Error sending ARP packets"), + // }; + + // println!("Waiting to receive"); + // thread::sleep(Duration::from_secs(10)); + // println!("Done!"); let mut devices = Vec::new(); - devices.push(Device {mac_address: String::from("mac"), ipv4_address: String::from("ip")}); + devices.push(Device { + mac_address: String::from("mac"), + ipv4_address: String::from("ip"), + }); devices } + +// async fn test_timeout() { +// sleep(Duration::from_secs(10)).await; +// } diff --git a/src/device_finders/arp/packet_send_receive.rs b/src/device_finders/arp/packet_send_receive.rs new file mode 100644 index 0000000..f237e4d --- /dev/null +++ b/src/device_finders/arp/packet_send_receive.rs @@ -0,0 +1,77 @@ +use pnet::datalink::{DataLinkReceiver, DataLinkSender, NetworkInterface}; +use pnet::ipnetwork::Ipv4Network; +use pnet::packet::arp::{ArpHardwareTypes, ArpOperations, ArpPacket, MutableArpPacket}; +use pnet::packet::ethernet::{EtherTypes, EthernetPacket, MutableEthernetPacket}; +use pnet::packet::{MutablePacket, Packet}; +use pnet::util::MacAddr; + +pub async fn send_packet( + mut tx: Box, + interface: NetworkInterface, + sender_ip: Ipv4Network, + sender_macaddr: MacAddr, +) { + for target_ip in sender_ip.iter() { + if target_ip == sender_ip.ip() { + continue; + } + println!("Sending to {}", target_ip); + for _ in 0..1 { + //arp packet + let mut arp_buf = [0u8; 28]; + let mut arp_packet = MutableArpPacket::new(&mut arp_buf).unwrap(); + + arp_packet.set_hardware_type(ArpHardwareTypes::Ethernet); + arp_packet.set_protocol_type(EtherTypes::Ipv4); + arp_packet.set_hw_addr_len(6); + arp_packet.set_operation(ArpOperations::Request); + arp_packet.set_proto_addr_len(4); + arp_packet.set_sender_hw_addr(sender_macaddr); + arp_packet.set_sender_proto_addr(sender_ip.ip()); + arp_packet.set_target_hw_addr(MacAddr::zero()); + arp_packet.set_target_proto_addr(target_ip); + + //ethernet packet + let mut ethernet_buf = [0u8; 42]; + let mut ethernet_packet = MutableEthernetPacket::new(&mut ethernet_buf).unwrap(); + + ethernet_packet.set_destination(MacAddr::broadcast()); + ethernet_packet.set_source(sender_macaddr); + ethernet_packet.set_ethertype(EtherTypes::Arp); + ethernet_packet.set_payload(arp_packet.packet_mut()); + + tx.send_to( + ðernet_packet.to_immutable().packet(), + Some(interface.clone()), + ); + // thread::sleep(Duration::from_millis(2)); + } + // thread::sleep(Duration::from_millis(2)); + } +} + +pub async fn listen_for_packets(mut rx: Box, ipv4_net: Ipv4Network) { + loop { + let arp_buffer = match rx.next() { + Ok(buffer) => buffer, + Err(_) => continue, + }; + let ethernet_packet = EthernetPacket::new(arp_buffer).unwrap(); + + if ethernet_packet.get_ethertype() == EtherTypes::Arp { + let arp_packet = ArpPacket::new(ethernet_packet.payload()).unwrap(); + if arp_packet.get_operation() == ArpOperations::Reply { + if arp_packet.get_target_proto_addr() == ipv4_net.ip() { + print!("."); + println!("Status ONLINE"); + println!( + "IP addr:\t{} \nMac addr:\t{}", + arp_packet.get_sender_proto_addr(), + arp_packet.get_sender_hw_addr() + ); + println!("----------------------"); + } + } + } + } +} diff --git a/src/main.rs b/src/main.rs index ec98c04..ea227df 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ mod device_finders; -fn main() { - let devices = device_finders::arp::find(); +#[tokio::main] +async fn main() { + let devices = device_finders::arp::find("eno1").await; for device in devices.iter() { println!("{}", device);