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