falco_plugin/tables/vtable/
mod.rs1use crate::error::last_error::LastError;
2use falco_plugin_api::{
3 ss_plugin_init_input, ss_plugin_owner_t, ss_plugin_rc, ss_plugin_state_type,
4 ss_plugin_table_info, ss_plugin_table_input, ss_plugin_table_t,
5};
6use thiserror::Error;
7
8pub mod fields;
9pub mod reader;
10pub mod writer;
11
12use crate::tables::LazyTableReader;
13use fields::TableFields;
14use writer::LazyTableWriter;
15
16#[derive(Error, Debug)]
17pub enum TableError {
18 #[error("Missing entry {0} in table operations vtable")]
19 BadVtable(&'static str),
20}
21
22#[derive(Debug)]
23pub struct TablesInput<'t> {
28 pub(crate) owner: *mut ss_plugin_owner_t,
29 pub(crate) last_error: LastError,
30 pub(crate) list_tables: unsafe extern "C-unwind" fn(
31 o: *mut ss_plugin_owner_t,
32 ntables: *mut u32,
33 ) -> *mut ss_plugin_table_info,
34 pub(crate) get_table: unsafe extern "C-unwind" fn(
35 o: *mut ss_plugin_owner_t,
36 name: *const ::std::os::raw::c_char,
37 key_type: ss_plugin_state_type,
38 ) -> *mut ss_plugin_table_t,
39 pub(crate) add_table: unsafe extern "C-unwind" fn(
40 o: *mut ss_plugin_owner_t,
41 in_: *const ss_plugin_table_input,
42 ) -> ss_plugin_rc,
43
44 pub(crate) reader_ext: LazyTableReader<'t>,
46
47 pub(crate) writer_ext: LazyTableWriter<'t>,
49
50 pub(crate) fields_ext: TableFields<'t>,
52}
53
54impl TablesInput<'_> {
55 pub(crate) fn try_from(value: &ss_plugin_init_input) -> Result<Option<Self>, TableError> {
56 if let Some(table_init_input) = unsafe { value.tables.as_ref() } {
57 let reader_ext = unsafe {
58 table_init_input
59 .reader_ext
60 .as_ref()
61 .ok_or(TableError::BadVtable("reader_ext"))?
62 };
63 let writer_ext = unsafe {
64 table_init_input
65 .writer_ext
66 .as_ref()
67 .ok_or(TableError::BadVtable("writer_ext"))?
68 };
69 let fields_ext = unsafe {
70 table_init_input
71 .fields_ext
72 .as_ref()
73 .ok_or(TableError::BadVtable("fields_ext"))?
74 };
75
76 let get_owner_last_error = value
77 .get_owner_last_error
78 .ok_or(TableError::BadVtable("get_owner_last_error"))?;
79 let last_error = unsafe { LastError::new(value.owner, get_owner_last_error) };
80
81 Ok(Some(TablesInput {
82 owner: value.owner,
83 last_error: last_error.clone(),
84 list_tables: table_init_input
85 .list_tables
86 .ok_or(TableError::BadVtable("list_tables"))?,
87 get_table: table_init_input
88 .get_table
89 .ok_or(TableError::BadVtable("get_table"))?,
90 add_table: table_init_input
91 .add_table
92 .ok_or(TableError::BadVtable("add_table"))?,
93 reader_ext: LazyTableReader::new(reader_ext, last_error.clone()),
94 writer_ext: LazyTableWriter::try_from(writer_ext, last_error)?,
95 fields_ext: TableFields::try_from(fields_ext)?,
96 }))
97 } else {
98 Ok(None)
99 }
100 }
101}
102
103impl TablesInput<'_> {
104 pub fn list_tables(&self) -> &[ss_plugin_table_info] {
110 let mut num_tables = 0u32;
111 let tables = unsafe { (self.list_tables)(self.owner, &mut num_tables as *mut _) };
112 if tables.is_null() {
113 &[]
114 } else {
115 unsafe { std::slice::from_raw_parts(tables, num_tables as usize) }
116 }
117 }
118}