1use std::io::Read;
2
3#[cfg(feature = "tokio")]
4use tokio::io::AsyncRead;
5
6use super::{PcapParser, RawPcapPacket};
7use crate::pcap::{PcapHeader, PcapPacket};
8use crate::read_buffer::ReadBuffer;
9use crate::{DataLink, Packet, errors::*};
10
11#[derive(Debug)]
32pub struct PcapReader<R> {
33 parser: PcapParser,
34 reader: ReadBuffer<R>,
35}
36
37impl<R> From<(PcapParser, ReadBuffer<R>)> for PcapReader<R> {
38 fn from(value: (PcapParser, ReadBuffer<R>)) -> Self {
39 Self { parser: value.0, reader: value.1 }
40 }
41}
42
43impl<'a> From<(PcapPacket<'a>, DataLink)> for Packet<'a> {
44 fn from(value: (PcapPacket<'a>, DataLink)) -> Self {
45 Self {
46 timestamp: Some(value.0.timestamp),
47 orig_len: value.0.orig_len,
48 data: value.0.data,
49 datalink: value.1,
50 }
51 }
52}
53
54impl<R> PcapReader<R> {
55 pub fn header(&self) -> PcapHeader {
57 self.parser.header()
58 }
59
60 pub fn datalink(&self) -> DataLink {
62 self.parser.header().datalink
63 }
64}
65
66impl<R: Read> PcapReader<R> {
67 pub fn new(reader: R) -> Result<PcapReader<R>, PcapError> {
78 let mut reader = ReadBuffer::new(reader);
79 let parser = reader.parse_with(PcapParser::new)?;
80
81 Ok(PcapReader { parser, reader })
82 }
83
84 pub fn into_reader(self) -> R {
86 self.reader.into_inner()
87 }
88
89 pub fn next_packet(&mut self) -> Option<Result<PcapPacket<'_>, PcapError>> {
91 match self.reader.has_data_left() {
92 Ok(has_data) => {
93 if has_data {
94 Some(self.reader.parse_with(|src| self.parser.next_packet(src)))
95 } else {
96 None
97 }
98 },
99 Err(e) => Some(Err(PcapError::IoError(e))),
100 }
101 }
102
103 pub fn next_raw_packet(&mut self) -> Option<Result<RawPcapPacket<'_>, PcapError>> {
105 match self.reader.has_data_left() {
106 Ok(has_data) => {
107 if has_data {
108 Some(self.reader.parse_with(|src| self.parser.next_raw_packet(src)))
109 } else {
110 None
111 }
112 },
113 Err(e) => Some(Err(PcapError::IoError(e))),
114 }
115 }
116}
117
118impl<R> AsRef<R> for PcapReader<R> {
119 fn as_ref(&self) -> &R {
120 self.reader.as_ref()
121 }
122}
123
124impl<R> AsMut<R> for PcapReader<R> {
125 fn as_mut(&mut self) -> &mut R {
126 self.reader.as_mut()
127 }
128}
129
130#[cfg(feature = "tokio")]
131impl<R: AsyncRead + Unpin> PcapReader<R> {
132 pub async fn async_new(reader: R) -> Result<PcapReader<R>, PcapError> {
143 let mut reader = ReadBuffer::new(reader);
144 let parser = reader.async_parse_with(PcapParser::async_new).await?;
145
146 Ok(PcapReader { parser, reader })
147 }
148
149 pub fn into_async_reader(self) -> R {
151 self.reader.into_inner()
152 }
153
154 pub async fn async_next_packet(&mut self) -> Option<Result<PcapPacket<'_>, PcapError>> {
156 match self.reader.async_has_data_left().await {
157 Ok(has_data) => {
158 if has_data {
159 Some(self.reader.async_parse_with(|src| self.parser.async_next_packet(src)).await)
160 } else {
161 None
162 }
163 },
164 Err(e) => Some(Err(PcapError::IoError(e))),
165 }
166 }
167
168 pub async fn async_next_raw_packet(&mut self) -> Option<Result<RawPcapPacket<'_>, PcapError>> {
170 match self.reader.async_has_data_left().await {
171 Ok(has_data) => {
172 if has_data {
173 Some(self.reader.async_parse_with(|src| self.parser.async_next_raw_packet(src)).await)
174 } else {
175 None
176 }
177 },
178 Err(e) => Some(Err(PcapError::IoError(e))),
179 }
180 }
181}