1use crate::{
2 eth::{EtherType, EthernetError},
3 getter_be,
4};
5use core::mem;
6
7use num_traits::FromPrimitive as _;
8
9#[repr(C)]
11#[derive(Debug, Copy, Clone)]
12#[cfg_attr(feature = "wincode", derive(wincode::SchemaRead, wincode::SchemaWrite))]
13#[cfg_attr(feature = "wincode", wincode(assert_zero_copy))]
14pub struct VlanHdr {
15 pub tci: [u8; 2],
17 pub ether_type: u16,
19}
20
21impl VlanHdr {
22 pub const LEN: usize = mem::size_of::<VlanHdr>();
23
24 #[inline]
25 fn tci(&self) -> u16 {
26 unsafe { getter_be!(self, tci, u16) }
28 }
29
30 #[inline]
32 pub fn pcp(&self) -> u8 {
33 (self.tci() >> 13) as u8
34 }
35
36 #[inline]
38 pub fn dei(&self) -> u8 {
39 ((self.tci() >> 12) & 1) as u8
40 }
41
42 #[inline]
44 pub fn vid(&self) -> u16 {
45 self.tci() & 0xFFF
46 }
47
48 #[inline]
50 pub fn ether_type(&self) -> Result<EtherType, EthernetError> {
51 EtherType::from_u16(self.ether_type).ok_or(EthernetError::InvalidEtherType(self.ether_type))
52 }
53}