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}