rust: move file functions out of SuricataContext

Ticket: 7667
pull/13884/head
Philippe Antoine 5 months ago committed by Victor Julien
parent 1f084f8cb7
commit 24503b0ead

@ -108,8 +108,6 @@ exclude = [
"JsonT",
"IKEState",
"IKETransaction",
"SuricataContext",
"SuricataFileContext",
"TFTPState",
"TFTPTransaction",
"free",

@ -21,7 +21,6 @@ use suricata_sys::sys::{AppProto, AppProtoEnum};
#[cfg(not(test))]
use suricata_sys::sys::SCAppLayerParserTriggerRawStreamInspection;
use crate::filecontainer::*;
use crate::flow::Flow;
#[repr(C)]
@ -69,77 +68,12 @@ macro_rules!BIT_U64 {
//
pub enum StreamingBufferConfig {}
pub type SCFileOpenFileWithId = extern "C" fn (
file_container: &FileContainer,
sbcfg: &StreamingBufferConfig,
track_id: u32,
name: *const u8, name_len: u16,
data: *const u8, data_len: u32,
flags: u16) -> i32;
pub type SCFileCloseFileById = extern "C" fn (
file_container: &FileContainer,
sbcfg: &StreamingBufferConfig,
track_id: u32,
data: *const u8, data_len: u32,
flags: u16) -> i32;
pub type SCFileAppendDataById = extern "C" fn (
file_container: &FileContainer,
sbcfg: &StreamingBufferConfig,
track_id: u32,
data: *const u8, data_len: u32) -> i32;
pub type SCFileAppendGAPById = extern "C" fn (
file_container: &FileContainer,
sbcfg: &StreamingBufferConfig,
track_id: u32,
data: *const u8, data_len: u32) -> i32;
pub type SCFileContainerRecycle = extern "C" fn (
file_container: &FileContainer,
sbcfg: &StreamingBufferConfig);
// A Suricata context that is passed in from C. This is alternative to
// using functions from Suricata directly, so they can be wrapped so
// Rust unit tests will still compile when they are not linked
// directly to the real function.
//
// This might add a little too much complexity to keep pure Rust test
// cases working.
#[allow(non_snake_case)]
#[repr(C)]
pub struct SuricataContext {
pub FileOpenFile: SCFileOpenFileWithId,
pub FileCloseFile: SCFileCloseFileById,
pub FileAppendData: SCFileAppendDataById,
pub FileAppendGAP: SCFileAppendGAPById,
pub FileContainerRecycle: SCFileContainerRecycle,
}
#[allow(non_snake_case)]
#[repr(C)]
pub struct SuricataFileContext {
pub files_sbcfg: &'static StreamingBufferConfig,
}
#[allow(unused_doc_comments)]
/// cbindgen:ignore
extern "C" {
pub fn SCGetContext() -> &'static mut SuricataContext;
}
pub static mut SC: Option<&'static SuricataContext> = None;
pub fn init_ffi(context: &'static SuricataContext)
{
unsafe {
SC = Some(context);
}
}
#[no_mangle]
pub extern "C" fn SCRustInit(context: &'static SuricataContext)
{
init_ffi(context);
}
/// SCAppLayerParserTriggerRawStreamInspection wrapper
#[cfg(not(test))]
pub(crate) fn sc_app_layer_parser_trigger_raw_stream_inspection(flow: *mut Flow, direction: i32) {

@ -17,85 +17,160 @@
//! This module handles file container operations (open, append, close).
use std::os::raw::c_void;
use std::ptr;
use std::os::raw::{c_void};
use crate::core::*;
#[repr(C)]
#[derive(Debug)]
pub struct FileContainer {
head: * mut c_void,
tail: * mut c_void,
head: *mut c_void,
tail: *mut c_void,
}
impl Default for FileContainer {
fn default() -> Self { Self {
head: ptr::null_mut(),
tail: ptr::null_mut(),
}}
fn default() -> Self {
Self {
head: ptr::null_mut(),
tail: ptr::null_mut(),
}
}
}
// Defined in util-file.h
#[allow(unused_doc_comments)]
/// cbindgen:ignore
extern "C" {
#[cfg(not(test))]
pub fn FileContainerRecycle(file_container: &mut FileContainer, sbcfg: &StreamingBufferConfig);
#[cfg(not(test))]
pub fn FileAppendGAPById(
file_container: &mut FileContainer, sbcfg: &StreamingBufferConfig, track_id: u32,
data: *const u8, data_len: u32,
) -> i32;
#[cfg(not(test))]
pub fn FileAppendDataById(
file_container: &mut FileContainer, sbcfg: &StreamingBufferConfig, track_id: u32,
data: *const u8, data_len: u32,
) -> i32;
#[cfg(not(test))]
pub fn FileCloseFileById(
file_container: &mut FileContainer, sbcfg: &StreamingBufferConfig, track_id: u32,
data: *const u8, data_len: u32, flags: u16,
) -> i32;
#[cfg(not(test))]
pub fn FileOpenFileWithId(
file_container: &mut FileContainer, sbcfg: &StreamingBufferConfig, track_id: u32,
name: *const u8, name_len: u16, data: *const u8, data_len: u32, flags: u16,
) -> i32;
}
#[cfg(test)]
#[allow(non_snake_case)]
pub(super) unsafe fn FileContainerRecycle(_fc: &mut FileContainer, _sbcfg: &StreamingBufferConfig) {
}
#[cfg(test)]
#[allow(non_snake_case)]
pub(super) unsafe fn FileAppendGAPById(
_fc: &mut FileContainer, _sbcfg: &StreamingBufferConfig, _track_id: u32, _data: *const u8,
_data_len: u32,
) -> i32 {
0
}
#[cfg(test)]
#[allow(non_snake_case)]
pub(super) unsafe fn FileAppendDataById(
_fc: &mut FileContainer, _sbcfg: &StreamingBufferConfig, _track_id: u32, _data: *const u8,
_data_len: u32,
) -> i32 {
0
}
#[cfg(test)]
#[allow(non_snake_case)]
pub(super) unsafe fn FileCloseFileById(
_fc: &mut FileContainer, _sbcfg: &StreamingBufferConfig, _track_id: u32, _data: *const u8,
_data_len: u32, _flags: u16,
) -> i32 {
0
}
#[cfg(test)]
#[allow(non_snake_case)]
pub(super) unsafe fn FileOpenFileWithId(
_fc: &mut FileContainer, _sbcfg: &StreamingBufferConfig, _track_id: u32, _name: *const u8,
_name_len: u16, _data: *const u8, _data_len: u32, _flags: u16,
) -> i32 {
0
}
impl FileContainer {
pub fn free(&mut self, cfg: &'static SuricataFileContext) {
SCLogDebug!("freeing self");
if let Some(c) = unsafe {SC} {
(c.FileContainerRecycle)(self, cfg.files_sbcfg);
unsafe {
FileContainerRecycle(self, cfg.files_sbcfg);
}
}
pub fn file_open(&mut self, cfg: &'static SuricataFileContext, track_id: u32, name: &[u8], flags: u16) -> i32 {
match unsafe {SC} {
None => panic!("BUG no suricata_config"),
Some(c) => {
SCLogDebug!("FILE {:p} OPEN flags {:04X}", &self, flags);
pub fn file_open(
&mut self, cfg: &'static SuricataFileContext, track_id: u32, name: &[u8], flags: u16,
) -> i32 {
SCLogDebug!("FILE {:p} OPEN flags {:04X}", &self, flags);
let res = (c.FileOpenFile)(self, cfg.files_sbcfg, track_id,
name.as_ptr(), name.len() as u16,
ptr::null(), 0u32, flags);
res
}
unsafe {
FileOpenFileWithId(
self,
cfg.files_sbcfg,
track_id,
name.as_ptr(),
name.len() as u16,
ptr::null(),
0u32,
flags,
)
}
}
pub fn file_append(&mut self, cfg: &'static SuricataFileContext, track_id: &u32, data: &[u8], is_gap: bool) -> i32 {
pub fn file_append(
&mut self, cfg: &'static SuricataFileContext, track_id: &u32, data: &[u8], is_gap: bool,
) -> i32 {
SCLogDebug!("FILECONTAINER: append {}", data.len());
if data.is_empty() {
return 0
return 0;
}
match unsafe {SC} {
None => panic!("BUG no suricata_config"),
Some(c) => {
let res = match is_gap {
false => {
SCLogDebug!("appending file data");
let r = (c.FileAppendData)(self, cfg.files_sbcfg, *track_id,
data.as_ptr(), data.len() as u32);
r
},
true => {
SCLogDebug!("appending GAP");
let r = (c.FileAppendGAP)(self, cfg.files_sbcfg, *track_id,
data.as_ptr(), data.len() as u32);
r
},
};
res
let res = match is_gap {
false => {
SCLogDebug!("appending file data");
unsafe {
FileAppendDataById(
self,
cfg.files_sbcfg,
*track_id,
data.as_ptr(),
data.len() as u32,
)
}
}
}
true => {
SCLogDebug!("appending GAP");
unsafe {
FileAppendGAPById(
self,
cfg.files_sbcfg,
*track_id,
data.as_ptr(),
data.len() as u32,
)
}
}
};
res
}
pub fn file_close(&mut self, cfg: &'static SuricataFileContext, track_id: &u32, flags: u16) -> i32 {
pub fn file_close(
&mut self, cfg: &'static SuricataFileContext, track_id: &u32, flags: u16,
) -> i32 {
SCLogDebug!("FILECONTAINER: CLOSEing");
match unsafe {SC} {
None => panic!("BUG no suricata_config"),
Some(c) => {
let res = (c.FileCloseFile)(self, cfg.files_sbcfg, *track_id, ptr::null(), 0u32, flags);
res
}
}
unsafe { FileCloseFileById(self, cfg.files_sbcfg, *track_id, ptr::null(), 0u32, flags) }
}
}

@ -21,9 +21,7 @@ use suricata_sys::sys::SCLogGetLogLevel;
pub fn init() {
unsafe {
let context = crate::core::SCGetContext();
crate::core::init_ffi(context);
// maybe we can get rid of this...
crate::debug::LEVEL = SCLogGetLogLevel();
}
}

@ -8,7 +8,7 @@ for l in sys.stdin:
if included == "rust.h" or included == "suricata-common.h":
continue
if includer == "src/suricata-common.h" or includer == "src/rust-context.h" or includer == "src/rust.h" or includer == "src/threads.h":
if includer == "src/suricata-common.h" or includer == "src/rust.h" or includer == "src/threads.h":
continue
if included == "util-file.h" and includer == "src/detect.h":

@ -435,7 +435,6 @@ noinst_HEADERS = \
runmode-unix-socket.h \
runmode-windivert.h \
runmodes.h \
rust-context.h \
rust.h \
source-af-packet.h \
source-af-xdp.h \
@ -1033,7 +1032,6 @@ libsuricata_c_a_SOURCES = \
runmode-unix-socket.c \
runmode-windivert.c \
runmodes.c \
rust-context.c \
source-af-packet.c \
source-af-xdp.c \
source-dpdk.c \

@ -28,8 +28,4 @@
void RegisterIKEParsers(void);
void IKEParserRegisterTests(void);
/** Opaque Rust types. */
typedef struct IKEState_ IKEState;
typedef struct IKETransaction_ IKETransaction;
#endif /* SURICATA_APP_LAYER_IKE_H */

@ -26,8 +26,4 @@
void RegisterTFTPParsers(void);
/** Opaque Rust types. */
typedef struct TFTPState_ TFTPState;
typedef struct TFTPTransaction_ TFTPTransaction;
#endif /* SURICATA_APP_LAYER_TFTP_H */

@ -1,38 +0,0 @@
/* Copyright (C) 2020 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.
*/
#include "suricata-common.h"
#include "rust-context.h"
#include "app-layer-parser.h"
#include "app-layer-events.h"
#include "app-layer-register.h"
#include "app-layer-htp-range.h"
#include "app-layer-htp-file.h"
#include "util-var.h"
const SuricataContext suricata_context = {
FileOpenFileWithId,
FileCloseFileById,
FileAppendDataById,
FileAppendGAPById,
FileContainerRecycle,
};
const SuricataContext *SCGetContext(void)
{
return &suricata_context;
}

@ -1,55 +0,0 @@
/* Copyright (C) 2017 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_RUST_CONTEXT_H
#define SURICATA_RUST_CONTEXT_H
#include "flow.h"
#include "detect.h"
#include "detect-engine-state.h" //DetectEngineState
#include "app-layer-ike.h" //IKEState, IKETransaction
#include "app-layer-tftp.h" //TFTPState, TFTPTransaction
#include "util-file.h"
struct AppLayerParser;
typedef struct SuricataContext_ {
int (*FileOpenFileWithId)(FileContainer *, const StreamingBufferConfig *,
uint32_t track_id, const uint8_t *name, uint16_t name_len,
const uint8_t *data, uint32_t data_len, uint16_t flags);
int (*FileCloseFileById)(FileContainer *, const StreamingBufferConfig *, uint32_t track_id,
const uint8_t *data, uint32_t data_len, uint16_t flags);
int (*FileAppendDataById)(FileContainer *, const StreamingBufferConfig *, uint32_t track_id,
const uint8_t *data, uint32_t data_len);
int (*FileAppendGAPById)(FileContainer *, const StreamingBufferConfig *, uint32_t track_id,
const uint8_t *data, uint32_t data_len);
void (*FileContainerRecycle)(FileContainer *ffc, const StreamingBufferConfig *);
} SuricataContext;
extern const SuricataContext suricata_context;
typedef struct SuricataFileContext_ {
const StreamingBufferConfig *sbcfg;
} SuricataFileContext;
const SuricataContext *SCGetContext(void);
#endif /* !SURICATA_RUST_CONTEXT_H */

@ -18,9 +18,21 @@
#ifndef SURICATA_RUST_H
#define SURICATA_RUST_H
// hack for include orders cf SCSha256
// Forward declarations needed by rust-bindings.h
typedef struct HttpRangeContainerBlock HttpRangeContainerBlock;
#include "rust-context.h"
// These need to be removed by making rust using a generic void
// in functions prototypes and then casting
typedef struct IKEState_ IKEState;
typedef struct IKETransaction_ IKETransaction;
typedef struct TFTPState_ TFTPState;
typedef struct TFTPTransaction_ TFTPTransaction;
typedef struct DetectEngineState_ DetectEngineState;
// may be improved by smaller include
#include "detect.h"
#include "rust-bindings.h"
#define JB_SET_STRING(jb, key, val) SCJbSetFormatted((jb), "\"" key "\":\"" val "\"")

@ -2964,8 +2964,6 @@ void SuricataMainLoop(void)
int InitGlobal(void)
{
SCRustInit(&suricata_context);
SC_ATOMIC_INIT(engine_stage);
/* initialize the logging subsys */

Loading…
Cancel
Save