diff --git a/doc/userguide/devguide/extending/app-layer/app-layer-frames.rst b/doc/userguide/devguide/extending/app-layer/app-layer-frames.rst index 8b7ca19a2f..c66f2e33eb 100644 --- a/doc/userguide/devguide/extending/app-layer/app-layer-frames.rst +++ b/doc/userguide/devguide/extending/app-layer/app-layer-frames.rst @@ -146,11 +146,11 @@ The Frame API calls parameters represent: ``StreamSlice`` contains the input data to the parser, alongside other Stream-related data important in parsing context. Definition is found in *applayer.rs*: -.. literalinclude:: ../../../../../rust/src/applayer.rs - :caption: rust/src/applayer.rs - :language: rust - :start-at: pub struct StreamSlice - :end-before: impl StreamSlice +.. literalinclude:: ../../../../../src/app-layer-parser.h + :caption: src/app-layer-parser.h + :language: C + :start-at: typedef struct StreamSlice { + :end-before: static inline C code diff --git a/rust/Makefile.am b/rust/Makefile.am index ccd7ea721f..6939ffb53c 100644 --- a/rust/Makefile.am +++ b/rust/Makefile.am @@ -150,6 +150,7 @@ if HAVE_BINDGEN --allowlist-type 'AppLayerGetTxIterState' \ --allowlist-type 'AppLayerStateData' \ --allowlist-type 'AppLayerGetTxIterTuple' \ + --allowlist-type 'StreamSlice' \ --allowlist-function 'SC.*' \ --allowlist-var 'SC.*' \ --opaque-type 'SCConfNode' \ diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index c1534347ee..fbe489037c 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -32,7 +32,10 @@ use suricata_sys::sys::{ DetectEngineState, GenericVar, }; -pub use suricata_sys::sys::{AppLayerGetFileState, AppLayerStateData, AppLayerGetTxIterTuple}; +pub use suricata_sys::sys::{ + AppLayerGetFileState, AppLayerStateData, AppLayerGetTxIterTuple, StreamSlice, +}; + #[cfg(not(test))] use suricata_sys::sys::{ SCAppLayerDecoderEventsFreeEvents, SCAppLayerDecoderEventsSetEventRaw, SCDetectEngineStateFree, @@ -47,20 +50,22 @@ macro_rules! cast_pointer { ($ptr:ident, $ty:ty) => ( &mut *($ptr as *mut $ty) ); } -#[repr(C)] -pub struct StreamSlice { - input: *const u8, - input_len: u32, - /// STREAM_* flags - flags: u8, - offset: u64, +pub trait StreamSliceRust { + #[cfg(test)] + fn from_slice(slice: &[u8], flags: u8, offset: u64) -> Self; + fn is_gap(&self) -> bool; + fn gap_size(&self) -> u32; + fn as_slice(&self) -> &[u8]; + fn is_empty(&self) -> bool; + fn len(&self) -> u32; + fn offset_from(&self, slice: &[u8]) -> u32; + fn flags(&self) -> u8; } -impl StreamSlice { - +impl StreamSliceRust for StreamSlice { /// Create a StreamSlice from a Rust slice. Useful in unit tests. #[cfg(test)] - pub fn from_slice(slice: &[u8], flags: u8, offset: u64) -> Self { + fn from_slice(slice: &[u8], flags: u8, offset: u64) -> Self { Self { input: slice.as_ptr(), input_len: slice.len() as u32, @@ -69,28 +74,28 @@ impl StreamSlice { } } - pub fn is_gap(&self) -> bool { + fn is_gap(&self) -> bool { self.input.is_null() && self.input_len > 0 } - pub fn gap_size(&self) -> u32 { + fn gap_size(&self) -> u32 { self.input_len } - pub fn as_slice(&self) -> &[u8] { + fn as_slice(&self) -> &[u8] { if self.input.is_null() && self.input_len == 0 { return &[]; } unsafe { std::slice::from_raw_parts(self.input, self.input_len as usize) } } - pub fn is_empty(&self) -> bool { + fn is_empty(&self) -> bool { self.input_len == 0 } - pub fn len(&self) -> u32 { + fn len(&self) -> u32 { self.input_len } - pub fn offset_from(&self, slice: &[u8]) -> u32 { + fn offset_from(&self, slice: &[u8]) -> u32 { self.len() - slice.len() as u32 } - pub fn flags(&self) -> u8 { + fn flags(&self) -> u8 { self.flags } } diff --git a/rust/src/dcerpc/dcerpc.rs b/rust/src/dcerpc/dcerpc.rs index ff69522d39..18347fb99f 100644 --- a/rust/src/dcerpc/dcerpc.rs +++ b/rust/src/dcerpc/dcerpc.rs @@ -1227,7 +1227,7 @@ pub unsafe extern "C" fn SCRegisterDcerpcParser() { #[cfg(test)] mod tests { - use crate::applayer::{AppLayerResult, StreamSlice}; + use crate::applayer::{AppLayerResult, StreamSlice, StreamSliceRust}; use crate::core::*; use crate::dcerpc::dcerpc::DCERPCState; use crate::direction::Direction; diff --git a/rust/src/frames.rs b/rust/src/frames.rs index 9951114525..4f32b94af5 100644 --- a/rust/src/frames.rs +++ b/rust/src/frames.rs @@ -19,6 +19,8 @@ use crate::applayer::StreamSlice; #[cfg(not(test))] +use crate::applayer::StreamSliceRust; +#[cfg(not(test))] use crate::core::STREAM_TOSERVER; use crate::direction::Direction; use crate::flow::Flow; diff --git a/rust/sys/src/sys.rs b/rust/sys/src/sys.rs index 9aa9a27a2c..a43254ac18 100644 --- a/rust/sys/src/sys.rs +++ b/rust/sys/src/sys.rs @@ -1055,6 +1055,24 @@ impl Default for AppLayerGetTxIterTuple { } } } +#[repr(C)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct StreamSlice { + pub input: *const u8, + pub input_len: u32, + #[doc = " STREAM_* flags"] + pub flags: u8, + pub offset: u64, +} +impl Default for StreamSlice { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} extern "C" { pub fn SCAppLayerParserReallocCtx(alproto: AppProto) -> ::std::os::raw::c_int; } diff --git a/src/app-layer-parser.h b/src/app-layer-parser.h index 9fb91ef1b3..62c1f5625e 100644 --- a/src/app-layer-parser.h +++ b/src/app-layer-parser.h @@ -147,6 +147,24 @@ typedef struct AppLayerGetTxIterTuple { bool has_next; } AppLayerGetTxIterTuple; +typedef struct StreamSlice { + const uint8_t *input; + uint32_t input_len; + /// STREAM_* flags + uint8_t flags; + uint64_t offset; +} StreamSlice; + +static inline const uint8_t *StreamSliceGetData(const StreamSlice *stream_slice) +{ + return stream_slice->input; +} + +static inline uint32_t StreamSliceGetDataLen(const StreamSlice *stream_slice) +{ + return stream_slice->input_len; +} + /** \brief tx iterator prototype */ typedef AppLayerGetTxIterTuple (*AppLayerGetTxIteratorFunc) (const uint8_t ipproto, const AppProto alproto, diff --git a/src/app-layer.h b/src/app-layer.h index 0558fad603..f46d529962 100644 --- a/src/app-layer.h +++ b/src/app-layer.h @@ -145,14 +145,4 @@ void AppLayerIncAllocErrorCounter(ThreadVars *tv, Flow *f); void AppLayerIncParserErrorCounter(ThreadVars *tv, Flow *f); void AppLayerIncInternalErrorCounter(ThreadVars *tv, Flow *f); -static inline const uint8_t *StreamSliceGetData(const StreamSlice *stream_slice) -{ - return stream_slice->input; -} - -static inline uint32_t StreamSliceGetDataLen(const StreamSlice *stream_slice) -{ - return stream_slice->input_len; -} - #endif diff --git a/src/rust.h b/src/rust.h index c0fe00add5..94620c0863 100644 --- a/src/rust.h +++ b/src/rust.h @@ -25,6 +25,7 @@ typedef struct Dataset Dataset; typedef struct DetectEngineState_ DetectEngineState; typedef enum AppLayerEventType AppLayerEventType; typedef struct AppLayerStateData AppLayerStateData; +typedef struct StreamSlice StreamSlice; // may be improved by smaller include #include "detect.h"