1pub mod mmap;
42
43use crate::error::Error;
44use crate::format::pcap::PcapHeader;
45use crate::format::pcapng as pcapng_mod;
46use crate::format::pcapng::Block;
47
48#[cfg(feature = "std")]
49use std::fs::File;
50#[cfg(feature = "std")]
51use std::io::{Read, Seek, SeekFrom};
52#[cfg(feature = "std")]
53use std::path::Path;
54
55fn read_u32(data: &[u8], offset: usize) -> Result<u32, Error> {
57 if data.len() < offset + 4 {
58 return Err(Error::truncated(offset + 4, data.len()));
59 }
60 Ok(u32::from_le_bytes([
61 data[offset],
62 data[offset + 1],
63 data[offset + 2],
64 data[offset + 3],
65 ]))
66}
67
68fn read_u16(data: &[u8], offset: usize) -> Result<u16, Error> {
70 if data.len() < offset + 2 {
71 return Err(Error::truncated(offset + 2, data.len()));
72 }
73 Ok(u16::from_le_bytes([data[offset], data[offset + 1]]))
74}
75
76#[derive(Debug, Clone)]
78pub struct PacketRef {
79 data: Vec<u8>,
80 timestamp_ns: u64,
81 original_len: u32,
82 captured_len: u32,
83}
84
85impl PacketRef {
86 pub fn new(data: &[u8], timestamp_ns: u64, original_len: u32, captured_len: u32) -> Self {
88 Self {
89 data: data.to_vec(),
90 timestamp_ns,
91 original_len,
92 captured_len,
93 }
94 }
95
96 pub fn data(&self) -> &[u8] {
98 &self.data
99 }
100
101 pub fn timestamp_ns(&self) -> u64 {
103 self.timestamp_ns
104 }
105
106 pub fn captured_len(&self) -> u32 {
108 self.captured_len
109 }
110
111 pub fn original_len(&self) -> u32 {
113 self.original_len
114 }
115
116 pub fn len(&self) -> usize {
118 self.data.len()
119 }
120
121 pub fn is_empty(&self) -> bool {
123 self.data.is_empty()
124 }
125}
126
127pub struct PcapReader<R> {
129 reader: R,
130 header: PcapHeader,
131 is_nano: bool,
132}
133
134impl<R: Read + Seek> PcapReader<R> {
135 pub fn from_reader(reader: R) -> Result<Self, Error> {
137 let mut reader = reader;
138 let mut header_buf = [0u8; 24];
139 reader.read_exact(&mut header_buf)?;
140
141 let (header, _) = PcapHeader::parse(&header_buf)?;
142
143 Ok(Self {
144 reader,
145 header,
146 is_nano: header.is_nano(),
147 })
148 }
149
150 pub fn header(&self) -> PcapHeader {
152 self.header
153 }
154
155 pub fn link_type(&self) -> u32 {
157 self.header.network
158 }
159
160 pub fn next_packet(&mut self) -> Result<Option<PacketRef>, Error> {
162 let mut pkthdr_buf = [0u8; 16];
163 match self.reader.read_exact(&mut pkthdr_buf) {
164 Ok(()) => {}
165 Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => return Ok(None),
166 Err(e) => return Err(Error::Io(e)),
167 }
168
169 let ts_sec = read_u32(&pkthdr_buf, 0)?;
170 let ts_usec = read_u32(&pkthdr_buf, 4)?;
171 let incl_len = read_u32(&pkthdr_buf, 8)?;
172 let orig_len = read_u32(&pkthdr_buf, 12)?;
173
174 let timestamp_ns = if self.is_nano {
175 (ts_sec as u64) * 1_000_000_000 + ts_usec as u64
176 } else {
177 (ts_sec as u64) * 1_000_000_000 + (ts_usec as u64) * 1000
178 };
179
180 let mut pkt_data = vec![0u8; incl_len as usize];
181 self.reader.read_exact(&mut pkt_data)?;
182
183 Ok(Some(PacketRef::new(
184 &pkt_data,
185 timestamp_ns,
186 orig_len,
187 incl_len,
188 )))
189 }
190}
191
192pub struct PcapIterator<R> {
194 reader: PcapReader<R>,
195}
196
197impl<R: Read + Seek> Iterator for PcapIterator<R> {
198 type Item = Result<PacketRef, Error>;
199
200 fn next(&mut self) -> Option<Self::Item> {
201 self.reader.next_packet().transpose()
202 }
203}
204
205pub struct PcapngReader<R> {
207 reader: R,
208 interfaces: Vec<Interface>,
209}
210
211pub struct Interface {
213 pub link_type: u16,
214 pub snap_len: u32,
215}
216
217impl<R: Read + Seek> PcapngReader<R> {
218 pub fn from_reader(mut reader: R) -> Result<Self, Error> {
220 let mut interfaces = Vec::new();
221
222 loop {
224 let mut type_buf = [0u8; 4];
226 if reader.read_exact(&mut type_buf).is_err() {
227 break;
228 }
229 let block_type = u32::from_le_bytes(type_buf);
230
231 let mut len_buf = [0u8; 4];
233 if reader.read_exact(&mut len_buf).is_err() {
234 break;
235 }
236 let block_len = u32::from_le_bytes(len_buf) as usize;
237
238 if !(12..=1024 * 1024).contains(&block_len) {
239 break;
240 }
241
242 let content_len = block_len - 12;
246 let mut block_data = vec![0u8; content_len];
247 if reader.read_exact(&mut block_data).is_err() {
248 break;
249 }
250
251 if block_type == pcapng_mod::block_type::IDB {
252 let link_type = read_u16(&block_data, 0)?;
254 let snap_len = read_u32(&block_data, 4)?;
255 interfaces.push(Interface {
256 link_type,
257 snap_len,
258 });
259 }
260
261 reader.seek(SeekFrom::Current(4))?;
263 }
264
265 reader.seek(SeekFrom::Start(0))?;
266
267 Ok(Self { reader, interfaces })
268 }
269
270 pub fn interfaces(&self) -> &[Interface] {
272 &self.interfaces
273 }
274
275 pub fn next_block(&mut self) -> Result<Option<Block>, Error> {
277 let mut type_buf = [0u8; 4];
279 match self.reader.read_exact(&mut type_buf) {
280 Ok(()) => {}
281 Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => return Ok(None),
282 Err(e) => return Err(Error::Io(e)),
283 }
284 let _block_type = u32::from_le_bytes(type_buf);
285
286 let mut len_buf = [0u8; 4];
288 match self.reader.read_exact(&mut len_buf) {
289 Ok(()) => {}
290 Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => return Ok(None),
291 Err(e) => return Err(Error::Io(e)),
292 }
293
294 let block_len = u32::from_le_bytes(len_buf) as usize;
295
296 if block_len < 12 {
297 return Err(Error::parse(0, "Block too small"));
298 }
299
300 let mut full_block = vec![0u8; block_len];
303 full_block[0..4].copy_from_slice(&type_buf);
304 full_block[4..8].copy_from_slice(&len_buf);
305 if self
307 .reader
308 .read_exact(&mut full_block[8..block_len - 4])
309 .is_err()
310 {
311 return Ok(None);
312 }
313 if self
315 .reader
316 .read_exact(&mut full_block[block_len - 4..block_len])
317 .is_err()
318 {
319 return Ok(None);
320 }
321
322 let offset = 0;
323 let result = pcapng_mod::parse_block(&full_block, offset);
324 match result {
325 Ok((block, _)) => Ok(Some(block)),
326 Err(_) => Ok(None),
327 }
328 }
329}
330
331#[cfg(feature = "std")]
332impl PcapReader<std::io::Cursor<Vec<u8>>> {
333 pub fn from_bytes(data: &[u8]) -> Result<Self, Error> {
335 Self::from_reader(std::io::Cursor::new(data.to_vec()))
336 }
337}
338
339#[cfg(feature = "std")]
340impl PcapngReader<std::io::Cursor<Vec<u8>>> {
341 pub fn from_bytes(data: &[u8]) -> Result<Self, Error> {
343 Self::from_reader(std::io::Cursor::new(data.to_vec()))
344 }
345}
346
347#[cfg(feature = "std")]
348impl PcapReader<File> {
349 pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
351 let file = File::open(path)?;
352 Self::from_reader(file)
353 }
354}
355
356#[cfg(feature = "std")]
357impl PcapngReader<File> {
358 pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
360 let file = File::open(path)?;
361 Self::from_reader(file)
362 }
363}