rust: move StreamSlice definition to C

and bindgen it to rust

Will make easier the bindgen of RustParser structure which uses
a callback which uses StreamSlice
pull/14758/head
Philippe Antoine 3 months ago committed by Victor Julien
parent 41f543ca35
commit 06f78b2a22

@ -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

@ -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' \

@ -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
}
}

@ -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;

@ -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;

@ -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::<Self>::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;
}

@ -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,

@ -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

@ -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"

Loading…
Cancel
Save