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(&ethertype) {
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}