1 use crate::*; 2 3 /// Deprecated use [`crate::NetHeaders`] instead. 4 #[deprecated(since = "0.14.0", note = "`IpHeader` was renamed to `NetHeaders`")] 5 pub type IpHeader = NetHeaders; 6 7 /// Headers on the network layer (e.g. IP, ARP, ...). 8 #[derive(Clone, Debug, Eq, PartialEq)] 9 #[allow(clippy::large_enum_variant)] 10 pub enum NetHeaders { 11 /// IPv4 header & extension headers. 12 Ipv4(Ipv4Header, Ipv4Extensions), 13 /// IPv6 header & extension headers. 14 Ipv6(Ipv6Header, Ipv6Extensions), 15 /// Address Resolution Protocol packet. 16 Arp(ArpPacket), 17 } 18 19 impl NetHeaders { 20 /// Returns true if the NetHeaders contains either IPv4 or IPv6. is_ip(&self) -> bool21 pub fn is_ip(&self) -> bool { 22 use NetHeaders::*; 23 matches!(self, Ipv4(_, _) | Ipv6(_, _)) 24 } 25 26 /// Returns references to the IPv4 header & extensions if the header contains IPv4 values. ipv4_ref(&self) -> Option<(&Ipv4Header, &Ipv4Extensions)>27 pub fn ipv4_ref(&self) -> Option<(&Ipv4Header, &Ipv4Extensions)> { 28 if let NetHeaders::Ipv4(header, exts) = self { 29 Some((header, exts)) 30 } else { 31 None 32 } 33 } 34 35 /// Returns references to the IPv6 header & extensions if the header contains IPv6 values. ipv6_ref(&self) -> Option<(&Ipv6Header, &Ipv6Extensions)>36 pub fn ipv6_ref(&self) -> Option<(&Ipv6Header, &Ipv6Extensions)> { 37 if let NetHeaders::Ipv6(header, exts) = self { 38 Some((header, exts)) 39 } else { 40 None 41 } 42 } 43 44 /// Sets all the next_header fields in the ipv4 & ipv6 header 45 /// as well as in all extension headers and returns the ether 46 /// type number. 47 /// 48 /// The given number will be set as the last "next_header" or 49 /// protocol number. try_set_next_headers( &mut self, last_next_header: IpNumber, ) -> Result<EtherType, err::net::NetSetNextHeaderError>50 pub fn try_set_next_headers( 51 &mut self, 52 last_next_header: IpNumber, 53 ) -> Result<EtherType, err::net::NetSetNextHeaderError> { 54 use NetHeaders::*; 55 match self { 56 Ipv4(ref mut header, ref mut extensions) => { 57 header.protocol = extensions.set_next_headers(last_next_header); 58 Ok(EtherType::IPV4) 59 } 60 Ipv6(ref mut header, ref mut extensions) => { 61 header.next_header = extensions.set_next_headers(last_next_header); 62 Ok(EtherType::IPV4) 63 } 64 Arp(_) => Err(err::net::NetSetNextHeaderError::ArpHeader), 65 } 66 } 67 68 /// Returns the size when the header & extension headers are serialized header_len(&self) -> usize69 pub fn header_len(&self) -> usize { 70 use crate::NetHeaders::*; 71 match *self { 72 Ipv4(ref header, ref extensions) => header.header_len() + extensions.header_len(), 73 Ipv6(_, ref extensions) => Ipv6Header::LEN + extensions.header_len(), 74 Arp(ref arp) => arp.packet_len(), 75 } 76 } 77 } 78 79 impl From<IpHeaders> for NetHeaders { 80 #[inline] from(value: IpHeaders) -> Self81 fn from(value: IpHeaders) -> Self { 82 match value { 83 IpHeaders::Ipv4(h, e) => NetHeaders::Ipv4(h, e), 84 IpHeaders::Ipv6(h, e) => NetHeaders::Ipv6(h, e), 85 } 86 } 87 } 88 89 impl From<ArpPacket> for NetHeaders { 90 #[inline] from(value: ArpPacket) -> Self91 fn from(value: ArpPacket) -> Self { 92 NetHeaders::Arp(value) 93 } 94 } 95 96 #[cfg(test)] 97 mod tests { 98 use crate::*; 99 use alloc::format; 100 101 #[test] debug()102 fn debug() { 103 let h = Ipv4Header { 104 ..Default::default() 105 }; 106 let e = Ipv4Extensions { 107 ..Default::default() 108 }; 109 let n = NetHeaders::Ipv4(h.clone(), e.clone()); 110 assert_eq!(format!("{n:?}"), format!("Ipv4({h:?}, {e:?})")); 111 } 112 113 #[test] clone_eq()114 fn clone_eq() { 115 let n = NetHeaders::Ipv4(Default::default(), Default::default()); 116 assert_eq!(n, n.clone()) 117 } 118 119 #[test] ipv4_ref()120 fn ipv4_ref() { 121 // ipv4 122 { 123 let h: Ipv4Header = Default::default(); 124 let e: Ipv4Extensions = Default::default(); 125 let s = NetHeaders::Ipv4(h.clone(), e.clone()); 126 assert_eq!(s.ipv4_ref(), Some((&h, &e))); 127 } 128 // ipv6 129 { 130 let h: Ipv6Header = Default::default(); 131 let e: Ipv6Extensions = Default::default(); 132 let s = NetHeaders::Ipv6(h.clone(), e.clone()); 133 assert_eq!(s.ipv4_ref(), None); 134 } 135 } 136 137 #[test] ipv6_ref()138 fn ipv6_ref() { 139 // ipv4 140 { 141 let h: Ipv4Header = Default::default(); 142 let e: Ipv4Extensions = Default::default(); 143 let s = NetHeaders::Ipv4(h.clone(), e.clone()); 144 assert_eq!(s.ipv6_ref(), None); 145 } 146 // ipv6 147 { 148 let h: Ipv6Header = Default::default(); 149 let e: Ipv6Extensions = Default::default(); 150 let s = NetHeaders::Ipv6(h.clone(), e.clone()); 151 assert_eq!(s.ipv6_ref(), Some((&h, &e))); 152 } 153 } 154 155 #[test] header_len()156 fn header_len() { 157 // ipv4 158 { 159 let h: Ipv4Header = Default::default(); 160 let e: Ipv4Extensions = Default::default(); 161 let s = NetHeaders::Ipv4(h.clone(), e.clone()); 162 assert_eq!(s.header_len(), h.header_len() + e.header_len()); 163 } 164 // ipv6 165 { 166 let h: Ipv6Header = Default::default(); 167 let e: Ipv6Extensions = Default::default(); 168 let s = NetHeaders::Ipv6(h.clone(), e.clone()); 169 assert_eq!(s.header_len(), h.header_len() + e.header_len()); 170 } 171 } 172 173 #[test] from()174 fn from() { 175 // ipv4 176 { 177 let h: Ipv4Header = Default::default(); 178 let e: Ipv4Extensions = Default::default(); 179 let s = IpHeaders::Ipv4(h.clone(), e.clone()); 180 let a: NetHeaders = s.clone().into(); 181 assert_eq!(a, NetHeaders::Ipv4(h.clone(), e.clone())); 182 } 183 // ipv6 184 { 185 let h: Ipv6Header = Default::default(); 186 let e: Ipv6Extensions = Default::default(); 187 let s = IpHeaders::Ipv6(h.clone(), e.clone()); 188 let a: NetHeaders = s.clone().into(); 189 assert_eq!(a, NetHeaders::Ipv6(h.clone(), e.clone())); 190 } 191 } 192 } 193