1 use crate::*;
2 
3 /// IEEE 802.1Q VLAN Tagging Header (can be single or double tagged).
4 #[derive(Clone, Debug, Eq, PartialEq)]
5 pub enum VlanHeader {
6     /// IEEE 802.1Q VLAN Tagging Header
7     Single(SingleVlanHeader),
8     /// IEEE 802.1Q double VLAN Tagging Header
9     Double(DoubleVlanHeader),
10 }
11 
12 impl VlanHeader {
13     /// All ether types that identify a vlan header.
14     pub const VLAN_ETHER_TYPES: [EtherType; 3] = [
15         ether_type::VLAN_TAGGED_FRAME,
16         ether_type::PROVIDER_BRIDGING,
17         ether_type::VLAN_DOUBLE_TAGGED_FRAME,
18     ];
19 
20     /// Write the IEEE 802.1Q VLAN single or double tagging header
21     #[cfg(feature = "std")]
22     #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
23     #[inline]
write<T: std::io::Write + Sized>(&self, writer: &mut T) -> Result<(), std::io::Error>24     pub fn write<T: std::io::Write + Sized>(&self, writer: &mut T) -> Result<(), std::io::Error> {
25         use VlanHeader::*;
26         match &self {
27             Single(header) => header.write(writer),
28             Double(header) => header.write(writer),
29         }
30     }
31 
32     /// Returns the ether type of the next header after the vlan header(s).
33     #[inline]
next_header(&self) -> EtherType34     pub fn next_header(&self) -> EtherType {
35         match self {
36             VlanHeader::Single(s) => s.ether_type,
37             VlanHeader::Double(d) => d.inner.ether_type,
38         }
39     }
40 
41     /// Length of the serialized header(s) in bytes.
42     #[inline]
header_len(&self) -> usize43     pub fn header_len(&self) -> usize {
44         use VlanHeader::*;
45         match &self {
46             Single(_) => SingleVlanHeader::LEN,
47             Double(_) => DoubleVlanHeader::LEN,
48         }
49     }
50 }
51 
52 #[cfg(test)]
53 mod test {
54     use super::*;
55     use crate::test_gens::*;
56     use alloc::{format, vec::Vec};
57     use proptest::prelude::*;
58 
59     #[test]
constants()60     fn constants() {
61         use ether_type::*;
62         use VlanHeader as V;
63 
64         assert_eq!(3, V::VLAN_ETHER_TYPES.len());
65         assert_eq!(VLAN_TAGGED_FRAME, V::VLAN_ETHER_TYPES[0]);
66         assert_eq!(PROVIDER_BRIDGING, V::VLAN_ETHER_TYPES[1]);
67         assert_eq!(VLAN_DOUBLE_TAGGED_FRAME, V::VLAN_ETHER_TYPES[2]);
68     }
69 
70     proptest! {
71         #[test]
72         fn clone_eq(
73             single in vlan_single_any(),
74             double in vlan_double_any(),
75         ) {
76             // single eq
77             {
78                 let value = VlanHeader::Single(single.clone());
79                 assert_eq!(value, value.clone());
80             }
81             // double
82             {
83                 let value = VlanHeader::Double(double);
84                 assert_eq!(value, value.clone());
85             }
86         }
87     }
88 
89     proptest! {
90         #[test]
91         fn dbg(
92             single in vlan_single_any(),
93             double in vlan_double_any(),
94         ) {
95             // single
96             {
97                 let value = VlanHeader::Single(single.clone());
98                 assert_eq!(
99                     &format!(
100                         "Single({:?})",
101                         single
102                     ),
103                     &format!("{:?}", value)
104                 );
105             }
106             // double
107             {
108                 let value = VlanHeader::Double(double.clone());
109                 assert_eq!(
110                     &format!(
111                         "Double({:?})",
112                         double
113                     ),
114                     &format!("{:?}", value)
115                 );
116             }
117         }
118     }
119 
120     proptest! {
121         #[test]
122         fn next_header(
123             single in vlan_single_any(),
124             double in vlan_double_any(),
125         ) {
126             // single
127             {
128                 let value = VlanHeader::Single(single.clone());
129                 assert_eq!(value.next_header(), single.ether_type);
130             }
131             // double
132             {
133                 let value = VlanHeader::Double(double.clone());
134                 assert_eq!(value.next_header(), double.inner.ether_type);
135             }
136         }
137     }
138 
139     proptest! {
140         #[test]
141         fn header_len(
142             single in vlan_single_any(),
143             double in vlan_double_any(),
144         ) {
145             // single
146             assert_eq!(
147                 SingleVlanHeader::LEN,
148                 VlanHeader::Single(single.clone()).header_len()
149             );
150             // double
151             assert_eq!(
152                 DoubleVlanHeader::LEN,
153                 VlanHeader::Double(double.clone()).header_len()
154             );
155         }
156     }
157 
158     proptest! {
159         #[test]
160         fn write(
161             single in vlan_single_any(),
162             double in vlan_double_any(),
163         ) {
164             // single
165             {
166                 let expected = {
167                     let mut buffer = Vec::with_capacity(single.header_len());
168                     single.write(&mut buffer).unwrap();
169                     buffer
170                 };
171                 let actual = {
172                     let mut buffer = Vec::with_capacity(single.header_len());
173                     VlanHeader::Single(single.clone()).write(&mut buffer).unwrap();
174                     buffer
175                 };
176                 assert_eq!(expected, actual);
177             }
178 
179             // double
180             {
181                 let expected = {
182                     let mut buffer = Vec::with_capacity(double.header_len());
183                     double.write(&mut buffer).unwrap();
184                     buffer
185                 };
186                 let actual = {
187                     let mut buffer = Vec::with_capacity(double.header_len());
188                     VlanHeader::Double(double.clone()).write(&mut buffer).unwrap();
189                     buffer
190                 };
191                 assert_eq!(expected, actual);
192             }
193         }
194     }
195 }
196