From: Pierre Chifflier Date: Thu, 26 Oct 2017 05:57:03 +0000 (+0200) Subject: rust/applayer: add registration iface for parsers X-Git-Tag: suricata-4.1.0-beta1~556 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e7c0a53cbf36c2342ebdde747be34b004c736f43;p=thirdparty%2Fsuricata.git rust/applayer: add registration iface for parsers Add Rust support for the common interface to declare and register all parsers. Add a common structure definition to contain all required elements required for registering a parser, similar to the C interface. This also reduces the risk of incorrectly registering a parser: the compiler prevents omitting required functions from the structure, and functions (even if external) are type-checked. Optional functions are explicitly marked. --- diff --git a/rust/gen-c-headers.py b/rust/gen-c-headers.py index ba7ce7defd..f965105b71 100755 --- a/rust/gen-c-headers.py +++ b/rust/gen-c-headers.py @@ -89,6 +89,7 @@ type_map = { "AppLayerEventType": "AppLayerEventType", "CLuaState": "lua_State", "Store": "Store", + "AppProto": "AppProto", } def convert_type(rs_type): diff --git a/rust/src/core.rs b/rust/src/core.rs index 975f280108..5b72e33c60 100644 --- a/rust/src/core.rs +++ b/rust/src/core.rs @@ -35,10 +35,21 @@ pub const APP_LAYER_EVENT_TYPE_PACKET : i32 = 2; pub const STREAM_TOSERVER: u8 = 0x04; pub const STREAM_TOCLIENT: u8 = 0x08; +// Application layer protocol identifiers (app-layer-protos.h) +pub type AppProto = libc::c_int; + +pub const ALPROTO_UNKNOWN : AppProto = 0; +pub static mut ALPROTO_FAILED : AppProto = 0; // updated during init + macro_rules!BIT_U64 { ($x:expr) => (1 << $x); } +// Defined in app-layer-protos.h +extern { + pub fn StringToAppProto(proto_name: *const u8) -> AppProto; +} + // // Function types for calls into C. // @@ -137,6 +148,7 @@ pub extern "C" fn rs_init(context: &'static mut SuricataContext) { unsafe { SC = Some(context); + ALPROTO_FAILED = StringToAppProto("failed\0".as_ptr()); } } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index fe37062f05..e8aa0fe4e2 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -35,6 +35,8 @@ pub mod json; pub mod applayer; pub mod filecontainer; pub mod filetracker; +#[macro_use] +pub mod parser; #[cfg(feature = "lua")] pub mod lua; diff --git a/rust/src/parser.rs b/rust/src/parser.rs new file mode 100644 index 0000000000..4e298b6476 --- /dev/null +++ b/rust/src/parser.rs @@ -0,0 +1,164 @@ +/* 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. + */ + +// written by Pierre Chifflier + +//! Parser registration functions and common interface + +use core::{DetectEngineState,Flow,AppLayerEventType,AppLayerDecoderEvents,AppProto}; +use filecontainer::FileContainer; + +use libc::{c_void,c_char,c_int}; + + +/// Rust parser declaration +#[repr(C)] +pub struct RustParser { + /// Parser name. + pub name: *const c_char, + /// Default port + pub default_port: *const c_char, + + /// IP Protocol (libc::IPPROTO_UDP, libc::IPPROTO_TCP, etc.) + pub ipproto: c_int, + + /// Probing function, for packets going to server + pub probe_ts: ProbeFn, + /// Probing function, for packets going to client + pub probe_tc: ProbeFn, + + /// Minimum frame depth for probing + pub min_depth: u16, + /// Maximum frame depth for probing + pub max_depth: u16, + + /// Allocation function for a new state + pub state_new: StateAllocFn, + /// Function called to free a state + pub state_free: StateFreeFn, + + /// Parsing function, for packets going to server + pub parse_ts: ParseFn, + /// Parsing function, for packets going to client + pub parse_tc: ParseFn, + + /// Get the current transaction count + pub get_tx_count: StateGetTxCntFn, + /// Get a transaction + pub get_tx: StateGetTxFn, + /// Function called to free a transaction + pub tx_free: StateTxFreeFn, + /// Function returning the current transaction completion status + pub tx_get_comp_st: StateGetTxCompletionStatusFn, + /// Function returning the current transaction progress + pub tx_get_progress: StateGetProgressFn, + + /// Logged transaction getter function + pub get_tx_logged: Option, + /// Logged transaction setter function + pub set_tx_logged: Option, + + /// Function called to get a detection state + pub get_de_state: GetDetectStateFn, + /// Function called to set a detection state + pub set_de_state: SetDetectStateFn, + /// Function to check if a detection state is present + pub has_de_state: Option, + + /// Function to check if there are events + pub has_events: Option, + /// Function to get events + pub get_events: Option, + /// Function to get an event description + pub get_eventinfo: Option, + + /// Function to allocate local storage + pub localstorage_new: Option, + /// Function to free local storage + pub localstorage_free: Option, + + /// Function to get transaction MPM ID + pub get_tx_mpm_id: Option, + /// Function to set transaction MPM ID + pub set_tx_mpm_id: Option, + + /// Function to get files + pub get_files: Option, +} + + + + +/// Create a slice, given a buffer and a length +/// +/// UNSAFE ! +#[macro_export] +macro_rules! build_slice { + ($buf:ident, $len:expr) => ( unsafe{ std::slice::from_raw_parts($buf, $len) } ); +} + +/// Cast pointer to a variable, as a mutable reference to an object +/// +/// UNSAFE ! +#[macro_export] +macro_rules! cast_pointer { + ($ptr:ident, $ty:ty) => ( unsafe{ &mut *($ptr as *mut $ty) } ); +} + +pub type ParseFn = extern "C" fn (flow: *const Flow, + state: *mut c_void, + pstate: *const c_void, + input: *const u8, + input_len: u32, + data: *const c_void) -> i8; +pub type ProbeFn = extern "C" fn (input:*const i8, input_len: u32, offset: *const i8) -> AppProto; +pub type StateAllocFn = extern "C" fn () -> *mut c_void; +pub type StateFreeFn = extern "C" fn (*mut c_void); +pub type StateTxFreeFn = extern "C" fn (*mut c_void, u64); +pub type StateGetTxFn = extern "C" fn (*mut c_void, u64) -> *mut c_void; +pub type StateGetTxCntFn = extern "C" fn (*mut c_void) -> u64; +pub type StateGetTxCompletionStatusFn = extern "C" fn (u8) -> c_int; +pub type StateGetProgressFn = extern "C" fn (*mut c_void, u8) -> c_int; +pub type HasDetectStateFn = extern "C" fn (*mut c_void) -> c_int; +pub type GetDetectStateFn = extern "C" fn (*mut c_void) -> *mut DetectEngineState; +pub type SetDetectStateFn = extern "C" fn (*mut c_void, *mut c_void, &mut DetectEngineState) -> c_int; +pub type GetEventInfoFn = extern "C" fn (*const c_char, *mut c_int, *mut AppLayerEventType) -> c_int; +pub type GetEventsFn = extern "C" fn (*mut c_void, u64) -> *mut AppLayerDecoderEvents; +pub type HasEventsFn = extern "C" fn (*mut c_void) -> c_int; +pub type GetTxLoggedFn = extern "C" fn (*mut c_void, *mut c_void, u32) -> c_int; +pub type SetTxLoggedFn = extern "C" fn (*mut c_void, *mut c_void, u32); +pub type LocalStorageNewFn = extern "C" fn () -> *mut c_void; +pub type LocalStorageFreeFn = extern "C" fn (*mut c_void); +pub type GetTxMpmIDFn = extern "C" fn (*mut c_void) -> u64; +pub type SetTxMpmIDFn = extern "C" fn (*mut c_void, u64) -> c_int; +pub type GetFilesFn = extern "C" fn (*mut c_void, u8) -> *mut FileContainer; + +// Defined in app-layer-register.h +extern { + pub fn AppLayerRegisterProtocolDetection(parser: *const RustParser, enable_default: c_int) -> AppProto; + pub fn AppLayerRegisterParser(parser: *const RustParser) -> AppProto; +} + +// Defined in app-layer-detect-proto.h +extern { + pub fn AppLayerProtoDetectConfProtoDetectionEnabled(ipproto: *const c_char, proto: *const c_char) -> c_int; +} + +// Defined in app-layer-parser.h +extern { + pub fn AppLayerParserConfParserEnabled(ipproto: *const c_char, proto: *const c_char) -> c_int; +}