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(i: &[u8]) -> IResult<&[u8], LegacyPcapBlock, PcapError<&[u8]>> {
68    if i.len() < 24 {
69        return Err(nom::Err::Incomplete(nom::Needed::new(24 - i.len())));
70    }
71    let ts_sec = u32::from_le_bytes(*array_ref4(i, 0));
72    let ts_usec = u32::from_le_bytes(*array_ref4(i, 4));
73    let caplen = u32::from_le_bytes(*array_ref4(i, 8));
74    let origlen = u32::from_le_bytes(*array_ref4(i, 12));
75    let (i, data) = take(caplen as usize)(&i[24..])?;
76    let block = LegacyPcapBlock {
77        ts_sec,
78        ts_usec,
79        caplen,
80        origlen,
81        data,
82    };
83    Ok((i, block))
84}