• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::*;
2 use alloc::vec::Vec;
3 
4 #[derive(Clone)]
5 pub(crate) struct TestPacket {
6     pub link: Option<LinkHeader>,
7     pub vlan: Option<VlanHeader>,
8     pub net: Option<NetHeaders>,
9     pub transport: Option<TransportHeader>,
10 }
11 
12 impl TestPacket {
len(&self, payload: &[u8]) -> usize13     pub fn len(&self, payload: &[u8]) -> usize {
14         self.link.as_ref().map_or(0, |x| x.header_len())
15             + self.vlan.as_ref().map_or(0, |x| x.header_len())
16             + self.net.as_ref().map_or(0, |x| x.header_len())
17             + self.transport.as_ref().map_or(0, |x| x.header_len())
18             + payload.len()
19     }
20 
to_vec(&self, payload: &[u8]) -> Vec<u8>21     pub fn to_vec(&self, payload: &[u8]) -> Vec<u8> {
22         let mut result = Vec::with_capacity(self.len(payload));
23         if let Some(link) = &self.link {
24             link.write(&mut result).unwrap();
25         }
26         if let Some(vlan) = &self.vlan {
27             vlan.write(&mut result).unwrap();
28         }
29         if let Some(net) = &self.net {
30             match net {
31                 NetHeaders::Ipv4(ipv4, exts) => {
32                     ipv4.write_raw(&mut result).unwrap();
33                     exts.write(&mut result, ipv4.protocol).unwrap();
34                 }
35                 NetHeaders::Ipv6(ipv6, exts) => {
36                     ipv6.write(&mut result).unwrap();
37                     exts.write(&mut result, ipv6.next_header).unwrap();
38                 }
39                 NetHeaders::Arp(arp) => {
40                     arp.write(&mut result).unwrap();
41                 }
42             }
43         }
44         if let Some(transport) = &self.transport {
45             transport.write(&mut result).unwrap();
46         }
47         result.extend_from_slice(payload);
48         result
49     }
50 
set_ether_type(&mut self, ether_type: EtherType)51     pub fn set_ether_type(&mut self, ether_type: EtherType) {
52         if let Some(vlan) = &mut self.vlan {
53             use VlanHeader::*;
54             match vlan {
55                 Single(single) => {
56                     single.ether_type = ether_type;
57                 }
58                 Double(double) => {
59                     double.inner.ether_type = ether_type;
60                 }
61             }
62         } else if let Some(link) = &mut self.link {
63             match link {
64                 LinkHeader::Ethernet2(ethernet) => ethernet.ether_type = ether_type,
65                 LinkHeader::LinuxSll(linux_sll) => {
66                     linux_sll.protocol_type.change_value(ether_type.0)
67                 }
68             }
69         }
70     }
71 
set_payload_len(&mut self, payload_len: usize)72     pub fn set_payload_len(&mut self, payload_len: usize) {
73         use NetHeaders::*;
74         match &mut self.net {
75             None => {}
76             Some(Ipv4(ref mut header, ref mut exts)) => {
77                 header
78                     .set_payload_len(
79                         exts.header_len()
80                             + self.transport.as_ref().map_or(0, |t| t.header_len())
81                             + payload_len,
82                     )
83                     .unwrap();
84             }
85             Some(Ipv6(ref mut header, ref mut exts)) => {
86                 header
87                     .set_payload_length(
88                         exts.header_len()
89                             + self.transport.as_ref().map_or(0, |t| t.header_len())
90                             + payload_len,
91                     )
92                     .unwrap();
93             }
94             Some(Arp(_)) => {}
95         }
96 
97         use TransportHeader::*;
98         match &mut self.transport {
99             None => {}
100             Some(Udp(ref mut udp)) => {
101                 udp.length = udp.header_len_u16() + payload_len as u16;
102             }
103             Some(Tcp(_)) => {}
104             Some(Icmpv4(_)) => {}
105             Some(Icmpv6(_)) => {}
106         }
107     }
108 
109     /// Set the length relative to the end of the ip headers.
set_payload_le_from_ip_on(&mut self, payload_len_from_ip_on: isize)110     pub fn set_payload_le_from_ip_on(&mut self, payload_len_from_ip_on: isize) {
111         use NetHeaders::*;
112         match self.net.as_mut().unwrap() {
113             Ipv4(ref mut header, ref mut exts) => {
114                 header
115                     .set_payload_len((exts.header_len() as isize + payload_len_from_ip_on) as usize)
116                     .unwrap();
117             }
118             Ipv6(ref mut header, ref mut exts) => {
119                 header
120                     .set_payload_length(
121                         (exts.header_len() as isize + payload_len_from_ip_on) as usize,
122                     )
123                     .unwrap();
124             }
125             Arp(_) => {}
126         }
127     }
128 
is_ip_payload_fragmented(&self) -> bool129     pub fn is_ip_payload_fragmented(&self) -> bool {
130         self.net.as_ref().map_or(false, |net| match net {
131             NetHeaders::Ipv4(h, _) => h.is_fragmenting_payload(),
132             NetHeaders::Ipv6(_, e) => e.is_fragmenting_payload(),
133             NetHeaders::Arp(_) => false,
134         })
135     }
136 }
137