rust/applayer: provide generic event info functions

Provide generic functions for get_event_info and
get_event_info_by_id. These functions can be used by any app-layer
event enum that implements AppLayerEvent.

Unfortunately the parser registration cannot use these functions
directly as generic functions cannot be #[no_mangle]. So they
do need small extern "C" wrappers around them.
pull/6324/head
Jason Ish 5 years ago committed by Victor Julien
parent 27d1ee98ce
commit 0fa7b5c2a2

@ -18,11 +18,12 @@
//! Parser registration functions and common interface
use std;
use crate::core::{DetectEngineState,Flow,AppLayerEventType,AppLayerDecoderEvents,AppProto};
use crate::core::{self,DetectEngineState,Flow,AppLayerEventType,AppLayerDecoderEvents,AppProto};
use crate::filecontainer::FileContainer;
use crate::applayer;
use std::os::raw::{c_void,c_char,c_int};
use crate::core::SC;
use std::ffi::CStr;
#[repr(C)]
#[derive(Default, Debug,PartialEq)]
@ -425,9 +426,61 @@ pub trait AppLayerEvent {
/// Convert the enum variant to a C-style string (suffixed with \0).
fn to_cstring(&self) -> &str;
/// Return the enum variant for the given name (as a CStr).
fn from_cstring(s: &std::ffi::CStr) -> Option<Self> where Self: std::marker::Sized;
/// Return the enum variant for the given name.
fn from_string(s: &str) -> Option<Self> where Self: std::marker::Sized;
/// Return the ID value of the enum variant.
fn as_i32(&self) -> i32;
}
/// Generic `get_info_info` implementation for enums implementing
/// AppLayerEvent.
///
/// Normally usage of this function will be generated by
/// derive(AppLayerEvent), for example:
///
/// #[derive(AppLayerEvent)]
/// enum AppEvent {
/// EventOne,
/// EventTwo,
/// }
///
/// get_event_info::<AppEvent>(...)
#[inline(always)]
pub fn get_event_info<T: AppLayerEvent>(
event_name: *const std::os::raw::c_char,
event_id: *mut std::os::raw::c_int,
event_type: *mut core::AppLayerEventType,
) -> std::os::raw::c_int {
if event_name == std::ptr::null() {
return -1;
}
unsafe {
let event = match CStr::from_ptr(event_name).to_str().map(T::from_string) {
Ok(Some(event)) => event.as_i32(),
_ => -1,
};
*event_type = core::APP_LAYER_EVENT_TYPE_TRANSACTION;
*event_id = event as std::os::raw::c_int;
return 0;
}
}
/// Generic `get_info_info_by_id` implementation for enums implementing
/// AppLayerEvent.
#[inline(always)]
pub fn get_event_info_by_id<T: AppLayerEvent>(
event_id: std::os::raw::c_int,
event_name: *mut *const std::os::raw::c_char,
event_type: *mut core::AppLayerEventType,
) -> i8 {
if let Some(e) = T::from_id(event_id as i32) {
unsafe {
*event_name = e.to_cstring().as_ptr() as *const std::os::raw::c_char;
*event_type = core::APP_LAYER_EVENT_TYPE_TRANSACTION;
}
return 0;
}
return -1;
}

Loading…
Cancel
Save