• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::*;
2 
3 /// Helper class for slicing packets
4 pub(crate) struct SlicedPacketCursor<'a> {
5     pub slice: &'a [u8],
6     pub offset: usize,
7     pub len_source: LenSource,
8     pub result: SlicedPacket<'a>,
9 }
10 
11 impl<'a> SlicedPacketCursor<'a> {
new(slice: &'a [u8]) -> SlicedPacketCursor<'a>12     pub fn new(slice: &'a [u8]) -> SlicedPacketCursor<'a> {
13         SlicedPacketCursor {
14             slice,
15             offset: 0,
16             len_source: LenSource::Slice,
17             result: SlicedPacket {
18                 link: None,
19                 vlan: None,
20                 net: None,
21                 transport: None,
22             },
23         }
24     }
25 
move_by(&mut self, len: usize)26     fn move_by(&mut self, len: usize) {
27         unsafe {
28             use core::slice::from_raw_parts;
29             self.slice = from_raw_parts(self.slice.as_ptr().add(len), self.slice.len() - len);
30         }
31         self.offset += len;
32     }
33 
slice_ethernet2(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError>34     pub fn slice_ethernet2(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError> {
35         use err::packet::SliceError::*;
36         use ether_type::*;
37         use LinkSlice::*;
38 
39         let result = Ethernet2Slice::from_slice_without_fcs(self.slice)
40             .map_err(|err| Len(err.add_offset(self.offset)))?;
41 
42         //cache the ether_type for later
43         let ether_type = result.ether_type();
44 
45         //set the new data
46         self.move_by(result.header_len());
47         self.result.link = Some(Ethernet2(result));
48 
49         //continue parsing (if required)
50         match ether_type {
51             ARP => self.slice_arp(),
52             IPV4 => self.slice_ipv4(),
53             IPV6 => self.slice_ipv6(),
54             VLAN_TAGGED_FRAME | PROVIDER_BRIDGING | VLAN_DOUBLE_TAGGED_FRAME => self.slice_vlan(),
55             _ => Ok(self.result),
56         }
57     }
58 
slice_linux_sll(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError>59     pub fn slice_linux_sll(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError> {
60         use err::packet::SliceError::*;
61 
62         let result = LinuxSllSlice::from_slice(self.slice).map_err(|err| match err {
63             err::linux_sll::HeaderSliceError::Len(len) => Len(len.add_offset(self.offset)),
64             err::linux_sll::HeaderSliceError::Content(content) => {
65                 err::packet::SliceError::LinuxSll(content)
66             }
67         })?;
68 
69         //cache the protocol type for later
70         let protocol_type = result.protocol_type();
71 
72         //set the new data
73         self.move_by(result.header_len());
74         self.result.link = Some(LinkSlice::LinuxSll(result));
75 
76         //continue parsing (if required)
77         match protocol_type {
78             LinuxSllProtocolType::EtherType(EtherType::ARP) => self.slice_arp(),
79             LinuxSllProtocolType::EtherType(EtherType::IPV4) => self.slice_ipv4(),
80             LinuxSllProtocolType::EtherType(EtherType::IPV6) => self.slice_ipv6(),
81             _ => Ok(self.result),
82         }
83     }
84 
slice_vlan(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError>85     pub fn slice_vlan(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError> {
86         use err::packet::SliceError::*;
87         use ether_type::*;
88         use VlanSlice::*;
89 
90         // cache the starting slice so the later combining
91         // of outer & inner vlan is defined behavior (for miri)
92         let outer_start_slice = self.slice;
93         let outer = SingleVlanSlice::from_slice(self.slice)
94             .map_err(|err| Len(err.add_offset(self.offset)))?;
95         self.result.vlan = Some(SingleVlan(outer.clone()));
96         self.move_by(outer.header_len());
97 
98         //check if it is a double vlan header
99         match outer.ether_type() {
100             //in case of a double vlan header continue with the inner
101             VLAN_TAGGED_FRAME | PROVIDER_BRIDGING | VLAN_DOUBLE_TAGGED_FRAME => {
102                 let inner = SingleVlanSlice::from_slice(self.slice)
103                     .map_err(|err| Len(err.add_offset(self.offset)))?;
104                 self.move_by(inner.header_len());
105 
106                 let inner_ether_type = inner.ether_type();
107                 self.result.vlan = Some(DoubleVlan(DoubleVlanSlice {
108                     slice: outer_start_slice,
109                 }));
110 
111                 match inner_ether_type {
112                     ARP => self.slice_arp(),
113                     IPV4 => self.slice_ipv4(),
114                     IPV6 => self.slice_ipv6(),
115                     _ => Ok(self.result),
116                 }
117             }
118             ARP => self.slice_arp(),
119             IPV4 => self.slice_ipv4(),
120             IPV6 => self.slice_ipv6(),
121             _ => Ok(self.result),
122         }
123     }
124 
slice_ip(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError>125     pub fn slice_ip(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError> {
126         use err::packet::SliceError::*;
127 
128         // slice header, extension headers and identify payload range
129         let ip = IpSlice::from_slice(self.slice).map_err(|err| {
130             use err::ip::SliceError as I;
131             match err {
132                 I::Len(mut err) => {
133                     err.layer_start_offset += self.offset;
134                     Len(err)
135                 }
136                 I::IpHeaders(err) => match err {
137                     err::ip::HeadersError::Ip(err) => Ip(err),
138                     err::ip::HeadersError::Ipv4Ext(err) => Ipv4Exts(err),
139                     err::ip::HeadersError::Ipv6Ext(err) => Ipv6Exts(err),
140                 },
141             }
142         })?;
143 
144         // safe data needed
145         let payload = ip.payload().clone();
146 
147         // set the new data
148         self.offset += unsafe {
149             // SAFETY: The payload is a subslice of self.slice.
150             // therefor calculating the offset from it is safe and
151             // the result should always be a positive number.
152             payload.payload.as_ptr().offset_from(self.slice.as_ptr()) as usize
153         };
154         self.len_source = payload.len_source;
155         self.slice = payload.payload;
156         self.result.net = Some(ip.into());
157 
158         // continue to the lower layers
159         if payload.fragmented {
160             Ok(self.result)
161         } else {
162             match payload.ip_number {
163                 ip_number::ICMP => self.slice_icmp4().map_err(Len),
164                 ip_number::UDP => self.slice_udp().map_err(Len),
165                 ip_number::TCP => self.slice_tcp().map_err(|err| {
166                     use err::tcp::HeaderSliceError as I;
167                     match err {
168                         I::Len(err) => Len(err),
169                         I::Content(err) => Tcp(err),
170                     }
171                 }),
172                 ip_number::IPV6_ICMP => self.slice_icmp6().map_err(Len),
173                 _ => Ok(self.result),
174             }
175         }
176     }
177 
slice_ipv4(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError>178     pub fn slice_ipv4(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError> {
179         use err::packet::SliceError::*;
180 
181         // slice ipv4 header & extension headers
182         let ipv4 = Ipv4Slice::from_slice(self.slice).map_err(|err| {
183             use err::ipv4::SliceError as I;
184             match err {
185                 I::Len(mut err) => {
186                     err.layer_start_offset += self.offset;
187                     Len(err)
188                 }
189                 I::Header(err) => Ipv4(err),
190                 I::Exts(err) => Ipv4Exts(err),
191             }
192         })?;
193 
194         // safe data needed in following steps
195         let payload = ipv4.payload().clone();
196 
197         // set the new data
198         self.offset += unsafe {
199             // SAFETY: The payload is a subslice of self.slice.
200             // therefor calculating the offset from it is safe and
201             // the result should always be a positive number.
202             payload.payload.as_ptr().offset_from(self.slice.as_ptr()) as usize
203         };
204         self.len_source = payload.len_source;
205         self.slice = payload.payload;
206         self.result.net = Some(NetSlice::Ipv4(ipv4));
207 
208         if payload.fragmented {
209             Ok(self.result)
210         } else {
211             match payload.ip_number {
212                 ip_number::UDP => self.slice_udp().map_err(Len),
213                 ip_number::TCP => self.slice_tcp().map_err(|err| {
214                     use err::tcp::HeaderSliceError as I;
215                     match err {
216                         I::Len(err) => Len(err),
217                         I::Content(err) => Tcp(err),
218                     }
219                 }),
220                 ip_number::ICMP => self.slice_icmp4().map_err(Len),
221                 ip_number::IPV6_ICMP => self.slice_icmp6().map_err(Len),
222                 _ => Ok(self.result),
223             }
224         }
225     }
226 
slice_ipv6(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError>227     pub fn slice_ipv6(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError> {
228         use err::packet::SliceError::*;
229 
230         let ipv6 = Ipv6Slice::from_slice(self.slice).map_err(|err| {
231             use err::ipv6::SliceError as I;
232             match err {
233                 I::Len(mut err) => {
234                     err.layer_start_offset += self.offset;
235                     Len(err)
236                 }
237                 I::Header(err) => Ipv6(err),
238                 I::Exts(err) => Ipv6Exts(err),
239             }
240         })?;
241 
242         // safe data needed in following steps
243         let payload = ipv6.payload().clone();
244 
245         // set the new data
246         self.offset += unsafe {
247             // SAFETY: The payload is a subslice of self.slice.
248             // therefor calculating the offset from it is safe and
249             // the result should always be a positive number.
250             ipv6.payload()
251                 .payload
252                 .as_ptr()
253                 .offset_from(self.slice.as_ptr()) as usize
254         };
255         self.len_source = ipv6.payload().len_source;
256         self.slice = ipv6.payload().payload;
257         self.result.net = Some(NetSlice::Ipv6(ipv6));
258 
259         // only try to decode the transport layer if the payload
260         // is not fragmented
261         if payload.fragmented {
262             Ok(self.result)
263         } else {
264             //parse the data bellow
265             match payload.ip_number {
266                 ip_number::ICMP => self.slice_icmp4().map_err(Len),
267                 ip_number::UDP => self.slice_udp().map_err(Len),
268                 ip_number::TCP => self.slice_tcp().map_err(|err| {
269                     use err::tcp::HeaderSliceError as I;
270                     match err {
271                         I::Len(err) => Len(err),
272                         I::Content(err) => Tcp(err),
273                     }
274                 }),
275                 ip_number::IPV6_ICMP => self.slice_icmp6().map_err(Len),
276                 _ => Ok(self.result),
277             }
278         }
279     }
280 
slice_arp(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError>281     pub fn slice_arp(mut self) -> Result<SlicedPacket<'a>, err::packet::SliceError> {
282         let result = ArpPacketSlice::from_slice(self.slice).map_err(|mut err| {
283             err.layer_start_offset += self.offset;
284             err::packet::SliceError::Len(err)
285         })?;
286 
287         //set the new data
288         self.move_by(result.slice().len());
289         self.result.net = Some(NetSlice::Arp(result.clone()));
290 
291         Ok(self.result)
292     }
293 
slice_icmp4(mut self) -> Result<SlicedPacket<'a>, err::LenError>294     pub fn slice_icmp4(mut self) -> Result<SlicedPacket<'a>, err::LenError> {
295         use crate::TransportSlice::*;
296 
297         let result = Icmpv4Slice::from_slice(self.slice).map_err(|mut err| {
298             err.layer_start_offset += self.offset;
299             if LenSource::Slice == err.len_source {
300                 err.len_source = self.len_source;
301             }
302             err
303         })?;
304 
305         //set the new data
306         self.move_by(result.slice().len());
307         self.result.transport = Some(Icmpv4(result.clone()));
308 
309         Ok(self.result)
310     }
311 
slice_icmp6(mut self) -> Result<SlicedPacket<'a>, err::LenError>312     pub fn slice_icmp6(mut self) -> Result<SlicedPacket<'a>, err::LenError> {
313         use crate::TransportSlice::*;
314 
315         let result = Icmpv6Slice::from_slice(self.slice).map_err(|mut err| {
316             err.layer_start_offset += self.offset;
317             if LenSource::Slice == err.len_source {
318                 err.len_source = self.len_source;
319             }
320             err
321         })?;
322 
323         //set the new data
324         self.move_by(result.slice().len());
325         self.result.transport = Some(Icmpv6(result.clone()));
326 
327         //done
328         Ok(self.result)
329     }
330 
slice_udp(mut self) -> Result<SlicedPacket<'a>, err::LenError>331     pub fn slice_udp(mut self) -> Result<SlicedPacket<'a>, err::LenError> {
332         use crate::TransportSlice::*;
333 
334         let result = UdpSlice::from_slice(self.slice).map_err(|mut err| {
335             err.layer_start_offset += self.offset;
336             if LenSource::Slice == err.len_source {
337                 err.len_source = self.len_source;
338             }
339             err
340         })?;
341 
342         //set the new data
343         self.move_by(result.slice().len());
344         self.result.transport = Some(Udp(result));
345 
346         // done
347         Ok(self.result)
348     }
349 
slice_tcp(mut self) -> Result<SlicedPacket<'a>, err::tcp::HeaderSliceError>350     pub fn slice_tcp(mut self) -> Result<SlicedPacket<'a>, err::tcp::HeaderSliceError> {
351         use crate::TransportSlice::*;
352 
353         let result = TcpSlice::from_slice(self.slice).map_err(|mut err| {
354             use err::tcp::HeaderSliceError::Len;
355             if let Len(err) = &mut err {
356                 err.layer_start_offset += self.offset;
357                 if LenSource::Slice == err.len_source {
358                     err.len_source = self.len_source;
359                 }
360             }
361             err
362         })?;
363 
364         //set the new data
365         self.move_by(result.slice().len());
366         self.result.transport = Some(Tcp(result));
367 
368         // done
369         Ok(self.result)
370     }
371 }
372