use crate::ethernet::EtherType;
use crate::PrimitiveValues;
use alloc::vec::Vec;
use xenet_macro::packet;
use xenet_macro_helper::types::*;
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum ClassOfService {
BK = 1,
BE = 0,
EE = 2,
CA = 3,
VI = 4,
VO = 5,
IC = 6,
NC = 7,
Unknown(u3),
}
impl ClassOfService {
pub fn new(value: u3) -> ClassOfService {
match value {
1 => ClassOfService::BK,
0 => ClassOfService::BE,
2 => ClassOfService::EE,
3 => ClassOfService::CA,
4 => ClassOfService::VI,
5 => ClassOfService::VO,
6 => ClassOfService::IC,
7 => ClassOfService::NC,
_ => ClassOfService::Unknown(value),
}
}
}
impl PrimitiveValues for ClassOfService {
type T = (u3,);
fn to_primitive_values(&self) -> (u3,) {
match *self {
ClassOfService::BK => (1,),
ClassOfService::BE => (0,),
ClassOfService::EE => (2,),
ClassOfService::CA => (3,),
ClassOfService::VI => (4,),
ClassOfService::VO => (5,),
ClassOfService::IC => (6,),
ClassOfService::NC => (7,),
ClassOfService::Unknown(n) => (n,),
}
}
}
#[packet]
pub struct Vlan {
#[construct_with(u3)]
pub priority_code_point: ClassOfService,
pub drop_eligible_indicator: u1,
pub vlan_identifier: u12be,
#[construct_with(u16be)]
pub ethertype: EtherType,
#[payload]
pub payload: Vec<u8>,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ethernet::EtherType;
#[test]
fn vlan_packet_test() {
let mut packet = [0u8; 4];
{
let mut vlan_header = MutableVlanPacket::new(&mut packet[..]).unwrap();
vlan_header.set_priority_code_point(ClassOfService::BE);
assert_eq!(vlan_header.get_priority_code_point(), ClassOfService::BE);
vlan_header.set_drop_eligible_indicator(0);
assert_eq!(vlan_header.get_drop_eligible_indicator(), 0);
vlan_header.set_ethertype(EtherType::Ipv4);
assert_eq!(vlan_header.get_ethertype(), EtherType::Ipv4);
vlan_header.set_vlan_identifier(0x100);
assert_eq!(vlan_header.get_vlan_identifier(), 0x100);
}
let ref_packet = [
0x01, 0x00, 0x08, 0x00,
]; assert_eq!(&ref_packet[..], &packet[..]);
}
}