pako_core/plugin_registry.rs
1// use crate::packet_info::PacketInfo;
2// use std::collections::HashMap;
3use std::sync::{Arc, Mutex};
4
5use log::trace;
6// use libpcap_tools::{Packet, ThreeTuple};
7use multimap::MultiMap;
8
9use crate::plugin::*;
10
11/// Shorthand definition for wrapped plugin
12pub type SafePlugin = Arc<Mutex<dyn Plugin>>;
13/// Unique identifier for a plugin instance
14pub type PluginID = usize;
15
16#[macro_export]
17macro_rules! build_safeplugin {
18 ($p:expr) => {
19 ::std::sync::Arc::new(::std::sync::Mutex::new($p))
20 };
21}
22
23#[derive(Clone, Eq, PartialEq, Hash)]
24pub struct PluginInfo {
25 pub layer: u8,
26 pub layer_filter: u16,
27}
28
29#[derive(Default)]
30pub struct PluginRegistry {
31 // plugins_l2: Vec<SafePlugin>,
32 // plugins_ethertype_ipv4: Vec<SafePlugin>,
33 // plugins_ethertype_ipv6: Vec<SafePlugin>,
34 // // OSI 3: network layer protocol (IPv4, IPv6, etc.)
35 // plugins_ethertype: HashMap<u16, Vec<SafePlugin>>,
36 // // plugins registered for all network layer protocols
37 // plugins_ethertype_all: Vec<SafePlugin>,
38 // // OSI 4: Transport layer (TCP, UDP, etc.)
39 // // Note: fixed-size (256)
40 // plugins_transport: Vec<Vec<SafePlugin>>,
41 // // plugins registered for all transport layer protocols
42 // plugins_transport_all: Vec<SafePlugin>,
43 plugins_all: Vec<SafePlugin>,
44
45 plugins: MultiMap<PluginInfo, SafePlugin>,
46}
47
48impl PluginRegistry {
49 pub fn new() -> Self {
50 // let mut v = Vec::with_capacity(256);
51 // for _ in 0..256 {
52 // v.push(Vec::new());
53 // }
54 // PluginRegistry {
55 // plugins_transport: v,
56 // ..PluginRegistry::default()
57 // }
58 PluginRegistry::default()
59 }
60
61 /// Return the count of different plugins
62 ///
63 /// A plugin can be registered for several layers, but it will count as one.
64 pub fn num_plugins(&self) -> usize {
65 self.plugins_all.len()
66 }
67
68 /// Add a plugin to the registry, and return the identifier
69 pub fn add_plugin(&mut self, plugin: SafePlugin) -> PluginID {
70 let id = self.plugins_all.len();
71 self.plugins_all.push(plugin);
72 id
73 }
74
75 // pub fn register_l2(&mut self, plugin: SafePlugin) {
76 // self.plugins_l2.push(plugin);
77 // }
78
79 // pub fn register_ethertype(&mut self, ethertype: u16, plugin: SafePlugin) {
80 // if ethertype == ETHERTYPE_IPV4 {
81 // self.plugins_ethertype_ipv4.push(plugin);
82 // } else if ethertype == ETHERTYPE_IPV6 {
83 // self.plugins_ethertype_ipv6.push(plugin);
84 // } else {
85 // let l = &mut self
86 // .plugins_ethertype
87 // .entry(ethertype)
88 // .or_insert_with(Vec::new);
89 // l.push(plugin);
90 // }
91 // }
92
93 // pub fn register_ethertype_all(&mut self, plugin: SafePlugin) {
94 // self.plugins_ethertype_all.push(plugin);
95 // }
96
97 // pub fn register_transport_layer(&mut self, proto: u8, plugin: SafePlugin) {
98 // let l = &mut self.plugins_transport[proto as usize];
99 // l.push(plugin);
100 // }
101
102 // pub fn register_transport_layer_all(&mut self, plugin: SafePlugin) {
103 // self.plugins_transport_all.push(plugin);
104 // }
105
106 // pub fn run_plugins_l2(&self, packet: &Packet, data: &[u8]) {
107 // for p in &self.plugins_l2 {
108 // p.lock().unwrap().handle_l2(&packet, &data);
109 // }
110 // }
111
112 // pub fn run_plugins_ethertype(
113 // &self,
114 // packet: &Packet,
115 // ethertype: u16,
116 // three_tuple: &ThreeTuple,
117 // data: &[u8],
118 // ) {
119 // if ethertype == ETHERTYPE_IPV4 {
120 // for p in &self.plugins_ethertype_ipv4 {
121 // p.lock()
122 // .unwrap()
123 // .handle_l3(packet, data, ethertype, three_tuple);
124 // }
125 // } else if ethertype == ETHERTYPE_IPV6 {
126 // for p in &self.plugins_ethertype_ipv6 {
127 // p.lock()
128 // .unwrap()
129 // .handle_l3(packet, data, ethertype, three_tuple);
130 // }
131 // } else if let Some(l) = self.plugins_ethertype.get(ðertype) {
132 // for p in &*l {
133 // p.lock()
134 // .unwrap()
135 // .handle_l3(packet, data, ethertype, three_tuple);
136 // }
137 // }
138 // for p in &self.plugins_ethertype_all {
139 // p.lock()
140 // .unwrap()
141 // .handle_l3(packet, data, ethertype, three_tuple);
142 // }
143 // }
144
145 // pub fn run_plugins_transport(&self, proto: u8, packet: &Packet, pinfo: &PacketInfo) {
146 // let l = &self.plugins_transport[proto as usize];
147 // for p in &*l {
148 // p.lock().unwrap().handle_l4(&packet, &pinfo);
149 // }
150 // for p in &self.plugins_transport_all {
151 // p.lock().unwrap().handle_l4(&packet, &pinfo);
152 // }
153 // }
154
155 /// Run function `F` on all known plugins (registered or not) matching `P`
156 pub fn run_plugins<F, P>(&self, mut predicate: P, mut f: F)
157 where
158 F: FnMut(&mut dyn Plugin),
159 P: FnMut(&dyn Plugin) -> bool,
160 {
161 self.plugins_all.iter().for_each(|p| {
162 let mut p = p.lock().unwrap();
163 if predicate(&*p) {
164 // debug!("Running callback for plugin {}", p.name());
165 f(&mut *p);
166 }
167 });
168 }
169
170 /// Register a layer for analysis, for the identified plugin
171 ///
172 /// `layer_filter` is a filter on the value relative to the layer: for L3,
173 /// use for ex. ETHERNET_IPV4, for L4, TRANSPORT_TCP, etc.
174 /// Special value `0` for `layer_filter` means all possible values.
175 pub fn register_layer(
176 &mut self,
177 layer: u8,
178 layer_filter: u16,
179 plugin_id: PluginID,
180 ) -> Result<(), PluginBuilderError> {
181 if plugin_id >= self.plugins_all.len() {
182 return Err(PluginBuilderError::Registration(
183 "Invalid Plugin ID".to_string(),
184 ));
185 }
186
187 trace!(
188 "registering plugin for layer={} filter=0x{:04x}",
189 layer,
190 layer_filter
191 );
192 let plugin = &self.plugins_all[plugin_id];
193 let plugin_info = PluginInfo {
194 layer,
195 layer_filter,
196 };
197 self.plugins.insert(plugin_info, plugin.clone());
198
199 Ok(())
200 }
201
202 /// Get plugins matching the given `layer` and `layer_filter`
203 pub fn get_plugins_for_layer(&self, layer: u8, layer_filter: u16) -> Option<&Vec<SafePlugin>> {
204 let plugin_info = PluginInfo {
205 layer,
206 layer_filter,
207 };
208 self.plugins.get_vec(&plugin_info)
209 }
210
211 /// Return an iterator on registered plugins
212 ///
213 /// The same plugin instance can be present multiple times, if registered with different `PluginInfo`
214 /// (for ex. layer filters).
215 pub fn iter_registered_plugins(&self) -> impl Iterator<Item = (&PluginInfo, &SafePlugin)> {
216 self.plugins.iter()
217 }
218
219 /// Return an iterator on all known plugins
220 ///
221 /// Known plugins are plugins present in the registry (registered or not for layers)
222 pub fn iter_plugins(&self) -> impl Iterator<Item = &SafePlugin> {
223 self.plugins_all.iter()
224 }
225}