1use crate::{
4 ethernet::EtherType,
5 packet::{MutablePacket, Packet},
6};
7use bytes::{Buf, BufMut, Bytes, BytesMut};
8use nex_core::bitfield::{u1, u12be};
9#[cfg(feature = "serde")]
10use serde::{Deserialize, Serialize};
11
12pub const VLAN_HEADER_LEN: usize = 4;
14
15#[repr(u8)]
17#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
18#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
19pub enum ClassOfService {
20 BK = 1,
22 BE = 0,
24 EE = 2,
26 CA = 3,
28 VI = 4,
30 VO = 5,
32 IC = 6,
34 NC = 7,
36 Unknown(u8),
38}
39
40impl ClassOfService {
41 pub fn new(val: u8) -> Self {
42 match val {
43 0 => ClassOfService::BE,
44 1 => ClassOfService::BK,
45 2 => ClassOfService::EE,
46 3 => ClassOfService::CA,
47 4 => ClassOfService::VI,
48 5 => ClassOfService::VO,
49 6 => ClassOfService::IC,
50 7 => ClassOfService::NC,
51 other => ClassOfService::Unknown(other),
52 }
53 }
54
55 pub fn value(&self) -> u8 {
56 match *self {
57 ClassOfService::BK => 1,
58 ClassOfService::BE => 0,
59 ClassOfService::EE => 2,
60 ClassOfService::CA => 3,
61 ClassOfService::VI => 4,
62 ClassOfService::VO => 5,
63 ClassOfService::IC => 6,
64 ClassOfService::NC => 7,
65 ClassOfService::Unknown(v) => v,
66 }
67 }
68}
69
70#[derive(Clone, Debug, PartialEq, Eq)]
72#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
73pub struct VlanHeader {
74 pub priority_code_point: ClassOfService,
75 pub drop_eligible_id: u1,
76 pub vlan_id: u12be,
77 pub ethertype: EtherType,
78}
79
80#[derive(Clone, Debug, PartialEq, Eq)]
82pub struct VlanPacket {
83 pub header: VlanHeader,
84 pub payload: Bytes,
85}
86
87impl Packet for VlanPacket {
88 type Header = VlanHeader;
89
90 fn from_buf(mut bytes: &[u8]) -> Option<Self> {
91 if bytes.len() < VLAN_HEADER_LEN {
92 return None;
93 }
94
95 let tci = bytes.get_u16();
97 let pcp = ClassOfService::new(((tci >> 13) & 0b111) as u8);
98 let drop_eligible_id = ((tci >> 12) & 0b1) as u1;
99 let vlan_id = (tci & 0x0FFF) as u12be;
100
101 let ethertype = EtherType::new(bytes.get_u16());
103
104 Some(VlanPacket {
106 header: VlanHeader {
107 priority_code_point: pcp,
108 drop_eligible_id,
109 vlan_id,
110 ethertype,
111 },
112 payload: Bytes::copy_from_slice(bytes),
113 })
114 }
115 fn from_bytes(mut bytes: Bytes) -> Option<Self> {
116 Self::from_buf(&mut bytes)
117 }
118
119 fn to_bytes(&self) -> Bytes {
120 let mut buf = BytesMut::with_capacity(VLAN_HEADER_LEN + self.payload.len());
121
122 let pcp_bits = (self.header.priority_code_point.value() as u16 & 0b111) << 13;
123 let dei_bits = (self.header.drop_eligible_id as u16 & 0b1) << 12;
124 let vlan_bits = self.header.vlan_id as u16 & 0x0FFF;
125
126 let tci = pcp_bits | dei_bits | vlan_bits;
127
128 buf.put_u16(tci);
129 buf.put_u16(self.header.ethertype.value());
130 buf.extend_from_slice(&self.payload);
131
132 buf.freeze()
133 }
134
135 fn header(&self) -> Bytes {
136 let mut buf = BytesMut::with_capacity(VLAN_HEADER_LEN);
137
138 let mut first = (self.header.priority_code_point.value() & 0b111) << 5;
139 first |= (self.header.drop_eligible_id & 0b1) << 4;
140 first |= ((self.header.vlan_id >> 8) & 0b0000_1111) as u8;
141
142 let second = (self.header.vlan_id & 0xFF) as u8;
143
144 buf.put_u8(first);
145 buf.put_u8(second);
146 buf.put_u16(self.header.ethertype.value());
147
148 buf.freeze()
149 }
150
151 fn payload(&self) -> Bytes {
152 self.payload.clone()
153 }
154
155 fn header_len(&self) -> usize {
156 VLAN_HEADER_LEN
157 }
158
159 fn payload_len(&self) -> usize {
160 self.payload.len()
161 }
162
163 fn total_len(&self) -> usize {
164 self.header_len() + self.payload_len()
165 }
166
167 fn into_parts(self) -> (Self::Header, Bytes) {
168 (self.header, self.payload)
169 }
170}
171
172pub struct MutableVlanPacket<'a> {
174 buffer: &'a mut [u8],
175}
176
177impl<'a> MutablePacket<'a> for MutableVlanPacket<'a> {
178 type Packet = VlanPacket;
179
180 fn new(buffer: &'a mut [u8]) -> Option<Self> {
181 if buffer.len() < VLAN_HEADER_LEN {
182 None
183 } else {
184 Some(Self { buffer })
185 }
186 }
187
188 fn packet(&self) -> &[u8] {
189 &*self.buffer
190 }
191
192 fn packet_mut(&mut self) -> &mut [u8] {
193 &mut *self.buffer
194 }
195
196 fn header(&self) -> &[u8] {
197 &self.packet()[..VLAN_HEADER_LEN]
198 }
199
200 fn header_mut(&mut self) -> &mut [u8] {
201 let (header, _) = (&mut *self.buffer).split_at_mut(VLAN_HEADER_LEN);
202 header
203 }
204
205 fn payload(&self) -> &[u8] {
206 &self.packet()[VLAN_HEADER_LEN..]
207 }
208
209 fn payload_mut(&mut self) -> &mut [u8] {
210 let (_, payload) = (&mut *self.buffer).split_at_mut(VLAN_HEADER_LEN);
211 payload
212 }
213}
214
215impl<'a> MutableVlanPacket<'a> {
216 pub fn new_unchecked(buffer: &'a mut [u8]) -> Self {
217 Self { buffer }
218 }
219
220 fn raw(&self) -> &[u8] {
221 &*self.buffer
222 }
223
224 fn raw_mut(&mut self) -> &mut [u8] {
225 &mut *self.buffer
226 }
227
228 pub fn get_priority_code_point(&self) -> ClassOfService {
229 let first = self.raw()[0];
230 ClassOfService::new(first >> 5)
231 }
232
233 pub fn set_priority_code_point(&mut self, class: ClassOfService) {
234 let buf = self.raw_mut();
235 buf[0] = (buf[0] & 0x1F) | ((class.value() & 0x07) << 5);
236 }
237
238 pub fn get_drop_eligible_id(&self) -> u1 {
239 ((self.raw()[0] >> 4) & 0x01) as u1
240 }
241
242 pub fn set_drop_eligible_id(&mut self, dei: u1) {
243 let buf = self.raw_mut();
244 buf[0] = (buf[0] & !(1 << 4)) | (((dei & 0x1) as u8) << 4);
245 }
246
247 pub fn get_vlan_id(&self) -> u16 {
248 let first = self.raw()[0] as u16 & 0x0F;
249 let second = self.raw()[1] as u16;
250 (first << 8) | second
251 }
252
253 pub fn set_vlan_id(&mut self, id: u16) {
254 let buf = self.raw_mut();
255 buf[0] = (buf[0] & 0xF0) | ((id >> 8) as u8 & 0x0F);
256 buf[1] = id as u8;
257 }
258
259 pub fn get_ethertype(&self) -> EtherType {
260 EtherType::new(u16::from_be_bytes([self.raw()[2], self.raw()[3]]))
261 }
262
263 pub fn set_ethertype(&mut self, ty: EtherType) {
264 self.raw_mut()[2..4].copy_from_slice(&ty.value().to_be_bytes());
265 }
266}
267
268#[cfg(test)]
269mod tests {
270 use super::*;
271
272 #[test]
273 fn test_vlan_parse() {
274 let raw = Bytes::from_static(&[
275 0x20, 0x00, 0x08, 0x00, b'x', b'y', b'z',
278 ]);
279
280 let packet = VlanPacket::from_bytes(raw.clone()).unwrap();
281
282 assert_eq!(packet.header.priority_code_point, ClassOfService::BK);
283 assert_eq!(packet.header.drop_eligible_id, 0);
284 assert_eq!(packet.header.vlan_id, 0x000);
285 assert_eq!(packet.header.ethertype, EtherType::Ipv4);
286 assert_eq!(packet.payload, Bytes::from_static(b"xyz"));
287 assert_eq!(packet.to_bytes(), raw);
288 }
289
290 #[test]
291 fn test_vlan_parse_2() {
292 let raw = Bytes::from_static(&[
293 0x01, 0x00, 0x08, 0x00, b'x', b'y', b'z',
296 ]);
297
298 let packet = VlanPacket::from_bytes(raw.clone()).unwrap();
299
300 assert_eq!(packet.header.priority_code_point, ClassOfService::BE);
301 assert_eq!(packet.header.drop_eligible_id, 0);
302 assert_eq!(packet.header.vlan_id, 0x100);
303 assert_eq!(packet.header.ethertype, EtherType::Ipv4);
304 assert_eq!(packet.payload, Bytes::from_static(b"xyz"));
305 assert_eq!(packet.to_bytes(), raw);
306 }
307
308 #[test]
309 fn test_mutable_vlan_packet_changes() {
310 let mut raw = [
311 0x00, 0x01, 0x08, 0x00, b'a', b'b',
314 ];
315
316 let mut packet = MutableVlanPacket::new(&mut raw).expect("mutable vlan");
317 assert_eq!(packet.get_vlan_id(), 1);
318 packet.set_priority_code_point(ClassOfService::VO);
319 packet.set_vlan_id(0x0abc);
320 packet.set_ethertype(EtherType::Ipv6);
321 packet.payload_mut()[0] = b'z';
322
323 let frozen = packet.freeze().expect("freeze");
324 assert_eq!(frozen.header.priority_code_point, ClassOfService::VO);
325 assert_eq!(frozen.header.vlan_id, 0x0abc);
326 assert_eq!(frozen.header.ethertype, EtherType::Ipv6);
327 assert_eq!(frozen.payload[0], b'z');
328 }
329}