diff --git a/src/config.rs b/src/config.rs index aa7d2d0..0147399 100644 --- a/src/config.rs +++ b/src/config.rs @@ -5,6 +5,7 @@ pub struct Config { max_packets_read: usize, snaplen: u32, buffer_size: u32, + datalink: Option, bpf: Option, buffer_for: std::time::Duration, blocking: bool, @@ -29,6 +30,15 @@ impl Config { self } + pub fn datalink(&self) -> &Option { + &self.datalink + } + + pub fn with_datalink_type(&mut self, datalink: i32) -> &mut Self { + self.datalink = Some(datalink); + self + } + pub fn buffer_size(&self) -> u32 { self.buffer_size } @@ -69,6 +79,7 @@ impl Config { max_packets_read: usize, snaplen: u32, buffer_size: u32, + datalink: Option, bpf: Option, buffer_for: std::time::Duration, blocking: bool, @@ -77,6 +88,7 @@ impl Config { max_packets_read, snaplen, buffer_size, + datalink, bpf, buffer_for, blocking, @@ -90,6 +102,7 @@ impl Default for Config { max_packets_read: 1000, snaplen: 65535, buffer_size: 16777216, + datalink: None, bpf: None, buffer_for: std::time::Duration::from_millis(100), blocking: false, diff --git a/src/handle.rs b/src/handle.rs index a14ccf7..de45f2f 100644 --- a/src/handle.rs +++ b/src/handle.rs @@ -157,6 +157,23 @@ impl Handle { } } + pub fn set_datalink(&self, datalink: i32) -> Result<&Self, Error> { + if 0 != unsafe { pcap_sys::pcap_set_datalink(self.handle, datalink as _) } { + Err(pcap_util::convert_libpcap_error(self.handle)) + } else { + Ok(self) + } + } + + pub fn get_datalink(&self) -> Result { + let r = unsafe { pcap_sys::pcap_datalink(self.handle) }; + if r < 0 { + Err(pcap_util::convert_libpcap_error(self.handle)) + } else { + Ok(r) + } + } + pub fn compile_bpf(&self, bpf: &str) -> Result { let mut bpf_program = pcap_sys::bpf_program { bf_len: 0, @@ -297,6 +314,7 @@ mod tests { assert!(handle.is_ok()); } + #[test] fn open_dead() { let _ = env_logger::try_init(); @@ -305,6 +323,22 @@ mod tests { assert!(handle.is_ok()); } + + #[test] + fn set_datalink() { + let _ = env_logger::try_init(); + + let handle = Handle::dead(0, 0).unwrap(); + + assert_eq!(handle.get_datalink().unwrap(), 0); + + let r = handle.set_datalink(108); + + assert!(r.is_err()); + + assert!(format!("{:?}", r.err().unwrap()).contains("not one of the DLTs supported")); + } + #[test] fn bpf_compile() { let _ = env_logger::try_init(); diff --git a/src/stream.rs b/src/stream.rs index dba5d8a..18d7a40 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -28,13 +28,16 @@ impl PacketStream { let live_capture = handle.is_live_capture(); if live_capture { - let h = handle + handle .set_snaplen(config.snaplen())? .set_promiscuous()? - .set_buffer_size(config.buffer_size())? - .activate()?; + .set_buffer_size(config.buffer_size())?; + if let Some(datalink) = config.datalink() { + handle.set_datalink(*datalink)?; + } + handle.activate()?; if !config.blocking() { - h.set_non_block()?; + handle.set_non_block()?; } if let Some(bpf) = config.bpf() {