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 raw_pcp = ((tci >> 13) & 0b111) as u8;
98 println!("DEBUG: tci=0x{:04x}, raw_pcp={}", tci, raw_pcp);
99 let pcp = ClassOfService::new(((tci >> 13) & 0b111) as u8);
100 let drop_eligible_id = ((tci >> 12) & 0b1) as u1;
101 let vlan_id = (tci & 0x0FFF) as u12be;
102
103 let ethertype = EtherType::new(bytes.get_u16());
105
106 Some(VlanPacket {
108 header: VlanHeader {
109 priority_code_point: pcp,
110 drop_eligible_id,
111 vlan_id,
112 ethertype,
113 },
114 payload: Bytes::copy_from_slice(bytes),
115 })
116 }
117 fn from_bytes(mut bytes: Bytes) -> Option<Self> {
118 Self::from_buf(&mut bytes)
119 }
120
121 fn to_bytes(&self) -> Bytes {
122 let mut buf = BytesMut::with_capacity(VLAN_HEADER_LEN + self.payload.len());
123
124 let pcp_bits = (self.header.priority_code_point.value() as u16 & 0b111) << 13;
125 let dei_bits = (self.header.drop_eligible_id as u16 & 0b1) << 12;
126 let vlan_bits = self.header.vlan_id as u16 & 0x0FFF;
127
128 let tci = pcp_bits | dei_bits | vlan_bits;
129
130 buf.put_u16(tci);
131 buf.put_u16(self.header.ethertype.value());
132 buf.extend_from_slice(&self.payload);
133
134 buf.freeze()
135 }
136
137 fn header(&self) -> Bytes {
138 let mut buf = BytesMut::with_capacity(VLAN_HEADER_LEN);
139
140 let mut first = (self.header.priority_code_point.value() & 0b111) << 5;
141 first |= (self.header.drop_eligible_id & 0b1) << 4;
142 first |= ((self.header.vlan_id >> 8) & 0b0000_1111) as u8;
143
144 let second = (self.header.vlan_id & 0xFF) as u8;
145
146 buf.put_u8(first);
147 buf.put_u8(second);
148 buf.put_u16(self.header.ethertype.value());
149
150 buf.freeze()
151 }
152
153 fn payload(&self) -> Bytes {
154 self.payload.clone()
155 }
156
157 fn header_len(&self) -> usize {
158 VLAN_HEADER_LEN
159 }
160
161 fn payload_len(&self) -> usize {
162 self.payload.len()
163 }
164
165 fn total_len(&self) -> usize {
166 self.header_len() + self.payload_len()
167 }
168
169 fn into_parts(self) -> (Self::Header, Bytes) {
170 (self.header, self.payload)
171 }
172}
173
174pub struct MutableVlanPacket<'a> {
176 buffer: &'a mut [u8],
177}
178
179impl<'a> MutablePacket<'a> for MutableVlanPacket<'a> {
180 type Packet = VlanPacket;
181
182 fn new(buffer: &'a mut [u8]) -> Option<Self> {
183 if buffer.len() < VLAN_HEADER_LEN {
184 None
185 } else {
186 Some(Self { buffer })
187 }
188 }
189
190 fn packet(&self) -> &[u8] {
191 &*self.buffer
192 }
193
194 fn packet_mut(&mut self) -> &mut [u8] {
195 &mut *self.buffer
196 }
197
198 fn header(&self) -> &[u8] {
199 &self.packet()[..VLAN_HEADER_LEN]
200 }
201
202 fn header_mut(&mut self) -> &mut [u8] {
203 let (header, _) = (&mut *self.buffer).split_at_mut(VLAN_HEADER_LEN);
204 header
205 }
206
207 fn payload(&self) -> &[u8] {
208 &self.packet()[VLAN_HEADER_LEN..]
209 }
210
211 fn payload_mut(&mut self) -> &mut [u8] {
212 let (_, payload) = (&mut *self.buffer).split_at_mut(VLAN_HEADER_LEN);
213 payload
214 }
215}
216
217impl<'a> MutableVlanPacket<'a> {
218 pub fn new_unchecked(buffer: &'a mut [u8]) -> Self {
219 Self { buffer }
220 }
221
222 fn raw(&self) -> &[u8] {
223 &*self.buffer
224 }
225
226 fn raw_mut(&mut self) -> &mut [u8] {
227 &mut *self.buffer
228 }
229
230 pub fn get_priority_code_point(&self) -> ClassOfService {
231 let first = self.raw()[0];
232 ClassOfService::new(first >> 5)
233 }
234
235 pub fn set_priority_code_point(&mut self, class: ClassOfService) {
236 let buf = self.raw_mut();
237 buf[0] = (buf[0] & 0x1F) | ((class.value() & 0x07) << 5);
238 }
239
240 pub fn get_drop_eligible_id(&self) -> u1 {
241 ((self.raw()[0] >> 4) & 0x01) as u1
242 }
243
244 pub fn set_drop_eligible_id(&mut self, dei: u1) {
245 let buf = self.raw_mut();
246 buf[0] = (buf[0] & !(1 << 4)) | (((dei & 0x1) as u8) << 4);
247 }
248
249 pub fn get_vlan_id(&self) -> u16 {
250 let first = self.raw()[0] as u16 & 0x0F;
251 let second = self.raw()[1] as u16;
252 (first << 8) | second
253 }
254
255 pub fn set_vlan_id(&mut self, id: u16) {
256 let buf = self.raw_mut();
257 buf[0] = (buf[0] & 0xF0) | ((id >> 8) as u8 & 0x0F);
258 buf[1] = id as u8;
259 }
260
261 pub fn get_ethertype(&self) -> EtherType {
262 EtherType::new(u16::from_be_bytes([self.raw()[2], self.raw()[3]]))
263 }
264
265 pub fn set_ethertype(&mut self, ty: EtherType) {
266 self.raw_mut()[2..4].copy_from_slice(&ty.value().to_be_bytes());
267 }
268}
269
270#[cfg(test)]
271mod tests {
272 use super::*;
273
274 #[test]
275 fn test_vlan_parse() {
276 let raw = Bytes::from_static(&[
277 0x20, 0x00, 0x08, 0x00, b'x', b'y', b'z',
280 ]);
281
282 let packet = VlanPacket::from_bytes(raw.clone()).unwrap();
283
284 assert_eq!(packet.header.priority_code_point, ClassOfService::BK);
285 assert_eq!(packet.header.drop_eligible_id, 0);
286 assert_eq!(packet.header.vlan_id, 0x000);
287 assert_eq!(packet.header.ethertype, EtherType::Ipv4);
288 assert_eq!(packet.payload, Bytes::from_static(b"xyz"));
289 assert_eq!(packet.to_bytes(), raw);
290 }
291
292 #[test]
293 fn test_vlan_parse_2() {
294 let raw = Bytes::from_static(&[
295 0x01, 0x00, 0x08, 0x00, b'x', b'y', b'z',
298 ]);
299
300 let packet = VlanPacket::from_bytes(raw.clone()).unwrap();
301
302 assert_eq!(packet.header.priority_code_point, ClassOfService::BE);
303 assert_eq!(packet.header.drop_eligible_id, 0);
304 assert_eq!(packet.header.vlan_id, 0x100);
305 assert_eq!(packet.header.ethertype, EtherType::Ipv4);
306 assert_eq!(packet.payload, Bytes::from_static(b"xyz"));
307 assert_eq!(packet.to_bytes(), raw);
308 }
309
310 #[test]
311 fn test_mutable_vlan_packet_changes() {
312 let mut raw = [
313 0x00, 0x01, 0x08, 0x00, b'a', b'b',
316 ];
317
318 let mut packet = MutableVlanPacket::new(&mut raw).expect("mutable vlan");
319 assert_eq!(packet.get_vlan_id(), 1);
320 packet.set_priority_code_point(ClassOfService::VO);
321 packet.set_vlan_id(0x0abc);
322 packet.set_ethertype(EtherType::Ipv6);
323 packet.payload_mut()[0] = b'z';
324
325 let frozen = packet.freeze().expect("freeze");
326 assert_eq!(frozen.header.priority_code_point, ClassOfService::VO);
327 assert_eq!(frozen.header.vlan_id, 0x0abc);
328 assert_eq!(frozen.header.ethertype, EtherType::Ipv6);
329 assert_eq!(frozen.payload[0], b'z');
330 }
331}