pcap/capture/
selectable.rs

1use std::os::unix::io::{AsRawFd, RawFd};
2
3use crate::{
4    capture::{Activated, Capture, State},
5    raw, Error,
6};
7
8/// Newtype [`Capture`] wrapper that exposes `pcap_get_selectable_fd()`.
9pub struct SelectableCapture<T: State + ?Sized> {
10    inner: Capture<T>,
11    fd: RawFd,
12}
13
14impl<T: Activated + ?Sized> SelectableCapture<T> {
15    pub fn new(capture: Capture<T>) -> Result<Self, Error> {
16        let fd = unsafe { raw::pcap_get_selectable_fd(capture.as_ptr()) };
17        if fd == -1 {
18            return Err(Error::InvalidRawFd);
19        }
20        Ok(Self { inner: capture, fd })
21    }
22
23    pub fn get_inner_mut(&mut self) -> &mut Capture<T> {
24        &mut self.inner
25    }
26}
27
28impl<T: Activated + ?Sized> AsRawFd for SelectableCapture<T> {
29    fn as_raw_fd(&self) -> RawFd {
30        self.fd
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use crate::{
37        capture::{testmod::test_capture, Active},
38        raw::testmod::{as_pcap_t, RAWMTX},
39    };
40
41    use super::*;
42
43    #[test]
44    fn test_selectable_capture() {
45        let _m = RAWMTX.lock();
46
47        let mut dummy: isize = 777;
48        let pcap = as_pcap_t(&mut dummy);
49
50        let test_capture = test_capture::<Active>(pcap);
51        let capture = test_capture.capture;
52
53        let ctx = raw::pcap_get_selectable_fd_context();
54        ctx.expect()
55            .withf_st(move |arg1| *arg1 == pcap)
56            .return_once(|_| 5);
57
58        let mut selectable = SelectableCapture::new(capture).unwrap();
59        assert!(!selectable.get_inner_mut().is_nonblock());
60        assert_eq!(selectable.as_raw_fd(), 5);
61    }
62
63    #[test]
64    fn test_selectable_capture_error() {
65        let _m = RAWMTX.lock();
66
67        let mut dummy: isize = 777;
68        let pcap = as_pcap_t(&mut dummy);
69
70        let test_capture = test_capture::<Active>(pcap);
71        let capture = test_capture.capture;
72
73        let ctx = raw::pcap_get_selectable_fd_context();
74        ctx.expect()
75            .withf_st(move |arg1| *arg1 == pcap)
76            .return_once(|_| -1);
77
78        let result = SelectableCapture::new(capture);
79        assert!(result.is_err());
80    }
81}