rust: move AppLayerResult definition to C

and bindgen it to rust

Will make easier the bindgen of RustParser structure which uses
a callback which uses AppLayerResult

Keep From<> impl in sys crate that defines it
pull/14758/head
Philippe Antoine 7 months ago committed by Victor Julien
parent 06f78b2a22
commit 8eaced3c1e

@ -150,6 +150,7 @@ if HAVE_BINDGEN
--allowlist-type 'AppLayerGetTxIterState' \
--allowlist-type 'AppLayerStateData' \
--allowlist-type 'AppLayerGetTxIterTuple' \
--allowlist-type 'AppLayerResult' \
--allowlist-type 'StreamSlice' \
--allowlist-function 'SC.*' \
--allowlist-var 'SC.*' \

@ -33,7 +33,8 @@ use suricata_sys::sys::{
};
pub use suricata_sys::sys::{
AppLayerGetFileState, AppLayerStateData, AppLayerGetTxIterTuple, StreamSlice,
AppLayerGetFileState, AppLayerGetTxIterTuple, AppLayerResult, AppLayerStateData,
StreamSlice,
};
#[cfg(not(test))]
@ -317,33 +318,35 @@ macro_rules!export_state_data_get {
}
}
#[repr(C)]
#[derive(Default,Debug,PartialEq, Eq,Copy,Clone)]
pub struct AppLayerResult {
pub status: i32,
pub consumed: u32,
pub needed: u32,
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 AppLayerResult {
impl AppLayerResultRust for AppLayerResult {
/// parser has successfully processed in the input, and has consumed all of it
pub fn ok() -> Self {
fn ok() -> Self {
Default::default()
}
/// parser has hit an unrecoverable error. Returning this to the API
/// leads to no further calls to the parser.
pub fn err() -> Self {
return Self {
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
pub fn incomplete(consumed: u32, needed: u32) -> Self {
fn incomplete(consumed: u32, needed: u32) -> Self {
return Self {
status: 1,
consumed,
@ -351,39 +354,19 @@ impl AppLayerResult {
};
}
pub fn is_ok(self) -> bool {
fn is_ok(&self) -> bool {
self.status == 0
}
pub fn is_err(self) -> bool {
fn is_err(&self) -> bool {
self.status == -1
}
pub fn is_incomplete(self) -> bool {
fn is_incomplete(&self) -> bool {
self.status == 1
}
}
impl From<bool> for AppLayerResult {
fn from(v: bool) -> Self {
if !v {
Self::err()
} else {
Self::ok()
}
}
}
impl From<i32> for AppLayerResult {
fn from(v: i32) -> Self {
if v < 0 {
Self::err()
} else {
Self::ok()
}
}
}
/// Rust parser declaration
#[repr(C)]
pub struct RustParser {

@ -106,15 +106,15 @@ impl BitTorrentDHTState {
}
}
pub fn parse(&mut self, input: &[u8], _direction: Direction) -> bool {
pub fn parse(&mut self, input: &[u8], _direction: Direction) -> AppLayerResult {
if !Self::is_dht(input) {
return true;
return AppLayerResult::ok();
}
let mut tx = self.new_tx(_direction);
let mut status = true;
let mut status = AppLayerResult::ok();
if let Err(_e) = parse_bittorrent_dht_packet(input, &mut tx) {
status = false;
status = AppLayerResult::err();
tx.set_event(BitTorrentDHTEvent::MalformedPacket);
SCLogDebug!("BitTorrent DHT Parsing Error: {}", _e);
}
@ -181,7 +181,7 @@ unsafe extern "C" fn parse(
) -> AppLayerResult {
let state = cast_pointer!(state, BitTorrentDHTState);
let buf = stream_slice.as_slice();
state.parse(buf, direction).into()
state.parse(buf, direction)
}
unsafe extern "C" fn state_get_tx(

@ -1227,7 +1227,7 @@ pub unsafe extern "C" fn SCRegisterDcerpcParser() {
#[cfg(test)]
mod tests {
use crate::applayer::{AppLayerResult, StreamSlice, StreamSliceRust};
use crate::applayer::{AppLayerResult, AppLayerResultRust, StreamSlice, StreamSliceRust};
use crate::core::*;
use crate::dcerpc::dcerpc::DCERPCState;
use crate::direction::Direction;

@ -410,7 +410,7 @@ pub unsafe extern "C" fn SCRegisterDcerpcUdpParser() {
#[cfg(test)]
mod tests {
use crate::applayer::AppLayerResult;
use crate::applayer::{AppLayerResult, AppLayerResultRust};
use crate::dcerpc::dcerpc_udp::DCERPCUDPState;
use crate::dcerpc::parser;

@ -122,7 +122,7 @@ impl SIPState {
}
// app-layer-frame-documentation tag start: parse_request
fn parse_request(&mut self, flow: *mut Flow, stream_slice: StreamSlice) -> bool {
fn parse_request(&mut self, flow: *mut Flow, stream_slice: StreamSlice) -> AppLayerResult {
let input = stream_slice.as_slice();
let _pdu = Frame::new(
flow,
@ -143,16 +143,16 @@ impl SIPState {
tx.request_line = req_line;
}
self.transactions.push_back(tx);
return true;
return AppLayerResult::ok();
}
// app-layer-frame-documentation tag end: parse_request
Err(Err::Incomplete(_)) => {
self.set_event(SIPEvent::IncompleteData);
return false;
return AppLayerResult::err();
}
Err(_) => {
self.set_event(SIPEvent::InvalidData);
return false;
return AppLayerResult::err();
}
}
}
@ -222,7 +222,7 @@ impl SIPState {
return AppLayerResult::ok();
}
fn parse_response(&mut self, flow: *mut Flow, stream_slice: StreamSlice) -> bool {
fn parse_response(&mut self, flow: *mut Flow, stream_slice: StreamSlice) -> AppLayerResult {
let input = stream_slice.as_slice();
let _pdu = Frame::new(
flow,
@ -243,15 +243,15 @@ impl SIPState {
tx.response_line = resp_line;
}
self.transactions.push_back(tx);
return true;
return AppLayerResult::ok();
}
Err(Err::Incomplete(_)) => {
self.set_event(SIPEvent::IncompleteData);
return false;
return AppLayerResult::err();
}
Err(_) => {
self.set_event(SIPEvent::InvalidData);
return false;
return AppLayerResult::err();
}
}
}
@ -453,7 +453,7 @@ unsafe extern "C" fn sip_parse_request(
stream_slice: StreamSlice, _data: *mut std::os::raw::c_void,
) -> AppLayerResult {
let state = cast_pointer!(state, SIPState);
state.parse_request(flow, stream_slice).into()
state.parse_request(flow, stream_slice)
}
unsafe extern "C" fn sip_parse_request_tcp(
@ -477,7 +477,7 @@ unsafe extern "C" fn sip_parse_response(
stream_slice: StreamSlice, _data: *mut std::os::raw::c_void,
) -> AppLayerResult {
let state = cast_pointer!(state, SIPState);
state.parse_response(flow, stream_slice).into()
state.parse_response(flow, stream_slice)
}
unsafe extern "C" fn sip_parse_response_tcp(

@ -162,7 +162,7 @@ impl<'a> SNMPState<'a> {
tx.info = Some(pdu_info);
}
fn handle_snmp_v12(&mut self, msg: SnmpMessage<'a>, _direction: Direction) -> i32 {
fn handle_snmp_v12(&mut self, msg: SnmpMessage<'a>, _direction: Direction) -> AppLayerResult {
let mut tx = self.new_tx(_direction);
// in the message, version is encoded as 0 (version 1) or 1 (version 2)
if self.version != msg.version + 1 {
@ -172,10 +172,10 @@ impl<'a> SNMPState<'a> {
self.add_pdu_info(&msg.pdu, &mut tx);
tx.community = Some(msg.community);
self.transactions.push(tx);
0
AppLayerResult::ok()
}
fn handle_snmp_v3(&mut self, msg: SnmpV3Message<'a>, _direction: Direction) -> i32 {
fn handle_snmp_v3(&mut self, msg: SnmpV3Message<'a>, _direction: Direction) -> AppLayerResult {
let mut tx = self.new_tx(_direction);
if self.version != msg.version {
SCLogDebug!("SNMP version mismatch: expected {}, received {}", self.version, msg.version);
@ -198,13 +198,13 @@ impl<'a> SNMPState<'a> {
}
}
self.transactions.push(tx);
0
AppLayerResult::ok()
}
/// Parse an SNMP request message
///
/// Returns 0 if successful, or -1 on error
fn parse(&mut self, i: &'a [u8], direction: Direction) -> i32 {
fn parse(&mut self, i: &'a [u8], direction: Direction) -> AppLayerResult {
if self.version == 0 {
if let Ok((_, x)) = parse_pdu_envelope_version(i) {
self.version = x;
@ -217,7 +217,7 @@ impl<'a> SNMPState<'a> {
Err(_e) => {
SCLogDebug!("parse_snmp failed: {:?}", _e);
self.set_event(SNMPEvent::MalformedData);
-1
AppLayerResult::err()
},
}
}
@ -293,7 +293,7 @@ unsafe extern "C" fn snmp_parse_request(_flow: *mut Flow,
_data: *mut std::os::raw::c_void,
) -> AppLayerResult {
let state = cast_pointer!(state,SNMPState);
state.parse(stream_slice.as_slice(), Direction::ToServer).into()
state.parse(stream_slice.as_slice(), Direction::ToServer)
}
unsafe extern "C" fn snmp_parse_response(_flow: *mut Flow,
@ -303,7 +303,7 @@ unsafe extern "C" fn snmp_parse_response(_flow: *mut Flow,
_data: *mut std::os::raw::c_void,
) -> AppLayerResult {
let state = cast_pointer!(state,SNMPState);
state.parse(stream_slice.as_slice(), Direction::ToClient).into()
state.parse(stream_slice.as_slice(), Direction::ToClient)
}
unsafe extern "C" fn snmp_state_get_tx(state: *mut std::os::raw::c_void,

@ -1073,6 +1073,13 @@ impl Default for StreamSlice {
}
}
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
pub struct AppLayerResult {
pub status: i32,
pub consumed: u32,
pub needed: u32,
}
extern "C" {
pub fn SCAppLayerParserReallocCtx(alproto: AppProto) -> ::std::os::raw::c_int;
}

@ -165,6 +165,12 @@ static inline uint32_t StreamSliceGetDataLen(const StreamSlice *stream_slice)
return stream_slice->input_len;
}
typedef struct AppLayerResult {
int32_t status;
uint32_t consumed;
uint32_t needed;
} AppLayerResult;
/** \brief tx iterator prototype */
typedef AppLayerGetTxIterTuple (*AppLayerGetTxIteratorFunc)
(const uint8_t ipproto, const AppProto alproto,

Loading…
Cancel
Save