• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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