pcap_parser/pcapng/
time.rs1use std::convert::TryFrom;
2
3use super::{OptionCode, PcapNGOption};
4
5pub fn build_ts_resolution(ts_resol: u8) -> Option<u64> {
9 let ts_mode = ts_resol & 0x80;
10 let unit = if ts_mode == 0 {
11 if ts_resol > 19 {
14 return None;
15 }
16 10u64.pow(ts_resol as u32)
17 } else {
18 if ts_resol > 63 {
21 return None;
22 }
23 1 << ((ts_resol & 0x7f) as u64)
24 };
25 Some(unit)
26}
27
28pub fn build_ts(ts_high: u32, ts_low: u32, ts_offset: u64, resolution: u64) -> (u32, u32) {
31 let if_tsoffset = ts_offset;
32 let ts: u64 = ((ts_high as u64) << 32) | (ts_low as u64);
33 let ts_sec = (if_tsoffset + (ts / resolution)) as u32;
34 let ts_fractional = (ts % resolution) as u32;
35 (ts_sec, ts_fractional)
36}
37
38pub fn build_ts_f64(ts_high: u32, ts_low: u32, ts_offset: u64, resolution: u64) -> f64 {
43 let ts: u64 = ((ts_high as u64) << 32) | (ts_low as u64);
44 let ts_sec = (ts_offset + (ts / resolution)) as u32;
45 let ts_fractional = (ts % resolution) as u32;
46 ts_sec as f64 + ((ts_fractional as f64) / (resolution as f64))
48}
49
50pub(crate) fn if_extract_tsoffset_and_tsresol(options: &[PcapNGOption]) -> (u8, i64) {
51 let mut if_tsresol: u8 = 6;
52 let mut if_tsoffset: i64 = 0;
53 for opt in options {
54 match opt.code {
55 OptionCode::IfTsresol => {
56 if !opt.value.is_empty() {
57 if_tsresol = opt.value[0];
58 }
59 }
60 OptionCode::IfTsoffset => {
61 if opt.value.len() >= 8 {
62 let int_bytes =
63 <[u8; 8]>::try_from(&opt.value[..8]).expect("Convert bytes to i64");
64 if_tsoffset = i64::from_le_bytes(int_bytes);
65 }
66 }
67 _ => (),
68 }
69 }
70 (if_tsresol, if_tsoffset)
71}
72
73#[cfg(test)]
74mod tests {
75 use hex_literal::hex;
76
77 use super::*;
78
79 #[test]
80 fn decode_ts() {
81 const INPUT_HIGH: [u8; 4] = hex!("97 c3 04 00");
85 const INPUT_LOW: [u8; 4] = hex!("aa 47 ca 64");
86 let ts_high = u32::from_le_bytes(INPUT_HIGH);
87 let ts_low = u32::from_le_bytes(INPUT_LOW);
88 let ts_offset = 0;
89 let resolution = build_ts_resolution(6).unwrap();
90 let (ts_sec, ts_usec) = build_ts(ts_high, ts_low, ts_offset, resolution);
93 eprintln!("{ts_sec}:{ts_usec}");
94
95 const EXPECTED_TS_SEC: u32 = 1340954905;
96 const EXPECTED_TS_USEC: u32 = 298858;
97 assert_eq!(ts_sec, EXPECTED_TS_SEC);
102 assert_eq!(ts_usec, EXPECTED_TS_USEC);
103 }
104}