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