From: Victor Julien Date: Wed, 18 Mar 2020 13:08:37 +0000 (+0100) Subject: app-layer: define AppLayerTxData and AppLayerTxConfig X-Git-Tag: suricata-6.0.0-beta1~194 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=411f428a388a96dc043ca583705b6c01e54721c7;p=thirdparty%2Fsuricata.git app-layer: define AppLayerTxData and AppLayerTxConfig AppLayerTxData is a structure each tx should include that will contain the common fields the engine needs for tracking logging, detection and possibly other things. AppLayerTxConfig will be used by the detection engine to configure the transaction. --- diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index 367ebb4deb..3514b5ef00 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -24,6 +24,59 @@ use crate::filecontainer::FileContainer; use crate::applayer; use std::os::raw::{c_void,c_char,c_int}; +#[repr(C)] +#[derive(Debug,PartialEq)] +pub struct AppLayerTxConfig { + /// config: log flags + log_flags: u8, +} + +impl AppLayerTxConfig { + pub fn new() -> Self { + Self { + log_flags: 0, + } + } + + pub fn add_log_flags(&mut self, flags: u8) { + self.log_flags |= flags; + } + pub fn set_log_flags(&mut self, flags: u8) { + self.log_flags = flags; + } + pub fn get_log_flags(&self) -> u8 { + self.log_flags + } +} + +#[repr(C)] +#[derive(Debug,PartialEq)] +pub struct AppLayerTxData { + /// config: log flags + pub config: AppLayerTxConfig, +} + +impl AppLayerTxData { + pub fn new() -> Self { + Self { + config: AppLayerTxConfig::new(), + } + } +} + +#[macro_export] +macro_rules!export_tx_data_get { + ($name:ident, $type:ty) => { + #[no_mangle] + pub unsafe extern "C" fn $name(tx: *mut std::os::raw::c_void) + -> *mut crate::applayer::AppLayerTxData + { + let tx = &mut *(tx as *mut $type); + &mut tx.tx_data + } + } +} + #[repr(C)] #[derive(Debug,PartialEq,Copy,Clone)] pub struct AppLayerResult { @@ -169,6 +222,8 @@ pub struct RustParser { // Function to get TX detect flags. pub get_tx_detect_flags: Option, + + pub get_tx_data: Option, } /// Create a slice, given a buffer and a length @@ -220,6 +275,7 @@ pub type GetTxIteratorFn = extern "C" fn (ipproto: u8, alproto: AppProto, -> AppLayerGetTxIterTuple; pub type GetTxDetectFlagsFn = unsafe extern "C" fn(*mut c_void, u8) -> u64; pub type SetTxDetectFlagsFn = unsafe extern "C" fn(*mut c_void, u8, u64); +pub type GetTxDataFn = unsafe extern "C" fn(*mut c_void) -> *mut AppLayerTxData; // Defined in app-layer-register.h extern { diff --git a/rust/src/applayertemplate/template.rs b/rust/src/applayertemplate/template.rs index cd5cae3358..6b241bfbdf 100644 --- a/rust/src/applayertemplate/template.rs +++ b/rust/src/applayertemplate/template.rs @@ -537,6 +537,7 @@ pub unsafe extern "C" fn rs_template_register_parser() { get_tx_iterator: Some(rs_template_state_get_tx_iterator), get_tx_detect_flags: None, set_tx_detect_flags: None, + get_tx_data: None, }; let ip_proto_str = CString::new("tcp").unwrap(); diff --git a/rust/src/dhcp/dhcp.rs b/rust/src/dhcp/dhcp.rs index 830d7a6d79..d38cf932e1 100644 --- a/rust/src/dhcp/dhcp.rs +++ b/rust/src/dhcp/dhcp.rs @@ -451,6 +451,7 @@ pub unsafe extern "C" fn rs_dhcp_register_parser() { get_tx_iterator : Some(rs_dhcp_state_get_tx_iterator), set_tx_detect_flags: None, get_tx_detect_flags: None, + get_tx_data : None, }; let ip_proto_str = CString::new("udp").unwrap(); diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index 6f2412f36b..c95d9df3ca 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -263,6 +263,7 @@ pub struct DNSTransaction { pub logged: LoggerFlags, pub de_state: Option<*mut core::DetectEngineState>, pub events: *mut core::AppLayerDecoderEvents, + pub tx_data: AppLayerTxData, } impl DNSTransaction { @@ -277,6 +278,7 @@ impl DNSTransaction { logged: LoggerFlags::new(), de_state: None, events: std::ptr::null_mut(), + tx_data: AppLayerTxData::new(), } } @@ -863,6 +865,15 @@ pub extern "C" fn rs_dns_state_get_events(tx: *mut std::os::raw::c_void) return tx.events; } +#[no_mangle] +pub extern "C" fn rs_dns_state_get_tx_data( + tx: *mut std::os::raw::c_void) + -> *mut AppLayerTxData +{ + let tx = cast_pointer!(tx, DNSTransaction); + return &mut tx.tx_data; +} + #[no_mangle] pub extern "C" fn rs_dns_tx_get_query_name(tx: &mut DNSTransaction, i: u16, @@ -1021,6 +1032,7 @@ pub unsafe extern "C" fn rs_dns_udp_register_parser() { set_tx_detect_flags: Some(rs_dns_tx_set_detect_flags), get_de_state: rs_dns_state_get_tx_detect_state, set_de_state: rs_dns_state_set_tx_detect_state, + get_tx_data: Some(rs_dns_state_get_tx_data), }; let ip_proto_str = CString::new("udp").unwrap(); @@ -1066,6 +1078,7 @@ pub unsafe extern "C" fn rs_dns_tcp_register_parser() { set_tx_detect_flags: Some(rs_dns_tx_set_detect_flags), get_de_state: rs_dns_state_get_tx_detect_state, set_de_state: rs_dns_state_set_tx_detect_state, + get_tx_data: Some(rs_dns_state_get_tx_data), }; let ip_proto_str = CString::new("tcp").unwrap(); diff --git a/rust/src/ikev2/ikev2.rs b/rust/src/ikev2/ikev2.rs index 435db8f246..86ac3a778f 100644 --- a/rust/src/ikev2/ikev2.rs +++ b/rust/src/ikev2/ikev2.rs @@ -735,6 +735,7 @@ pub unsafe extern "C" fn rs_register_ikev2_parser() { get_tx_iterator : None, get_tx_detect_flags: None, set_tx_detect_flags: None, + get_tx_data : None, }; let ip_proto_str = CString::new("udp").unwrap(); diff --git a/rust/src/krb/krb5.rs b/rust/src/krb/krb5.rs index d6c8ba54d7..9602a0a4de 100644 --- a/rust/src/krb/krb5.rs +++ b/rust/src/krb/krb5.rs @@ -682,6 +682,7 @@ pub unsafe extern "C" fn rs_register_krb5_parser() { get_tx_iterator : None, get_tx_detect_flags: Some(rs_krb5_tx_detect_flags_get), set_tx_detect_flags: Some(rs_krb5_tx_detect_flags_set), + get_tx_data : None, }; // register UDP parser let ip_proto_str = CString::new("udp").unwrap(); diff --git a/rust/src/ntp/ntp.rs b/rust/src/ntp/ntp.rs index a076ce094e..4a73f9e1c7 100644 --- a/rust/src/ntp/ntp.rs +++ b/rust/src/ntp/ntp.rs @@ -434,6 +434,7 @@ pub unsafe extern "C" fn rs_register_ntp_parser() { get_tx_iterator : None, get_tx_detect_flags: None, set_tx_detect_flags: None, + get_tx_data : None, }; let ip_proto_str = CString::new("udp").unwrap(); diff --git a/rust/src/rdp/rdp.rs b/rust/src/rdp/rdp.rs index f719f492fc..d4a4d327da 100644 --- a/rust/src/rdp/rdp.rs +++ b/rust/src/rdp/rdp.rs @@ -532,6 +532,7 @@ pub unsafe extern "C" fn rs_rdp_register_parser() { get_tx_iterator: None, get_tx_detect_flags: None, set_tx_detect_flags: None, + get_tx_data: None, }; let ip_proto_str = std::ffi::CString::new("tcp").unwrap(); diff --git a/rust/src/rfb/rfb.rs b/rust/src/rfb/rfb.rs index 73480564eb..5abbf7b6ca 100644 --- a/rust/src/rfb/rfb.rs +++ b/rust/src/rfb/rfb.rs @@ -724,6 +724,7 @@ pub unsafe extern "C" fn rs_rfb_register_parser() { get_tx_iterator: Some(rs_rfb_state_get_tx_iterator), get_tx_detect_flags: Some(rs_rfb_get_tx_detect_flags), set_tx_detect_flags: Some(rs_rfb_set_tx_detect_flags), + get_tx_data: None, }; let ip_proto_str = CString::new("tcp").unwrap(); diff --git a/rust/src/sip/sip.rs b/rust/src/sip/sip.rs index 87dde30901..fb3b21a649 100755 --- a/rust/src/sip/sip.rs +++ b/rust/src/sip/sip.rs @@ -412,6 +412,7 @@ pub unsafe extern "C" fn rs_sip_register_parser() { get_tx_iterator: None, get_tx_detect_flags: None, set_tx_detect_flags: None, + get_tx_data: None, }; let ip_proto_str = CString::new("udp").unwrap(); diff --git a/rust/src/snmp/snmp.rs b/rust/src/snmp/snmp.rs index 1a2b357f64..5eb45a9b7e 100644 --- a/rust/src/snmp/snmp.rs +++ b/rust/src/snmp/snmp.rs @@ -614,6 +614,7 @@ pub unsafe extern "C" fn rs_register_snmp_parser() { get_tx_iterator : None, get_tx_detect_flags: Some(rs_snmp_get_tx_detect_flags), set_tx_detect_flags: Some(rs_snmp_set_tx_detect_flags), + get_tx_data : None, }; let ip_proto_str = CString::new("udp").unwrap(); if AppLayerProtoDetectConfProtoDetectionEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { diff --git a/rust/src/ssh/ssh.rs b/rust/src/ssh/ssh.rs index 11201c8f7c..7d20b04cd6 100644 --- a/rust/src/ssh/ssh.rs +++ b/rust/src/ssh/ssh.rs @@ -581,6 +581,7 @@ pub unsafe extern "C" fn rs_ssh_register_parser() { get_tx_iterator: None, get_tx_detect_flags: Some(rs_ssh_get_tx_detect_flags), set_tx_detect_flags: Some(rs_ssh_set_tx_detect_flags), + get_tx_data: None, }; let ip_proto_str = CString::new("tcp").unwrap(); diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index 5009a48419..dae0d24877 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -125,6 +125,7 @@ typedef struct AppLayerParserProtoCtx_ uint64_t (*GetTxDetectFlags)(void *tx, uint8_t dir); void (*SetTxDetectFlags)(void *tx, uint8_t dir, uint64_t); + AppLayerTxData *(*GetTxData)(void *tx); void (*SetStreamDepthFlag)(void *tx, uint8_t flags); @@ -594,6 +595,16 @@ void AppLayerParserRegisterDetectFlagsFuncs(uint8_t ipproto, AppProto alproto, SCReturn; } +void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto, + AppLayerTxData *(*GetTxData)(void *tx)) +{ + SCEnter(); + + alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxData = GetTxData; + + SCReturn; +} + void AppLayerParserRegisterSetStreamDepthFlag(uint8_t ipproto, AppProto alproto, void (*SetStreamDepthFlag)(void *tx, uint8_t flags)) { @@ -1159,6 +1170,16 @@ void AppLayerParserSetTxDetectFlags(uint8_t ipproto, AppProto alproto, void *tx, SCReturn; } +AppLayerTxData *AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void *tx) +{ + SCEnter(); + if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxData) { + AppLayerTxData *d = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxData(tx); + SCReturnPtr(d, "AppLayerTxData"); + } + SCReturnPtr(NULL, "AppLayerTxData"); +} + /***** General *****/ /** \retval int -1 in case of unrecoverable error. App-layer tracking stops for this flow. diff --git a/src/app-layer-parser.h b/src/app-layer-parser.h index 36161cd0ea..7b7e44e13f 100644 --- a/src/app-layer-parser.h +++ b/src/app-layer-parser.h @@ -187,6 +187,9 @@ void AppLayerParserRegisterDetectFlagsFuncs(uint8_t ipproto, AppProto alproto, void AppLayerParserRegisterSetStreamDepthFlag(uint8_t ipproto, AppProto alproto, void (*SetStreamDepthFlag)(void *tx, uint8_t flags)); +void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto, + AppLayerTxData *(*GetTxData)(void *tx)); + /***** Get and transaction functions *****/ AppLayerGetTxIteratorFunc AppLayerGetTxIterator(const uint8_t ipproto, @@ -236,6 +239,8 @@ uint64_t AppLayerParserGetTxDetectFlags(uint8_t ipproto, AppProto alproto, void void AppLayerParserSetTxDetectFlags(uint8_t ipproto, AppProto alproto, void *tx, uint8_t dir, uint64_t); bool AppLayerParserSupportsTxDetectFlags(AppProto alproto); +AppLayerTxData *AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void *tx); + /***** General *****/ int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *tctx, Flow *f, AppProto alproto, diff --git a/src/app-layer-register.c b/src/app-layer-register.c index 88799e73a7..06c6d026e9 100644 --- a/src/app-layer-register.c +++ b/src/app-layer-register.c @@ -176,6 +176,11 @@ int AppLayerRegisterParser(const struct AppLayerParser *p, AppProto alproto) p->GetTxDetectFlags, p->SetTxDetectFlags); } + if (p->GetTxData) { + AppLayerParserRegisterTxDataFunc(p->ip_proto, alproto, + p->GetTxData); + } + return 0; } diff --git a/src/app-layer-register.h b/src/app-layer-register.h index 7e90a4f061..ea6190ee10 100644 --- a/src/app-layer-register.h +++ b/src/app-layer-register.h @@ -71,6 +71,8 @@ typedef struct AppLayerParser { void (*SetTxDetectFlags)(void *, uint8_t, uint64_t); uint64_t (*GetTxDetectFlags)(void *, uint8_t); + + AppLayerTxData *(*GetTxData)(void *tx); } AppLayerParser; /**