libnsave/
capture.rs

1use crate::configure::*;
2use crate::packet::*;
3use pcap::Activated;
4use pcap::Capture as PcapCap;
5use pcap::Device;
6use std::sync::Arc;
7
8#[derive(Debug)]
9pub enum CaptureError {
10    CapErr,
11}
12
13pub struct Capture {
14    cap: PcapCap<dyn Activated>,
15}
16
17impl Capture {
18    pub fn init_capture(configure: &'static Configure) -> Result<Capture, CaptureError> {
19        if configure.pcap_file.is_some() {
20            return Ok(Self::init_from_file(configure).unwrap());
21        }
22        Self::init_interface(configure)
23    }
24
25    fn init_from_file(configure: &'static Configure) -> Result<Capture, CaptureError> {
26        let mut cap = PcapCap::from_file(configure.pcap_file.as_ref().unwrap()).unwrap();
27        if configure.filter.is_some() {
28            let res = cap.filter(configure.filter.as_ref().unwrap(), true);
29            if res.is_err() {
30                println!("capture filter error {:?}", res);
31                return Err(CaptureError::CapErr);
32            }
33        }
34
35        let capture = Capture { cap: cap.into() };
36        Ok(capture)
37    }
38
39    fn init_interface(configure: &'static Configure) -> Result<Capture, CaptureError> {
40        let device = Self::get_device(Some(&configure.interface))?;
41        let mut cap = pcap::Capture::from_device(device)
42            .unwrap()
43            .promisc(true)
44            .snaplen(configure.pkt_len)
45            .immediate_mode(true)
46            .open()
47            .unwrap();
48        if configure.filter.is_some() {
49            let res = cap.filter(configure.filter.as_ref().unwrap(), true);
50            if res.is_err() {
51                println!("capture filter error {:?}", res);
52                return Err(CaptureError::CapErr);
53            }
54        }
55
56        let capture = Capture { cap: cap.into() };
57        Ok(capture)
58    }
59
60    fn get_device(interface: Option<&String>) -> Result<Device, CaptureError> {
61        if let Some(name) = interface {
62            for dev in pcap::Device::list().expect("device lookup failed") {
63                if dev.name == *name {
64                    return Ok(dev);
65                }
66            }
67            Err(CaptureError::CapErr)
68        } else {
69            let dev = pcap::Device::lookup()
70                .expect("device lookup failed")
71                .expect("no device available");
72            Ok(dev)
73        }
74    }
75
76    pub fn next_packet(&mut self, timestamp: u128) -> Result<Arc<Packet>, CaptureError> {
77        match self.cap.next_packet() {
78            Ok(pcap_pkt) => Ok(Arc::new(Packet::new(pcap_pkt.data.to_vec(), timestamp))),
79            Err(_) => Err(CaptureError::CapErr),
80        }
81    }
82}