Skip to main content

flowscope/layers/
tunnel.rs

1//! Tunnel-header slices: GRE + VXLAN + GTP-U.
2//!
3//! Each tunnel slice holds the tunnel header bytes. The inner
4//! encapsulated frame is parsed into additional `Layer`s by the
5//! tunnel-walking loop in [`super::Layers::from_sliced`].
6
7use super::LayerKind;
8
9/// GRE (Generic Routing Encapsulation) header slice.
10///
11/// RFC 2784 fixed 4-byte header; RFC 2890 + variants add
12/// optional Checksum, Key, Sequence fields conditionally.
13#[derive(Debug, Clone, Copy)]
14pub struct GreSlice<'a> {
15    raw: &'a [u8],
16}
17
18impl<'a> GreSlice<'a> {
19    pub(crate) fn new(raw: &'a [u8]) -> Self {
20        Self { raw }
21    }
22
23    /// Checksum-present bit.
24    pub fn has_checksum(&self) -> bool {
25        self.raw[0] & 0x80 != 0
26    }
27
28    /// Key-present bit.
29    pub fn has_key(&self) -> bool {
30        self.raw[0] & 0x20 != 0
31    }
32
33    /// Sequence-number-present bit.
34    pub fn has_sequence(&self) -> bool {
35        self.raw[0] & 0x10 != 0
36    }
37
38    /// Protocol type (EtherType of the encapsulated payload).
39    pub fn protocol_type(&self) -> u16 {
40        u16::from_be_bytes([self.raw[2], self.raw[3]])
41    }
42
43    /// Compute the header length in bytes given the present
44    /// optional fields. 4-byte base + 4 each for checksum, key,
45    /// sequence.
46    pub fn header_len(&self) -> usize {
47        let mut len = 4;
48        if self.has_checksum() {
49            len += 4;
50        }
51        if self.has_key() {
52            len += 4;
53        }
54        if self.has_sequence() {
55            len += 4;
56        }
57        len
58    }
59
60    pub fn header(&self) -> &'a [u8] {
61        &self.raw[..self.header_len().min(self.raw.len())]
62    }
63
64    pub fn bytes(&self) -> &'a [u8] {
65        self.raw
66    }
67
68    pub fn kind(&self) -> LayerKind {
69        LayerKind::Gre
70    }
71}
72
73/// VXLAN header slice (RFC 7348).
74///
75/// Fixed 8-byte header: 1-byte flags + 3-byte reserved +
76/// 3-byte VNI (Virtual Network Identifier) + 1-byte reserved.
77#[derive(Debug, Clone, Copy)]
78pub struct VxlanSlice<'a> {
79    raw: &'a [u8],
80}
81
82impl<'a> VxlanSlice<'a> {
83    pub(crate) fn new(raw: &'a [u8]) -> Self {
84        Self { raw }
85    }
86
87    /// VNI-valid flag (bit 4 of the flags byte; RFC mandates).
88    pub fn valid(&self) -> bool {
89        self.raw[0] & 0x08 != 0
90    }
91
92    /// 24-bit Virtual Network Identifier.
93    pub fn vni(&self) -> u32 {
94        ((self.raw[4] as u32) << 16) | ((self.raw[5] as u32) << 8) | (self.raw[6] as u32)
95    }
96
97    pub fn header(&self) -> &'a [u8] {
98        &self.raw[..8.min(self.raw.len())]
99    }
100
101    pub fn bytes(&self) -> &'a [u8] {
102        self.raw
103    }
104
105    pub fn kind(&self) -> LayerKind {
106        LayerKind::Vxlan
107    }
108}
109
110/// GTP-U header slice (3GPP TS 29.281).
111///
112/// Mandatory 8-byte header: flags + msg type + length + TEID.
113/// Optional sequence + N-PDU + next-extension headers add
114/// further bytes when their flag bits are set.
115#[derive(Debug, Clone, Copy)]
116pub struct GtpUSlice<'a> {
117    raw: &'a [u8],
118}
119
120impl<'a> GtpUSlice<'a> {
121    pub(crate) fn new(raw: &'a [u8]) -> Self {
122        Self { raw }
123    }
124
125    /// GTP version (3 bits — should be `1` for GTP-U).
126    pub fn version(&self) -> u8 {
127        (self.raw[0] >> 5) & 0x07
128    }
129
130    /// Sequence-flag (S bit).
131    pub fn has_sequence(&self) -> bool {
132        self.raw[0] & 0x02 != 0
133    }
134
135    /// N-PDU-flag (PN bit).
136    pub fn has_n_pdu(&self) -> bool {
137        self.raw[0] & 0x01 != 0
138    }
139
140    /// Next-extension flag (E bit).
141    pub fn has_extension(&self) -> bool {
142        self.raw[0] & 0x04 != 0
143    }
144
145    /// Message type byte.
146    pub fn msg_type(&self) -> u8 {
147        self.raw[1]
148    }
149
150    /// 32-bit TEID (Tunnel Endpoint Identifier).
151    pub fn teid(&self) -> u32 {
152        u32::from_be_bytes([self.raw[4], self.raw[5], self.raw[6], self.raw[7]])
153    }
154
155    /// Header length including optional fields.
156    pub fn header_len(&self) -> usize {
157        let mut len = 8;
158        if self.has_sequence() || self.has_n_pdu() || self.has_extension() {
159            len += 4;
160        }
161        len
162    }
163
164    pub fn header(&self) -> &'a [u8] {
165        &self.raw[..self.header_len().min(self.raw.len())]
166    }
167
168    pub fn bytes(&self) -> &'a [u8] {
169        self.raw
170    }
171
172    pub fn kind(&self) -> LayerKind {
173        LayerKind::GtpU
174    }
175}