1use crate::*;
2
3#[deprecated(since = "0.14.0", note = "`IpHeader` was renamed to `NetHeaders`")]
5pub type IpHeader = NetHeaders;
6
7#[derive(Clone, Debug, Eq, PartialEq)]
9#[allow(clippy::large_enum_variant)]
10pub enum NetHeaders {
11 Ipv4(Ipv4Header, Ipv4Extensions),
13 Ipv6(Ipv6Header, Ipv6Extensions),
15 Arp(ArpPacket),
17}
18
19impl NetHeaders {
20 #[inline]
22 pub fn is_ip(&self) -> bool {
23 use NetHeaders::*;
24 matches!(self, Ipv4(_, _) | Ipv6(_, _))
25 }
26
27 #[inline]
29 pub fn is_ipv4(&self) -> bool {
30 use NetHeaders::*;
31 matches!(self, Ipv4(_, _))
32 }
33
34 #[inline]
36 pub fn is_ipv6(&self) -> bool {
37 use NetHeaders::*;
38 matches!(self, Ipv6(_, _))
39 }
40
41 #[inline]
43 pub fn is_arp(&self) -> bool {
44 use NetHeaders::*;
45 matches!(self, Arp(_))
46 }
47
48 #[inline]
50 pub fn ipv4_ref(&self) -> Option<(&Ipv4Header, &Ipv4Extensions)> {
51 if let NetHeaders::Ipv4(header, exts) = self {
52 Some((header, exts))
53 } else {
54 None
55 }
56 }
57
58 #[inline]
60 pub fn ipv6_ref(&self) -> Option<(&Ipv6Header, &Ipv6Extensions)> {
61 if let NetHeaders::Ipv6(header, exts) = self {
62 Some((header, exts))
63 } else {
64 None
65 }
66 }
67
68 #[inline]
70 pub fn arp_ref(&self) -> Option<&ArpPacket> {
71 if let NetHeaders::Arp(arp) = self {
72 Some(arp)
73 } else {
74 None
75 }
76 }
77
78 pub fn try_set_next_headers(
85 &mut self,
86 last_next_header: IpNumber,
87 ) -> Result<EtherType, err::net::NetSetNextHeaderError> {
88 use NetHeaders::*;
89 match self {
90 Ipv4(ref mut header, ref mut extensions) => {
91 header.protocol = extensions.set_next_headers(last_next_header);
92 Ok(EtherType::IPV4)
93 }
94 Ipv6(ref mut header, ref mut extensions) => {
95 header.next_header = extensions.set_next_headers(last_next_header);
96 Ok(EtherType::IPV6)
97 }
98 Arp(_) => Err(err::net::NetSetNextHeaderError::ArpHeader),
99 }
100 }
101
102 pub fn header_len(&self) -> usize {
104 use crate::NetHeaders::*;
105 match *self {
106 Ipv4(ref header, ref extensions) => header.header_len() + extensions.header_len(),
107 Ipv6(_, ref extensions) => Ipv6Header::LEN + extensions.header_len(),
108 Arp(ref arp) => arp.packet_len(),
109 }
110 }
111}
112
113impl From<IpHeaders> for NetHeaders {
114 #[inline]
115 fn from(value: IpHeaders) -> Self {
116 match value {
117 IpHeaders::Ipv4(h, e) => NetHeaders::Ipv4(h, e),
118 IpHeaders::Ipv6(h, e) => NetHeaders::Ipv6(h, e),
119 }
120 }
121}
122
123impl From<ArpPacket> for NetHeaders {
124 #[inline]
125 fn from(value: ArpPacket) -> Self {
126 NetHeaders::Arp(value)
127 }
128}
129
130#[cfg(test)]
131mod tests {
132 use crate::*;
133 use alloc::format;
134
135 #[test]
136 fn debug() {
137 let h = Ipv4Header {
138 ..Default::default()
139 };
140 let e = Ipv4Extensions {
141 ..Default::default()
142 };
143 let n = NetHeaders::Ipv4(h.clone(), e.clone());
144 assert_eq!(format!("{n:?}"), format!("Ipv4({h:?}, {e:?})"));
145 }
146
147 #[test]
148 fn clone_eq() {
149 let n = NetHeaders::Ipv4(Default::default(), Default::default());
150 assert_eq!(n, n.clone())
151 }
152
153 #[test]
154 fn ipv4_ipv6_arp_refs_and_is() {
155 {
157 let h: Ipv4Header = Default::default();
158 let e: Ipv4Extensions = Default::default();
159 let s = NetHeaders::Ipv4(h.clone(), e.clone());
160 assert_eq!(s.ipv4_ref(), Some((&h, &e)));
161 assert_eq!(s.ipv6_ref(), None);
162 assert_eq!(s.arp_ref(), None);
163 assert!(s.is_ip());
164 assert!(s.is_ipv4());
165 assert_eq!(false, s.is_ipv6());
166 assert_eq!(false, s.is_arp());
167 }
168 {
170 let h: Ipv6Header = Default::default();
171 let e: Ipv6Extensions = Default::default();
172 let s = NetHeaders::Ipv6(h.clone(), e.clone());
173 assert_eq!(s.ipv4_ref(), None);
174 assert_eq!(s.ipv6_ref(), Some((&h, &e)));
175 assert_eq!(s.arp_ref(), None);
176 assert!(s.is_ip());
177 assert_eq!(false, s.is_ipv4());
178 assert!(s.is_ipv6());
179 assert_eq!(false, s.is_arp());
180 }
181 {
183 let h: ArpPacket = ArpPacket::new(
184 ArpHardwareId::ETHERNET,
185 EtherType::IPV4,
186 ArpOperation::REPLY,
187 &[0; 6],
188 &[0; 4],
189 &[0; 6],
190 &[0; 4],
191 )
192 .unwrap();
193 let s = NetHeaders::Arp(h.clone());
194 assert_eq!(s.ipv4_ref(), None);
195 assert_eq!(s.ipv6_ref(), None);
196 assert_eq!(s.arp_ref(), Some(&h));
197 assert_eq!(false, s.is_ip());
198 assert_eq!(false, s.is_ipv4());
199 assert_eq!(false, s.is_ipv6());
200 assert!(s.is_arp());
201 }
202 }
203
204 #[test]
205 fn try_set_next_headers() {
206 {
208 let h: Ipv4Header = Default::default();
209 let e: Ipv4Extensions = Default::default();
210 let mut s = NetHeaders::Ipv4(h.clone(), e.clone());
211 assert_eq!(s.try_set_next_headers(IpNumber::UDP), Ok(EtherType::IPV4));
212 assert_eq!(s.ipv4_ref().unwrap().0.protocol, IpNumber::UDP);
213 }
214 {
216 let h: Ipv6Header = Default::default();
217 let e: Ipv6Extensions = Default::default();
218 let mut s = NetHeaders::Ipv6(h.clone(), e.clone());
219 assert_eq!(s.try_set_next_headers(IpNumber::UDP), Ok(EtherType::IPV6));
220 assert_eq!(s.ipv6_ref().unwrap().0.next_header, IpNumber::UDP);
221 }
222 {
224 let h: ArpPacket = ArpPacket::new(
225 ArpHardwareId::ETHERNET,
226 EtherType::IPV4,
227 ArpOperation::REPLY,
228 &[0; 6],
229 &[0; 4],
230 &[0; 6],
231 &[0; 4],
232 )
233 .unwrap();
234 let mut s = NetHeaders::Arp(h.clone());
235 assert_eq!(
236 s.try_set_next_headers(IpNumber::UDP),
237 Err(err::net::NetSetNextHeaderError::ArpHeader)
238 );
239 assert_eq!(s.arp_ref().unwrap(), &h);
240 }
241 }
242
243 #[test]
244 fn header_len() {
245 {
247 let h: Ipv4Header = Default::default();
248 let e: Ipv4Extensions = Default::default();
249 let s = NetHeaders::Ipv4(h.clone(), e.clone());
250 assert_eq!(s.header_len(), h.header_len() + e.header_len());
251 }
252 {
254 let h: Ipv6Header = Default::default();
255 let e: Ipv6Extensions = Default::default();
256 let s = NetHeaders::Ipv6(h.clone(), e.clone());
257 assert_eq!(s.header_len(), h.header_len() + e.header_len());
258 }
259 {
261 let h: ArpPacket = ArpPacket::new(
262 ArpHardwareId::ETHERNET,
263 EtherType::IPV4,
264 ArpOperation::REPLY,
265 &[0; 6],
266 &[0; 4],
267 &[0; 6],
268 &[0; 4],
269 )
270 .unwrap();
271 let s = NetHeaders::Arp(h.clone());
272 assert_eq!(s.header_len(), h.packet_len(),);
273 }
274 }
275
276 #[test]
277 fn from() {
278 {
280 let h: Ipv4Header = Default::default();
281 let e: Ipv4Extensions = Default::default();
282 let s = IpHeaders::Ipv4(h.clone(), e.clone());
283 let a: NetHeaders = s.clone().into();
284 assert_eq!(a, NetHeaders::Ipv4(h.clone(), e.clone()));
285 }
286 {
288 let h: Ipv6Header = Default::default();
289 let e: Ipv6Extensions = Default::default();
290 let s = IpHeaders::Ipv6(h.clone(), e.clone());
291 let a: NetHeaders = s.clone().into();
292 assert_eq!(a, NetHeaders::Ipv6(h.clone(), e.clone()));
293 }
294 {
296 let h: ArpPacket = ArpPacket::new(
297 ArpHardwareId::ETHERNET,
298 EtherType::IPV4,
299 ArpOperation::REPLY,
300 &[0; 6],
301 &[0; 4],
302 &[0; 6],
303 &[0; 4],
304 )
305 .unwrap();
306 let a: NetHeaders = h.clone().into();
307 assert_eq!(a, NetHeaders::Arp(h));
308 }
309 }
310}