pako_tools/
context.rs

1use std::convert::TryFrom;
2
3use pcap_parser::*;
4
5use crate::duration::Duration;
6
7/// Block parsing context
8#[derive(Clone, Default)]
9pub struct ParseBlockContext {
10    /// Index of current block in the pcap file
11    pub block_index: usize,
12}
13
14/// pcap parsing context
15#[derive(Clone, Default)]
16pub struct ParseContext {
17    /// Timestamp of first packet seen
18    pub first_packet_ts: Duration,
19    /// Relative timestamp of current packet
20    pub rel_ts: Duration,
21    /// Index of current packet in pcap file
22    pub pcap_index: usize,
23}
24
25/// Information related to a network interface used for capture
26#[derive(Clone)]
27pub struct InterfaceInfo {
28    /// The `Linktype` used for data format
29    pub link_type: Linktype,
30    /// Time resolution
31    pub if_tsresol: u8,
32    /// Time resolution unit
33    pub ts_unit: u64,
34    /// Time offset
35    pub if_tsoffset: u64,
36    /// Maximum number of octets captured from each packet.
37    pub snaplen: u32,
38}
39
40impl Default for InterfaceInfo {
41    fn default() -> Self {
42        InterfaceInfo {
43            link_type: Linktype(0),
44            if_tsresol: 0,
45            ts_unit: 0,
46            if_tsoffset: 0,
47            snaplen: 0,
48        }
49    }
50}
51pub fn pcapng_build_interface<'a>(idb: &'a InterfaceDescriptionBlock<'a>) -> InterfaceInfo {
52    let link_type = idb.linktype;
53    // extract if_tsoffset and if_tsresol
54    let mut if_tsresol: u8 = 6;
55    let mut ts_unit: u64 = 1_000_000;
56    let mut if_tsoffset: u64 = 0;
57    for opt in idb.options.iter() {
58        match opt.code {
59            OptionCode::IfTsresol => {
60                if !opt.value.is_empty() {
61                    if_tsresol = opt.value[0];
62                    if let Some(resol) = pcap_parser::build_ts_resolution(if_tsresol) {
63                        ts_unit = resol;
64                    }
65                }
66            }
67            OptionCode::IfTsoffset => {
68                if opt.value.len() >= 8 {
69                    let int_bytes = <[u8; 8]>::try_from(opt.value).expect("Convert bytes to u64");
70                    if_tsoffset = u64::from_le_bytes(int_bytes) /* LittleEndian::read_u64(opt.value) */;
71                }
72            }
73            _ => (),
74        }
75    }
76    InterfaceInfo {
77        link_type,
78        if_tsresol,
79        ts_unit,
80        if_tsoffset,
81        snaplen: idb.snaplen,
82    }
83}
84
85// pub fn pcapng_build_packet<'a>(
86//     if_info: &InterfaceInfo,
87//     block: Block<'a>,
88// ) -> Option<Packet<'a>> {
89//     pcapng::packet_of_block(block, if_info.if_tsoffset, if_info.if_tsresol)
90// }