use crate::protocol::codec::Decode; use nom::bits; use nom::error::Error; use nom::number; use nom::sequence; use nom::IResult; /****************************************************************************** * Struct ******************************************************************************/ #[derive(Clone, Debug, PartialEq, Eq)] pub struct MPLSHeader { pub label: u32, pub experimental: u8, pub bottom_of_stack: bool, pub ttl: u8, } #[derive(Clone, Debug, PartialEq, Eq)] // Ethernet pseudowire (PW) https://tools.ietf.org/html/rfc4448#section-3.1 pub struct PWEthHeader { pub control_word: u32, } /****************************************************************************** * API ******************************************************************************/ fn bit_decode(input: &[u8]) -> IResult<&[u8], (u32, u8, u8, u8)> { bits::bits::<_, _, Error<_>, _, _>(sequence::tuple(( bits::streaming::take(20u8), bits::streaming::take(3u8), bits::streaming::take(1u8), bits::streaming::take(8u8), )))(input) } impl Decode for MPLSHeader { type Iterm = MPLSHeader; fn decode(input: &[u8]) -> IResult<&[u8], MPLSHeader> { let (input, (label, experimental, bottom_of_stack, ttl)) = bit_decode(input)?; Ok(( input, MPLSHeader { label, experimental, bottom_of_stack: bottom_of_stack == 1, ttl, }, )) } } impl Decode for PWEthHeader { type Iterm = PWEthHeader; fn decode(input: &[u8]) -> IResult<&[u8], PWEthHeader> { let (input, control_word) = number::streaming::be_u32(input)?; Ok((input, PWEthHeader { control_word })) } } /****************************************************************************** * TEST ******************************************************************************/ #[cfg(test)] mod tests { use super::MPLSHeader; use crate::protocol::codec::Decode; const LAST_SLICE: &'static [u8] = &[0xff]; #[test] fn mpls_header_decode() { /* * MultiProtocol Label Switching Header, Label: 18, Exp: 5, S: 0, TTL: 255 * 0000 0000 0000 0001 0010 .... .... .... = MPLS Label: 18 (0x00012) * .... .... .... .... .... 101. .... .... = MPLS Experimental Bits: 5 * .... .... .... .... .... ...0 .... .... = MPLS Bottom Of Label Stack: 0 * .... .... .... .... .... .... 1111 1111 = MPLS TTL: 255 * MultiProtocol Label Switching Header, Label: 16, Exp: 5, S: 1, TTL: 255 * 0000 0000 0000 0001 0000 .... .... .... = MPLS Label: 16 (0x00010) * .... .... .... .... .... 101. .... .... = MPLS Experimental Bits: 5 * .... .... .... .... .... ...1 .... .... = MPLS Bottom Of Label Stack: 1 * .... .... .... .... .... .... 1111 1111 = MPLS TTL: 255 */ let bytes = [0x00, 0x01, 0x2a, 0xff, 0x00, 0x01, 0x0b, 0xff, 0xff]; let expectation1 = MPLSHeader { label: 18, experimental: 5, bottom_of_stack: false, ttl: 255, }; let expectation2 = MPLSHeader { label: 16, experimental: 5, bottom_of_stack: true, ttl: 255, }; assert_eq!(MPLSHeader::decode(&bytes), Ok((&bytes[4..], expectation1))); assert_eq!( MPLSHeader::decode(&bytes[4..]), Ok((LAST_SLICE, expectation2)) ); // example let mut payload = &bytes[..]; while let Ok((remain, header)) = MPLSHeader::decode(payload) { println!("return: {:?}, payload: {}", header, remain.len()); payload = remain; if header.bottom_of_stack { break; } } // assert_eq!(1, 0); } }