pcap_file/pcap/
reader.rs

1use std::io::Read;
2
3use super::{PcapParser, RawPcapPacket};
4use crate::errors::*;
5use crate::pcap::{PcapHeader, PcapPacket};
6use crate::read_buffer::ReadBuffer;
7
8
9/// Reads a pcap from a reader.
10///
11/// # Example
12///
13/// ```rust,no_run
14/// use std::fs::File;
15///
16/// use pcap_file::pcap::PcapReader;
17///
18/// let file_in = File::open("test.pcap").expect("Error opening file");
19/// let mut pcap_reader = PcapReader::new(file_in).unwrap();
20///
21/// // Read test.pcap
22/// while let Some(pkt) = pcap_reader.next_packet() {
23///     //Check if there is no error
24///     let pkt = pkt.unwrap();
25///
26///     //Do something
27/// }
28/// ```
29#[derive(Debug)]
30pub struct PcapReader<R: Read> {
31    parser: PcapParser,
32    reader: ReadBuffer<R>,
33}
34
35impl<R: Read> PcapReader<R> {
36    /// Creates a new [`PcapReader`] from an existing reader.
37    ///
38    /// This function reads the global pcap header of the file to verify its integrity.
39    ///
40    /// The underlying reader must point to a valid pcap file/stream.
41    ///
42    /// # Errors
43    /// The data stream is not in a valid pcap file format.
44    ///
45    /// The underlying data are not readable.
46    pub fn new(reader: R) -> Result<PcapReader<R>, PcapError> {
47        let mut reader = ReadBuffer::new(reader);
48        let parser = reader.parse_with(PcapParser::new)?;
49
50        Ok(PcapReader { parser, reader })
51    }
52
53    /// Consumes [`Self`], returning the wrapped reader.
54    pub fn into_reader(self) -> R {
55        self.reader.into_inner()
56    }
57
58    /// Returns the next [`PcapPacket`].
59    pub fn next_packet(&mut self) -> Option<Result<PcapPacket, PcapError>> {
60        match self.reader.has_data_left() {
61            Ok(has_data) => {
62                if has_data {
63                    Some(self.reader.parse_with(|src| self.parser.next_packet(src)))
64                }
65                else {
66                    None
67                }
68            },
69            Err(e) => Some(Err(PcapError::IoError(e))),
70        }
71    }
72
73    /// Returns the next [`RawPcapPacket`].
74    pub fn next_raw_packet(&mut self) -> Option<Result<RawPcapPacket, PcapError>> {
75        match self.reader.has_data_left() {
76            Ok(has_data) => {
77                if has_data {
78                    Some(self.reader.parse_with(|src| self.parser.next_raw_packet(src)))
79                }
80                else {
81                    None
82                }
83            },
84            Err(e) => Some(Err(PcapError::IoError(e))),
85        }
86    }
87
88    /// Returns the global header of the pcap.
89    pub fn header(&self) -> PcapHeader {
90        self.parser.header()
91    }
92}