rust/ffi: move app-layer traits to ffi crate

Ticket: 7666

Traits around structures defined in C and bindgened to rust
pull/15265/head
Philippe Antoine 3 months ago committed by Victor Julien
parent f803c25f24
commit 9677851637

@ -30,7 +30,7 @@ use suricata::applayer::{
state_get_tx_iterator, AppLayerEvent, AppLayerTxData, State, Transaction,
APP_LAYER_PARSER_EOF_TC, APP_LAYER_PARSER_EOF_TS, APP_LAYER_PARSER_OPT_ACCEPT_GAPS,
};
use suricata::applayer::{AppLayerResultRust, StreamSliceRust};
use suricata_ffi::applayer::{AppLayerResultRust, StreamSliceRust};
use suricata_ffi::conf::conf_get;
use suricata_ffi::{
build_slice, cast_pointer, export_state_data_get, export_tx_data_get, SCLogError, SCLogNotice,

@ -17,6 +17,8 @@
//! App-layer utils.
use suricata_sys::sys::{AppLayerResult, StreamSlice};
#[macro_export]
macro_rules! export_tx_data_get {
($name:ident, $type:ty) => {
@ -40,3 +42,100 @@ macro_rules! export_state_data_get {
}
};
}
pub trait AppLayerResultRust {
fn ok() -> Self;
fn err() -> Self;
fn incomplete(consumed: u32, needed: u32) -> Self;
fn is_ok(&self) -> bool;
fn is_err(&self) -> bool;
fn is_incomplete(&self) -> bool;
}
impl AppLayerResultRust for AppLayerResult {
/// parser has successfully processed in the input, and has consumed all of it
fn ok() -> Self {
Default::default()
}
/// parser has hit an unrecoverable error. Returning this to the API
/// leads to no further calls to the parser.
fn err() -> Self {
AppLayerResult {
status: -1,
..Default::default()
}
}
/// parser needs more data. Through 'consumed' it will indicate how many
/// of the input bytes it has consumed. Through 'needed' it will indicate
/// how many more bytes it needs before getting called again.
/// Note: consumed should never be more than the input len
/// needed + consumed should be more than the input len
fn incomplete(consumed: u32, needed: u32) -> Self {
Self {
status: 1,
consumed,
needed,
}
}
fn is_ok(&self) -> bool {
self.status == 0
}
fn is_err(&self) -> bool {
self.status == -1
}
fn is_incomplete(&self) -> bool {
self.status == 1
}
}
pub trait StreamSliceRust {
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 StreamSliceRust for StreamSlice {
/// Create a StreamSlice from a Rust slice. Useful in unit tests.
fn from_slice(slice: &[u8], flags: u8, offset: u64) -> Self {
Self {
input: slice.as_ptr(),
input_len: slice.len() as u32,
flags,
offset,
}
}
fn is_gap(&self) -> bool {
self.input.is_null() && self.input_len > 0
}
fn gap_size(&self) -> u32 {
self.input_len
}
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) }
}
fn is_empty(&self) -> bool {
self.input_len == 0
}
fn len(&self) -> u32 {
self.input_len
}
fn offset_from(&self, slice: &[u8]) -> u32 {
self.len() - slice.len() as u32
}
fn flags(&self) -> u8 {
self.flags
}
}

@ -41,56 +41,6 @@ use suricata_sys::sys::SCAppLayerDecoderEventsSetEventRaw;
pub use suricata_ffi::cast_pointer;
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 StreamSliceRust for StreamSlice {
/// Create a StreamSlice from a Rust slice. Useful in unit tests.
#[cfg(test)]
fn from_slice(slice: &[u8], flags: u8, offset: u64) -> Self {
Self {
input: slice.as_ptr(),
input_len: slice.len() as u32,
flags,
offset
}
}
fn is_gap(&self) -> bool {
self.input.is_null() && self.input_len > 0
}
fn gap_size(&self) -> u32 {
self.input_len
}
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) }
}
fn is_empty(&self) -> bool {
self.input_len == 0
}
fn len(&self) -> u32 {
self.input_len
}
fn offset_from(&self, slice: &[u8]) -> u32 {
self.len() - slice.len() as u32
}
fn flags(&self) -> u8 {
self.flags
}
}
#[derive(Debug, Default, Eq, PartialEq)]
pub struct AppLayerTxData(pub suricata_sys::sys::AppLayerTxData);
@ -184,54 +134,7 @@ pub unsafe extern "C" fn SCTxDataUpdateFileFlags(txd: &mut suricata_sys::sys::Ap
pub use suricata_ffi::{export_tx_data_get, export_state_data_get};
pub trait AppLayerResultRust {
fn ok() -> Self;
fn err() -> Self;
fn incomplete(consumed: u32, needed: u32) -> Self;
fn is_ok(&self) -> bool;
fn is_err(&self) -> bool;
fn is_incomplete(&self) -> bool;
}
impl AppLayerResultRust for AppLayerResult {
/// parser has successfully processed in the input, and has consumed all of it
fn ok() -> Self {
Default::default()
}
/// parser has hit an unrecoverable error. Returning this to the API
/// leads to no further calls to the parser.
fn err() -> Self {
return AppLayerResult{
status: -1,
..Default::default()
};
}
/// parser needs more data. Through 'consumed' it will indicate how many
/// of the input bytes it has consumed. Through 'needed' it will indicate
/// how many more bytes it needs before getting called again.
/// Note: consumed should never be more than the input len
/// needed + consumed should be more than the input len
fn incomplete(consumed: u32, needed: u32) -> Self {
return Self {
status: 1,
consumed,
needed,
};
}
fn is_ok(&self) -> bool {
self.status == 0
}
fn is_err(&self) -> bool {
self.status == -1
}
fn is_incomplete(&self) -> bool {
self.status == 1
}
}
pub use suricata_ffi::applayer::{AppLayerResultRust, StreamSliceRust};
/// Rust parser declaration
#[repr(C)]

Loading…
Cancel
Save