packet_strata/
metadata.rs

1use crate::timestamp::Timestamp;
2use pcap_parser::{EnhancedPacketBlock, LegacyPcapBlock, SimplePacketBlock};
3use std::cmp::min;
4
5pub trait PacketMetadata {
6    fn caplen(&self) -> u32;
7    fn origlen(&self) -> u32;
8    fn data(&self) -> &[u8];
9    fn timestamp(&self) -> Timestamp;
10}
11
12impl<'a> PacketMetadata for LegacyPcapBlock<'a> {
13    #[inline]
14    fn timestamp(&self) -> Timestamp {
15        Timestamp((self.ts_sec as u64) * 1_000_000_000 + self.ts_usec as u64 * 1000)
16    }
17
18    #[inline]
19    fn caplen(&self) -> u32 {
20        self.caplen
21    }
22
23    #[inline]
24    fn origlen(&self) -> u32 {
25        self.origlen
26    }
27
28    #[inline]
29    fn data(&self) -> &[u8] {
30        self.data
31    }
32}
33
34impl<'a> PacketMetadata for EnhancedPacketBlock<'a> {
35    #[inline]
36    fn timestamp(&self) -> Timestamp {
37        let raw_ts = ((self.ts_high as u64) << 32) | (self.ts_low as u64);
38        let maybe_ns = raw_ts / 1_000_000_000;
39
40        // Heuristic Thresholds:
41        // Lower: 100_000_000 (Year 1973).
42        //        Safe because modern microsecond timestamps / 10^9 result in ~1.7 million,
43        //        which is well below this 100 million threshold.
44        // Upper: 4_300_000_000 (Year 2106).
45        //        Prevents u32 overflow.
46
47        if (100_000_000..=4_000_000_000).contains(&maybe_ns) {
48            Timestamp(raw_ts)
49        } else {
50            Timestamp(raw_ts * 1000)
51        }
52    }
53
54    #[inline]
55    fn caplen(&self) -> u32 {
56        self.caplen
57    }
58
59    #[inline]
60    fn origlen(&self) -> u32 {
61        self.origlen
62    }
63
64    #[inline]
65    fn data(&self) -> &[u8] {
66        self.data
67    }
68}
69
70impl<'a> PacketMetadata for SimplePacketBlock<'a> {
71    #[inline]
72    fn timestamp(&self) -> Timestamp {
73        Timestamp(0)
74    }
75
76    #[inline]
77    fn caplen(&self) -> u32 {
78        min(self.origlen, self.data.len() as u32)
79    }
80
81    #[inline]
82    fn origlen(&self) -> u32 {
83        self.origlen
84    }
85
86    #[inline]
87    fn data(&self) -> &[u8] {
88        self.data
89    }
90}