network_types/
vlan.rs

1use crate::{eth::EtherType, getter_be};
2use core::mem;
3
4/// VLAN tag header structure
5#[repr(C, packed)]
6#[derive(Debug, Copy, Clone)]
7#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
8pub struct VlanHdr {
9    /// First 2 bytes containing PCP (3 bits), DEI (1 bit), and VLAN ID (12 bits)
10    pub tci: [u8; 2],
11    /// EtherType field indicating the protocol encapsulated in the payload
12    pub eth_type: EtherType,
13}
14
15impl VlanHdr {
16    pub const LEN: usize = mem::size_of::<VlanHdr>();
17
18    #[inline]
19    fn tci(&self) -> u16 {
20        // SAFETY: Pointer arithmetic in bounds of the struct.
21        unsafe { getter_be!(self, tci, u16) }
22    }
23
24    /// Extract the Priority Code Point (PCP) from the VLAN header
25    #[inline]
26    pub fn pcp(&self) -> u8 {
27        (self.tci() >> 13) as u8
28    }
29
30    /// Extract the Drop Eligible Indicator (DEI) from the VLAN header
31    #[inline]
32    pub fn dei(&self) -> u8 {
33        ((self.tci() >> 12) & 1) as u8
34    }
35
36    /// Extract the VLAN ID from the VLAN header
37    #[inline]
38    pub fn vid(&self) -> u16 {
39        self.tci() & 0xFFF
40    }
41
42    /// Get the EtherType value
43    #[inline]
44    pub fn eth_type(&self) -> EtherType {
45        self.eth_type
46    }
47}