1use crate::blocks::PcapBlock;
2use crate::error::PcapError;
3use crate::linktype::Linktype;
4use crate::pcap::parse_pcap_header;
5use crate::pcapng::parse_sectionheaderblock;
6use crate::traits::PcapReaderIterator;
7use crate::{LegacyPcapReader, PcapNGReader};
8use circular::Buffer;
9use nom::Needed;
10use std::io::Read;
11
12pub trait Capture {
14 fn get_datalink(&self) -> Linktype;
15
16 fn get_snaplen(&self) -> u32;
17
18 fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = PcapBlock<'a>> + 'a>;
19}
20
21pub fn create_reader<'b, R>(
34 capacity: usize,
35 mut reader: R,
36) -> Result<Box<dyn PcapReaderIterator + Send + 'b>, PcapError<&'static [u8]>>
37where
38 R: Read + Send + 'b,
39{
40 let mut buffer = Buffer::with_capacity(capacity);
41 let sz = reader.read(buffer.space()).or(Err(PcapError::ReadError))?;
42 if sz == 0 {
43 return Err(PcapError::Eof);
44 }
45 buffer.fill(sz);
46 if parse_sectionheaderblock(buffer.data()).is_ok() {
48 return PcapNGReader::from_buffer(buffer, reader)
49 .map(|r| Box::new(r) as Box<dyn PcapReaderIterator + Send>);
50 }
51 match parse_pcap_header(buffer.data()) {
52 Ok(_) => LegacyPcapReader::from_buffer(buffer, reader)
53 .map(|r| Box::new(r) as Box<dyn PcapReaderIterator + Send>),
54 Err(nom::Err::Incomplete(Needed::Size(n))) => Err(PcapError::Incomplete(n.into())),
55 Err(nom::Err::Incomplete(Needed::Unknown)) => Err(PcapError::Incomplete(0)),
56 _ => Err(PcapError::HeaderNotRecognized),
57 }
58}