1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
use crate::protocol::codec::Decode;
use nom::bits;
use nom::error::Error;
use nom::number;
use nom::sequence;
use nom::IResult;
/******************************************************************************
* Struct
******************************************************************************/
#[derive(Debug, PartialEq)]
pub struct MPLSHeader {
pub label: u32,
pub experimental: u8,
pub bottom_of_stack: bool,
pub ttl: u8,
}
// Ethernet pseudowire (PW) https://tools.ietf.org/html/rfc4448#section-3.1
#[derive(Debug, PartialEq)]
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);
}
}
|