1use std::{fmt, ops::Deref};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct Packet<'a> {
6 pub header: &'a PacketHeader,
9 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)]
30pub struct PacketHeader {
32 pub ts: libc::timeval,
34 pub caplen: u32,
36 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 #[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}