Thanks to visit codestin.com
Credit goes to docs.rs

etherparse/net/
net_headers.rs

1use crate::*;
2
3/// Deprecated use [`crate::NetHeaders`] instead.
4#[deprecated(since = "0.14.0", note = "`IpHeader` was renamed to `NetHeaders`")]
5pub 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)]
10pub 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
19impl NetHeaders {
20    /// Returns true if the NetHeaders contains either IPv4 or IPv6.
21    #[inline]
22    pub fn is_ip(&self) -> bool {
23        use NetHeaders::*;
24        matches!(self, Ipv4(_, _) | Ipv6(_, _))
25    }
26
27    /// Returns true if the NetHeaders contains IPv4.
28    #[inline]
29    pub fn is_ipv4(&self) -> bool {
30        use NetHeaders::*;
31        matches!(self, Ipv4(_, _))
32    }
33
34    /// Returns true if the NetHeaders contains IPv6.
35    #[inline]
36    pub fn is_ipv6(&self) -> bool {
37        use NetHeaders::*;
38        matches!(self, Ipv6(_, _))
39    }
40
41    /// Returns true if the NetHeaders contains ARP.
42    #[inline]
43    pub fn is_arp(&self) -> bool {
44        use NetHeaders::*;
45        matches!(self, Arp(_))
46    }
47
48    /// Returns references to the IPv4 header & extensions if the header contains IPv4 values.
49    #[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    /// Returns references to the IPv6 header & extensions if the header contains IPv6 values.
59    #[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    /// Returns references to the ARP packet if the header contains ARP values.
69    #[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    /// Sets all the next_header fields in the ipv4 & ipv6 header
79    /// as well as in all extension headers and returns the ether
80    /// type number.
81    ///
82    /// The given number will be set as the last "next_header" or
83    /// protocol number.
84    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    /// Returns the size when the header & extension headers are serialized
103    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        // ipv4
156        {
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        // ipv6
169        {
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        // arp
182        {
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        // ipv4
207        {
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        // ipv6
215        {
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        // arp
223        {
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        // ipv4
246        {
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        // ipv6
253        {
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        // arp
260        {
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        // ipv4
279        {
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        // ipv6
287        {
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        // arp
295        {
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}