1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use std::io;
use super::def;
use super::PcapError;
use super::CapturedPacket;
use bytepack::Unpacker;
pub struct PcapReader<R : io::Read> {
reader: R,
network: u32,
state: Option<PcapState>,
}
struct PcapState {
file_header: def::PcapFileHeader,
packet_buffer: Vec<u8>,
}
impl<R : io::Read> PcapReader<R> {
pub fn new(mut reader: R) -> Result<Self, PcapError> {
let fh = reader.unpack::<def::PcapFileHeaderInFile>()?;
let fh = def::PcapFileHeader::try_from(fh).ok_or(PcapError::InvalidFileHeader)?;
let buffer = vec![0; fh.snaplen.into()];
Ok(PcapReader {
reader: reader,
network: fh.network,
state: Some(PcapState {
file_header: fh,
packet_buffer: buffer,
}),
})
}
pub fn get_linktype(&self) -> u32 {
self.network
}
pub fn get_snaplen(&self) -> usize {
match self.state.as_ref() {
None => 0,
Some(state) => state.packet_buffer.len()
}
}
pub fn next<'a>(&'a mut self) -> Result<Option<CapturedPacket<'a>>, PcapError> {
if self.state.is_none() {
return Ok(None);
}
let rh = self.reader.unpack::<def::PcapRecordHeader>();
if let Err(e) = rh {
return if e.kind() == io::ErrorKind::UnexpectedEof {
self.state = None;
Ok(None)
} else {
Err(PcapError::from(e))
};
}
let mut rh = rh.unwrap();
let state = self.state.as_mut().unwrap();
rh.swap_bytes(&state.file_header);
let mut toread = rh.incl_len as usize;
if state.packet_buffer.capacity() < toread {
while toread > state.packet_buffer.capacity() {
self.reader.read_exact(state.packet_buffer.as_mut_slice())?;
toread -= state.packet_buffer.capacity();
}
self.reader.read_exact(&mut state.packet_buffer[..toread])?;
return Err(PcapError::InvalidPacketSize);
}
let buf = &mut state.packet_buffer[..toread];
self.reader.read_exact(buf)?;
let orig_len = rh.orig_len as usize;
if orig_len as u32 != rh.orig_len {
return Err(PcapError::InvalidPacketSize);
}
if let Some(t) = rh.get_time(&state.file_header) {
Ok(Some(CapturedPacket { time: t, data: buf, orig_len: orig_len }))
} else {
Err(PcapError::InvalidDate)
}
}
}