Skip to main content

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
39        // Try to determine if timestamp is microseconds or nanoseconds.
40        // Modern timestamps (e.g. 2024) in microseconds are ~1.7e15
41        // In nanoseconds they are ~1.7e18
42        // We use a threshold of 1e16 to distinguish.
43
44        if raw_ts < 10_000_000_000_000_000 {
45            // microseconds, convert to nanoseconds
46            Timestamp(raw_ts * 1000)
47        } else {
48            // nanoseconds
49            Timestamp(raw_ts)
50        }
51    }
52
53    #[inline]
54    fn caplen(&self) -> u32 {
55        self.caplen
56    }
57
58    #[inline]
59    fn origlen(&self) -> u32 {
60        self.origlen
61    }
62
63    #[inline]
64    fn data(&self) -> &[u8] {
65        self.data
66    }
67}
68
69impl<'a> PacketMetadata for SimplePacketBlock<'a> {
70    #[inline]
71    fn timestamp(&self) -> Timestamp {
72        Timestamp(0)
73    }
74
75    #[inline]
76    fn caplen(&self) -> u32 {
77        min(self.origlen, self.data.len() as u32)
78    }
79
80    #[inline]
81    fn origlen(&self) -> u32 {
82        self.origlen
83    }
84
85    #[inline]
86    fn data(&self) -> &[u8] {
87        self.data
88    }
89}