From db06234645a5eac6ddc93465c17bd857c38a8fa0 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Thu, 23 Jan 2025 16:14:36 -0600 Subject: [PATCH 1/6] configure: check for existence of bindgen --- configure.ac | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure.ac b/configure.ac index ca964d9039a0..a721e6cebb4c 100644 --- a/configure.ac +++ b/configure.ac @@ -2269,6 +2269,9 @@ fi fi fi + AC_PATH_PROG([BINDGEN], [bindgen], [no]) + AM_CONDITIONAL([HAVE_BINDGEN], [test "x$BINDGEN" != "xno"]) + AC_PATH_PROG(CBINDGEN, cbindgen, "no") if test "x$CBINDGEN" != "xno"; then cbindgen_version=$(cbindgen --version 2>&1 | cut -d' ' -f2-) From 31aaee8832b737a4fb23eec184b42086e0b2b63b Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Thu, 23 Jan 2025 16:19:09 -0600 Subject: [PATCH 2/6] rust/sys: stub in suricata-sys crate for Rust bindings to C Follow Rust convention of using a "sys" crate for bindings to C functions. The bindings don't exist yet, but will be generated by bindgen and put into this crate. --- configure.ac | 1 + rust/Cargo.toml.in | 3 ++- rust/Makefile.am | 6 +++++- rust/sys/Cargo.toml.in | 6 ++++++ rust/sys/Makefile.am | 3 +++ rust/sys/src/lib.rs | 16 ++++++++++++++++ 6 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 rust/sys/Cargo.toml.in create mode 100644 rust/sys/Makefile.am create mode 100644 rust/sys/src/lib.rs diff --git a/configure.ac b/configure.ac index a721e6cebb4c..c9db17e14f78 100644 --- a/configure.ac +++ b/configure.ac @@ -2519,6 +2519,7 @@ AC_SUBST(enable_non_bundled_htp) AM_CONDITIONAL([BUILD_SHARED_LIBRARY], [test "x$enable_shared" = "xyes"] && [test "x$can_build_shared_library" = "xyes"]) AC_CONFIG_FILES(Makefile src/Makefile rust/Makefile rust/Cargo.lock rust/Cargo.toml rust/derive/Cargo.toml rust/.cargo/config.toml) +AC_CONFIG_FILES(rust/sys/Makefile rust/sys/Cargo.toml) AC_CONFIG_FILES(qa/Makefile qa/coccinelle/Makefile) AC_CONFIG_FILES(rules/Makefile doc/Makefile doc/userguide/Makefile) AC_CONFIG_FILES(contrib/Makefile contrib/file_processor/Makefile contrib/file_processor/Action/Makefile contrib/file_processor/Processor/Makefile) diff --git a/rust/Cargo.toml.in b/rust/Cargo.toml.in index 8fad5fee77e3..5093c78eaac4 100644 --- a/rust/Cargo.toml.in +++ b/rust/Cargo.toml.in @@ -7,7 +7,7 @@ edition = "2021" rust-version = "1.67.1" [workspace] -members = [".", "./derive"] +members = [".", "./derive", "sys"] [lib] crate-type = ["staticlib", "rlib"] @@ -68,6 +68,7 @@ hex = "~0.4.3" time = "~0.3.36" suricata-derive = { path = "./derive", version = "@PACKAGE_VERSION@" } +suricata-sys = { path = "./sys", version = "@PACKAGE_VERSION@" } suricata-lua-sys = { version = "0.1.0-alpha.5" } diff --git a/rust/Makefile.am b/rust/Makefile.am index d53eb97090e1..b9d2af56eba8 100644 --- a/rust/Makefile.am +++ b/rust/Makefile.am @@ -1,10 +1,14 @@ +SUBDIRS = sys + EXTRA_DIST = src derive \ .cargo/config.toml.in \ cbindgen.toml \ dist/rust-bindings.h \ vendor \ Cargo.toml Cargo.lock \ - derive/Cargo.toml + derive/Cargo.toml \ + sys \ + sys/Cargo.toml if !DEBUG RELEASE = --release diff --git a/rust/sys/Cargo.toml.in b/rust/sys/Cargo.toml.in new file mode 100644 index 000000000000..518fe36db910 --- /dev/null +++ b/rust/sys/Cargo.toml.in @@ -0,0 +1,6 @@ +[package] +name = "suricata-sys" +version = "@PACKAGE_VERSION@" +edition = "2021" +license = "GPL-2.0-only" +description = "Bindings to Suricata C interface" diff --git a/rust/sys/Makefile.am b/rust/sys/Makefile.am new file mode 100644 index 000000000000..acf00aeb6850 --- /dev/null +++ b/rust/sys/Makefile.am @@ -0,0 +1,3 @@ +EXTRA_DIST = Cargo.toml + +all-local: Cargo.toml diff --git a/rust/sys/src/lib.rs b/rust/sys/src/lib.rs new file mode 100644 index 000000000000..48917a9d99c7 --- /dev/null +++ b/rust/sys/src/lib.rs @@ -0,0 +1,16 @@ +/* Copyright (C) 2025 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. + */ From af17e4ad2d6ff85e13190dbc7383a9dc8b35e34c Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Thu, 23 Jan 2025 16:26:25 -0600 Subject: [PATCH 3/6] rust: integrate bindgen to generate Rust bindings to C Bindgen works by processing a header file which includes all other header files it should generate bindings for. For this I've created bindgen.h which just includes app-layer-protos.h for now as an example. These bindings are then generated and saved in the "suricata-sys" crate and become availale as "suricata_sys::sys". --- rust/Makefile.am | 35 +++++++++++++++++++++++++++++ rust/sys/src/lib.rs | 6 +++++ rust/sys/src/sys.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++ src/Makefile.am | 1 + src/bindgen.h | 34 ++++++++++++++++++++++++++++ 5 files changed, 130 insertions(+) create mode 100644 rust/sys/src/sys.rs create mode 100644 src/bindgen.h diff --git a/rust/Makefile.am b/rust/Makefile.am index b9d2af56eba8..4b46c5af88d0 100644 --- a/rust/Makefile.am +++ b/rust/Makefile.am @@ -79,14 +79,49 @@ clean-local: distclean-local: rm -rf vendor dist +check-bindgen-bindings: +if HAVE_BINDGEN + if test "$(top_srcdir)" = "$(top_builddir)"; then \ + cp sys/src/sys.rs sys/src/sys.rs.orig; \ + $(MAKE) update-bindings; \ + if diff sys/src/sys.rs sys/src/sys.rs.orig > /dev/null 2>&1; then \ + rm -f sys/src/sys.rs.orig; \ + else \ + echo "WARNING: bindgen bindings may be out of date"; \ + fi \ + else \ + echo "Not checking bindings for out of tree build"; \ + fi +else + @echo "Unable to check bindgen bindings: bindgen not found" +endif + check: cd $(abs_top_srcdir)/rust && \ $(CARGO_ENV) \ $(CARGO) test --all $(RELEASE) --features "$(RUST_FEATURES)" + $(MAKE) check-bindgen-bindings vendor: $(CARGO_ENV) $(CARGO) vendor +update-bindings: +if HAVE_BINDGEN + $(BINDGEN) \ + -o sys/src/sys.rs \ + --rust-target 1.71 \ + --disable-header-comment \ + --default-enum-style rust \ + --allowlist-type 'AppProto.*' \ + --allowlist-function 'AppProto.*' \ + $(abs_top_srcdir)/src/bindgen.h \ + -- \ + -DHAVE_CONFIG_H -I../src -I../rust/gen $(CPPFLAGS) +else + @echo "error: bindgen not installed, can't update bindings" + exit 1 +endif + if HAVE_CBINDGEN gen/rust-bindings.h: $(RUST_SURICATA_LIB) cd $(abs_top_srcdir)/rust && \ diff --git a/rust/sys/src/lib.rs b/rust/sys/src/lib.rs index 48917a9d99c7..470f6e7a37ee 100644 --- a/rust/sys/src/lib.rs +++ b/rust/sys/src/lib.rs @@ -14,3 +14,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ + +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(clippy::all)] + +pub mod sys; diff --git a/rust/sys/src/sys.rs b/rust/sys/src/sys.rs new file mode 100644 index 000000000000..61c35d8d2e21 --- /dev/null +++ b/rust/sys/src/sys.rs @@ -0,0 +1,54 @@ +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum AppProtoEnum { + ALPROTO_UNKNOWN = 0, + ALPROTO_FAILED = 1, + ALPROTO_HTTP1 = 2, + ALPROTO_FTP = 3, + ALPROTO_SMTP = 4, + ALPROTO_TLS = 5, + ALPROTO_SSH = 6, + ALPROTO_IMAP = 7, + ALPROTO_JABBER = 8, + ALPROTO_SMB = 9, + ALPROTO_DCERPC = 10, + ALPROTO_IRC = 11, + ALPROTO_DNS = 12, + ALPROTO_MODBUS = 13, + ALPROTO_ENIP = 14, + ALPROTO_DNP3 = 15, + ALPROTO_NFS = 16, + ALPROTO_NTP = 17, + ALPROTO_FTPDATA = 18, + ALPROTO_TFTP = 19, + ALPROTO_IKE = 20, + ALPROTO_KRB5 = 21, + ALPROTO_QUIC = 22, + ALPROTO_DHCP = 23, + ALPROTO_SNMP = 24, + ALPROTO_SIP = 25, + ALPROTO_RFB = 26, + ALPROTO_MQTT = 27, + ALPROTO_PGSQL = 28, + ALPROTO_TELNET = 29, + ALPROTO_WEBSOCKET = 30, + ALPROTO_LDAP = 31, + ALPROTO_DOH2 = 32, + ALPROTO_TEMPLATE = 33, + ALPROTO_RDP = 34, + ALPROTO_HTTP2 = 35, + ALPROTO_BITTORRENT_DHT = 36, + ALPROTO_POP3 = 37, + ALPROTO_HTTP = 38, + ALPROTO_MAX_STATIC = 39, +} +pub type AppProto = u16; +extern "C" { + #[doc = " \\brief Maps the ALPROTO_*, to its string equivalent.\n\n \\param alproto App layer protocol id.\n\n \\retval String equivalent for the alproto."] + pub fn AppProtoToString(alproto: AppProto) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn AppProtoRegisterProtoString( + alproto: AppProto, proto_name: *const ::std::os::raw::c_char, + ); +} diff --git a/src/Makefile.am b/src/Makefile.am index 615816953542..bd479d7a4d97 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,6 +43,7 @@ noinst_HEADERS = \ app-layer-ssl.h \ app-layer-tftp.h \ app-layer-imap.h \ + bindgen.h \ build-info.h \ conf.h \ conf-yaml-loader.h \ diff --git a/src/bindgen.h b/src/bindgen.h new file mode 100644 index 000000000000..9db5d0f6091d --- /dev/null +++ b/src/bindgen.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2025 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. + */ + +/** + * \file Input to bindgen to generate Rust bindings. + * + * This file should include every header that should have Rust + * bindings generated for it. It is then used by bindgen to generate + * the Rust bindings. + */ + +#ifndef SURICATA_BINDGEN_H +#define SURICATA_BINDGEN_H + +#include "stdint.h" +#include "stdbool.h" + +#include "app-layer-protos.h" + +#endif From 770cd3c9915e14b714dab5812ae0c335cfa5cbc5 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Thu, 23 Jan 2025 16:40:22 -0600 Subject: [PATCH 4/6] rust: use AppProto from generated bindings instead of duplicating Have bindgen generate bindings for app-layer-protos.h, then use the generated definitions of AppProto/AppProtoEnum instead if defining them ourselves. This header was chosen as its used by Rust, and its a simple header with no circular dependencies. --- rust/src/applayer.rs | 3 ++- rust/src/applayertemplate/template.rs | 3 ++- rust/src/bittorrent_dht/bittorrent_dht.rs | 4 +++- rust/src/core.rs | 9 ++++----- rust/src/dcerpc/dcerpc.rs | 3 ++- rust/src/dcerpc/dcerpc_udp.rs | 5 +++-- rust/src/detect/mod.rs | 3 ++- rust/src/dhcp/dhcp.rs | 4 +++- rust/src/dns/dns.rs | 1 + rust/src/enip/enip.rs | 3 ++- rust/src/http2/http2.rs | 1 + rust/src/ike/ike.rs | 1 + rust/src/krb/krb5.rs | 3 ++- rust/src/ldap/ldap.rs | 1 + rust/src/modbus/modbus.rs | 3 ++- rust/src/mqtt/mqtt.rs | 1 + rust/src/nfs/nfs.rs | 1 + rust/src/ntp/ntp.rs | 3 ++- rust/src/pgsql/pgsql.rs | 3 ++- rust/src/quic/quic.rs | 3 ++- rust/src/rdp/rdp.rs | 3 ++- rust/src/rfb/rfb.rs | 3 ++- rust/src/sip/sip.rs | 3 ++- rust/src/smb/smb.rs | 1 + rust/src/snmp/snmp.rs | 1 + rust/src/ssh/ssh.rs | 1 + rust/src/telnet/telnet.rs | 3 ++- rust/src/websocket/websocket.rs | 3 ++- 28 files changed, 52 insertions(+), 24 deletions(-) diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index cd75d43933de..c1cd8014fdcb 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,AppLayerEventType,AppProto}; +use crate::core::{self,DetectEngineState,AppLayerEventType}; use crate::direction::Direction; use crate::filecontainer::FileContainer; use crate::flow::Flow; @@ -30,6 +30,7 @@ use crate::core::StreamingBufferConfig; // Make the AppLayerEvent derive macro available to users importing // AppLayerEvent from this module. pub use suricata_derive::AppLayerEvent; +use suricata_sys::sys::AppProto; #[repr(C)] pub struct StreamSlice { diff --git a/rust/src/applayertemplate/template.rs b/rust/src/applayertemplate/template.rs index 9f706a74bba0..88f66af34b3a 100644 --- a/rust/src/applayertemplate/template.rs +++ b/rust/src/applayertemplate/template.rs @@ -18,9 +18,10 @@ use super::parser; use crate::applayer::{self, *}; use crate::conf::conf_get; -use crate::core::{AppProto, ALPROTO_UNKNOWN, IPPROTO_TCP}; +use crate::core::{ALPROTO_UNKNOWN, IPPROTO_TCP}; use crate::flow::Flow; use nom7 as nom; +use suricata_sys::sys::AppProto; use std; use std::collections::VecDeque; use std::ffi::CString; diff --git a/rust/src/bittorrent_dht/bittorrent_dht.rs b/rust/src/bittorrent_dht/bittorrent_dht.rs index 812625b3debd..3f447635dbbf 100644 --- a/rust/src/bittorrent_dht/bittorrent_dht.rs +++ b/rust/src/bittorrent_dht/bittorrent_dht.rs @@ -15,11 +15,13 @@ * 02110-1301, USA. */ +use suricata_sys::sys::AppProto; + use crate::applayer::{self, *}; use crate::bittorrent_dht::parser::{ parse_bittorrent_dht_packet, BitTorrentDHTError, BitTorrentDHTRequest, BitTorrentDHTResponse, }; -use crate::core::{AppProto, ALPROTO_UNKNOWN, IPPROTO_UDP}; +use crate::core::{ALPROTO_UNKNOWN, IPPROTO_UDP}; use crate::direction::Direction; use crate::flow::Flow; use std::ffi::CString; diff --git a/rust/src/core.rs b/rust/src/core.rs index 7e1094a39e90..736d08967763 100644 --- a/rust/src/core.rs +++ b/rust/src/core.rs @@ -18,6 +18,8 @@ //! This module exposes items from the core "C" code to Rust. use std; +use suricata_sys::sys::{AppProto, AppProtoEnum}; + use crate::filecontainer::*; use crate::flow::Flow; @@ -41,11 +43,8 @@ pub const STREAM_GAP: u8 = 0x10; pub const STREAM_DEPTH: u8 = 0x20; pub const STREAM_MIDSTREAM:u8 = 0x40; -// Application layer protocol identifiers (app-layer-protos.h) -pub type AppProto = u16; - -pub const ALPROTO_UNKNOWN : AppProto = 0; -pub const ALPROTO_FAILED : AppProto = 1; +pub const ALPROTO_UNKNOWN : AppProto = AppProtoEnum::ALPROTO_UNKNOWN as AppProto; +pub const ALPROTO_FAILED : AppProto = AppProtoEnum::ALPROTO_FAILED as AppProto; pub const IPPROTO_TCP : u8 = 6; pub const IPPROTO_UDP : u8 = 17; diff --git a/rust/src/dcerpc/dcerpc.rs b/rust/src/dcerpc/dcerpc.rs index c8c377a3724e..7d57be9f0dcd 100644 --- a/rust/src/dcerpc/dcerpc.rs +++ b/rust/src/dcerpc/dcerpc.rs @@ -23,6 +23,7 @@ use crate::flow::Flow; use nom7::error::{Error, ErrorKind}; use nom7::number::Endianness; use nom7::{Err, IResult, Needed}; +use suricata_sys::sys::AppProto; use std; use std::cmp; use std::ffi::CString; @@ -1178,7 +1179,7 @@ pub unsafe extern "C" fn rs_dcerpc_parse_response( } #[no_mangle] -pub extern "C" fn rs_dcerpc_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: core::AppProto) -> *mut std::os::raw::c_void { +pub extern "C" fn rs_dcerpc_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void { let state = DCERPCState::new(); let boxed = Box::new(state); return Box::into_raw(boxed) as *mut _; diff --git a/rust/src/dcerpc/dcerpc_udp.rs b/rust/src/dcerpc/dcerpc_udp.rs index 673d1608ae4a..e2d14e7c41d6 100644 --- a/rust/src/dcerpc/dcerpc_udp.rs +++ b/rust/src/dcerpc/dcerpc_udp.rs @@ -24,6 +24,7 @@ use crate::dcerpc::dcerpc::{ use crate::direction::{Direction, DIR_BOTH}; use crate::flow::Flow; use nom7::Err; +use suricata_sys::sys::AppProto; use std; use std::ffi::CString; use std::collections::VecDeque; @@ -252,7 +253,7 @@ pub extern "C" fn rs_dcerpc_udp_state_free(state: *mut std::os::raw::c_void) { } #[no_mangle] -pub extern "C" fn rs_dcerpc_udp_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: core::AppProto) -> *mut std::os::raw::c_void { +pub extern "C" fn rs_dcerpc_udp_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void { let state = DCERPCUDPState::new(); let boxed = Box::new(state); return Box::into_raw(boxed) as *mut _; @@ -313,7 +314,7 @@ fn probe(input: &[u8]) -> (bool, bool) { } pub unsafe extern "C" fn rs_dcerpc_probe_udp(_f: *const Flow, direction: u8, input: *const u8, - len: u32, rdir: *mut u8) -> core::AppProto + len: u32, rdir: *mut u8) -> AppProto { SCLogDebug!("Probing the packet for DCERPC/UDP"); if len == 0 || input.is_null() { diff --git a/rust/src/detect/mod.rs b/rust/src/detect/mod.rs index c00f0dfdeb18..7eb3ecdf1920 100644 --- a/rust/src/detect/mod.rs +++ b/rust/src/detect/mod.rs @@ -31,9 +31,10 @@ pub mod uri; pub mod tojson; pub mod vlan; -use crate::core::AppProto; use std::os::raw::{c_int, c_void}; +use suricata_sys::sys::AppProto; + /// EnumString trait that will be implemented on enums that /// derive StringEnum. pub trait EnumString { diff --git a/rust/src/dhcp/dhcp.rs b/rust/src/dhcp/dhcp.rs index 965535375021..42d0a57824c1 100644 --- a/rust/src/dhcp/dhcp.rs +++ b/rust/src/dhcp/dhcp.rs @@ -15,8 +15,10 @@ * 02110-1301, USA. */ +use suricata_sys::sys::AppProto; + use crate::applayer::{self, *}; -use crate::core::{AppProto, ALPROTO_UNKNOWN, IPPROTO_UDP}; +use crate::core::{ALPROTO_UNKNOWN, IPPROTO_UDP}; use crate::dhcp::parser::*; use crate::flow::Flow; use std; diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index 30c1254274b8..7b2f67b43a2a 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -30,6 +30,7 @@ use crate::frames::Frame; use nom7::number::streaming::be_u16; use nom7::{Err, IResult}; +use suricata_sys::sys::AppProto; /// DNS record types. pub const DNS_RECORD_TYPE_A: u16 = 1; diff --git a/rust/src/enip/enip.rs b/rust/src/enip/enip.rs index d58efde5b00f..0cf2cbcc2adb 100644 --- a/rust/src/enip/enip.rs +++ b/rust/src/enip/enip.rs @@ -20,7 +20,7 @@ use super::parser; use crate::applayer::{self, *}; use crate::conf::conf_get; use crate::core::{ - AppProto, ALPROTO_FAILED, ALPROTO_UNKNOWN, IPPROTO_TCP, IPPROTO_UDP, + ALPROTO_FAILED, ALPROTO_UNKNOWN, IPPROTO_TCP, IPPROTO_UDP, STREAM_TOCLIENT, STREAM_TOSERVER, }; use crate::detect::EnumString; @@ -28,6 +28,7 @@ use crate::direction::Direction; use crate::flow::Flow; use crate::frames::Frame; use nom7 as nom; +use suricata_sys::sys::AppProto; use std; use std::collections::VecDeque; use std::ffi::CString; diff --git a/rust/src/http2/http2.rs b/rust/src/http2/http2.rs index fd5cf12abd31..eac3c884828b 100644 --- a/rust/src/http2/http2.rs +++ b/rust/src/http2/http2.rs @@ -32,6 +32,7 @@ use crate::frames::Frame; use crate::dns::dns::{dns_parse_request, dns_parse_response, DNSTransaction}; use nom7::Err; +use suricata_sys::sys::AppProto; use std; use std::collections::VecDeque; use std::ffi::CString; diff --git a/rust/src/ike/ike.rs b/rust/src/ike/ike.rs index 297b01f61c49..c62499d6e625 100644 --- a/rust/src/ike/ike.rs +++ b/rust/src/ike/ike.rs @@ -29,6 +29,7 @@ use crate::ike::ikev1::{handle_ikev1, IkeV1Header, Ikev1Container}; use crate::ike::ikev2::{handle_ikev2, Ikev2Container}; use crate::ike::parser::*; use nom7::Err; +use suricata_sys::sys::AppProto; use std; use std::collections::HashSet; use std::ffi::CString; diff --git a/rust/src/krb/krb5.rs b/rust/src/krb/krb5.rs index 9d90cdd992a7..4a07ea45a84b 100644 --- a/rust/src/krb/krb5.rs +++ b/rust/src/krb/krb5.rs @@ -26,9 +26,10 @@ use der_parser::ber::Class; use kerberos_parser::krb5_parser; use kerberos_parser::krb5::{EncryptionType,ErrorCode,MessageType,PrincipalName,Realm,KrbError}; use asn1_rs::FromDer; +use suricata_sys::sys::AppProto; use crate::applayer::{self, *}; use crate::core; -use crate::core::{AppProto,ALPROTO_FAILED,ALPROTO_UNKNOWN, IPPROTO_TCP, IPPROTO_UDP}; +use crate::core::{ALPROTO_FAILED,ALPROTO_UNKNOWN, IPPROTO_TCP, IPPROTO_UDP}; use crate::direction::Direction; use crate::flow::Flow; diff --git a/rust/src/ldap/ldap.rs b/rust/src/ldap/ldap.rs index 3223fc8bf9fa..867b122cfb56 100644 --- a/rust/src/ldap/ldap.rs +++ b/rust/src/ldap/ldap.rs @@ -24,6 +24,7 @@ use crate::direction::Direction; use crate::flow::Flow; use crate::frames::*; use nom7 as nom; +use suricata_sys::sys::AppProto; use std; use std::collections::VecDeque; use std::ffi::CString; diff --git a/rust/src/modbus/modbus.rs b/rust/src/modbus/modbus.rs index 33cb9787c47e..52486b5b22b0 100644 --- a/rust/src/modbus/modbus.rs +++ b/rust/src/modbus/modbus.rs @@ -15,7 +15,7 @@ * 02110-1301, USA. */ use crate::applayer::{self, *}; -use crate::core::{AppProto, ALPROTO_FAILED, ALPROTO_UNKNOWN, IPPROTO_TCP}; +use crate::core::{ALPROTO_FAILED, ALPROTO_UNKNOWN, IPPROTO_TCP}; use crate::flow::Flow; use std::ffi::CString; @@ -25,6 +25,7 @@ use sawp::error::ErrorKind as SawpErrorKind; use sawp::parser::{Direction, Parse}; use sawp::probe::{Probe, Status}; use sawp_modbus::{self, AccessType, ErrorFlags, Flags, Message}; +use suricata_sys::sys::AppProto; pub const REQUEST_FLOOD: usize = 500; // Default unreplied Modbus requests are considered a flood pub const MODBUS_PARSER: sawp_modbus::Modbus = sawp_modbus::Modbus { probe_strict: true }; diff --git a/rust/src/mqtt/mqtt.rs b/rust/src/mqtt/mqtt.rs index 697d2ef266cb..71e90573de93 100644 --- a/rust/src/mqtt/mqtt.rs +++ b/rust/src/mqtt/mqtt.rs @@ -27,6 +27,7 @@ use crate::direction::Direction; use crate::flow::Flow; use crate::frames::*; use nom7::Err; +use suricata_sys::sys::AppProto; use std; use std::collections::VecDeque; use std::ffi::CString; diff --git a/rust/src/nfs/nfs.rs b/rust/src/nfs/nfs.rs index 48a6bba1c18b..9d8872e9a788 100644 --- a/rust/src/nfs/nfs.rs +++ b/rust/src/nfs/nfs.rs @@ -23,6 +23,7 @@ use std::collections::HashMap; use std::ffi::CString; use nom7::{Err, Needed}; +use suricata_sys::sys::AppProto; use crate::applayer; use crate::applayer::*; diff --git a/rust/src/ntp/ntp.rs b/rust/src/ntp/ntp.rs index 576e1b6fc80d..e6f1dd656254 100644 --- a/rust/src/ntp/ntp.rs +++ b/rust/src/ntp/ntp.rs @@ -21,13 +21,14 @@ extern crate ntp_parser; use self::ntp_parser::*; use crate::applayer::{self, *}; use crate::core; -use crate::core::{AppProto, ALPROTO_FAILED, ALPROTO_UNKNOWN}; +use crate::core::{ALPROTO_FAILED, ALPROTO_UNKNOWN}; use crate::direction::Direction; use crate::flow::Flow; use std; use std::ffi::CString; use nom7::Err; +use suricata_sys::sys::AppProto; #[derive(AppLayerEvent)] pub enum NTPEvent { diff --git a/rust/src/pgsql/pgsql.rs b/rust/src/pgsql/pgsql.rs index 4054eac0c3c7..0ea9d6106744 100644 --- a/rust/src/pgsql/pgsql.rs +++ b/rust/src/pgsql/pgsql.rs @@ -22,10 +22,11 @@ use super::parser::{self, ConsolidatedDataRowPacket, PgsqlBEMessage, PgsqlFEMessage}; use crate::applayer::*; use crate::conf::*; -use crate::core::{AppProto, ALPROTO_FAILED, ALPROTO_UNKNOWN, IPPROTO_TCP, *}; +use crate::core::{ALPROTO_FAILED, ALPROTO_UNKNOWN, IPPROTO_TCP, *}; use crate::direction::Direction; use crate::flow::Flow; use nom7::{Err, IResult}; +use suricata_sys::sys::AppProto; use std; use std::collections::VecDeque; use std::ffi::CString; diff --git a/rust/src/quic/quic.rs b/rust/src/quic/quic.rs index 442cfc944a65..94f4edc62f31 100644 --- a/rust/src/quic/quic.rs +++ b/rust/src/quic/quic.rs @@ -22,9 +22,10 @@ use super::{ parser::{quic_pkt_num, QuicData, QuicHeader, QuicType}, }; use crate::{applayer::{self, *}, direction::Direction, flow::Flow}; -use crate::core::{AppProto, ALPROTO_FAILED, ALPROTO_UNKNOWN, IPPROTO_UDP}; +use crate::core::{ALPROTO_FAILED, ALPROTO_UNKNOWN, IPPROTO_UDP}; use std::collections::VecDeque; use std::ffi::CString; +use suricata_sys::sys::AppProto; use tls_parser::TlsExtensionType; static mut ALPROTO_QUIC: AppProto = ALPROTO_UNKNOWN; diff --git a/rust/src/rdp/rdp.rs b/rust/src/rdp/rdp.rs index b5684aa248a9..45c924e49ef1 100644 --- a/rust/src/rdp/rdp.rs +++ b/rust/src/rdp/rdp.rs @@ -20,10 +20,11 @@ //! RDP application layer use crate::applayer::{self, *}; -use crate::core::{AppProto, ALPROTO_UNKNOWN, IPPROTO_TCP}; +use crate::core::{ALPROTO_UNKNOWN, IPPROTO_TCP}; use crate::flow::Flow; use crate::rdp::parser::*; use nom7::Err; +use suricata_sys::sys::AppProto; use std; use std::collections::VecDeque; use tls_parser::{parse_tls_plaintext, TlsMessage, TlsMessageHandshake, TlsRecordType}; diff --git a/rust/src/rfb/rfb.rs b/rust/src/rfb/rfb.rs index 6901c973dd74..3c34196171fb 100644 --- a/rust/src/rfb/rfb.rs +++ b/rust/src/rfb/rfb.rs @@ -21,11 +21,12 @@ use super::parser; use crate::applayer; use crate::applayer::*; -use crate::core::{AppProto, ALPROTO_UNKNOWN, IPPROTO_TCP}; +use crate::core::{ALPROTO_UNKNOWN, IPPROTO_TCP}; use crate::direction::Direction; use crate::flow::Flow; use crate::frames::*; use nom7::Err; +use suricata_sys::sys::AppProto; use std; use std::ffi::CString; use std::os::raw::c_char; diff --git a/rust/src/sip/sip.rs b/rust/src/sip/sip.rs index 1743953f1f33..d0549685facd 100755 --- a/rust/src/sip/sip.rs +++ b/rust/src/sip/sip.rs @@ -19,12 +19,13 @@ use crate::applayer::{self, *}; use crate::core; -use crate::core::{AppProto, ALPROTO_UNKNOWN, IPPROTO_TCP, IPPROTO_UDP}; +use crate::core::{ALPROTO_UNKNOWN, IPPROTO_TCP, IPPROTO_UDP}; use crate::direction::Direction; use crate::flow::Flow; use crate::frames::*; use crate::sip::parser::*; use nom7::Err; +use suricata_sys::sys::AppProto; use std; use std::collections::VecDeque; use std::ffi::CString; diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index 43a44545ad09..2ff1ad15ea43 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -34,6 +34,7 @@ use nom7::{Err, Needed}; use nom7::error::{make_error, ErrorKind}; use lru::LruCache; +use suricata_sys::sys::AppProto; use std::num::NonZeroUsize; use crate::core::*; diff --git a/rust/src/snmp/snmp.rs b/rust/src/snmp/snmp.rs index a30e182aefb4..aa4b0b3f60d2 100644 --- a/rust/src/snmp/snmp.rs +++ b/rust/src/snmp/snmp.rs @@ -30,6 +30,7 @@ use der_parser::ber::BerObjectContent; use der_parser::der::parse_der_sequence; use nom7::{Err, IResult}; use nom7::error::{ErrorKind, make_error}; +use suricata_sys::sys::AppProto; #[derive(AppLayerEvent)] pub enum SNMPEvent { diff --git a/rust/src/ssh/ssh.rs b/rust/src/ssh/ssh.rs index e0c4ecc7c0c8..202969958b76 100644 --- a/rust/src/ssh/ssh.rs +++ b/rust/src/ssh/ssh.rs @@ -22,6 +22,7 @@ use crate::direction::Direction; use crate::flow::Flow; use crate::frames::Frame; use nom7::Err; +use suricata_sys::sys::AppProto; use std::ffi::CString; use std::sync::atomic::{AtomicBool, Ordering}; diff --git a/rust/src/telnet/telnet.rs b/rust/src/telnet/telnet.rs index 01f0e38c9ab4..88dcd3638eaf 100644 --- a/rust/src/telnet/telnet.rs +++ b/rust/src/telnet/telnet.rs @@ -16,12 +16,13 @@ */ use std; -use crate::core::{ALPROTO_UNKNOWN, AppProto, IPPROTO_TCP}; +use crate::core::{ALPROTO_UNKNOWN, IPPROTO_TCP}; use crate::applayer::{self, *}; use crate::flow::Flow; use crate::frames::*; use std::ffi::CString; use nom7::IResult; +use suricata_sys::sys::AppProto; use super::parser; static mut ALPROTO_TELNET: AppProto = ALPROTO_UNKNOWN; diff --git a/rust/src/websocket/websocket.rs b/rust/src/websocket/websocket.rs index 3f49efbc19ee..516065ebfbc2 100644 --- a/rust/src/websocket/websocket.rs +++ b/rust/src/websocket/websocket.rs @@ -18,7 +18,7 @@ use super::parser; use crate::applayer::{self, *}; use crate::conf::conf_get; -use crate::core::{AppProto, ALPROTO_FAILED, ALPROTO_UNKNOWN, IPPROTO_TCP}; +use crate::core::{ALPROTO_FAILED, ALPROTO_UNKNOWN, IPPROTO_TCP}; use crate::direction::Direction; use crate::flow::Flow; use crate::frames::Frame; @@ -27,6 +27,7 @@ use nom7 as nom; use nom7::Needed; use flate2::read::DeflateDecoder; +use suricata_sys::sys::AppProto; use std; use std::collections::VecDeque; From 66e4d9807b06e9cbae9b6f09649c862b62c27e49 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Fri, 24 Jan 2025 08:59:39 -0600 Subject: [PATCH 5/6] github-ci: test that bindgen bindings are up to date Regenerates the `sys.rs` and looks for any difference. Check will fail if there is a difference. --- .github/workflows/rust.yml | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 28d8b3ee7218..3571edd6a452 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -21,20 +21,18 @@ jobs: runs-on: ubuntu-latest container: almalinux:9 steps: - - name: Cache rust - uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 - with: - path: ~/.cargo - key: check-rust - - name: Install system packages run: | - dnf -y install dnf-plugins-core + dnf -y install dnf-plugins-core epel-release dnf config-manager --set-enabled crb dnf -y install \ autoconf \ automake \ - cargo-vendor \ + bindgen \ + cargo \ + cbindgen \ + clang-devel \ + clippy \ diffutils \ numactl-devel \ dpdk-devel \ @@ -61,21 +59,28 @@ jobs: python3-devel \ python3-sphinx \ python3-yaml \ + rust \ + rustfmt \ sudo \ which \ zlib-devel - - name: Installing Rust - run: | - curl https://sh.rustup.rs -sSf | sh -s -- -y - echo "$HOME/.cargo/bin" >> $GITHUB_PATH - - name: Install cbindgen - run: cargo install --debug cbindgen - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - run: git config --global --add safe.directory /__w/suricata/suricata - run: ./scripts/bundle.sh - run: ./autogen.sh - run: ./configure --enable-warnings + - name: Checking bindgen output + working-directory: rust + run: | + bindgen --version + make check-bindgen-bindings + diff=$(git diff sys) + if [ "${diff}" ]; then + echo "${diff}" + echo "::error ::Bindgen bindings appear to be out of date" + exit 1 + fi - run: cargo clippy --all-features --fix --allow-no-vcs working-directory: rust - run: | From 9844b39f2af8f4fe9e548828234a203851ad43dd Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Fri, 24 Jan 2025 09:05:03 -0600 Subject: [PATCH 6/6] rust: add auto-generated header to sys.rs We don't keep bindgen's autogenerated do not edit line as it contains the bindgen version which could break the CI check for out of date bindings. So add our own do not edit line. --- rust/Makefile.am | 1 + rust/sys/src/sys.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/rust/Makefile.am b/rust/Makefile.am index 4b46c5af88d0..5e3cd5ff82f8 100644 --- a/rust/Makefile.am +++ b/rust/Makefile.am @@ -117,6 +117,7 @@ if HAVE_BINDGEN $(abs_top_srcdir)/src/bindgen.h \ -- \ -DHAVE_CONFIG_H -I../src -I../rust/gen $(CPPFLAGS) + sed -i '1i\// This file is automatically generated. Do not edit.\n' sys/src/sys.rs else @echo "error: bindgen not installed, can't update bindings" exit 1 diff --git a/rust/sys/src/sys.rs b/rust/sys/src/sys.rs index 61c35d8d2e21..1c358f7b5a15 100644 --- a/rust/sys/src/sys.rs +++ b/rust/sys/src/sys.rs @@ -1,3 +1,5 @@ +// This file is automatically generated. Do not edit. + #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum AppProtoEnum {