1
use std::{fmt, ops::Deref};
2

            
3
/// Represents a packet returned from pcap.
4
#[derive(Debug, Clone, PartialEq, Eq)]
5
pub struct Packet<'a> {
6
    /// The packet header provided by pcap, including the timeval, captured length, and packet
7
    /// length
8
    pub header: &'a PacketHeader,
9
    /// The captured packet data
10
    pub data: &'a [u8],
11
}
12

            
13
impl<'a> Packet<'a> {
14
    #[doc(hidden)]
15
1242
    pub fn new(header: &'a PacketHeader, data: &'a [u8]) -> Packet<'a> {
16
1242
        Packet { header, data }
17
1242
    }
18
}
19

            
20
impl<'b> Deref for Packet<'b> {
21
    type Target = [u8];
22

            
23
6
    fn deref(&self) -> &[u8] {
24
6
        self.data
25
6
    }
26
}
27

            
28
#[repr(C)]
29
#[derive(Copy, Clone)]
30
/// Represents a packet header provided by pcap, including the timeval, caplen and len.
31
pub struct PacketHeader {
32
    /// The time when the packet was captured
33
    pub ts: libc::timeval,
34
    /// The number of bytes of the packet that are available from the capture
35
    pub caplen: u32,
36
    /// The length of the packet, in bytes (which might be more than the number of bytes available
37
    /// from the capture, if the length of the packet is larger than the maximum number of bytes to
38
    /// capture)
39
    pub len: u32,
40
}
41

            
42
impl fmt::Debug for PacketHeader {
43
2
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44
2
        write!(
45
2
            f,
46
2
            "PacketHeader {{ ts: {}.{:06}, caplen: {}, len: {} }}",
47
2
            self.ts.tv_sec, self.ts.tv_usec, self.caplen, self.len
48
2
        )
49
2
    }
50
}
51

            
52
impl PartialEq for PacketHeader {
53
414
    fn eq(&self, rhs: &PacketHeader) -> bool {
54
414
        self.ts.tv_sec == rhs.ts.tv_sec
55
414
            && self.ts.tv_usec == rhs.ts.tv_usec
56
414
            && self.caplen == rhs.caplen
57
414
            && self.len == rhs.len
58
414
    }
59
}
60

            
61
impl Eq for PacketHeader {}
62

            
63
#[cfg(test)]
64
mod tests {
65
    use crate::raw;
66

            
67
    use super::*;
68

            
69
    static HEADER: PacketHeader = PacketHeader {
70
        ts: libc::timeval {
71
            tv_sec: 5,
72
            tv_usec: 50,
73
        },
74
        caplen: 5,
75
        len: 9,
76
    };
77

            
78
    #[test]
79
    fn test_packet_header_size() {
80
        use std::mem::size_of;
81
        assert_eq!(size_of::<PacketHeader>(), size_of::<raw::pcap_pkthdr>());
82
    }
83

            
84
    #[test]
85
    fn test_packet_header_clone() {
86
        // For code coverag purposes.
87
        #[allow(clippy::clone_on_copy)]
88
        let header_clone = HEADER.clone();
89
        assert_eq!(header_clone, HEADER);
90
    }
91

            
92
    #[test]
93
    fn test_packet_header_display() {
94
        assert!(!format!("{:?}", HEADER).is_empty());
95
    }
96
}