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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
use std::borrow::Cow;
use std::io::Write;
use std::time::Duration;
use byteorder_slice::byteorder::WriteBytesExt;
use byteorder_slice::result::ReadSlice;
use byteorder_slice::ByteOrder;
use derive_into_owned::IntoOwned;
use crate::errors::*;
use crate::TsResolution;
#[derive(Clone, Debug, IntoOwned)]
pub struct PcapPacket<'a> {
pub timestamp: Duration,
pub orig_len: u32,
pub data: Cow<'a, [u8]>,
}
impl<'a> PcapPacket<'a> {
pub fn new(timestamp: Duration, orig_len: u32, data: &'a [u8]) -> PcapPacket<'a> {
PcapPacket { timestamp, orig_len, data: Cow::Borrowed(data) }
}
pub fn new_owned(timestamp: Duration, orig_len: u32, data: Vec<u8>) -> PcapPacket<'static> {
PcapPacket { timestamp, orig_len, data: Cow::Owned(data) }
}
pub fn from_slice<B: ByteOrder>(slice: &'a [u8], ts_resolution: TsResolution, snap_len: u32) -> PcapResult<(&'a [u8], PcapPacket<'a>)> {
let (rem, raw_packet) = RawPcapPacket::from_slice::<B>(slice)?;
let s = Self::try_from_raw_packet(raw_packet, ts_resolution, snap_len)?;
Ok((rem, s))
}
pub fn write_to<W: Write, B: ByteOrder>(&self, writer: &mut W, ts_resolution: TsResolution, snap_len: u32) -> PcapResult<usize> {
let ts_sec = self
.timestamp
.as_secs()
.try_into()
.map_err(|_| PcapError::InvalidField("PcapPacket: timestamp_secs > u32::MAX"))?;
let mut ts_frac = self.timestamp.subsec_nanos();
if ts_resolution == TsResolution::MicroSecond {
ts_frac /= 1000;
}
let incl_len = self.data.len().try_into().map_err(|_| PcapError::InvalidField("PcapPacket: incl_len > u32::MAX"))?;
let orig_len = self.orig_len;
if incl_len > snap_len {
return Err(PcapError::InvalidField("PcapPacket: incl_len > snap_len"));
}
if incl_len > orig_len {
return Err(PcapError::InvalidField("PcapPacket: incl_len > orig_len"));
}
let raw_packet = RawPcapPacket { ts_sec, ts_frac, incl_len, orig_len, data: Cow::Borrowed(&self.data[..]) };
raw_packet.write_to::<_, B>(writer)
}
pub fn try_from_raw_packet(raw: RawPcapPacket<'a>, ts_resolution: TsResolution, snap_len: u32) -> PcapResult<Self> {
let ts_sec = raw.ts_sec;
let mut ts_nsec = raw.ts_frac;
if ts_resolution == TsResolution::MicroSecond {
ts_nsec = ts_nsec.checked_mul(1000).ok_or(PcapError::InvalidField("PacketHeader ts_nanosecond is invalid"))?;
}
if ts_nsec >= 1_000_000_000 {
return Err(PcapError::InvalidField("PacketHeader ts_nanosecond >= 1_000_000_000"));
}
let incl_len = raw.incl_len;
let orig_len = raw.orig_len;
if incl_len > snap_len {
return Err(PcapError::InvalidField("PacketHeader incl_len > snap_len"));
}
if orig_len > snap_len {
return Err(PcapError::InvalidField("PacketHeader orig_len > snap_len"));
}
if incl_len > orig_len {
return Err(PcapError::InvalidField("PacketHeader incl_len > orig_len"));
}
Ok(PcapPacket { timestamp: Duration::new(ts_sec as u64, ts_nsec), orig_len, data: raw.data })
}
}
#[derive(Clone, Debug, IntoOwned)]
pub struct RawPcapPacket<'a> {
pub ts_sec: u32,
pub ts_frac: u32,
pub incl_len: u32,
pub orig_len: u32,
pub data: Cow<'a, [u8]>,
}
impl<'a> RawPcapPacket<'a> {
pub fn from_slice<B: ByteOrder>(mut slice: &'a [u8]) -> PcapResult<(&'a [u8], Self)> {
if slice.len() < 16 {
return Err(PcapError::IncompleteBuffer);
}
let ts_sec = slice.read_u32::<B>().unwrap();
let ts_frac = slice.read_u32::<B>().unwrap();
let incl_len = slice.read_u32::<B>().unwrap();
let orig_len = slice.read_u32::<B>().unwrap();
let pkt_len = incl_len as usize;
if slice.len() < pkt_len {
return Err(PcapError::IncompleteBuffer);
}
let packet = RawPcapPacket { ts_sec, ts_frac, incl_len, orig_len, data: Cow::Borrowed(&slice[..pkt_len]) };
let rem = &slice[pkt_len..];
Ok((rem, packet))
}
pub fn write_to<W: Write, B: ByteOrder>(&self, writer: &mut W) -> PcapResult<usize> {
writer.write_u32::<B>(self.ts_sec).map_err(PcapError::IoError)?;
writer.write_u32::<B>(self.ts_frac).map_err(PcapError::IoError)?;
writer.write_u32::<B>(self.incl_len).map_err(PcapError::IoError)?;
writer.write_u32::<B>(self.orig_len).map_err(PcapError::IoError)?;
writer.write_all(&self.data).map_err(PcapError::IoError)?;
Ok(16 + self.data.len())
}
pub fn try_into_pcap_packet(self, ts_resolution: TsResolution, snap_len: u32) -> PcapResult<PcapPacket<'a>> {
PcapPacket::try_from_raw_packet(self, ts_resolution, snap_len)
}
}