1
use std::ptr::NonNull;
2

            
3
use crate::{
4
    capture::{Capture, Dead},
5
    linktype::Linktype,
6
    raw, Error,
7
};
8

            
9
#[cfg(libpcap_1_5_0)]
10
use crate::capture::Precision;
11

            
12
impl Capture<Dead> {
13
    /// Creates a "fake" capture handle for the given link type.
14
26
    pub fn dead(linktype: Linktype) -> Result<Capture<Dead>, Error> {
15
26
        let handle = unsafe { raw::pcap_open_dead(linktype.0, 65535) };
16
26
        Ok(Capture::from(
17
26
            NonNull::<raw::pcap_t>::new(handle).ok_or(Error::InsufficientMemory)?,
18
        ))
19
26
    }
20

            
21
    /// Creates a "fake" capture handle for the given link type and timestamp precision.
22
    #[cfg(libpcap_1_5_0)]
23
2
    pub fn dead_with_precision(
24
2
        linktype: Linktype,
25
2
        precision: Precision,
26
2
    ) -> Result<Capture<Dead>, Error> {
27
2
        let handle = unsafe {
28
2
            raw::pcap_open_dead_with_tstamp_precision(linktype.0, 65535, precision as u32)
29
2
        };
30
2
        Ok(Capture::from(
31
2
            NonNull::<raw::pcap_t>::new(handle).ok_or(Error::InsufficientMemory)?,
32
        ))
33
2
    }
34
}
35

            
36
#[cfg(test)]
37
mod tests {
38
    #[cfg(libpcap_1_5_0)]
39
    use mockall::predicate;
40

            
41
    use crate::raw::testmod::{as_pcap_t, RAWMTX};
42

            
43
    use super::*;
44

            
45
    #[test]
46
    fn test_dead() {
47
        let _m = RAWMTX.lock();
48

            
49
        let mut dummy: isize = 777;
50
        let pcap = as_pcap_t(&mut dummy);
51

            
52
        let ctx = raw::pcap_open_dead_context();
53
        ctx.expect().return_once_st(move |_, _| pcap);
54

            
55
        let ctx = raw::pcap_close_context();
56
        ctx.expect()
57
            .withf_st(move |ptr| *ptr == pcap)
58
            .return_once(|_| {});
59

            
60
        let result = Capture::dead(Linktype::ETHERNET);
61
        assert!(result.is_ok());
62
    }
63

            
64
    #[test]
65
    #[cfg(libpcap_1_5_0)]
66
    fn test_dead_with_precision() {
67
        let _m = RAWMTX.lock();
68

            
69
        let mut dummy: isize = 777;
70
        let pcap = as_pcap_t(&mut dummy);
71

            
72
        let ctx = raw::pcap_open_dead_with_tstamp_precision_context();
73
        ctx.expect()
74
            .with(predicate::always(), predicate::always(), predicate::eq(1))
75
            .return_once_st(move |_, _, _| pcap);
76

            
77
        let ctx = raw::pcap_close_context();
78
        ctx.expect()
79
            .withf_st(move |ptr| *ptr == pcap)
80
            .return_once(|_| {});
81

            
82
        let result = Capture::dead_with_precision(Linktype::ETHERNET, Precision::Nano);
83
        assert!(result.is_ok());
84
    }
85
}