From dcfaa2cbc2e4dd30c6c445b22da1d79428a5fd2c Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Mon, 28 Oct 2024 15:42:10 -0600 Subject: [PATCH 1/8] rust: integrate bindgen to generate rust bindings to C Add a minimal integration of bindgen to the build. Bindgen is integrated at compile time with a "build.rs" file that for now only generates AppLayerEventType Rust bindings. This required some refactoring of the C so app-layer-events.h did not also include "rust.h", which causes issues for bindgen, probably related to circular references. AppLayerEventType was chosen as the first step as its an argument type some app-layer functions that we may want to use bindgen to export Rust, and one of the requirements of bindgen might be that C functions should only use datatypes defined in C, and not Rust. Following such a rule also prevents circular dependencies between Rust and C code. Bindgen generates the bindings in a file named "bindings.rs" in the target/ direction, which "sys.rs" will statically "include" at compiling name, making these bindings available under package "crate::sys". "build.rs" had to be placed in the non-standard location of "src/build.rs" (its usually alongside Cargo.toml) to satisfy the out-of-tree build requirements of distcheck. Note that bindgen is also available as a command line tool which could be used instead of integrating this at compile time, however the tool requires a newer version of Rust than our MSRV, and may present additional issues with respect to autoconf and distcheck. --- rust/Cargo.toml.in | 9 +++++++++ rust/Makefile.am | 13 ++++++++++--- rust/derive/src/applayerevent.rs | 4 ++-- rust/src/applayer.rs | 15 ++++++++------- rust/src/build.rs | 33 ++++++++++++++++++++++++++++++++ rust/src/core.rs | 8 -------- rust/src/ftp/event.rs | 2 +- rust/src/lib.rs | 3 +++ rust/src/smb/smb.rs | 1 + rust/src/sys.rs | 19 ++++++++++++++++++ src/app-layer-events.c | 1 + src/app-layer-events.h | 6 +++++- src/rust.h | 1 + 13 files changed, 93 insertions(+), 22 deletions(-) create mode 100644 rust/src/build.rs create mode 100644 rust/src/sys.rs diff --git a/rust/Cargo.toml.in b/rust/Cargo.toml.in index a1b53e3b58ca..da9543eec573 100644 --- a/rust/Cargo.toml.in +++ b/rust/Cargo.toml.in @@ -5,6 +5,7 @@ license = "GPL-2.0-only" description = "Suricata Rust components" edition = "2021" rust-version = "1.67.1" +build = "src/build.rs" [workspace] members = [".", "./derive"] @@ -72,3 +73,11 @@ suricata-lua-sys = { version = "0.1.0-alpha.3" } [dev-dependencies] test-case = "~3.3.1" hex = "~0.4.3" + +[build-dependencies] +# Pin as bindgen 0.70.1 requires Rust 1.70.0+ +bindgen = "=0.69.4" + +# Most recent version to support Rust 1.67. 0.5.9 requires 1.70.0. +# - Not used directly but Suricata, but by bindgen. +home = "=0.5.5" diff --git a/rust/Makefile.am b/rust/Makefile.am index be80a806f1aa..1de30ee687d0 100644 --- a/rust/Makefile.am +++ b/rust/Makefile.am @@ -34,6 +34,11 @@ if RUST_CROSS_COMPILE RUST_TARGET = --target $(host_triplet) endif +CARGO_VARS = TOP_BUILDDIR=$(abs_top_builddir) \ + TOP_SRCDIR=$(abs_top_srcdir) \ + CARGO_TARGET_DIR="$(abs_top_builddir)/rust/target" \ + SURICATA_LUA_SYS_HEADER_DST="$(abs_top_builddir)/rust/gen" + all-local: Cargo.toml mkdir -p $(abs_top_builddir)/rust/gen if HAVE_CYGPATH @@ -46,8 +51,7 @@ if HAVE_CYGPATH else cd $(abs_top_srcdir)/rust && \ @rustup_home@ CARGO_HOME="$(CARGO_HOME)" \ - CARGO_TARGET_DIR="$(abs_top_builddir)/rust/target" \ - SURICATA_LUA_SYS_HEADER_DST="$(abs_top_builddir)/rust/gen" \ + $(CARGO_VARS) \ $(CARGO) build $(RELEASE) $(NIGHTLY_ARGS) \ --features "$(RUST_FEATURES)" $(RUST_TARGET) endif @@ -93,7 +97,10 @@ gen/rust-bindings.h: endif doc: - CARGO_HOME=$(CARGO_HOME) $(CARGO) doc --all-features --no-deps + CARGO_HOME=$(CARGO_HOME) \ + $(CARGO_VARS) \ + SURICATA_LUA_SYS_HEADER_DST="" $(CARGO) doc \ + --all-features --no-deps if HAVE_CBINDGEN dist/rust-bindings.h: diff --git a/rust/derive/src/applayerevent.rs b/rust/derive/src/applayerevent.rs index 1b1a3f86ee9c..a51bd69ee384 100644 --- a/rust/derive/src/applayerevent.rs +++ b/rust/derive/src/applayerevent.rs @@ -89,7 +89,7 @@ pub fn derive_app_layer_event(input: TokenStream) -> TokenStream { unsafe extern "C" fn get_event_info( event_name: *const std::os::raw::c_char, event_id: *mut u8, - event_type: *mut #crate_id::core::AppLayerEventType, + event_type: *mut #crate_id::sys::AppLayerEventType, ) -> std::os::raw::c_int { #crate_id::applayer::get_event_info::<#name>(event_name, event_id, event_type) } @@ -97,7 +97,7 @@ pub fn derive_app_layer_event(input: TokenStream) -> TokenStream { unsafe extern "C" fn get_event_info_by_id( event_id: u8, event_name: *mut *const std::os::raw::c_char, - event_type: *mut #crate_id::core::AppLayerEventType, + event_type: *mut #crate_id::sys::AppLayerEventType, ) -> std::os::raw::c_int { #crate_id::applayer::get_event_info_by_id::<#name>(event_id, event_name, event_type) } diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index ac9800d63439..6e3d5909ad4a 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -18,8 +18,9 @@ //! Parser registration functions and common interface module. use std; -use crate::core::{self,DetectEngineState,Flow,AppLayerEventType,AppProto,Direction}; +use crate::core::{self,DetectEngineState,Flow,AppProto,Direction}; use crate::filecontainer::FileContainer; +use crate::sys::AppLayerEventType; use std::os::raw::{c_void,c_char,c_int}; use crate::core::SC; use std::ffi::CStr; @@ -583,13 +584,13 @@ pub trait AppLayerEvent { unsafe extern "C" fn get_event_info( event_name: *const std::os::raw::c_char, event_id: *mut u8, - event_type: *mut core::AppLayerEventType, + event_type: *mut AppLayerEventType, ) -> std::os::raw::c_int; unsafe extern "C" fn get_event_info_by_id( event_id: u8, event_name: *mut *const std::os::raw::c_char, - event_type: *mut core::AppLayerEventType, + event_type: *mut AppLayerEventType, ) -> std::os::raw::c_int; } @@ -612,7 +613,7 @@ pub trait AppLayerEvent { pub unsafe fn get_event_info( event_name: *const std::os::raw::c_char, event_id: *mut u8, - event_type: *mut core::AppLayerEventType, + event_type: *mut AppLayerEventType, ) -> std::os::raw::c_int { if event_name.is_null() { return -1; @@ -624,7 +625,7 @@ pub unsafe fn get_event_info( return -1; } }; - *event_type = core::AppLayerEventType::APP_LAYER_EVENT_TYPE_TRANSACTION; + *event_type = AppLayerEventType::APP_LAYER_EVENT_TYPE_TRANSACTION; *event_id = event; return 0; } @@ -635,11 +636,11 @@ pub unsafe fn get_event_info( pub unsafe fn get_event_info_by_id( event_id: u8, event_name: *mut *const std::os::raw::c_char, - event_type: *mut core::AppLayerEventType, + event_type: *mut AppLayerEventType, ) -> std::os::raw::c_int { if let Some(e) = T::from_id(event_id) { *event_name = e.to_cstring().as_ptr() as *const std::os::raw::c_char; - *event_type = core::AppLayerEventType::APP_LAYER_EVENT_TYPE_TRANSACTION; + *event_type = AppLayerEventType::APP_LAYER_EVENT_TYPE_TRANSACTION; return 0; } return -1; diff --git a/rust/src/build.rs b/rust/src/build.rs new file mode 100644 index 000000000000..f784d2b618c6 --- /dev/null +++ b/rust/src/build.rs @@ -0,0 +1,33 @@ +// builds.rs for Suricata +// +// Currently this build.rs only uses bindgen to build some Rust +// bindings to the Suricata C code. +// +// For more info on Rust and the build.rs file, see: +// https://doc.rust-lang.org/cargo/reference/build-scripts.html +fn main() { + let src_dir = std::env::var("TOP_SRCDIR").unwrap_or_else(|_| "..".to_string()); + let build_dir = std::env::var("TOP_BUILDDIR").unwrap_or_else(|_| "..".to_string()); + + // Pull in a simple header that presents no issues with bindgen at + // this time. Multiple headers can be specified. + let bindings = bindgen::Builder::default() + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .header(format!("{}/src/app-layer-events.h", &src_dir)) + .allowlist_item("AppLayerEventType") + .rustified_enum("AppLayerEventType") + .clang_arg("-DHAVE_CONFIG_H") + .clang_arg("-D__SCFILENAME__=\"\"") + .clang_arg(format!("-I{}/src", &build_dir)) + .generate() + .unwrap(); + + // Write out the bindings. *Rules* say we should only write into + // the target directory (idiomatically the OUT_DIR env var), so + // we'll pull them into our namespace using an include!() macro + // (current in sys.rs). + let out_path = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .unwrap(); +} diff --git a/rust/src/core.rs b/rust/src/core.rs index a628b300384a..94d364e80d74 100644 --- a/rust/src/core.rs +++ b/rust/src/core.rs @@ -25,14 +25,6 @@ use crate::debug_validate_fail; pub enum DetectEngineState {} pub enum AppLayerDecoderEvents {} -#[repr(C)] -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -#[allow(non_camel_case_types)] -pub enum AppLayerEventType { - APP_LAYER_EVENT_TYPE_TRANSACTION = 1, - APP_LAYER_EVENT_TYPE_PACKET = 2, -} - pub const STREAM_START: u8 = 0x01; pub const STREAM_EOF: u8 = 0x02; pub const STREAM_TOSERVER: u8 = 0x04; diff --git a/rust/src/ftp/event.rs b/rust/src/ftp/event.rs index cc327369d875..519da9da9b85 100644 --- a/rust/src/ftp/event.rs +++ b/rust/src/ftp/event.rs @@ -15,7 +15,7 @@ * 02110-1301, USA. */ -use crate::core::AppLayerEventType; +use crate::sys::AppLayerEventType; use std::os::raw::{c_char, c_int}; #[derive(Debug, PartialEq, Eq, AppLayerEvent)] diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 7a99cd2532e5..665721d9558f 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -134,3 +134,6 @@ pub mod ldap; #[allow(unused_imports)] pub use suricata_lua_sys; + +// Generated Rust bindings from C. +pub mod sys; diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index 7dab8debbc74..75628cc46bd8 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -54,6 +54,7 @@ use crate::smb::session::*; use crate::smb::events::*; use crate::smb::files::*; use crate::smb::smb2_ioctl::*; +use crate::sys::AppLayerEventType; #[derive(AppLayerFrameType)] pub enum SMBFrameType { diff --git a/rust/src/sys.rs b/rust/src/sys.rs new file mode 100644 index 000000000000..9c224b35a540 --- /dev/null +++ b/rust/src/sys.rs @@ -0,0 +1,19 @@ +/* Copyright (C) 2024 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#![allow(non_camel_case_types)] +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/src/app-layer-events.c b/src/app-layer-events.c index eb32ea394671..a10eb40de204 100644 --- a/src/app-layer-events.c +++ b/src/app-layer-events.c @@ -23,6 +23,7 @@ */ #include "app-layer-events.h" +#include "rust.h" #include "util-enum.h" int SCAppLayerGetEventIdByName(const char *event_name, SCEnumCharMap *table, uint8_t *event_id) diff --git a/src/app-layer-events.h b/src/app-layer-events.h index 7b4e5e06d075..0c633fb57603 100644 --- a/src/app-layer-events.h +++ b/src/app-layer-events.h @@ -27,9 +27,13 @@ /* contains fwd declaration of AppLayerDecoderEvents_ */ #include "decode.h" -#include "rust.h" #include "util-enum.h" +typedef enum AppLayerEventType { + APP_LAYER_EVENT_TYPE_TRANSACTION = 1, + APP_LAYER_EVENT_TYPE_PACKET = 2, +} AppLayerEventType; + /** * \brief Data structure to store app layer decoder events. */ diff --git a/src/rust.h b/src/rust.h index 03cff24c8d26..4ad060275d76 100644 --- a/src/rust.h +++ b/src/rust.h @@ -21,6 +21,7 @@ // hack for include orders cf SCSha256 typedef struct HttpRangeContainerBlock HttpRangeContainerBlock; #include "rust-context.h" +#include "app-layer-events.h" #include "rust-bindings.h" #define JB_SET_STRING(jb, key, val) jb_set_formatted((jb), "\"" key "\":\"" val "\"") From 2c0e6a20d2ab91031b92b7581dd0d3803e688b41 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Mon, 28 Oct 2024 15:56:16 -0600 Subject: [PATCH 2/8] github-ci: add clang Required for bindgen. --- .github/workflows/builds.yml | 22 +++++++++++++++++----- .github/workflows/rust.yml | 1 + 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 8d5def58c889..8201e90b9432 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -95,6 +95,7 @@ jobs: automake \ cargo-vendor \ cbindgen \ + clang \ diffutils \ numactl-devel \ dpdk-devel \ @@ -251,6 +252,7 @@ jobs: autoconf \ automake \ cbindgen \ + clang \ diffutils \ numactl-devel \ dpdk-devel \ @@ -497,6 +499,7 @@ jobs: autoconf \ automake \ cargo-vendor \ + clang \ diffutils \ numactl-devel \ dpdk-devel \ @@ -594,6 +597,7 @@ jobs: autoconf \ automake \ cargo-vendor \ + clang \ diffutils \ numactl-devel \ dpdk-devel \ @@ -883,6 +887,7 @@ jobs: cargo \ cbindgen \ ccache \ + clang \ diffutils \ file-devel \ gcc \ @@ -1074,6 +1079,7 @@ jobs: cargo \ cbindgen \ ccache \ + clang \ diffutils \ file-devel \ gcc \ @@ -1325,7 +1331,8 @@ jobs: sudo \ git \ libtool \ - which + which \ + clang - name: Install Almalinux 9 extra repositories run : | @@ -1333,7 +1340,6 @@ jobs: dnf -y install dnf-plugins-core epel-release dnf config-manager --set-enabled crb - - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 - uses: ./.github/actions/install-cbindgen - run: git config --global --add safe.directory /__w/suricata/suricata @@ -2101,6 +2107,7 @@ jobs: autoconf \ automake \ cargo \ + clang \ git \ jq \ libtool \ @@ -2253,6 +2260,7 @@ jobs: autoconf \ automake \ cargo \ + clang \ git \ jq \ libtool \ @@ -2541,6 +2549,7 @@ jobs: autoconf \ automake \ cargo \ + clang \ git \ jq \ libtool \ @@ -2636,6 +2645,7 @@ jobs: autoconf \ automake \ build-essential \ + clang \ cmake \ curl \ dpdk-dev \ @@ -2821,6 +2831,7 @@ jobs: automake \ build-essential \ cmake \ + clang \ curl \ dpdk-dev \ git \ @@ -3107,7 +3118,7 @@ jobs: with: msystem: MINGW64 update: true - install: git mingw-w64-x86_64-toolchain automake1.16 automake-wrapper autoconf libtool libyaml-devel pcre2-devel jansson-devel make mingw-w64-x86_64-libyaml mingw-w64-x86_64-pcre2 mingw-w64-x86_64-rust mingw-w64-x86_64-jansson unzip p7zip python-setuptools mingw-w64-x86_64-python-yaml mingw-w64-x86_64-jq mingw-w64-x86_64-libxml2 + install: git mingw-w64-x86_64-toolchain mingw-w64-x86_64-clang automake1.16 automake-wrapper autoconf libtool libyaml-devel pcre2-devel jansson-devel make mingw-w64-x86_64-libyaml mingw-w64-x86_64-pcre2 mingw-w64-x86_64-rust mingw-w64-x86_64-jansson unzip p7zip python-setuptools mingw-w64-x86_64-python-yaml mingw-w64-x86_64-jq mingw-w64-x86_64-libxml2 # hack: install our own cbindgen system wide as we can't get the # preinstalled one to be picked up by configure - name: cbindgen @@ -3163,7 +3174,7 @@ jobs: with: msystem: MINGW64 update: true - install: git mingw-w64-x86_64-toolchain automake1.16 automake-wrapper autoconf libtool libyaml-devel pcre2-devel jansson-devel make mingw-w64-x86_64-libyaml mingw-w64-x86_64-pcre2 mingw-w64-x86_64-rust mingw-w64-x86_64-jansson unzip p7zip python-setuptools mingw-w64-x86_64-python-yaml mingw-w64-x86_64-jq mingw-w64-x86_64-libxml2 libpcap-devel mingw-w64-x86_64-libpcap + install: git mingw-w64-x86_64-toolchain mingw-w64-x86_64-clang automake1.16 automake-wrapper autoconf libtool libyaml-devel pcre2-devel jansson-devel make mingw-w64-x86_64-libyaml mingw-w64-x86_64-pcre2 mingw-w64-x86_64-rust mingw-w64-x86_64-jansson unzip p7zip python-setuptools mingw-w64-x86_64-python-yaml mingw-w64-x86_64-jq mingw-w64-x86_64-libxml2 libpcap-devel mingw-w64-x86_64-libpcap # hack: install our own cbindgen system wide as we can't get the # preinstalled one to be picked up by configure - name: cbindgen @@ -3207,7 +3218,7 @@ jobs: with: msystem: MINGW64 update: true - install: git mingw-w64-x86_64-toolchain automake1.16 automake-wrapper autoconf libtool libyaml-devel pcre2-devel jansson-devel make mingw-w64-x86_64-libyaml mingw-w64-x86_64-pcre2 mingw-w64-x86_64-rust mingw-w64-x86_64-jansson unzip p7zip python-setuptools mingw-w64-x86_64-python-yaml mingw-w64-x86_64-jq mingw-w64-x86_64-libxml2 libpcap-devel mingw-w64-x86_64-libpcap + install: git mingw-w64-x86_64-toolchain mingw-w64-x86_64-clang automake1.16 automake-wrapper autoconf libtool libyaml-devel pcre2-devel jansson-devel make mingw-w64-x86_64-libyaml mingw-w64-x86_64-pcre2 mingw-w64-x86_64-rust mingw-w64-x86_64-jansson unzip p7zip python-setuptools mingw-w64-x86_64-python-yaml mingw-w64-x86_64-jq mingw-w64-x86_64-libxml2 libpcap-devel mingw-w64-x86_64-libpcap # hack: install our own cbindgen system wide as we can't get the # preinstalled one to be picked up by configure - name: cbindgen @@ -3267,6 +3278,7 @@ jobs: dnf -y install \ autoconf \ automake \ + clang \ diffutils \ numactl-devel \ dpdk-devel \ diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 96f3ee920fc1..6041c4f2e54f 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -35,6 +35,7 @@ jobs: autoconf \ automake \ cargo-vendor \ + clang \ diffutils \ numactl-devel \ dpdk-devel \ From 9a65dbf1000fdaed4432fdd0b70eb4602686c9b6 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Mon, 28 Oct 2024 16:10:11 -0600 Subject: [PATCH 3/8] app-layer: rename AppLayerEventType to SCAppLayerEventType Follow the naming scheme for public exports. --- rust/derive/src/applayerevent.rs | 4 ++-- rust/src/applayer.rs | 18 +++++++++--------- rust/src/build.rs | 4 ++-- rust/src/ftp/event.rs | 6 +++--- rust/src/smb/smb.rs | 6 +++--- src/app-layer-dnp3.c | 4 ++-- src/app-layer-events.c | 4 ++-- src/app-layer-events.h | 8 ++++---- src/app-layer-htp.c | 4 ++-- src/app-layer-parser.c | 12 ++++++------ src/app-layer-parser.h | 8 ++++---- src/app-layer-register.h | 4 ++-- src/app-layer-smtp.c | 4 ++-- src/app-layer-ssl.c | 4 ++-- src/app-layer-tftp.c | 2 +- src/detect-app-layer-event.c | 6 +++--- src/output-json-anomaly.c | 2 +- 17 files changed, 50 insertions(+), 50 deletions(-) diff --git a/rust/derive/src/applayerevent.rs b/rust/derive/src/applayerevent.rs index a51bd69ee384..52373a497cbb 100644 --- a/rust/derive/src/applayerevent.rs +++ b/rust/derive/src/applayerevent.rs @@ -89,7 +89,7 @@ pub fn derive_app_layer_event(input: TokenStream) -> TokenStream { unsafe extern "C" fn get_event_info( event_name: *const std::os::raw::c_char, event_id: *mut u8, - event_type: *mut #crate_id::sys::AppLayerEventType, + event_type: *mut #crate_id::sys::SCAppLayerEventType, ) -> std::os::raw::c_int { #crate_id::applayer::get_event_info::<#name>(event_name, event_id, event_type) } @@ -97,7 +97,7 @@ pub fn derive_app_layer_event(input: TokenStream) -> TokenStream { unsafe extern "C" fn get_event_info_by_id( event_id: u8, event_name: *mut *const std::os::raw::c_char, - event_type: *mut #crate_id::sys::AppLayerEventType, + event_type: *mut #crate_id::sys::SCAppLayerEventType, ) -> std::os::raw::c_int { #crate_id::applayer::get_event_info_by_id::<#name>(event_id, event_name, event_type) } diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index 6e3d5909ad4a..ff8a8f4844e8 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -20,7 +20,7 @@ use std; use crate::core::{self,DetectEngineState,Flow,AppProto,Direction}; use crate::filecontainer::FileContainer; -use crate::sys::AppLayerEventType; +use crate::sys::SCAppLayerEventType; use std::os::raw::{c_void,c_char,c_int}; use crate::core::SC; use std::ffi::CStr; @@ -445,8 +445,8 @@ pub type StateTxFreeFn = unsafe extern "C" fn (*mut c_void, u64); pub type StateGetTxFn = unsafe extern "C" fn (*mut c_void, u64) -> *mut c_void; pub type StateGetTxCntFn = unsafe extern "C" fn (*mut c_void) -> u64; pub type StateGetProgressFn = unsafe extern "C" fn (*mut c_void, u8) -> c_int; -pub type GetEventInfoFn = unsafe extern "C" fn (*const c_char, event_id: *mut u8, *mut AppLayerEventType) -> c_int; -pub type GetEventInfoByIdFn = unsafe extern "C" fn (event_id: u8, *mut *const c_char, *mut AppLayerEventType) -> c_int; +pub type GetEventInfoFn = unsafe extern "C" fn (*const c_char, event_id: *mut u8, *mut SCAppLayerEventType) -> c_int; +pub type GetEventInfoByIdFn = unsafe extern "C" fn (event_id: u8, *mut *const c_char, *mut SCAppLayerEventType) -> c_int; pub type LocalStorageNewFn = extern "C" fn () -> *mut c_void; pub type LocalStorageFreeFn = extern "C" fn (*mut c_void); pub type GetTxFilesFn = unsafe extern "C" fn (*mut c_void, u8) -> AppLayerGetFileState; @@ -584,13 +584,13 @@ pub trait AppLayerEvent { unsafe extern "C" fn get_event_info( event_name: *const std::os::raw::c_char, event_id: *mut u8, - event_type: *mut AppLayerEventType, + event_type: *mut SCAppLayerEventType, ) -> std::os::raw::c_int; unsafe extern "C" fn get_event_info_by_id( event_id: u8, event_name: *mut *const std::os::raw::c_char, - event_type: *mut AppLayerEventType, + event_type: *mut SCAppLayerEventType, ) -> std::os::raw::c_int; } @@ -613,7 +613,7 @@ pub trait AppLayerEvent { pub unsafe fn get_event_info( event_name: *const std::os::raw::c_char, event_id: *mut u8, - event_type: *mut AppLayerEventType, + event_type: *mut SCAppLayerEventType, ) -> std::os::raw::c_int { if event_name.is_null() { return -1; @@ -625,7 +625,7 @@ pub unsafe fn get_event_info( return -1; } }; - *event_type = AppLayerEventType::APP_LAYER_EVENT_TYPE_TRANSACTION; + *event_type = SCAppLayerEventType::APP_LAYER_EVENT_TYPE_TRANSACTION; *event_id = event; return 0; } @@ -636,11 +636,11 @@ pub unsafe fn get_event_info( pub unsafe fn get_event_info_by_id( event_id: u8, event_name: *mut *const std::os::raw::c_char, - event_type: *mut AppLayerEventType, + event_type: *mut SCAppLayerEventType, ) -> std::os::raw::c_int { if let Some(e) = T::from_id(event_id) { *event_name = e.to_cstring().as_ptr() as *const std::os::raw::c_char; - *event_type = AppLayerEventType::APP_LAYER_EVENT_TYPE_TRANSACTION; + *event_type = SCAppLayerEventType::APP_LAYER_EVENT_TYPE_TRANSACTION; return 0; } return -1; diff --git a/rust/src/build.rs b/rust/src/build.rs index f784d2b618c6..a03436b053c5 100644 --- a/rust/src/build.rs +++ b/rust/src/build.rs @@ -14,8 +14,8 @@ fn main() { let bindings = bindgen::Builder::default() .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) .header(format!("{}/src/app-layer-events.h", &src_dir)) - .allowlist_item("AppLayerEventType") - .rustified_enum("AppLayerEventType") + .allowlist_item("SCAppLayerEventType") + .rustified_enum("SCAppLayerEventType") .clang_arg("-DHAVE_CONFIG_H") .clang_arg("-D__SCFILENAME__=\"\"") .clang_arg(format!("-I{}/src", &build_dir)) diff --git a/rust/src/ftp/event.rs b/rust/src/ftp/event.rs index 519da9da9b85..a7edc1688176 100644 --- a/rust/src/ftp/event.rs +++ b/rust/src/ftp/event.rs @@ -15,7 +15,7 @@ * 02110-1301, USA. */ -use crate::sys::AppLayerEventType; +use crate::sys::SCAppLayerEventType; use std::os::raw::{c_char, c_int}; #[derive(Debug, PartialEq, Eq, AppLayerEvent)] @@ -33,7 +33,7 @@ pub enum FtpEvent { /// Unsafe as called from C. #[no_mangle] pub unsafe extern "C" fn ftp_get_event_info( - event_name: *const c_char, event_id: *mut u8, event_type: *mut AppLayerEventType, + event_name: *const c_char, event_id: *mut u8, event_type: *mut SCAppLayerEventType, ) -> c_int { crate::applayer::get_event_info::(event_name, event_id, event_type) } @@ -44,7 +44,7 @@ pub unsafe extern "C" fn ftp_get_event_info( /// Unsafe as called from C. #[no_mangle] pub unsafe extern "C" fn ftp_get_event_info_by_id( - event_id: u8, event_name: *mut *const c_char, event_type: *mut AppLayerEventType, + event_id: u8, event_name: *mut *const c_char, event_type: *mut SCAppLayerEventType, ) -> c_int { crate::applayer::get_event_info_by_id::(event_id, event_name, event_type) as c_int } diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index 75628cc46bd8..e5f170beed75 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -54,7 +54,7 @@ use crate::smb::session::*; use crate::smb::events::*; use crate::smb::files::*; use crate::smb::smb2_ioctl::*; -use crate::sys::AppLayerEventType; +use crate::sys::SCAppLayerEventType; #[derive(AppLayerFrameType)] pub enum SMBFrameType { @@ -2206,7 +2206,7 @@ pub unsafe extern "C" fn rs_smb_get_tx_data( pub unsafe extern "C" fn rs_smb_state_get_event_info_by_id( event_id: u8, event_name: *mut *const std::os::raw::c_char, - event_type: *mut AppLayerEventType, + event_type: *mut SCAppLayerEventType, ) -> std::os::raw::c_int { SMBEvent::get_event_info_by_id(event_id, event_name, event_type) } @@ -2215,7 +2215,7 @@ pub unsafe extern "C" fn rs_smb_state_get_event_info_by_id( pub unsafe extern "C" fn rs_smb_state_get_event_info( event_name: *const std::os::raw::c_char, event_id: *mut u8, - event_type: *mut AppLayerEventType, + event_type: *mut SCAppLayerEventType, ) -> std::os::raw::c_int { SMBEvent::get_event_info(event_name, event_id, event_type) } diff --git a/src/app-layer-dnp3.c b/src/app-layer-dnp3.c index c995667ee0e3..6b7a4d1ce781 100644 --- a/src/app-layer-dnp3.c +++ b/src/app-layer-dnp3.c @@ -1432,7 +1432,7 @@ static int DNP3GetAlstateProgress(void *tx, uint8_t direction) * \brief App-layer support. */ static int DNP3StateGetEventInfo( - const char *event_name, uint8_t *event_id, AppLayerEventType *event_type) + const char *event_name, uint8_t *event_id, SCAppLayerEventType *event_type) { if (SCAppLayerGetEventIdByName(event_name, dnp3_decoder_event_table, event_id) == 0) { *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION; @@ -1445,7 +1445,7 @@ static int DNP3StateGetEventInfo( * \brief App-layer support. */ static int DNP3StateGetEventInfoById( - uint8_t event_id, const char **event_name, AppLayerEventType *event_type) + uint8_t event_id, const char **event_name, SCAppLayerEventType *event_type) { *event_name = SCMapEnumValueToName(event_id, dnp3_decoder_event_table); if (*event_name == NULL) { diff --git a/src/app-layer-events.c b/src/app-layer-events.c index a10eb40de204..87d72d890c89 100644 --- a/src/app-layer-events.c +++ b/src/app-layer-events.c @@ -62,7 +62,7 @@ SCEnumCharMap app_layer_event_pkt_table[ ] = { }; int AppLayerGetEventInfoById( - uint8_t event_id, const char **event_name, AppLayerEventType *event_type) + uint8_t event_id, const char **event_name, SCAppLayerEventType *event_type) { *event_name = SCMapEnumValueToName(event_id, app_layer_event_pkt_table); if (*event_name == NULL) { @@ -166,7 +166,7 @@ SCEnumCharMap det_ctx_event_table[] = { }; int DetectEngineGetEventInfo( - const char *event_name, uint8_t *event_id, AppLayerEventType *event_type) + const char *event_name, uint8_t *event_id, SCAppLayerEventType *event_type) { if (SCAppLayerGetEventIdByName(event_name, det_ctx_event_table, event_id) == 0) { *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION; diff --git a/src/app-layer-events.h b/src/app-layer-events.h index 0c633fb57603..2542e200faec 100644 --- a/src/app-layer-events.h +++ b/src/app-layer-events.h @@ -29,10 +29,10 @@ #include "decode.h" #include "util-enum.h" -typedef enum AppLayerEventType { +typedef enum SCAppLayerEventType { APP_LAYER_EVENT_TYPE_TRANSACTION = 1, APP_LAYER_EVENT_TYPE_PACKET = 2, -} AppLayerEventType; +} SCAppLayerEventType; /** * \brief Data structure to store app layer decoder events. @@ -61,7 +61,7 @@ enum { int AppLayerGetPktEventInfo(const char *event_name, uint8_t *event_id); int AppLayerGetEventInfoById( - uint8_t event_id, const char **event_name, AppLayerEventType *event_type); + uint8_t event_id, const char **event_name, SCAppLayerEventType *event_type); void AppLayerDecoderEventsSetEventRaw(AppLayerDecoderEvents **sevents, uint8_t event); static inline int AppLayerDecoderEventsIsEventSet( @@ -82,7 +82,7 @@ static inline int AppLayerDecoderEventsIsEventSet( void AppLayerDecoderEventsResetEvents(AppLayerDecoderEvents *events); void AppLayerDecoderEventsFreeEvents(AppLayerDecoderEvents **events); int DetectEngineGetEventInfo( - const char *event_name, uint8_t *event_id, AppLayerEventType *event_type); + const char *event_name, uint8_t *event_id, SCAppLayerEventType *event_type); int SCAppLayerGetEventIdByName(const char *event_name, SCEnumCharMap *table, uint8_t *event_id); #endif /* SURICATA_APP_LAYER_EVENTS_H */ diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index 4acc105bab9a..810fe4ac83df 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -2705,7 +2705,7 @@ void *HtpGetTxForH2(void *alstate) } static int HTPStateGetEventInfo( - const char *event_name, uint8_t *event_id, AppLayerEventType *event_type) + const char *event_name, uint8_t *event_id, SCAppLayerEventType *event_type) { if (SCAppLayerGetEventIdByName(event_name, http_decoder_event_table, event_id) == 0) { *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION; @@ -2715,7 +2715,7 @@ static int HTPStateGetEventInfo( } static int HTPStateGetEventInfoById( - uint8_t event_id, const char **event_name, AppLayerEventType *event_type) + uint8_t event_id, const char **event_name, SCAppLayerEventType *event_type) { *event_name = SCMapEnumValueToName(event_id, http_decoder_event_table); if (*event_name == NULL) { diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index 48a6e47c2d9e..965b8e17e9a3 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -94,9 +94,9 @@ typedef struct AppLayerParserProtoCtx_ int complete_ts; int complete_tc; int (*StateGetEventInfoById)( - uint8_t event_id, const char **event_name, AppLayerEventType *event_type); + uint8_t event_id, const char **event_name, SCAppLayerEventType *event_type); int (*StateGetEventInfo)( - const char *event_name, uint8_t *event_id, AppLayerEventType *event_type); + const char *event_name, uint8_t *event_id, SCAppLayerEventType *event_type); AppLayerStateData *(*GetStateData)(void *state); AppLayerTxData *(*GetTxData)(void *tx); @@ -532,7 +532,7 @@ void AppLayerParserRegisterStateProgressCompletionStatus( void AppLayerParserRegisterGetEventInfoById(uint8_t ipproto, AppProto alproto, int (*StateGetEventInfoById)( - uint8_t event_id, const char **event_name, AppLayerEventType *event_type)) + uint8_t event_id, const char **event_name, SCAppLayerEventType *event_type)) { SCEnter(); @@ -554,7 +554,7 @@ void AppLayerParserRegisterGetFrameFuncs(uint8_t ipproto, AppProto alproto, void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto, int (*StateGetEventInfo)( - const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)) + const char *event_name, uint8_t *event_id, SCAppLayerEventType *event_type)) { SCEnter(); @@ -1100,7 +1100,7 @@ int AppLayerParserGetStateProgressCompletionStatus(AppProto alproto, } int AppLayerParserGetEventInfo(uint8_t ipproto, AppProto alproto, const char *event_name, - uint8_t *event_id, AppLayerEventType *event_type) + uint8_t *event_id, SCAppLayerEventType *event_type) { SCEnter(); const int ipproto_map = FlowGetProtoMapping(ipproto); @@ -1110,7 +1110,7 @@ int AppLayerParserGetEventInfo(uint8_t ipproto, AppProto alproto, const char *ev } int AppLayerParserGetEventInfoById(uint8_t ipproto, AppProto alproto, uint8_t event_id, - const char **event_name, AppLayerEventType *event_type) + const char **event_name, SCAppLayerEventType *event_type) { SCEnter(); const int ipproto_map = FlowGetProtoMapping(ipproto); diff --git a/src/app-layer-parser.h b/src/app-layer-parser.h index 64fc70205e70..22575bf21401 100644 --- a/src/app-layer-parser.h +++ b/src/app-layer-parser.h @@ -196,10 +196,10 @@ void AppLayerParserRegisterStateProgressCompletionStatus( AppProto alproto, const int ts, const int tc); void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto, int (*StateGetEventInfo)( - const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)); + const char *event_name, uint8_t *event_id, SCAppLayerEventType *event_type)); void AppLayerParserRegisterGetEventInfoById(uint8_t ipproto, AppProto alproto, int (*StateGetEventInfoById)( - uint8_t event_id, const char **event_name, AppLayerEventType *event_type)); + uint8_t event_id, const char **event_name, SCAppLayerEventType *event_type)); void AppLayerParserRegisterGetFrameFuncs(uint8_t ipproto, AppProto alproto, AppLayerParserGetFrameIdByNameFn GetFrameIdByName, AppLayerParserGetFrameNameByIdFn GetFrameNameById); @@ -239,9 +239,9 @@ uint64_t AppLayerParserGetTxCnt(const Flow *, void *alstate); void *AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id); int AppLayerParserGetStateProgressCompletionStatus(AppProto alproto, uint8_t direction); int AppLayerParserGetEventInfo(uint8_t ipproto, AppProto alproto, const char *event_name, - uint8_t *event_id, AppLayerEventType *event_type); + uint8_t *event_id, SCAppLayerEventType *event_type); int AppLayerParserGetEventInfoById(uint8_t ipproto, AppProto alproto, uint8_t event_id, - const char **event_name, AppLayerEventType *event_type); + const char **event_name, SCAppLayerEventType *event_type); uint64_t AppLayerParserGetTransactionActive(const Flow *f, AppLayerParserState *pstate, uint8_t direction); diff --git a/src/app-layer-register.h b/src/app-layer-register.h index 6f489c73e248..76b9d9b1549e 100644 --- a/src/app-layer-register.h +++ b/src/app-layer-register.h @@ -52,9 +52,9 @@ typedef struct AppLayerParser { int (*StateGetProgress)(void *alstate, uint8_t direction); int (*StateGetEventInfo)( - const char *event_name, uint8_t *event_id, AppLayerEventType *event_type); + const char *event_name, uint8_t *event_id, SCAppLayerEventType *event_type); int (*StateGetEventInfoById)( - uint8_t event_id, const char **event_name, AppLayerEventType *event_type); + uint8_t event_id, const char **event_name, SCAppLayerEventType *event_type); void *(*LocalStorageAlloc)(void); void (*LocalStorageFree)(void *); diff --git a/src/app-layer-smtp.c b/src/app-layer-smtp.c index ec4799605cbd..0ee54616a7c2 100644 --- a/src/app-layer-smtp.c +++ b/src/app-layer-smtp.c @@ -1645,7 +1645,7 @@ static void SMTPFreeMpmState(void) } static int SMTPStateGetEventInfo( - const char *event_name, uint8_t *event_id, AppLayerEventType *event_type) + const char *event_name, uint8_t *event_id, SCAppLayerEventType *event_type) { if (SCAppLayerGetEventIdByName(event_name, smtp_decoder_event_table, event_id) == 0) { *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION; @@ -1655,7 +1655,7 @@ static int SMTPStateGetEventInfo( } static int SMTPStateGetEventInfoById( - uint8_t event_id, const char **event_name, AppLayerEventType *event_type) + uint8_t event_id, const char **event_name, SCAppLayerEventType *event_type) { *event_name = SCMapEnumValueToName(event_id, smtp_decoder_event_table); if (*event_name == NULL) { diff --git a/src/app-layer-ssl.c b/src/app-layer-ssl.c index 05ba2239b281..335dceb8d229 100644 --- a/src/app-layer-ssl.c +++ b/src/app-layer-ssl.c @@ -2981,7 +2981,7 @@ static const char *SSLStateGetFrameNameById(const uint8_t frame_id) } static int SSLStateGetEventInfo( - const char *event_name, uint8_t *event_id, AppLayerEventType *event_type) + const char *event_name, uint8_t *event_id, SCAppLayerEventType *event_type) { if (SCAppLayerGetEventIdByName(event_name, tls_decoder_event_table, event_id) == 0) { *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION; @@ -2991,7 +2991,7 @@ static int SSLStateGetEventInfo( } static int SSLStateGetEventInfoById( - uint8_t event_id, const char **event_name, AppLayerEventType *event_type) + uint8_t event_id, const char **event_name, SCAppLayerEventType *event_type) { *event_name = SCMapEnumValueToName(event_id, tls_decoder_event_table); if (*event_name == NULL) { diff --git a/src/app-layer-tftp.c b/src/app-layer-tftp.c index 4a9b41176af2..caa23c5c23ba 100644 --- a/src/app-layer-tftp.c +++ b/src/app-layer-tftp.c @@ -63,7 +63,7 @@ static void TFTPStateTxFree(void *state, uint64_t tx_id) } static int TFTPStateGetEventInfo( - const char *event_name, uint8_t *event_id, AppLayerEventType *event_type) + const char *event_name, uint8_t *event_id, SCAppLayerEventType *event_type) { return -1; } diff --git a/src/detect-app-layer-event.c b/src/detect-app-layer-event.c index ce10c289d317..6fbcbfe5cf48 100644 --- a/src/detect-app-layer-event.c +++ b/src/detect-app-layer-event.c @@ -141,8 +141,8 @@ static int DetectAppLayerEventPktMatch(DetectEngineThreadCtx *det_ctx, aled->event_id); } -static DetectAppLayerEventData *DetectAppLayerEventParsePkt(const char *arg, - AppLayerEventType *event_type) +static DetectAppLayerEventData *DetectAppLayerEventParsePkt( + const char *arg, SCAppLayerEventType *event_type) { uint8_t event_id = 0; if (AppLayerGetPktEventInfo(arg, &event_id) != 0) { @@ -193,7 +193,7 @@ static int DetectAppLayerEventSetup(DetectEngineCtx *de_ctx, Signature *s, const while (*arg != '\0' && isspace((unsigned char)*arg)) arg++; - AppLayerEventType event_type; + SCAppLayerEventType event_type; DetectAppLayerEventData *data = NULL; if (strchr(arg, '.') == NULL) { diff --git a/src/output-json-anomaly.c b/src/output-json-anomaly.c index 241cb974a758..42b8b0359684 100644 --- a/src/output-json-anomaly.c +++ b/src/output-json-anomaly.c @@ -181,7 +181,7 @@ static int AnomalyAppLayerDecoderEventJson(JsonAnomalyLogThread *aft, const char *event_name = NULL; uint8_t event_code = decoder_events->events[i]; - AppLayerEventType event_type; + SCAppLayerEventType event_type; int r; if (is_pktlayer) { r = AppLayerGetEventInfoById(event_code, &event_name, &event_type); From 122d65ed956c5e25cd09fe70a3df1b26331c5a0d Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Mon, 28 Oct 2024 16:14:56 -0600 Subject: [PATCH 4/8] app-layer: remove prototypes from decode.h This lets us remove decode.h from app-layer-events.h as pulling in app-layer-events.h shouldn't result in pulling in dpdk, and other includes not related to app-layer-events. decode.h also doesn't need those forward declarations anymore due to previous changes. --- src/app-layer-events.h | 6 +++--- src/decode.h | 8 ++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/app-layer-events.h b/src/app-layer-events.h index 2542e200faec..7f46d4a02435 100644 --- a/src/app-layer-events.h +++ b/src/app-layer-events.h @@ -26,7 +26,7 @@ #define SURICATA_APP_LAYER_EVENTS_H /* contains fwd declaration of AppLayerDecoderEvents_ */ -#include "decode.h" +#include "suricata-common.h" #include "util-enum.h" typedef enum SCAppLayerEventType { @@ -37,7 +37,7 @@ typedef enum SCAppLayerEventType { /** * \brief Data structure to store app layer decoder events. */ -struct AppLayerDecoderEvents_ { +typedef struct AppLayerDecoderEvents_ { /* array of events */ uint8_t *events; /* number of events in the above buffer */ @@ -46,7 +46,7 @@ struct AppLayerDecoderEvents_ { uint8_t events_buffer_size; /* last logged */ uint8_t event_last_logged; -}; +} AppLayerDecoderEvents; /* app layer pkt level events */ enum { diff --git a/src/decode.h b/src/decode.h index 510a7960e5d6..ac784389ad27 100644 --- a/src/decode.h +++ b/src/decode.h @@ -94,18 +94,14 @@ enum PktSrcEnum { #include "util-validate.h" +#include "app-layer-events.h" + /* forward declarations */ struct DetectionEngineThreadCtx_; typedef struct AppLayerThreadCtx_ AppLayerThreadCtx; struct PktPool_; -/* declare these here as they are called from the - * PACKET_RECYCLE and PACKET_CLEANUP macro's. */ -typedef struct AppLayerDecoderEvents_ AppLayerDecoderEvents; -void AppLayerDecoderEventsResetEvents(AppLayerDecoderEvents *events); -void AppLayerDecoderEventsFreeEvents(AppLayerDecoderEvents **events); - /* Address */ typedef struct Address_ { char family; From 50993f222a05f8140c48f73fc5529b309dca48cf Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Tue, 29 Oct 2024 11:56:53 -0600 Subject: [PATCH 5/8] bindgen: export SCAppLayerStateGetEventInfoByIdFn from C to Rust Instead of defining this function pointer in type in Rust, and having it in C signatures, create a type and export it to Rust. To facilitate this, and new header has been creates, "app-layer-types.h", this is to avoid the circular reference of C headers pulling in "rust.h" which are required to generate Rust bindings. --- rust/src/applayer.rs | 2 +- rust/src/build.rs | 2 ++ src/Makefile.am | 1 + src/app-layer-events.h | 6 +----- src/app-layer-parser.c | 5 ++--- src/app-layer-types.h | 31 +++++++++++++++++++++++++++++++ src/rust.h | 1 + 7 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 src/app-layer-types.h diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index ff8a8f4844e8..89f922eabc9e 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -375,7 +375,7 @@ pub struct RustParser { /// Function to get an event id from a description pub get_eventinfo: Option, /// Function to get an event description from an event id - pub get_eventinfo_byid: Option, + pub get_eventinfo_byid: crate::sys::SCAppLayerStateGetEventInfoByIdFn, /// Function to allocate local storage pub localstorage_new: Option, diff --git a/rust/src/build.rs b/rust/src/build.rs index a03436b053c5..5bd2444514d8 100644 --- a/rust/src/build.rs +++ b/rust/src/build.rs @@ -16,6 +16,8 @@ fn main() { .header(format!("{}/src/app-layer-events.h", &src_dir)) .allowlist_item("SCAppLayerEventType") .rustified_enum("SCAppLayerEventType") + .header(format!("{}/src/app-layer-types.h", &src_dir)) + .allowlist_item("SCAppLayer.*") .clang_arg("-DHAVE_CONFIG_H") .clang_arg("-D__SCFILENAME__=\"\"") .clang_arg(format!("-I{}/src", &build_dir)) diff --git a/src/Makefile.am b/src/Makefile.am index 6970d709f35c..fe5047dcdce7 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,6 +42,7 @@ noinst_HEADERS = \ app-layer-ssh.h \ app-layer-ssl.h \ app-layer-tftp.h \ + app-layer-types.h \ app-layer-imap.h \ build-info.h \ conf.h \ diff --git a/src/app-layer-events.h b/src/app-layer-events.h index 7f46d4a02435..c33db5db3e26 100644 --- a/src/app-layer-events.h +++ b/src/app-layer-events.h @@ -27,13 +27,9 @@ /* contains fwd declaration of AppLayerDecoderEvents_ */ #include "suricata-common.h" +#include "app-layer-types.h" #include "util-enum.h" -typedef enum SCAppLayerEventType { - APP_LAYER_EVENT_TYPE_TRANSACTION = 1, - APP_LAYER_EVENT_TYPE_PACKET = 2, -} SCAppLayerEventType; - /** * \brief Data structure to store app layer decoder events. */ diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index 965b8e17e9a3..0d9f0bb6c9d6 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -530,9 +530,8 @@ void AppLayerParserRegisterStateProgressCompletionStatus( alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].complete_tc = tc; } -void AppLayerParserRegisterGetEventInfoById(uint8_t ipproto, AppProto alproto, - int (*StateGetEventInfoById)( - uint8_t event_id, const char **event_name, SCAppLayerEventType *event_type)) +void AppLayerParserRegisterGetEventInfoById( + uint8_t ipproto, AppProto alproto, SCAppLayerStateGetEventInfoByIdFn StateGetEventInfoById) { SCEnter(); diff --git a/src/app-layer-types.h b/src/app-layer-types.h new file mode 100644 index 000000000000..08f8ed526f67 --- /dev/null +++ b/src/app-layer-types.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2024 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef SURICATA_APP_LAYER_TYPES_H +#define SURICATA_APP_LAYER_TYPES_H + +#include + +typedef enum SCAppLayerEventType { + APP_LAYER_EVENT_TYPE_TRANSACTION = 1, + APP_LAYER_EVENT_TYPE_PACKET = 2, +} SCAppLayerEventType; + +typedef int (*SCAppLayerStateGetEventInfoByIdFn)( + uint8_t event_id, const char **event_name, SCAppLayerEventType *event_type); + +#endif /* !SURICATA_APP_LAYER_TYPES_H */ diff --git a/src/rust.h b/src/rust.h index 4ad060275d76..251254e351a1 100644 --- a/src/rust.h +++ b/src/rust.h @@ -22,6 +22,7 @@ typedef struct HttpRangeContainerBlock HttpRangeContainerBlock; #include "rust-context.h" #include "app-layer-events.h" +#include "app-layer-types.h" #include "rust-bindings.h" #define JB_SET_STRING(jb, key, val) jb_set_formatted((jb), "\"" key "\":\"" val "\"") From 207d7b82c79ea4e6acf14c6e5298db54d36a3104 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Tue, 29 Oct 2024 12:26:32 -0600 Subject: [PATCH 6/8] bindgen: export AppProto and AppProtoEnum to Rust This exposes the C define ALPROTO values to Rust without having to perform some runtime initialization with init_ffi. As app-layer-protos.h was clean of a circular reference to rust.h we could use it directly, it just needed the addition of suricata-common.h. --- rust/src/applayer.rs | 4 +++- rust/src/build.rs | 28 +++++++++++++++++++--------- rust/src/core.rs | 10 ++++------ rust/src/ldap/ldap.rs | 4 ++-- rust/src/modbus/modbus.rs | 2 +- rust/src/ntp/ntp.rs | 2 +- rust/src/smb/smb.rs | 2 +- src/app-layer-protos.h | 2 ++ 8 files changed, 33 insertions(+), 21 deletions(-) diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index 89f922eabc9e..091aa408c111 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -18,7 +18,7 @@ //! Parser registration functions and common interface module. use std; -use crate::core::{self,DetectEngineState,Flow,AppProto,Direction}; +use crate::core::{self,DetectEngineState,Flow,Direction}; use crate::filecontainer::FileContainer; use crate::sys::SCAppLayerEventType; use std::os::raw::{c_void,c_char,c_int}; @@ -26,6 +26,8 @@ use crate::core::SC; use std::ffi::CStr; use crate::core::StreamingBufferConfig; +pub use crate::sys::AppProto; + // Make the AppLayerEvent derive macro available to users importing // AppLayerEvent from this module. pub use suricata_derive::AppLayerEvent; diff --git a/rust/src/build.rs b/rust/src/build.rs index 5bd2444514d8..86bb6d0430b3 100644 --- a/rust/src/build.rs +++ b/rust/src/build.rs @@ -11,18 +11,28 @@ fn main() { // Pull in a simple header that presents no issues with bindgen at // this time. Multiple headers can be specified. - let bindings = bindgen::Builder::default() + let mut builder = bindgen::Builder::default() .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) - .header(format!("{}/src/app-layer-events.h", &src_dir)) - .allowlist_item("SCAppLayerEventType") - .rustified_enum("SCAppLayerEventType") - .header(format!("{}/src/app-layer-types.h", &src_dir)) - .allowlist_item("SCAppLayer.*") .clang_arg("-DHAVE_CONFIG_H") .clang_arg("-D__SCFILENAME__=\"\"") - .clang_arg(format!("-I{}/src", &build_dir)) - .generate() - .unwrap(); + .clang_arg(format!("-I{}/src", &build_dir)); + + let headers = &["app-layer-types.h", "app-layer-protos.h"]; + for header in headers { + builder = builder.header(format!("{}/src/{}", &src_dir, header)); + } + + // Patterns. + builder = builder + .allowlist_item("SCAppLayer.*") + .allowlist_item("AppProto.*"); + + // Rustified enums. + builder = builder + .rustified_enum("SCAppLayerEventType") + .rustified_enum("AppProtoEnum"); + + let bindings = builder.generate().unwrap(); // Write out the bindings. *Rules* say we should only write into // the target directory (idiomatically the OUT_DIR env var), so diff --git a/rust/src/core.rs b/rust/src/core.rs index 94d364e80d74..3807e6e0429d 100644 --- a/rust/src/core.rs +++ b/rust/src/core.rs @@ -21,6 +21,8 @@ use std; use crate::filecontainer::*; use crate::debug_validate_fail; +pub use crate::sys::{AppProto, AppProtoEnum}; + /// Opaque C types. pub enum DetectEngineState {} pub enum AppLayerDecoderEvents {} @@ -97,11 +99,8 @@ impl From for u8 { } } -// Application layer protocol identifiers (app-layer-protos.h) -pub type AppProto = u16; - -pub const ALPROTO_UNKNOWN : AppProto = 0; -pub static mut ALPROTO_FAILED : AppProto = 0; // updated during init +pub const ALPROTO_UNKNOWN : AppProto = AppProtoEnum::ALPROTO_UNKNOWN as u16; +pub const ALPROTO_FAILED : AppProto = AppProtoEnum::ALPROTO_FAILED as u16; pub const IPPROTO_TCP : u8 = 6; pub const IPPROTO_UDP : u8 = 17; @@ -244,7 +243,6 @@ pub fn init_ffi(context: &'static SuricataContext) { unsafe { SC = Some(context); - ALPROTO_FAILED = StringToAppProto("failed\0".as_ptr()); } } diff --git a/rust/src/ldap/ldap.rs b/rust/src/ldap/ldap.rs index 4c9c3947d7a8..4fea91547658 100644 --- a/rust/src/ldap/ldap.rs +++ b/rust/src/ldap/ldap.rs @@ -469,7 +469,7 @@ fn probe(input: &[u8], direction: Direction, rdir: *mut u8) -> AppProto { Ok((_, msg)) => { let ldap_msg = LdapMessage::from(msg); if ldap_msg.is_unknown() { - return unsafe { ALPROTO_FAILED }; + return ALPROTO_FAILED; } if direction == Direction::ToServer && !ldap_msg.is_request() { unsafe { @@ -487,7 +487,7 @@ fn probe(input: &[u8], direction: Direction, rdir: *mut u8) -> AppProto { return ALPROTO_UNKNOWN; } Err(_e) => { - return unsafe { ALPROTO_FAILED }; + return ALPROTO_FAILED; } } } diff --git a/rust/src/modbus/modbus.rs b/rust/src/modbus/modbus.rs index 0d0c73371ef0..9401fc6922d0 100644 --- a/rust/src/modbus/modbus.rs +++ b/rust/src/modbus/modbus.rs @@ -281,7 +281,7 @@ pub extern "C" fn rs_modbus_probe( match MODBUS_PARSER.probe(slice, Direction::Unknown) { Status::Recognized => unsafe { ALPROTO_MODBUS }, Status::Incomplete => ALPROTO_UNKNOWN, - Status::Unrecognized => unsafe { ALPROTO_FAILED }, + Status::Unrecognized => ALPROTO_FAILED, } } diff --git a/rust/src/ntp/ntp.rs b/rust/src/ntp/ntp.rs index ae723bbb21cd..e17648c4c960 100644 --- a/rust/src/ntp/ntp.rs +++ b/rust/src/ntp/ntp.rs @@ -259,7 +259,7 @@ pub extern "C" fn ntp_probing_parser(_flow: *const Flow, return ALPROTO_UNKNOWN; }, Err(_) => { - return unsafe{ALPROTO_FAILED}; + return ALPROTO_FAILED; }, } } diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index e5f170beed75..7f703f9aad0b 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -2106,7 +2106,7 @@ fn smb_probe_tcp(flags: u8, slice: &[u8], rdir: *mut u8, begins: bool) -> AppPro } } SCLogDebug!("no smb"); - unsafe { return ALPROTO_FAILED; } + return ALPROTO_FAILED; } // probing confirmation parser diff --git a/src/app-layer-protos.h b/src/app-layer-protos.h index 348203ac2f53..e17cd791f56b 100644 --- a/src/app-layer-protos.h +++ b/src/app-layer-protos.h @@ -25,6 +25,8 @@ #ifndef SURICATA_APP_LAYER_PROTOS_H #define SURICATA_APP_LAYER_PROTOS_H +#include "suricata-common.h" + enum AppProtoEnum { ALPROTO_UNKNOWN = 0, ALPROTO_HTTP1, From c3a1bbb7192586deb166a6706026d935f56d9f60 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Tue, 29 Oct 2024 12:39:51 -0600 Subject: [PATCH 7/8] dhcp: use ALPROTO_DHCP from bindgen --- rust/src/dhcp/dhcp.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rust/src/dhcp/dhcp.rs b/rust/src/dhcp/dhcp.rs index 5b6f4b4a085a..b6ea86a0d249 100644 --- a/rust/src/dhcp/dhcp.rs +++ b/rust/src/dhcp/dhcp.rs @@ -17,12 +17,13 @@ use crate::applayer::{self, *}; use crate::core; -use crate::core::{ALPROTO_UNKNOWN, AppProto, Flow, IPPROTO_UDP}; +use crate::core::{ALPROTO_UNKNOWN, Flow, IPPROTO_UDP}; use crate::dhcp::parser::*; +use crate::sys::AppProtoEnum; use std; use std::ffi::CString; -pub(super) static mut ALPROTO_DHCP: AppProto = ALPROTO_UNKNOWN; +pub(super) static ALPROTO_DHCP: AppProto = AppProtoEnum::ALPROTO_DHCP as AppProto; static DHCP_MIN_FRAME_LEN: u32 = 232; @@ -305,10 +306,9 @@ pub unsafe extern "C" fn rs_dhcp_register_parser() { let ip_proto_str = CString::new("udp").unwrap(); if AppLayerProtoDetectConfProtoDetectionEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { - let alproto = AppLayerRegisterProtocolDetection(&parser, 1); - ALPROTO_DHCP = alproto; + AppLayerRegisterProtocolDetection(&parser, 1); if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { - let _ = AppLayerRegisterParser(&parser, alproto); + let _ = AppLayerRegisterParser(&parser, ALPROTO_DHCP); } } else { SCLogDebug!("Protocol detector and parser disabled for DHCP."); From 17b9f5e0d9db2e028834385a6cc1e0f051ae7a02 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Tue, 29 Oct 2024 12:45:49 -0600 Subject: [PATCH 8/8] bindgen: try passing in CFLAGS to get all include directories For example, to find npcap on Windows builds which are in a non-standard location. --- rust/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rust/Makefile.am b/rust/Makefile.am index 1de30ee687d0..99efed0c831d 100644 --- a/rust/Makefile.am +++ b/rust/Makefile.am @@ -37,7 +37,8 @@ endif CARGO_VARS = TOP_BUILDDIR=$(abs_top_builddir) \ TOP_SRCDIR=$(abs_top_srcdir) \ CARGO_TARGET_DIR="$(abs_top_builddir)/rust/target" \ - SURICATA_LUA_SYS_HEADER_DST="$(abs_top_builddir)/rust/gen" + SURICATA_LUA_SYS_HEADER_DST="$(abs_top_builddir)/rust/gen" \ + CFLAGS="$(CFLAGS)" all-local: Cargo.toml mkdir -p $(abs_top_builddir)/rust/gen