1use crate::layer::{LayerKind, ethertype, ip_protocol};
7
8#[derive(Debug, Clone, Copy)]
13pub struct LayerBinding {
14 pub upper: LayerKind,
16 pub lower: LayerKind,
18 pub field_name: &'static str,
20 pub field_value: u16,
22}
23
24impl LayerBinding {
25 pub const fn new(
26 lower: LayerKind,
27 upper: LayerKind,
28 field_name: &'static str,
29 field_value: u16,
30 ) -> Self {
31 Self {
32 upper,
33 lower,
34 field_name,
35 field_value,
36 }
37 }
38}
39
40pub static LAYER_BINDINGS: &[LayerBinding] = &[
44 LayerBinding::new(LayerKind::Ethernet, LayerKind::Arp, "type", ethertype::ARP),
46 LayerBinding::new(
47 LayerKind::Ethernet,
48 LayerKind::Ipv4,
49 "type",
50 ethertype::IPV4,
51 ),
52 LayerBinding::new(
53 LayerKind::Ethernet,
54 LayerKind::Ipv6,
55 "type",
56 ethertype::IPV6,
57 ),
58 LayerBinding::new(
59 LayerKind::Ethernet,
60 LayerKind::Dot1Q,
61 "type",
62 ethertype::VLAN,
63 ),
64 LayerBinding::new(
65 LayerKind::Ethernet,
66 LayerKind::Dot1AD,
67 "type",
68 ethertype::DOT1AD,
69 ),
70 LayerBinding::new(
71 LayerKind::Ethernet,
72 LayerKind::Dot1AH,
73 "type",
74 ethertype::DOT1AH,
75 ),
76 LayerBinding::new(LayerKind::Ethernet, LayerKind::LLC, "type", 122), LayerBinding::new(LayerKind::Dot3, LayerKind::LLC, "len", 0), LayerBinding::new(LayerKind::Dot1Q, LayerKind::Arp, "type", ethertype::ARP),
81 LayerBinding::new(LayerKind::Dot1Q, LayerKind::Ipv4, "type", ethertype::IPV4),
82 LayerBinding::new(LayerKind::Dot1Q, LayerKind::Ipv6, "type", ethertype::IPV6),
83 LayerBinding::new(LayerKind::Dot1Q, LayerKind::Dot1Q, "type", ethertype::VLAN),
84 LayerBinding::new(
85 LayerKind::Dot1Q,
86 LayerKind::Dot1AD,
87 "type",
88 ethertype::DOT1AD,
89 ),
90 LayerBinding::new(
91 LayerKind::Dot1Q,
92 LayerKind::Dot1AH,
93 "type",
94 ethertype::DOT1AH,
95 ),
96 LayerBinding::new(
98 LayerKind::Dot1AD,
99 LayerKind::Dot1AD,
100 "type",
101 ethertype::DOT1AD,
102 ),
103 LayerBinding::new(LayerKind::Dot1AD, LayerKind::Dot1Q, "type", ethertype::VLAN),
104 LayerBinding::new(
105 LayerKind::Dot1AD,
106 LayerKind::Dot1AH,
107 "type",
108 ethertype::DOT1AH,
109 ),
110 LayerBinding::new(
112 LayerKind::Ipv4,
113 LayerKind::Tcp,
114 "proto",
115 ip_protocol::TCP as u16,
116 ),
117 LayerBinding::new(
118 LayerKind::Ipv4,
119 LayerKind::Udp,
120 "proto",
121 ip_protocol::UDP as u16,
122 ),
123 LayerBinding::new(
124 LayerKind::Ipv4,
125 LayerKind::Icmp,
126 "proto",
127 ip_protocol::ICMP as u16,
128 ),
129 LayerBinding::new(LayerKind::Tcp, LayerKind::Tls, "dport", 443),
131 LayerBinding::new(LayerKind::Tcp, LayerKind::Dns, "dport", 53),
132 LayerBinding::new(LayerKind::Tcp, LayerKind::Http, "dport", 80),
133 LayerBinding::new(LayerKind::Tcp, LayerKind::Http, "dport", 8080),
134 LayerBinding::new(LayerKind::Tcp, LayerKind::Http, "dport", 8000),
135 LayerBinding::new(LayerKind::Tcp, LayerKind::Http, "dport", 8008),
136 LayerBinding::new(LayerKind::Tcp, LayerKind::Http, "dport", 8888),
137 LayerBinding::new(LayerKind::Udp, LayerKind::Dns, "dport", 53),
139 LayerBinding::new(LayerKind::Udp, LayerKind::Quic, "dport", 443),
140 LayerBinding::new(LayerKind::Udp, LayerKind::Quic, "dport", 4433),
141 LayerBinding::new(LayerKind::Udp, LayerKind::L2tp, "dport", 1701),
142 LayerBinding::new(
144 LayerKind::Ipv6,
145 LayerKind::Tcp,
146 "nh",
147 ip_protocol::TCP as u16,
148 ),
149 LayerBinding::new(
150 LayerKind::Ipv6,
151 LayerKind::Udp,
152 "nh",
153 ip_protocol::UDP as u16,
154 ),
155 LayerBinding::new(
156 LayerKind::Ipv6,
157 LayerKind::Icmpv6,
158 "nh",
159 ip_protocol::ICMPV6 as u16,
160 ),
161];
162
163pub fn find_binding(lower: LayerKind, upper: LayerKind) -> Option<&'static LayerBinding> {
165 LAYER_BINDINGS
166 .iter()
167 .find(|b| b.lower == lower && b.upper == upper)
168}
169
170pub fn find_bindings_from(lower: LayerKind) -> impl Iterator<Item = &'static LayerBinding> {
172 LAYER_BINDINGS.iter().filter(move |b| b.lower == lower)
173}
174
175pub fn find_bindings_to(upper: LayerKind) -> impl Iterator<Item = &'static LayerBinding> {
177 LAYER_BINDINGS.iter().filter(move |b| b.upper == upper)
178}
179
180pub fn infer_upper_layer(lower: LayerKind, field_name: &str, value: u16) -> Option<LayerKind> {
185 LAYER_BINDINGS
186 .iter()
187 .find(|b| b.lower == lower && b.field_name == field_name && b.field_value == value)
188 .map(|b| b.upper)
189}
190
191pub fn expected_upper_layers(lower: LayerKind) -> Vec<LayerKind> {
193 find_bindings_from(lower).map(|b| b.upper).collect()
194}
195
196#[derive(Debug, Clone, Default)]
198pub struct BindingRegistry {
199 bindings: Vec<LayerBinding>,
200}
201
202impl BindingRegistry {
203 pub fn new() -> Self {
204 Self::default()
205 }
206
207 pub fn with_defaults() -> Self {
209 Self {
210 bindings: LAYER_BINDINGS.to_vec(),
211 }
212 }
213
214 pub fn register(
216 &mut self,
217 lower: LayerKind,
218 upper: LayerKind,
219 field_name: &'static str,
220 field_value: u16,
221 ) {
222 self.bindings
224 .retain(|b| !(b.lower == lower && b.upper == upper));
225 self.bindings
226 .push(LayerBinding::new(lower, upper, field_name, field_value));
227 }
228
229 pub fn find(&self, lower: LayerKind, upper: LayerKind) -> Option<&LayerBinding> {
231 self.bindings
232 .iter()
233 .find(|b| b.lower == lower && b.upper == upper)
234 }
235
236 pub fn find_from(&self, lower: LayerKind) -> impl Iterator<Item = &LayerBinding> {
238 self.bindings.iter().filter(move |b| b.lower == lower)
239 }
240
241 pub fn infer_upper(&self, lower: LayerKind, field_name: &str, value: u16) -> Option<LayerKind> {
243 self.bindings
244 .iter()
245 .find(|b| b.lower == lower && b.field_name == field_name && b.field_value == value)
246 .map(|b| b.upper)
247 }
248}
249
250pub fn apply_binding(lower: LayerKind, upper: LayerKind) -> Option<(&'static str, u16)> {
254 find_binding(lower, upper).map(|b| (b.field_name, b.field_value))
255}
256
257#[cfg(test)]
258mod tests {
259 use super::*;
260
261 #[test]
262 fn test_find_binding() {
263 let binding = find_binding(LayerKind::Ethernet, LayerKind::Arp);
264 assert!(binding.is_some());
265 let b = binding.unwrap();
266 assert_eq!(b.field_name, "type");
267 assert_eq!(b.field_value, 0x0806);
268 }
269
270 #[test]
271 fn test_find_bindings_from() {
272 let bindings: Vec<_> = find_bindings_from(LayerKind::Ethernet).collect();
273 assert!(bindings.len() >= 3); }
275
276 #[test]
277 fn test_infer_upper_layer() {
278 assert_eq!(
279 infer_upper_layer(LayerKind::Ethernet, "type", 0x0800),
280 Some(LayerKind::Ipv4)
281 );
282 assert_eq!(
283 infer_upper_layer(LayerKind::Ethernet, "type", 0x0806),
284 Some(LayerKind::Arp)
285 );
286 assert_eq!(
287 infer_upper_layer(LayerKind::Ipv4, "proto", 6),
288 Some(LayerKind::Tcp)
289 );
290 }
291
292 #[test]
293 fn test_apply_binding() {
294 let result = apply_binding(LayerKind::Ethernet, LayerKind::Ipv6);
295 assert_eq!(result, Some(("type", 0x86DD)));
296 }
297
298 #[test]
299 fn test_binding_registry() {
300 let mut registry = BindingRegistry::with_defaults();
301
302 registry.register(LayerKind::Ethernet, LayerKind::Raw, "type", 0x1234);
304
305 let binding = registry.find(LayerKind::Ethernet, LayerKind::Raw);
306 assert!(binding.is_some());
307 assert_eq!(binding.unwrap().field_value, 0x1234);
308 }
309
310 #[test]
311 fn test_expected_upper_layers() {
312 let uppers = expected_upper_layers(LayerKind::Ethernet);
313 assert!(uppers.contains(&LayerKind::Arp));
314 assert!(uppers.contains(&LayerKind::Ipv4));
315 assert!(uppers.contains(&LayerKind::Ipv6));
316 }
317}