From 364d2c077d529bb01b3ca5cc3f53b1b9beb5d712 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 20 Jan 2026 22:42:05 +0100 Subject: [PATCH] rust: bindgen SCAppLayerRegisterParser Ticket: 7662 --- examples/plugins/altemplate/src/template.rs | 3 +- rust/Makefile.am | 8 - rust/src/applayer.rs | 51 +++++- rust/sys/src/sys.rs | 179 +++++++++++++++++--- src/app-layer-register.c | 2 +- src/app-layer-register.h | 2 +- 6 files changed, 204 insertions(+), 41 deletions(-) diff --git a/examples/plugins/altemplate/src/template.rs b/examples/plugins/altemplate/src/template.rs index 261cab741d..48a65129e9 100644 --- a/examples/plugins/altemplate/src/template.rs +++ b/examples/plugins/altemplate/src/template.rs @@ -26,6 +26,7 @@ use std; use std::collections::VecDeque; use std::ffi::CString; use std::os::raw::{c_char, c_int, c_void}; + use suricata::applayer::{AppLayerResultRust, StreamSliceRust}; use suricata::applayer::{ applayer_register_protocol_detection, state_get_tx_iterator, AppLayerEvent, AppLayerRegisterParser, AppLayerResult, AppLayerStateData, AppLayerTxData, RustParser, State, @@ -221,7 +222,7 @@ impl TemplateState { start = rem; if let Some(tx) = self.find_request() { - tx.tx_data.updated_tc = true; + tx.tx_data.0.updated_tc = true; tx.response = Some(response); SCLogNotice!("Found response for request:"); SCLogNotice!("- Request: {:?}", tx.request); diff --git a/rust/Makefile.am b/rust/Makefile.am index 0558725c99..dce38d127e 100644 --- a/rust/Makefile.am +++ b/rust/Makefile.am @@ -145,14 +145,6 @@ if HAVE_BINDGEN --allowlist-function 'AppProto.*' \ --allowlist-function 'File.*' \ --allowlist-type 'SC.*' \ - --allowlist-type 'AppLayerEventType' \ - --allowlist-type 'AppLayerGetFileState' \ - --allowlist-type 'AppLayerGetTxIterState' \ - --allowlist-type 'AppLayerStateData' \ - --allowlist-type 'AppLayerGetTxIterTuple' \ - --allowlist-type 'AppLayerResult' \ - --allowlist-type 'AppLayerTxData' \ - --allowlist-type 'StreamSlice' \ --no-copy 'AppLayerTxData' \ --allowlist-function 'SC.*' \ --allowlist-var 'SC.*' \ diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index b4e0c94e27..43da73d148 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -387,11 +387,52 @@ pub type GetFrameNameById = unsafe extern "C" fn(u8) -> *const c_char; pub type GetStateIdByName = unsafe extern "C" fn(*const c_char, u8) -> c_int; pub type GetStateNameById = unsafe extern "C" fn(c_int, u8) -> *const c_char; -// Defined in app-layer-register.h -#[allow(unused_doc_comments)] -/// cbindgen:ignore -extern "C" { - pub fn AppLayerRegisterParser(parser: *const RustParser, alproto: AppProto) -> c_int; +use suricata_sys::sys::{AppLayerParser, SCAppLayerRegisterParser}; + +#[allow(non_snake_case)] +pub fn AppLayerRegisterParser(parser: &RustParser, alproto: AppProto) -> c_int { + let det = AppLayerParser{ + name: parser.name, + default_port: parser.default_port, + ip_proto: parser.ipproto, + ProbeTS: parser.probe_ts, + ProbeTC: parser.probe_tc, + min_depth: parser.min_depth, + max_depth: parser.max_depth, + + StateAlloc: Some(parser.state_new), + StateFree: Some(parser.state_free), + + ParseTS: Some(parser.parse_ts), + ParseTC: Some(parser.parse_tc), + + StateGetTxCnt: Some(parser.get_tx_count), + StateGetTx: Some(parser.get_tx), + StateTransactionFree: Some(parser.tx_free), + + complete_ts: parser.tx_comp_st_ts, + complete_tc: parser.tx_comp_st_tc, + StateGetProgress: Some(parser.tx_get_progress), + + StateGetEventInfo: parser.get_eventinfo, + StateGetEventInfoById: parser.get_eventinfo_byid, + LocalStorageAlloc: parser.localstorage_new, + LocalStorageFree: parser.localstorage_free, + + GetTxFiles: parser.get_tx_files, + GetTxIterator: parser.get_tx_iterator, + GetStateData: Some(parser.get_state_data), + GetTxData: Some(parser.get_tx_data), + ApplyTxConfig: parser.apply_tx_config, + + flags: parser.flags, + + GetFrameIdByName: parser.get_frame_id_by_name, + GetFrameNameById: parser.get_frame_name_by_id, + GetStateIdByName: parser.get_state_id_by_name, + GetStateNameById: parser.get_state_name_by_id, + }; + unsafe {SCAppLayerRegisterParser(&det, alproto) } } use suricata_sys::sys::{AppLayerProtocolDetect, SCAppLayerRegisterProtocolDetection}; diff --git a/rust/sys/src/sys.rs b/rust/sys/src/sys.rs index 77d3b31cb9..20e5bc9cb8 100644 --- a/rust/sys/src/sys.rs +++ b/rust/sys/src/sys.rs @@ -1001,6 +1001,41 @@ extern "C" { ) -> ::std::os::raw::c_int; } #[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] +pub struct AppLayerResult { + pub status: i32, + pub consumed: u32, + pub needed: u32, +} +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct StreamSlice { + pub input: *const u8, + pub input_len: u32, + #[doc = " STREAM_* flags"] + pub flags: u8, + pub offset: u64, +} +impl Default for StreamSlice { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " \\brief Prototype for parsing functions"] +pub type AppLayerParserFPtr = ::std::option::Option< + unsafe extern "C" fn( + f: *mut Flow, + protocol_state: *mut ::std::os::raw::c_void, + pstate: *mut AppLayerParserState, + stream_slice: StreamSlice, + local_storage: *mut ::std::os::raw::c_void, + ) -> AppLayerResult, +>; +#[repr(C)] #[derive(Copy, Clone)] pub struct AppLayerGetTxIterState { pub un: AppLayerGetTxIterState__bindgen_ty_1, @@ -1051,31 +1086,6 @@ impl Default for AppLayerGetTxIterTuple { } } #[repr(C)] -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct StreamSlice { - pub input: *const u8, - pub input_len: u32, - #[doc = " STREAM_* flags"] - pub flags: u8, - pub offset: u64, -} -impl Default for StreamSlice { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] -pub struct AppLayerResult { - pub status: i32, - pub consumed: u32, - pub needed: u32, -} -#[repr(C)] #[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] pub struct AppLayerTxConfig { #[doc = " config: log flags"] @@ -1121,6 +1131,22 @@ impl Default for AppLayerTxData { extern "C" { pub fn SCAppLayerTxDataCleanup(txd: *mut AppLayerTxData); } +#[doc = " \\param name progress name to get the id for\n \\param direction STREAM_TOSERVER/STREAM_TOCLIENT"] +pub type AppLayerParserGetStateIdByNameFn = ::std::option::Option< + unsafe extern "C" fn( + name: *const ::std::os::raw::c_char, + direction: u8, + ) -> ::std::os::raw::c_int, +>; +#[doc = " \\param id progress value id to get the name for\n \\param direction STREAM_TOSERVER/STREAM_TOCLIENT"] +pub type AppLayerParserGetStateNameByIdFn = ::std::option::Option< + unsafe extern "C" fn(id: ::std::os::raw::c_int, direction: u8) -> *const ::std::os::raw::c_char, +>; +pub type AppLayerParserGetFrameIdByNameFn = ::std::option::Option< + unsafe extern "C" fn(frame_name: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int, +>; +pub type AppLayerParserGetFrameNameByIdFn = + ::std::option::Option *const ::std::os::raw::c_char>; extern "C" { pub fn SCAppLayerParserReallocCtx(alproto: AppProto) -> ::std::os::raw::c_int; } @@ -1149,6 +1175,103 @@ extern "C" { extern "C" { pub fn FileApplyTxFlags(txd: *const AppLayerTxData, direction: u8, file: *mut File); } +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct AppLayerParser { + pub name: *const ::std::os::raw::c_char, + pub default_port: *const ::std::os::raw::c_char, + pub ip_proto: u8, + pub ProbeTS: ProbingParserFPtr, + pub ProbeTC: ProbingParserFPtr, + pub min_depth: u16, + pub max_depth: u16, + pub StateAlloc: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: AppProto, + ) -> *mut ::std::os::raw::c_void, + >, + pub StateFree: ::std::option::Option, + pub ParseTS: AppLayerParserFPtr, + pub ParseTC: AppLayerParserFPtr, + pub StateGetTxCnt: + ::std::option::Option u64>, + pub StateGetTx: ::std::option::Option< + unsafe extern "C" fn( + alstate: *mut ::std::os::raw::c_void, + tx_id: u64, + ) -> *mut ::std::os::raw::c_void, + >, + pub StateTransactionFree: + ::std::option::Option, + pub complete_ts: ::std::os::raw::c_int, + pub complete_tc: ::std::os::raw::c_int, + pub StateGetProgress: ::std::option::Option< + unsafe extern "C" fn( + alstate: *mut ::std::os::raw::c_void, + direction: u8, + ) -> ::std::os::raw::c_int, + >, + pub StateGetEventInfo: ::std::option::Option< + unsafe extern "C" fn( + event_name: *const ::std::os::raw::c_char, + event_id: *mut u8, + event_type: *mut AppLayerEventType, + ) -> ::std::os::raw::c_int, + >, + pub StateGetEventInfoById: ::std::option::Option< + unsafe extern "C" fn( + event_id: u8, + event_name: *mut *const ::std::os::raw::c_char, + event_type: *mut AppLayerEventType, + ) -> ::std::os::raw::c_int, + >, + pub LocalStorageAlloc: + ::std::option::Option *mut ::std::os::raw::c_void>, + pub LocalStorageFree: + ::std::option::Option, + pub GetTxFiles: ::std::option::Option< + unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void, arg2: u8) -> AppLayerGetFileState, + >, + pub GetTxIterator: ::std::option::Option< + unsafe extern "C" fn( + ipproto: u8, + alproto: AppProto, + alstate: *mut ::std::os::raw::c_void, + min_tx_id: u64, + max_tx_id: u64, + istate: *mut AppLayerGetTxIterState, + ) -> AppLayerGetTxIterTuple, + >, + pub GetStateData: ::std::option::Option< + unsafe extern "C" fn(state: *mut ::std::os::raw::c_void) -> *mut AppLayerStateData, + >, + pub GetTxData: ::std::option::Option< + unsafe extern "C" fn(tx: *mut ::std::os::raw::c_void) -> *mut AppLayerTxData, + >, + pub ApplyTxConfig: ::std::option::Option< + unsafe extern "C" fn( + state: *mut ::std::os::raw::c_void, + tx: *mut ::std::os::raw::c_void, + mode: ::std::os::raw::c_int, + arg1: AppLayerTxConfig, + ), + >, + pub flags: u32, + pub GetFrameIdByName: AppLayerParserGetFrameIdByNameFn, + pub GetFrameNameById: AppLayerParserGetFrameNameByIdFn, + pub GetStateIdByName: AppLayerParserGetStateIdByNameFn, + pub GetStateNameById: AppLayerParserGetStateNameByIdFn, +} +impl Default for AppLayerParser { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} #[doc = " First part of AppLayerParser, needed only for protocol detection"] #[repr(C)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -1181,6 +1304,12 @@ extern "C" { parser: *const AppLayerProtocolDetect, enable_default: ::std::os::raw::c_int, ) -> AppProto; } +extern "C" { + #[doc = " \\brief App layer protocol registration function.\n\n \\param parser The parser declaration structure.\n \\param alproto The application layer protocol identifier.\n\n \\retval 0 if successful. On error, this function never returns."] + pub fn SCAppLayerRegisterParser( + p: *const AppLayerParser, alproto: AppProto, + ) -> ::std::os::raw::c_int; +} extern "C" { pub fn SCAppLayerRegisterParserAlias( proto_name: *const ::std::os::raw::c_char, proto_alias: *const ::std::os::raw::c_char, diff --git a/src/app-layer-register.c b/src/app-layer-register.c index a69caa4b70..221ba193f3 100644 --- a/src/app-layer-register.c +++ b/src/app-layer-register.c @@ -91,7 +91,7 @@ AppProto SCAppLayerRegisterProtocolDetection( return alproto; } -int AppLayerRegisterParser(const struct AppLayerParser *p, AppProto alproto) +int SCAppLayerRegisterParser(const struct AppLayerParser *p, AppProto alproto) { const char *ip_proto_str = NULL; diff --git a/src/app-layer-register.h b/src/app-layer-register.h index 8266db59cc..8fbd3d6d41 100644 --- a/src/app-layer-register.h +++ b/src/app-layer-register.h @@ -113,7 +113,7 @@ AppProto SCAppLayerRegisterProtocolDetection( * * \retval 0 if successful. On error, this function never returns. */ -int AppLayerRegisterParser(const struct AppLayerParser *p, AppProto alproto); +int SCAppLayerRegisterParser(const struct AppLayerParser *p, AppProto alproto); int SCAppLayerRegisterParserAlias(const char *proto_name, const char *proto_alias);