pcap_parser/pcap/
capture.rs1use crate::blocks::{PcapBlock, PcapBlockOwned};
2use crate::capture::Capture;
3use crate::error::PcapError;
4use crate::linktype::Linktype;
5use crate::pcap::{parse_pcap_frame, parse_pcap_header, LegacyPcapBlock, PcapHeader};
6use nom::combinator::complete;
7use nom::multi::many0;
8use nom::{IResult, Needed, Parser as _};
9use std::fmt;
10
11pub struct LegacyPcapSlice<'a> {
35 pub header: PcapHeader,
36 rem: &'a [u8],
38}
39
40impl LegacyPcapSlice<'_> {
41 pub fn from_slice(i: &[u8]) -> Result<LegacyPcapSlice<'_>, nom::Err<PcapError<&[u8]>>> {
42 let (rem, header) = parse_pcap_header(i)?;
43 Ok(LegacyPcapSlice { header, rem })
44 }
45}
46
47impl<'a> Iterator for LegacyPcapSlice<'a> {
50 type Item = Result<PcapBlockOwned<'a>, nom::Err<PcapError<&'a [u8]>>>;
51
52 fn next(&mut self) -> Option<Self::Item> {
53 if self.rem.is_empty() {
54 return None;
55 }
56 let r = parse_pcap_frame(self.rem).map(|(rem, b)| {
57 self.rem = rem;
58 PcapBlockOwned::from(b)
59 });
60 Some(r)
61 }
62}
63
64pub struct PcapCapture<'a> {
66 pub header: PcapHeader,
67
68 pub blocks: Vec<LegacyPcapBlock<'a>>,
69}
70
71impl PcapCapture<'_> {
72 pub fn from_file(i: &[u8]) -> Result<PcapCapture<'_>, PcapError<&[u8]>> {
73 match parse_pcap(i) {
74 Ok((_, pcap)) => Ok(pcap),
75 Err(nom::Err::Error(e)) | Err(nom::Err::Failure(e)) => Err(e),
76 Err(nom::Err::Incomplete(Needed::Size(n))) => Err(PcapError::Incomplete(n.into())),
77 Err(nom::Err::Incomplete(Needed::Unknown)) => Err(PcapError::Incomplete(0)),
78 }
79 }
80}
81
82impl fmt::Debug for PcapCapture<'_> {
83 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
84 writeln!(f, "PcapCapture:")
85 }
86}
87
88pub struct LegacyPcapIterator<'a> {
90 cap: &'a PcapCapture<'a>,
91 idx: usize,
92}
93
94impl<'a> Iterator for LegacyPcapIterator<'a> {
95 type Item = PcapBlock<'a>;
96
97 fn next(&mut self) -> Option<PcapBlock<'a>> {
98 self.cap.blocks.get(self.idx).map(|b| {
99 self.idx += 1;
100 PcapBlock::from(b)
101 })
102 }
103}
104
105impl Capture for PcapCapture<'_> {
106 fn get_datalink(&self) -> Linktype {
107 self.header.network
108 }
109
110 fn get_snaplen(&self) -> u32 {
111 self.header.snaplen
112 }
113
114 fn iter<'b>(&'b self) -> Box<dyn Iterator<Item = PcapBlock<'b>> + 'b> {
115 Box::new(LegacyPcapIterator { cap: self, idx: 0 })
116 }
117}
118
119pub fn parse_pcap(i: &[u8]) -> IResult<&[u8], PcapCapture<'_>, PcapError<&[u8]>> {
123 let (i, header) = parse_pcap_header(i)?;
124 let (i, blocks) = many0(complete(parse_pcap_frame)).parse(i)?;
125 Ok((i, PcapCapture { header, blocks }))
126}