libpacket/
vlan.rs

1//! A VLAN packet abstraction.
2
3use crate::ethernet::EtherType;
4use crate::{types::*, Packet, PrimitiveValues};
5
6/// Represents an IEEE 802.1p class of a service.
7#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub struct ClassOfService(pub u3);
9
10impl ClassOfService {
11    /// Create a new `ClassOfService` instance.
12    pub fn new(value: u3) -> ClassOfService {
13        ClassOfService(value)
14    }
15}
16
17impl PrimitiveValues for ClassOfService {
18    type T = (u3,);
19    fn to_primitive_values(&self) -> (u3,) {
20        (self.0,)
21    }
22}
23
24/// IEEE 802.1p classes of service as defined in
25/// https://en.wikipedia.org/wiki/IEEE_P802.1p.
26#[allow(non_snake_case)]
27#[allow(non_upper_case_globals)]
28pub mod ClassesOfService {
29    use super::ClassOfService;
30
31    /// Background
32    pub const BK: ClassOfService = ClassOfService(1);
33
34    /// Best Effort
35    pub const BE: ClassOfService = ClassOfService(0);
36
37    /// Excellent Effort
38    pub const EE: ClassOfService = ClassOfService(2);
39
40    /// Critical Applications
41    pub const CA: ClassOfService = ClassOfService(3);
42
43    /// Video, < 100 ms latency
44    pub const VI: ClassOfService = ClassOfService(4);
45
46    /// Voice, < 10 ms latency
47    pub const VO: ClassOfService = ClassOfService(5);
48
49    /// Internetwork Control
50    pub const IC: ClassOfService = ClassOfService(6);
51
52    /// Network Control
53    pub const NC: ClassOfService = ClassOfService(7);
54}
55
56/// Represents a VLAN-tagged packet.
57#[derive(Debug, Packet)]
58pub struct Vlan {
59    #[construct_with(u3)]
60    pub priority_code_point: ClassOfService,
61    pub drop_eligible_indicator: u1,
62    pub vlan_identifier: u12be,
63    #[construct_with(u16be)]
64    pub ethertype: EtherType,
65    #[payload]
66    pub payload: Vec<u8>,
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72    use crate::ethernet::EtherTypes;
73
74    #[test]
75    fn vlan_packet_test() {
76        let mut packet = [0u8; 4];
77        {
78            let mut vlan_header = MutableVlanPacket::new(&mut packet[..]).unwrap();
79            vlan_header.set_priority_code_point(ClassesOfService::BE);
80            assert_eq!(vlan_header.get_priority_code_point(), ClassesOfService::BE);
81
82            vlan_header.set_drop_eligible_indicator(0);
83            assert_eq!(vlan_header.get_drop_eligible_indicator(), 0);
84
85            vlan_header.set_ethertype(EtherTypes::Ipv4);
86            assert_eq!(vlan_header.get_ethertype(), EtherTypes::Ipv4);
87
88            vlan_header.set_vlan_identifier(0x100);
89            assert_eq!(vlan_header.get_vlan_identifier(), 0x100);
90        }
91
92        let ref_packet = [
93            0x01, // PCP, DEI, and first nibble of VID
94            0x00, // Remainder of VID
95            0x08, // First byte of ethertype
96            0x00,
97        ]; // Second byte of ethertype
98        assert_eq!(&ref_packet[..], &packet[..]);
99    }
100}