mirror of
https://github.com/rzuasti/oott.git
synced 2026-07-08 19:21:54 +02:00
Restructured modules, integrated async-arp
This commit is contained in:
Generated
+11
@@ -178,6 +178,12 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
|
||||
|
||||
[[package]]
|
||||
name = "ipnetwork"
|
||||
version = "0.20.0"
|
||||
@@ -226,7 +232,12 @@ checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65"
|
||||
name = "oott"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"afpacket",
|
||||
"async-arp",
|
||||
"futures",
|
||||
"ipnet",
|
||||
"pnet",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -5,3 +5,8 @@ edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
async-arp = "0.4.0"
|
||||
afpacket = {version = "0.2.3", features = ["async-tokio"]}
|
||||
ipnet = "2.11.0"
|
||||
pnet = "0.35.0"
|
||||
tokio = {version = "1.43.0", features = ["io-util", "time", "rt", "macros", "sync"]}
|
||||
futures = "0.3.31"
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
use crate::device_finders::Device;
|
||||
use async_arp::{Client, ClientConfigBuilder, ClientSpinner, ProbeStatus, Result};
|
||||
use std::io::Write;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
mod helper_async_arp;
|
||||
|
||||
pub fn find() -> Vec<Device> {
|
||||
let mut devices = Vec::new();
|
||||
devices.push(Device {
|
||||
mac_address: String::from("mac1"),
|
||||
});
|
||||
devices.push(Device {
|
||||
mac_address: String::from("mac2"),
|
||||
});
|
||||
devices.push(Device {
|
||||
mac_address: String::from("mac3"),
|
||||
});
|
||||
let devices = helper_async_arp::execute_probe(&String::from("eno1"));
|
||||
|
||||
devices
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
use async_arp::{Client, ClientConfigBuilder, ProbeStatus};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use crate::device_finders::Device;
|
||||
mod common;
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
pub async fn execute_probe(iface: &str) -> Vec<Device> {
|
||||
let interface = common::interface_from(&iface);
|
||||
let net = common::net_from(&interface).unwrap();
|
||||
|
||||
let client = Client::new(
|
||||
ClientConfigBuilder::new(&iface)
|
||||
.with_response_timeout(Duration::from_millis(500))
|
||||
.build(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let inputs = common::generate_probe_inputs(net, interface);
|
||||
let start = Instant::now();
|
||||
|
||||
let futures = inputs.into_iter().map(|input| client.probe(input));
|
||||
let outcomes = futures::future::join_all(futures).await;
|
||||
let scan_duration = start.elapsed();
|
||||
|
||||
let occupied = outcomes
|
||||
.into_iter()
|
||||
.filter_map(|outcome| outcome.ok())
|
||||
.filter(|outcome| outcome.status == ProbeStatus::Occupied);
|
||||
|
||||
let mut devices = Vec::new();
|
||||
for outcome in occupied {
|
||||
devices.push(Device {
|
||||
mac_address: outcome.target_ip.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
devices
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
use async_arp::{ProbeInput, ProbeInputBuilder};
|
||||
use ipnet::Ipv4Net;
|
||||
use pnet::datalink::{self, NetworkInterface};
|
||||
use std::net::IpAddr;
|
||||
|
||||
// Generate the probe inputs for a scan
|
||||
pub(crate) fn generate_probe_inputs(net: Ipv4Net, interface: NetworkInterface) -> Vec<ProbeInput> {
|
||||
net.hosts()
|
||||
.map(|target_ip| {
|
||||
let sender_mac = interface
|
||||
.mac
|
||||
.ok_or("interface does not have mac address")
|
||||
.unwrap();
|
||||
ProbeInputBuilder::new()
|
||||
.with_sender_mac(sender_mac)
|
||||
.with_target_ip(target_ip)
|
||||
.build()
|
||||
.unwrap()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
// Find the desired network interface
|
||||
pub(crate) fn interface_from(interface_name: &str) -> NetworkInterface {
|
||||
datalink::interfaces()
|
||||
.into_iter()
|
||||
.find(|iface| iface.name == interface_name)
|
||||
.ok_or_else(|| format!("interface {} not found", interface_name))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
// Find the network from which we are probing
|
||||
pub(crate) fn net_from(interface: &NetworkInterface) -> Option<Ipv4Net> {
|
||||
let net = interface
|
||||
.ips
|
||||
.iter()
|
||||
.filter(|net| net.is_ipv4())
|
||||
.take(1)
|
||||
.next()?;
|
||||
if let IpAddr::V4(ipv4) = net.ip() {
|
||||
Some(Ipv4Net::new(ipv4, net.prefix()).unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user