Struct pcap_parser::PcapNGReader
source · [−]pub struct PcapNGReader<R> where
R: Read, { /* private fields */ }
Expand description
Parsing iterator over pcap-ng data (streaming version)
Pcap-NG Reader
This reader is a streaming parser based on a circular buffer, which means memory
usage is constant, and that it can be used to parse huge files or infinite streams.
It creates an abstraction over any input providing the Read
trait, and takes care
of managing the circular buffer to provide an iterator-like interface.
The first call to next
should return the a Section Header Block (SHB), marking the start of a
new section.
For each section, calls to next
will return blocks, some of them containing data (SPB, EPB),
and others containing information (IDB, NRB, etc.).
Some information must be stored (for ex. the data link type from the IDB) to be able to parse following block contents. Usually, a list of interfaces must be stored, with the data link type and capture length, for each section. These values are used when parsing Enhanced Packet Blocks (which gives an interface ID - the index, starting from 0) and Simple Packet Blocks (which assume an interface index of 0).
The size of the circular buffer has to be big enough for at least one complete block. Using a larger value (at least 65k) is advised to avoid frequent reads and buffer shifts.
There are precautions to take when reading multiple blocks before consuming data. See PcapReaderIterator for details.
Example
use pcap_parser::*;
use pcap_parser::traits::PcapReaderIterator;
use std::fs::File;
let file = File::open(path).unwrap();
let mut num_blocks = 0;
let mut reader = PcapNGReader::new(65536, file).expect("PcapNGReader");
let mut if_linktypes = Vec::new();
loop {
match reader.next() {
Ok((offset, block)) => {
println!("got new block");
num_blocks += 1;
match block {
PcapBlockOwned::NG(Block::SectionHeader(ref _shb)) => {
// starting a new section, clear known interfaces
if_linktypes = Vec::new();
},
PcapBlockOwned::NG(Block::InterfaceDescription(ref idb)) => {
if_linktypes.push(idb.linktype);
},
PcapBlockOwned::NG(Block::EnhancedPacket(ref epb)) => {
assert!((epb.if_id as usize) < if_linktypes.len());
let linktype = if_linktypes[epb.if_id as usize];
#[cfg(feature="data")]
let res = pcap_parser::data::get_packetdata(epb.data, linktype, epb.caplen as usize);
},
PcapBlockOwned::NG(Block::SimplePacket(ref spb)) => {
assert!(if_linktypes.len() > 0);
let linktype = if_linktypes[0];
let blen = (spb.block_len1 - 16) as usize;
#[cfg(feature="data")]
let res = pcap_parser::data::get_packetdata(spb.data, linktype, blen);
},
PcapBlockOwned::NG(_) => {
// can be statistics (ISB), name resolution (NRB), etc.
eprintln!("unsupported block");
},
PcapBlockOwned::Legacy(_)
| PcapBlockOwned::LegacyHeader(_) => unreachable!(),
}
reader.consume(offset);
},
Err(PcapError::Eof) => break,
Err(PcapError::Incomplete) => {
eprintln!("Could not read complete data block.");
eprintln!("Hint: the reader buffer size may be too small, or the input file nay be truncated.");
break;
},
Err(e) => panic!("error while reading: {:?}", e),
}
}
println!("num_blocks: {}", num_blocks);
Implementations
sourceimpl<R> PcapNGReader<R> where
R: Read,
impl<R> PcapNGReader<R> where
R: Read,
sourcepub fn new(
capacity: usize,
reader: R
) -> Result<PcapNGReader<R>, PcapError<&'static [u8]>>
pub fn new(
capacity: usize,
reader: R
) -> Result<PcapNGReader<R>, PcapError<&'static [u8]>>
Creates a new PcapNGReader<R>
with the provided buffer capacity.
sourcepub fn from_buffer(
buffer: Buffer,
reader: R
) -> Result<PcapNGReader<R>, PcapError<&'static [u8]>>
pub fn from_buffer(
buffer: Buffer,
reader: R
) -> Result<PcapNGReader<R>, PcapError<&'static [u8]>>
Creates a new PcapNGReader<R>
using the provided Buffer
.
Trait Implementations
sourceimpl<R> PcapReaderIterator for PcapNGReader<R> where
R: Read,
impl<R> PcapReaderIterator for PcapNGReader<R> where
R: Read,
sourcefn next(&mut self) -> Result<(usize, PcapBlockOwned<'_>), PcapError<&[u8]>>
fn next(&mut self) -> Result<(usize, PcapBlockOwned<'_>), PcapError<&[u8]>>
Get the next pcap block, if possible. Returns the number of bytes read and the block. Read more
sourcefn consume_noshift(&mut self, offset: usize)
fn consume_noshift(&mut self, offset: usize)
Consume date, but do not change the buffer. Blocks already read are still valid.
sourcefn refill(&mut self) -> Result<(), PcapError<&[u8]>>
fn refill(&mut self) -> Result<(), PcapError<&[u8]>>
Refill the internal buffer, shifting it if necessary. Read more
sourcefn position(&self) -> usize
fn position(&self) -> usize
Get the position in the internal buffer. Can be used to determine if refill
is required.
sourcefn data(&self) -> &[u8]ⓘNotable traits for &'_ [u8]impl<'_> Read for &'_ [u8]impl<'_> Write for &'_ mut [u8]
fn data(&self) -> &[u8]ⓘNotable traits for &'_ [u8]impl<'_> Read for &'_ [u8]impl<'_> Write for &'_ mut [u8]
Returns a slice with all the available data
sourcefn reader_exhausted(&self) -> bool
fn reader_exhausted(&self) -> bool
Returns true if underlying reader is exhausted Read more
Auto Trait Implementations
impl<R> RefUnwindSafe for PcapNGReader<R> where
R: RefUnwindSafe,
impl<R> Send for PcapNGReader<R> where
R: Send,
impl<R> Sync for PcapNGReader<R> where
R: Sync,
impl<R> Unpin for PcapNGReader<R> where
R: Unpin,
impl<R> UnwindSafe for PcapNGReader<R> where
R: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more