1use std::convert::TryInto;
4
5use serde::Serialize;
6
7use crate::errors::Error;
8use crate::layers::ethernet;
9use crate::types::{ETHERTYPE_MPLS_MULTICAST, ETHERTYPE_MPLS_UNICAST};
10use crate::Layer;
11
12use super::ipv4::IPv4;
13
14pub const MPLS_HEADER_LENGTH: usize = 4_usize;
16
17pub(crate) fn register_defaults() -> Result<(), Error> {
19 ethernet::register_ethertype(ETHERTYPE_MPLS_UNICAST, MPLS::creator)?;
20 ethernet::register_ethertype(ETHERTYPE_MPLS_MULTICAST, MPLS::creator)
21}
22
23#[derive(Debug, Default, Serialize, Copy, Clone)]
24pub struct MPLSLabel {
25 #[serde(serialize_with = "crate::types::hex::serialize_lower_hex_u32")]
27 label: u32, #[serde(serialize_with = "crate::types::hex::serialize_lower_hex_u8")]
29 exp: u8, bos: bool, #[serde(serialize_with = "crate::types::hex::serialize_lower_hex_u8")]
33 ttl: u8, }
35
36#[derive(Debug, Default, Serialize, Clone)]
37pub struct MPLS {
38 labels: Vec<MPLSLabel>,
39}
40
41impl MPLS {
42 pub fn creator() -> Box<dyn Layer + Send> {
43 Box::<MPLS>::default()
44 }
45}
46
47impl Layer for MPLS {
48 fn decode_bytes(
49 &mut self,
50 bytes: &[u8],
51 ) -> Result<(Option<Box<dyn Layer + Send>>, usize), Error> {
52 if bytes.len() < MPLS_HEADER_LENGTH {
53 return Err(Error::TooShort {
54 required: MPLS_HEADER_LENGTH,
55 available: bytes.len(),
56 data: hex::encode(bytes),
57 });
58 }
59
60 let mut byte_offset = 0;
61
62 loop {
63 let label =
65 u32::from_be_bytes(bytes[byte_offset..(byte_offset + 4)].try_into().unwrap()) >> 12;
66 let exp = u8::from_be(bytes[byte_offset + 2] << 4) >> 5;
67 let bos = bytes[byte_offset + 2] & 0x01 == 0x01;
68 let ttl = bytes[byte_offset + 3];
69
70 self.labels.push(MPLSLabel {
71 label,
72 exp,
73 bos,
74 ttl,
75 });
76 byte_offset += MPLS_HEADER_LENGTH;
77
78 if bos {
79 break;
80 }
81 }
82
83 Ok((Some(IPv4::creator()), byte_offset))
85 }
86
87 fn name(&self) -> &'static str {
88 "MPLS"
89 }
90
91 fn short_name(&self) -> &'static str {
92 "mpls"
93 }
94}
95
96#[cfg(test)]
97mod tests {
98
99 use crate::layers;
100 use crate::{Layer, Packet, ENCAP_TYPE_ETH};
101
102 wasm_tests! {
103 #[test]
104 fn parse_valid_mpls_packet() {
105 let _ = layers::register_defaults();
106
107 let mpls_packet = vec![
108 0x00, 0x30, 0x96, 0xe6, 0xfc, 0x39, 0x00, 0x30, 0x96, 0x05, 0x28, 0x38, 0x88, 0x47,
109 0x00, 0x01, 0xdd, 0xff, 0x45, 0xc0, 0x00, 0x28, 0x00, 0x03, 0x00, 0x00, 0xff, 0x06,
110 0xa4, 0xe8, 0x0a, 0x01, 0x02, 0x01, 0x0a, 0x22, 0x00, 0x01, 0x2a, 0xf9, 0x00, 0x17,
111 0x98, 0x32, 0x10, 0x05, 0x8d, 0xd5, 0x8e, 0xa5, 0x50, 0x10, 0x10, 0x20, 0x99, 0xcd,
112 0x00, 0x00, 0x00, 0x00,
113 ];
114
115 let mut mpls: Box<dyn Layer> = Box::new(super::MPLS::default());
116
117 let p = mpls.decode_bytes(&mpls_packet[28..]);
118 assert!(p.is_ok(), "{:#?}", mpls);
119 }
120
121 #[test]
122 fn test_mpls_parse_regression() {
123 let _ = layers::register_defaults();
124
125 let test_packet_mpls = vec![
133 0x00, 0x30, 0x96, 0xe6, 0xfc, 0x39, 0x00, 0x30, 0x96, 0x05, 0x28, 0x38, 0x88, 0x47,
134 0x00, 0x01, 0xdd, 0xff, 0x45, 0xc0, 0x00, 0x28, 0x00, 0x03, 0x00, 0x00, 0xff, 0x06,
135 0xa4, 0xe8, 0x0a, 0x01, 0x02, 0x01, 0x0a, 0x22, 0x00, 0x01, 0x2a, 0xf9, 0x00, 0x17,
136 0x98, 0x32, 0x10, 0x05, 0x8d, 0xd5, 0x8e, 0xa5, 0x50, 0x10, 0x10, 0x20, 0x99, 0xcd,
137 0x00, 0x00, 0x00, 0x00,
138 ];
139
140 let p = Packet::from_bytes(&test_packet_mpls, ENCAP_TYPE_ETH);
141 assert!(p.is_ok());
142 let p = p.unwrap();
143 assert!(p.layers.len() == 4, "{:#?}", p);
144 }
145 }
146}