Skip to content

Commit

Permalink
feat: introduce improved capture device init #22
Browse files Browse the repository at this point in the history
  • Loading branch information
SkuldNorniern committed Jan 8, 2024
1 parent d0f4f03 commit 9ed0479
Showing 1 changed file with 83 additions and 0 deletions.
83 changes: 83 additions & 0 deletions src/net/capture.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use pcap::{Capture, Active, Device,Error as PcapError,Address};
use std::time::Instant;

#[derive(Debug)]
pub enum CaptureError {
Cap(PcapError),
Other(String),
DeviceNotFound(String),
InitializationError(String),
InvalidDeviceIndex(String),
}

impl From<pcap::Error> for CaptureError {
fn from(err: PcapError) -> Self {
CaptureError::Cap(err)
}
}

impl From<String> for CaptureError {
fn from(err: String) -> Self {
CaptureError::Other(err)
}
}

pub struct CaptureDevice{
pub name: String,
pub desc: String,
pub address: Vec<Address>,
pub capture: Capture<Active>,
}

impl CaptureDevice{
pub fn new(device: Device) -> Result<CaptureDevice, CaptureError> {
let capture = initialize_capture(device.clone())?;

Ok(CaptureDevice {
name: device.name,
desc: device.desc.as_deref().unwrap_or("").to_string(),
address: device.addresses,
capture,
})
}
}
pub fn list_devices() -> Result<Vec<Device>, CaptureError> {
Ok(Device::list().map_err(CaptureError::Cap)?)
}
pub fn find_device(identifier: &str) -> Result<Device, CaptureError> {
let start = Instant::now();
println!("Requested Device: {}", identifier);

let devices = list_devices()?;

if let Ok(index) = identifier.parse::<usize>() {
if let Some(device) = devices.get(index) {
let duration = start.elapsed();
println!("Device {} captured in {:?}", device.name, duration);
return Ok(device.clone());
} else {
return Err(CaptureError::InvalidDeviceIndex(identifier.to_string()));
}
}

for device in devices {
if device.name == identifier {
let duration = start.elapsed();
println!("{} device captured in {:?}", identifier, duration);
return Ok(device);
}
}

Err(CaptureError::DeviceNotFound(identifier.to_string()))
}

fn initialize_capture(device: Device) -> Result<Capture<Active>, CaptureError> {
Capture::from_device(device)
.map_err(CaptureError::Cap)?
.promisc(true)
.snaplen(1024)
.timeout(60000)
.immediate_mode(true)
.open()
.map_err(|_| CaptureError::InitializationError("Capture initialization error".into()))
}

0 comments on commit 9ed0479

Please sign in to comment.