pcap_parser/pcap/
frame.rs

1use nom::bytes::streaming::take;
2use nom::IResult;
3
4use crate::utils::array_ref4;
5use crate::PcapError;
6
7/// Container for network data in legacy Pcap files
8#[derive(Debug)]
9pub struct LegacyPcapBlock<'a> {
10    pub ts_sec: u32,
11    pub ts_usec: u32,
12    pub caplen: u32,
13    pub origlen: u32,
14    pub data: &'a [u8],
15}
16
17/// Read a PCAP record header and data
18///
19/// Each PCAP record starts with a small header, and is followed by packet data.
20/// The packet data format depends on the LinkType.
21pub fn parse_pcap_frame(i: &[u8]) -> IResult<&[u8], LegacyPcapBlock<'_>, PcapError<&[u8]>> {
22    if i.len() < 16 {
23        return Err(nom::Err::Incomplete(nom::Needed::new(16 - i.len())));
24    }
25    let ts_sec = u32::from_le_bytes(*array_ref4(i, 0));
26    let ts_usec = u32::from_le_bytes(*array_ref4(i, 4));
27    let caplen = u32::from_le_bytes(*array_ref4(i, 8));
28    let origlen = u32::from_le_bytes(*array_ref4(i, 12));
29    let (i, data) = take(caplen as usize)(&i[16..])?;
30    let block = LegacyPcapBlock {
31        ts_sec,
32        ts_usec,
33        caplen,
34        origlen,
35        data,
36    };
37    Ok((i, block))
38}
39
40/// Read a PCAP record header and data (big-endian)
41///
42/// Each PCAP record starts with a small header, and is followed by packet data.
43/// The packet data format depends on the LinkType.
44pub fn parse_pcap_frame_be(i: &[u8]) -> IResult<&[u8], LegacyPcapBlock<'_>, PcapError<&[u8]>> {
45    if i.len() < 16 {
46        return Err(nom::Err::Incomplete(nom::Needed::new(16 - i.len())));
47    }
48    let ts_sec = u32::from_be_bytes(*array_ref4(i, 0));
49    let ts_usec = u32::from_be_bytes(*array_ref4(i, 4));
50    let caplen = u32::from_be_bytes(*array_ref4(i, 8));
51    let origlen = u32::from_be_bytes(*array_ref4(i, 12));
52    let (i, data) = take(caplen as usize)(&i[16..])?;
53    let block = LegacyPcapBlock {
54        ts_sec,
55        ts_usec,
56        caplen,
57        origlen,
58        data,
59    };
60    Ok((i, block))
61}
62
63/// Read a PCAP record header and data ("modified" pcap format)
64///
65/// Each PCAP record starts with a small header, and is followed by packet data.
66/// The packet data format depends on the LinkType.
67pub fn parse_pcap_frame_modified(
68    i: &[u8],
69) -> IResult<&[u8], LegacyPcapBlock<'_>, PcapError<&[u8]>> {
70    if i.len() < 24 {
71        return Err(nom::Err::Incomplete(nom::Needed::new(24 - i.len())));
72    }
73    let ts_sec = u32::from_le_bytes(*array_ref4(i, 0));
74    let ts_usec = u32::from_le_bytes(*array_ref4(i, 4));
75    let caplen = u32::from_le_bytes(*array_ref4(i, 8));
76    let origlen = u32::from_le_bytes(*array_ref4(i, 12));
77    let (i, data) = take(caplen as usize)(&i[24..])?;
78    let block = LegacyPcapBlock {
79        ts_sec,
80        ts_usec,
81        caplen,
82        origlen,
83        data,
84    };
85    Ok((i, block))
86}