pcap/
packet.rs

1use std::{fmt, ops::Deref};
2
3/// Represents a packet returned from pcap.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub 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
13impl<'a> Packet<'a> {
14    #[doc(hidden)]
15    pub fn new(header: &'a PacketHeader, data: &'a [u8]) -> Packet<'a> {
16        Packet { header, data }
17    }
18}
19
20impl Deref for Packet<'_> {
21    type Target = [u8];
22
23    fn deref(&self) -> &[u8] {
24        self.data
25    }
26}
27
28#[repr(C)]
29#[derive(Copy, Clone)]
30/// Represents a packet header provided by pcap, including the timeval, caplen and len.
31pub 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
42impl fmt::Debug for PacketHeader {
43    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44        write!(
45            f,
46            "PacketHeader {{ ts: {}.{:06}, caplen: {}, len: {} }}",
47            self.ts.tv_sec, self.ts.tv_usec, self.caplen, self.len
48        )
49    }
50}
51
52impl PartialEq for PacketHeader {
53    fn eq(&self, rhs: &PacketHeader) -> bool {
54        self.ts.tv_sec == rhs.ts.tv_sec
55            && self.ts.tv_usec == rhs.ts.tv_usec
56            && self.caplen == rhs.caplen
57            && self.len == rhs.len
58    }
59}
60
61impl Eq for PacketHeader {}
62
63#[cfg(test)]
64mod 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}