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}