From: Victor Julien Date: Mon, 26 Apr 2021 12:36:32 +0000 (+0200) Subject: app-layer: introduce common AppLayerStateData API X-Git-Tag: suricata-7.0.0-beta1~145 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c27df6304d6c9620962671e39ace277c78556269;p=thirdparty%2Fsuricata.git app-layer: introduce common AppLayerStateData API Add per state structure for storing flags and other variables. --- diff --git a/rust/cbindgen.toml b/rust/cbindgen.toml index bccb19fd19..635b972945 100644 --- a/rust/cbindgen.toml +++ b/rust/cbindgen.toml @@ -73,6 +73,7 @@ documentation_style = "doxy" # default: [] include = [ "StreamSlice", + "AppLayerStateData", "AppLayerGetTxIterTuple", "RdpState", "SIPState", diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index a08741b02b..d6b08ad5a0 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -173,6 +173,36 @@ macro_rules!export_tx_data_get { } } +#[repr(C)] +#[derive(Default,Debug,PartialEq,Copy,Clone)] +pub struct AppLayerStateData { + pub file_flags: u16, +} + +impl AppLayerStateData { + pub fn new() -> Self { + Self { + file_flags: 0, + } + } + pub fn update_file_flags(&mut self, flags: u16) { + self.file_flags |= flags; + } +} + +#[macro_export] +macro_rules!export_state_data_get { + ($name:ident, $type:ty) => { + #[no_mangle] + pub unsafe extern "C" fn $name(state: *mut std::os::raw::c_void) + -> *mut crate::applayer::AppLayerStateData + { + let state = &mut *(state as *mut $type); + &mut state.state_data + } + } +} + #[repr(C)] #[derive(Default,Debug,PartialEq,Copy,Clone)] pub struct AppLayerResult { @@ -297,6 +327,7 @@ pub struct RustParser { /// Function to get the TX iterator pub get_tx_iterator: Option, + pub get_state_data: GetStateDataFn, pub get_tx_data: GetTxDataFn, // Function to apply config to a TX. Optional. Normal (bidirectional) @@ -356,6 +387,7 @@ pub type GetTxIteratorFn = unsafe extern "C" fn (ipproto: u8, alproto: AppPro istate: &mut u64) -> AppLayerGetTxIterTuple; pub type GetTxDataFn = unsafe extern "C" fn(*mut c_void) -> *mut AppLayerTxData; +pub type GetStateDataFn = unsafe extern "C" fn(*mut c_void) -> *mut AppLayerStateData; pub type ApplyTxConfigFn = unsafe extern "C" fn (*mut c_void, *mut c_void, c_int, AppLayerTxConfig); pub type TruncateFn = unsafe extern "C" fn (*mut c_void, u8); pub type GetFrameIdByName = unsafe extern "C" fn(*const c_char) -> c_int; diff --git a/rust/src/applayertemplate/template.rs b/rust/src/applayertemplate/template.rs index 3db22ea343..12719b5b65 100644 --- a/rust/src/applayertemplate/template.rs +++ b/rust/src/applayertemplate/template.rs @@ -54,6 +54,7 @@ impl Transaction for TemplateTransaction { } pub struct TemplateState { + state_data: AppLayerStateData, tx_id: u64, transactions: VecDeque, request_gap: bool, @@ -73,6 +74,7 @@ impl State for TemplateState { impl TemplateState { pub fn new() -> Self { Self { + state_data: AppLayerStateData::new(), tx_id: 0, transactions: VecDeque::new(), request_gap: false, @@ -423,6 +425,7 @@ pub unsafe extern "C" fn rs_template_get_response_buffer( } export_tx_data_get!(rs_template_get_tx_data, TemplateTransaction); +export_state_data_get!(rs_template_get_state_data, TemplateState); // Parser name as a C style string. const PARSER_NAME: &'static [u8] = b"template-rust\0"; @@ -455,6 +458,7 @@ pub unsafe extern "C" fn rs_template_register_parser() { get_files: None, get_tx_iterator: Some(applayer::state_get_tx_iterator::), get_tx_data: rs_template_get_tx_data, + get_state_data: rs_template_get_state_data, apply_tx_config: None, flags: APP_LAYER_PARSER_OPT_ACCEPT_GAPS, truncate: None, diff --git a/rust/src/dcerpc/dcerpc.rs b/rust/src/dcerpc/dcerpc.rs index a70bcb64f8..91e698d90e 100644 --- a/rust/src/dcerpc/dcerpc.rs +++ b/rust/src/dcerpc/dcerpc.rs @@ -321,6 +321,7 @@ pub struct DCERPCState { pub ts_ssn_trunc: bool, /// true if Truncated in this direction pub tc_ssn_trunc: bool, pub flow: Option<*const core::Flow>, + state_data: AppLayerStateData, } impl State for DCERPCState { @@ -1337,6 +1338,7 @@ fn register_pattern_probe() -> i8 { 0 } +export_state_data_get!(rs_dcerpc_get_state_data, DCERPCState); // Parser name as a C style string. pub const PARSER_NAME: &'static [u8] = b"dcerpc\0"; @@ -1368,6 +1370,7 @@ pub unsafe extern "C" fn rs_dcerpc_register_parser() { get_files: None, get_tx_iterator: Some(applayer::state_get_tx_iterator::), get_tx_data: rs_dcerpc_get_tx_data, + get_state_data: rs_dcerpc_get_state_data, apply_tx_config: None, flags: APP_LAYER_PARSER_OPT_ACCEPT_GAPS, truncate: None, diff --git a/rust/src/dcerpc/dcerpc_udp.rs b/rust/src/dcerpc/dcerpc_udp.rs index 4648e9148e..c66bfdea04 100644 --- a/rust/src/dcerpc/dcerpc_udp.rs +++ b/rust/src/dcerpc/dcerpc_udp.rs @@ -55,6 +55,7 @@ pub struct DCERPCHdrUdp { #[derive(Default, Debug)] pub struct DCERPCUDPState { + state_data: AppLayerStateData, pub tx_id: u64, pub transactions: VecDeque, } @@ -333,6 +334,8 @@ fn register_pattern_probe() -> i8 { 0 } +export_state_data_get!(rs_dcerpc_udp_get_state_data, DCERPCUDPState); + #[no_mangle] pub unsafe extern "C" fn rs_dcerpc_udp_register_parser() { let parser = RustParser { @@ -360,6 +363,7 @@ pub unsafe extern "C" fn rs_dcerpc_udp_register_parser() { get_files: None, get_tx_iterator: Some(applayer::state_get_tx_iterator::), get_tx_data: rs_dcerpc_udp_get_tx_data, + get_state_data: rs_dcerpc_udp_get_state_data, apply_tx_config: None, flags: APP_LAYER_PARSER_OPT_UNIDIR_TXS, truncate: None, diff --git a/rust/src/dhcp/dhcp.rs b/rust/src/dhcp/dhcp.rs index 063f981f7e..2365194299 100644 --- a/rust/src/dhcp/dhcp.rs +++ b/rust/src/dhcp/dhcp.rs @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2020 Open Information Security Foundation +/* Copyright (C) 2018-2021 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 @@ -99,6 +99,8 @@ impl Transaction for DHCPTransaction { #[derive(Default)] pub struct DHCPState { + state_data: AppLayerStateData, + // Internal transaction ID. tx_id: u64, @@ -264,6 +266,7 @@ pub unsafe extern "C" fn rs_dhcp_state_free(state: *mut std::os::raw::c_void) { } export_tx_data_get!(rs_dhcp_get_tx_data, DHCPTransaction); +export_state_data_get!(rs_dhcp_get_state_data, DHCPState); const PARSER_NAME: &'static [u8] = b"dhcp\0"; @@ -296,6 +299,7 @@ pub unsafe extern "C" fn rs_dhcp_register_parser() { get_files : None, get_tx_iterator : Some(applayer::state_get_tx_iterator::), get_tx_data : rs_dhcp_get_tx_data, + get_state_data : rs_dhcp_get_state_data, apply_tx_config : None, flags : APP_LAYER_PARSER_OPT_UNIDIR_TXS, truncate : None, diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index d6ba77e37e..5aafd73924 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -315,6 +315,8 @@ impl ConfigTracker { #[derive(Default)] pub struct DNSState { + state_data: AppLayerStateData, + // Internal transaction ID. pub tx_id: u64, @@ -824,6 +826,8 @@ pub unsafe extern "C" fn rs_dns_state_get_tx_data( return &mut tx.tx_data; } +export_state_data_get!(rs_dns_get_state_data, DNSState); + #[no_mangle] pub unsafe extern "C" fn rs_dns_tx_get_query_name(tx: &mut DNSTransaction, i: u32, @@ -979,6 +983,7 @@ pub unsafe extern "C" fn rs_dns_udp_register_parser() { get_files: None, get_tx_iterator: Some(crate::applayer::state_get_tx_iterator::), get_tx_data: rs_dns_state_get_tx_data, + get_state_data: rs_dns_get_state_data, apply_tx_config: Some(rs_dns_apply_tx_config), flags: APP_LAYER_PARSER_OPT_UNIDIR_TXS, truncate: None, @@ -1024,6 +1029,7 @@ pub unsafe extern "C" fn rs_dns_tcp_register_parser() { get_files: None, get_tx_iterator: Some(crate::applayer::state_get_tx_iterator::), get_tx_data: rs_dns_state_get_tx_data, + get_state_data: rs_dns_get_state_data, apply_tx_config: Some(rs_dns_apply_tx_config), flags: APP_LAYER_PARSER_OPT_ACCEPT_GAPS | APP_LAYER_PARSER_OPT_UNIDIR_TXS, truncate: None, diff --git a/rust/src/http2/http2.rs b/rust/src/http2/http2.rs index 533ea491b0..b83c5de74b 100644 --- a/rust/src/http2/http2.rs +++ b/rust/src/http2/http2.rs @@ -393,6 +393,7 @@ impl HTTP2DynTable { } pub struct HTTP2State { + state_data: AppLayerStateData, tx_id: u64, request_frame_size: u32, response_frame_size: u32, @@ -416,6 +417,7 @@ impl State for HTTP2State { impl HTTP2State { pub fn new() -> Self { Self { + state_data: AppLayerStateData::new(), tx_id: 0, request_frame_size: 0, response_frame_size: 0, @@ -1042,6 +1044,7 @@ impl HTTP2State { // C exports. export_tx_data_get!(rs_http2_get_tx_data, HTTP2Transaction); +export_state_data_get!(rs_http2_get_state_data, HTTP2State); /// C entry point for a probing parser. #[no_mangle] @@ -1214,6 +1217,7 @@ pub unsafe extern "C" fn rs_http2_register_parser() { get_files: Some(rs_http2_getfiles), get_tx_iterator: Some(applayer::state_get_tx_iterator::), get_tx_data: rs_http2_get_tx_data, + get_state_data: rs_http2_get_state_data, apply_tx_config: None, flags: 0, truncate: None, diff --git a/rust/src/ike/ike.rs b/rust/src/ike/ike.rs index 53b91bbd8b..16f9866dcb 100644 --- a/rust/src/ike/ike.rs +++ b/rust/src/ike/ike.rs @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 Open Information Security Foundation +/* Copyright (C) 2020-2021 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 @@ -138,6 +138,7 @@ impl IKETransaction { #[derive(Default)] pub struct IKEState { + state_data: AppLayerStateData, tx_id: u64, pub transactions: Vec, @@ -394,6 +395,7 @@ const PARSER_NAME: &'static [u8] = b"ike\0"; const PARSER_ALIAS: &'static [u8] = b"ikev2\0"; export_tx_data_get!(rs_ike_get_tx_data, IKETransaction); +export_state_data_get!(rs_ike_get_state_data, IKEState); #[no_mangle] pub unsafe extern "C" fn rs_ike_register_parser() { @@ -423,6 +425,7 @@ pub unsafe extern "C" fn rs_ike_register_parser() { get_files: None, get_tx_iterator: Some(applayer::state_get_tx_iterator::), get_tx_data: rs_ike_get_tx_data, + get_state_data: rs_ike_get_state_data, apply_tx_config: None, flags: APP_LAYER_PARSER_OPT_UNIDIR_TXS, truncate: None, diff --git a/rust/src/krb/krb5.rs b/rust/src/krb/krb5.rs index fdee89d3ca..293db1f864 100644 --- a/rust/src/krb/krb5.rs +++ b/rust/src/krb/krb5.rs @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2020 Open Information Security Foundation +/* Copyright (C) 2017-2021 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 @@ -36,6 +36,8 @@ pub enum KRB5Event { } pub struct KRB5State { + state_data: AppLayerStateData, + pub req_id: u8, pub record_ts: usize, @@ -103,6 +105,7 @@ pub fn to_hex_string(bytes: &[u8]) -> String { impl KRB5State { pub fn new() -> KRB5State { KRB5State{ + state_data: AppLayerStateData::new(), req_id: 0, record_ts: 0, defrag_buf_ts: Vec::new(), @@ -525,6 +528,7 @@ pub unsafe extern "C" fn rs_krb5_parse_response_tcp(_flow: *const core::Flow, } export_tx_data_get!(rs_krb5_get_tx_data, KRB5Transaction); +export_state_data_get!(rs_krb5_get_state_data, KRB5State); const PARSER_NAME : &'static [u8] = b"krb5\0"; @@ -556,6 +560,7 @@ pub unsafe extern "C" fn rs_register_krb5_parser() { get_files : None, get_tx_iterator : Some(applayer::state_get_tx_iterator::), get_tx_data : rs_krb5_get_tx_data, + get_state_data : rs_krb5_get_state_data, apply_tx_config : None, flags : APP_LAYER_PARSER_OPT_UNIDIR_TXS, truncate : None, diff --git a/rust/src/modbus/modbus.rs b/rust/src/modbus/modbus.rs index 9d10d04ddc..164d8d1a55 100644 --- a/rust/src/modbus/modbus.rs +++ b/rust/src/modbus/modbus.rs @@ -90,6 +90,7 @@ impl ModbusTransaction { } pub struct ModbusState { + state_data: AppLayerStateData, pub transactions: Vec, tx_id: u64, givenup: bool, // Indicates flood @@ -108,6 +109,7 @@ impl State for ModbusState { impl ModbusState { pub fn new() -> Self { Self { + state_data: AppLayerStateData::new(), transactions: Vec::new(), tx_id: 0, givenup: false, @@ -378,6 +380,8 @@ pub unsafe extern "C" fn rs_modbus_state_get_tx_data( &mut tx.tx_data } +export_state_data_get!(rs_modbus_get_state_data, ModbusState); + #[no_mangle] pub unsafe extern "C" fn rs_modbus_register_parser() { let default_port = std::ffi::CString::new("[502]").unwrap(); @@ -406,6 +410,7 @@ pub unsafe extern "C" fn rs_modbus_register_parser() { get_files: None, get_tx_iterator: Some(applayer::state_get_tx_iterator::), get_tx_data: rs_modbus_state_get_tx_data, + get_state_data: rs_modbus_get_state_data, apply_tx_config: None, flags: 0, truncate: None, diff --git a/rust/src/mqtt/mqtt.rs b/rust/src/mqtt/mqtt.rs index 2d7b592973..2c310a9517 100644 --- a/rust/src/mqtt/mqtt.rs +++ b/rust/src/mqtt/mqtt.rs @@ -97,6 +97,7 @@ impl Transaction for MQTTTransaction { } pub struct MQTTState { + state_data: AppLayerStateData, tx_id: u64, pub protocol_version: u8, transactions: VecDeque, @@ -120,6 +121,7 @@ impl State for MQTTState { impl MQTTState { pub fn new() -> Self { Self { + state_data: AppLayerStateData::new(), tx_id: 0, protocol_version: 0, transactions: VecDeque::new(), @@ -722,6 +724,7 @@ pub unsafe extern "C" fn rs_mqtt_tx_set_logged( const PARSER_NAME: &'static [u8] = b"mqtt\0"; export_tx_data_get!(rs_mqtt_get_tx_data, MQTTTransaction); +export_state_data_get!(rs_mqtt_get_state_data, MQTTState); #[no_mangle] pub unsafe extern "C" fn rs_mqtt_register_parser(cfg_max_msg_len: u32) { @@ -753,6 +756,7 @@ pub unsafe extern "C" fn rs_mqtt_register_parser(cfg_max_msg_len: u32) { get_files: None, get_tx_iterator: Some(crate::applayer::state_get_tx_iterator::), get_tx_data: rs_mqtt_get_tx_data, + get_state_data: rs_mqtt_get_state_data, apply_tx_config: None, flags: APP_LAYER_PARSER_OPT_UNIDIR_TXS, truncate: None, diff --git a/rust/src/nfs/nfs.rs b/rust/src/nfs/nfs.rs index 25176d4bfe..bf6ec90a27 100644 --- a/rust/src/nfs/nfs.rs +++ b/rust/src/nfs/nfs.rs @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Open Information Security Foundation +/* Copyright (C) 2017-2021 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 @@ -281,6 +281,8 @@ pub fn filetracker_newchunk(ft: &mut FileTransferTracker, files: &mut FileContai #[derive(Debug)] pub struct NFSState { + state_data: AppLayerStateData, + /// map xid to procedure so replies can lookup the procedure pub requestmap: HashMap, @@ -338,6 +340,7 @@ impl NFSState { /// Allocation function for a new TLS parser instance pub fn new() -> NFSState { NFSState { + state_data: AppLayerStateData::new(), requestmap:HashMap::new(), namemap:HashMap::new(), transactions: Vec::new(), @@ -1686,6 +1689,8 @@ pub unsafe extern "C" fn rs_nfs_get_tx_data( return &mut tx.tx_data; } +export_state_data_get!(rs_nfs_get_state_data, NFSState); + /// return procedure(s) in the tx. At 0 return the main proc, /// otherwise get procs from the 'file_additional_procs'. /// Keep calling until 0 is returned. @@ -1974,6 +1979,7 @@ pub unsafe extern "C" fn rs_nfs_register_parser() { get_files: Some(rs_nfs_getfiles), get_tx_iterator: Some(applayer::state_get_tx_iterator::), get_tx_data: rs_nfs_get_tx_data, + get_state_data: rs_nfs_get_state_data, apply_tx_config: None, flags: APP_LAYER_PARSER_OPT_ACCEPT_GAPS, truncate: None, @@ -2052,6 +2058,7 @@ pub unsafe extern "C" fn rs_nfs_udp_register_parser() { get_files: Some(rs_nfs_getfiles), get_tx_iterator: Some(applayer::state_get_tx_iterator::), get_tx_data: rs_nfs_get_tx_data, + get_state_data: rs_nfs_get_state_data, apply_tx_config: None, flags: APP_LAYER_PARSER_OPT_UNIDIR_TXS, truncate: None, diff --git a/rust/src/ntp/ntp.rs b/rust/src/ntp/ntp.rs index 12ec8c40a3..aad352e968 100644 --- a/rust/src/ntp/ntp.rs +++ b/rust/src/ntp/ntp.rs @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2020 Open Information Security Foundation +/* Copyright (C) 2017-2021 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 @@ -36,6 +36,8 @@ pub enum NTPEvent { } pub struct NTPState { + state_data: AppLayerStateData, + /// List of transactions for this session transactions: Vec, @@ -65,7 +67,8 @@ impl Transaction for NTPTransaction { impl NTPState { pub fn new() -> NTPState { - NTPState{ + NTPState { + state_data: AppLayerStateData::new(), transactions: Vec::new(), events: 0, tx_id: 0, @@ -263,6 +266,7 @@ pub extern "C" fn ntp_probing_parser(_flow: *const Flow, } export_tx_data_get!(rs_ntp_get_tx_data, NTPTransaction); +export_state_data_get!(rs_ntp_get_state_data, NTPState); const PARSER_NAME : &'static [u8] = b"ntp\0"; @@ -294,6 +298,7 @@ pub unsafe extern "C" fn rs_register_ntp_parser() { get_files : None, get_tx_iterator : Some(applayer::state_get_tx_iterator::), get_tx_data : rs_ntp_get_tx_data, + get_state_data : rs_ntp_get_state_data, apply_tx_config : None, flags : APP_LAYER_PARSER_OPT_UNIDIR_TXS, truncate : None, diff --git a/rust/src/pgsql/pgsql.rs b/rust/src/pgsql/pgsql.rs index daf6111742..56c09b9c29 100644 --- a/rust/src/pgsql/pgsql.rs +++ b/rust/src/pgsql/pgsql.rs @@ -119,6 +119,7 @@ pub enum PgsqlStateProgress { #[derive(Debug)] pub struct PgsqlState { + state_data: AppLayerStateData, tx_id: u64, transactions: VecDeque, request_gap: bool, @@ -142,6 +143,7 @@ impl State for PgsqlState { impl PgsqlState { pub fn new() -> Self { Self { + state_data: AppLayerStateData::new(), tx_id: 0, transactions: VecDeque::new(), request_gap: false, @@ -696,6 +698,7 @@ pub extern "C" fn rs_pgsql_tx_get_alstate_progress( } export_tx_data_get!(rs_pgsql_get_tx_data, PgsqlTransaction); +export_state_data_get!(rs_pgsql_get_state_data, PgsqlState); // Parser name as a C style string. const PARSER_NAME: &'static [u8] = b"pgsql\0"; @@ -731,6 +734,7 @@ pub unsafe extern "C" fn rs_pgsql_register_parser() { crate::applayer::state_get_tx_iterator::, ), get_tx_data: rs_pgsql_get_tx_data, + get_state_data: rs_pgsql_get_state_data, apply_tx_config: None, flags: APP_LAYER_PARSER_OPT_ACCEPT_GAPS, truncate: None, diff --git a/rust/src/quic/quic.rs b/rust/src/quic/quic.rs index 01b46ad6c4..6010b04e37 100644 --- a/rust/src/quic/quic.rs +++ b/rust/src/quic/quic.rs @@ -86,6 +86,7 @@ impl QuicTransaction { } pub struct QuicState { + state_data: AppLayerStateData, max_tx_id: u64, keys: Option, hello_tc: bool, @@ -96,6 +97,7 @@ pub struct QuicState { impl Default for QuicState { fn default() -> Self { Self { + state_data: AppLayerStateData::new(), max_tx_id: 0, keys: None, hello_tc: false, @@ -441,6 +443,7 @@ pub unsafe extern "C" fn rs_quic_state_get_tx_iterator( } export_tx_data_get!(rs_quic_get_tx_data, QuicTransaction); +export_state_data_get!(rs_quic_get_state_data, QuicState); // Parser name as a C style string. const PARSER_NAME: &[u8] = b"quic\0"; @@ -473,6 +476,7 @@ pub unsafe extern "C" fn rs_quic_register_parser() { get_files: None, get_tx_iterator: Some(rs_quic_state_get_tx_iterator), get_tx_data: rs_quic_get_tx_data, + get_state_data: rs_quic_get_state_data, apply_tx_config: None, flags: APP_LAYER_PARSER_OPT_UNIDIR_TXS, truncate: None, diff --git a/rust/src/rdp/rdp.rs b/rust/src/rdp/rdp.rs index 2e740daee0..e911712038 100644 --- a/rust/src/rdp/rdp.rs +++ b/rust/src/rdp/rdp.rs @@ -107,6 +107,7 @@ pub extern "C" fn rs_rdp_tx_get_progress( #[derive(Debug, PartialEq)] pub struct RdpState { + state_data: AppLayerStateData, next_id: u64, transactions: VecDeque, tls_parsing: bool, @@ -126,6 +127,7 @@ impl State for RdpState { impl RdpState { fn new() -> Self { Self { + state_data: AppLayerStateData::new(), next_id: 0, transactions: VecDeque::new(), tls_parsing: false, @@ -454,6 +456,7 @@ pub unsafe extern "C" fn rs_rdp_parse_tc( } export_tx_data_get!(rs_rdp_get_tx_data, RdpTransaction); +export_state_data_get!(rs_rdp_get_state_data, RdpState); // // registration @@ -489,6 +492,7 @@ pub unsafe extern "C" fn rs_rdp_register_parser() { get_files: None, get_tx_iterator: Some(applayer::state_get_tx_iterator::), get_tx_data: rs_rdp_get_tx_data, + get_state_data: rs_rdp_get_state_data, apply_tx_config: None, flags: APP_LAYER_PARSER_OPT_UNIDIR_TXS, truncate: None, diff --git a/rust/src/rfb/rfb.rs b/rust/src/rfb/rfb.rs index f0e3a25c86..ea858f4068 100644 --- a/rust/src/rfb/rfb.rs +++ b/rust/src/rfb/rfb.rs @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 Open Information Security Foundation +/* Copyright (C) 2020-2021 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 @@ -78,6 +78,7 @@ impl RFBTransaction { } pub struct RFBState { + state_data: AppLayerStateData, tx_id: u64, transactions: Vec, state: parser::RFBGlobalState @@ -97,6 +98,7 @@ impl State for RFBState { impl RFBState { pub fn new() -> Self { Self { + state_data: AppLayerStateData::new(), tx_id: 0, transactions: Vec::new(), state: parser::RFBGlobalState::TCServerProtocolVersion @@ -570,6 +572,7 @@ pub unsafe extern "C" fn rs_rfb_tx_get_alstate_progress( const PARSER_NAME: &'static [u8] = b"rfb\0"; export_tx_data_get!(rs_rfb_get_tx_data, RFBTransaction); +export_state_data_get!(rs_rfb_get_state_data, RFBState); #[no_mangle] pub unsafe extern "C" fn rs_rfb_register_parser() { @@ -598,6 +601,7 @@ pub unsafe extern "C" fn rs_rfb_register_parser() { get_files: None, get_tx_iterator: Some(applayer::state_get_tx_iterator::), get_tx_data: rs_rfb_get_tx_data, + get_state_data: rs_rfb_get_state_data, apply_tx_config: None, flags: 0, truncate: None, diff --git a/rust/src/sip/sip.rs b/rust/src/sip/sip.rs index 1c335dbcd9..d59098cf23 100755 --- a/rust/src/sip/sip.rs +++ b/rust/src/sip/sip.rs @@ -46,6 +46,7 @@ pub enum SIPEvent { } pub struct SIPState { + state_data: AppLayerStateData, transactions: Vec, tx_id: u64, } @@ -78,6 +79,7 @@ impl Transaction for SIPTransaction { impl SIPState { pub fn new() -> SIPState { SIPState { + state_data: AppLayerStateData::new(), transactions: Vec::new(), tx_id: 0, } @@ -339,6 +341,7 @@ pub unsafe extern "C" fn rs_sip_parse_response( } export_tx_data_get!(rs_sip_get_tx_data, SIPTransaction); +export_state_data_get!(rs_sip_get_state_data, SIPState); const PARSER_NAME: &'static [u8] = b"sip\0"; @@ -370,6 +373,7 @@ pub unsafe extern "C" fn rs_sip_register_parser() { get_files: None, get_tx_iterator: Some(applayer::state_get_tx_iterator::), get_tx_data: rs_sip_get_tx_data, + get_state_data: rs_sip_get_state_data, apply_tx_config: None, flags: APP_LAYER_PARSER_OPT_UNIDIR_TXS, truncate: None, diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index e53f9417cb..2b429037fe 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -752,6 +752,8 @@ pub fn u32_as_bytes(i: u32) -> [u8;4] { #[derive(Default, Debug)] pub struct SMBState<> { + pub state_data: AppLayerStateData, + /// map ssn/tree/msgid to vec (guid/name/share) pub ssn2vec_map: HashMap>, /// map guid to filename @@ -826,6 +828,7 @@ impl SMBState { /// Allocation function for a new TLS parser instance pub fn new() -> Self { Self { + state_data:AppLayerStateData::new(), ssn2vec_map:HashMap::new(), guid2name_map:HashMap::new(), ssn2vecoffset_map:HashMap::new(), @@ -2292,6 +2295,8 @@ pub unsafe extern "C" fn rs_smb_tx_get_alstate_progress(tx: *mut ffi::c_void, } +export_state_data_get!(rs_smb_get_state_data, SMBState); + #[no_mangle] pub unsafe extern "C" fn rs_smb_get_tx_data( tx: *mut std::os::raw::c_void) @@ -2424,6 +2429,7 @@ pub unsafe extern "C" fn rs_smb_register_parser() { get_files: Some(rs_smb_getfiles), get_tx_iterator: Some(applayer::state_get_tx_iterator::), get_tx_data: rs_smb_get_tx_data, + get_state_data: rs_smb_get_state_data, apply_tx_config: None, flags: APP_LAYER_PARSER_OPT_ACCEPT_GAPS, truncate: Some(rs_smb_state_truncate), diff --git a/rust/src/snmp/snmp.rs b/rust/src/snmp/snmp.rs index e6a7698204..dc2d1bf260 100644 --- a/rust/src/snmp/snmp.rs +++ b/rust/src/snmp/snmp.rs @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2020 Open Information Security Foundation +/* Copyright (C) 2017-2021 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 @@ -37,6 +37,8 @@ pub enum SNMPEvent { } pub struct SNMPState<'a> { + state_data: AppLayerStateData, + /// SNMP protocol version pub version: u32, @@ -88,6 +90,7 @@ impl<'a> Transaction for SNMPTransaction<'a> { impl<'a> SNMPState<'a> { pub fn new() -> SNMPState<'a> { SNMPState{ + state_data: AppLayerStateData::new(), version: 0, transactions: Vec::new(), tx_id: 0, @@ -367,6 +370,7 @@ pub unsafe extern "C" fn rs_snmp_probing_parser(_flow: *const Flow, } export_tx_data_get!(rs_snmp_get_tx_data, SNMPTransaction); +export_state_data_get!(rs_snmp_get_state_data, SNMPState); const PARSER_NAME : &'static [u8] = b"snmp\0"; @@ -398,6 +402,7 @@ pub unsafe extern "C" fn rs_register_snmp_parser() { get_files : None, get_tx_iterator : Some(applayer::state_get_tx_iterator::), get_tx_data : rs_snmp_get_tx_data, + get_state_data : rs_snmp_get_state_data, apply_tx_config : None, flags : APP_LAYER_PARSER_OPT_UNIDIR_TXS, truncate : None, diff --git a/rust/src/ssh/ssh.rs b/rust/src/ssh/ssh.rs index de716557d7..f77f3ea16c 100644 --- a/rust/src/ssh/ssh.rs +++ b/rust/src/ssh/ssh.rs @@ -96,12 +96,14 @@ impl SSHTransaction { } pub struct SSHState { + state_data: AppLayerStateData, transaction: SSHTransaction, } impl SSHState { pub fn new() -> Self { Self { + state_data: AppLayerStateData::new(), transaction: SSHTransaction::new(), } } @@ -332,6 +334,7 @@ impl SSHState { // C exports. export_tx_data_get!(rs_ssh_get_tx_data, SSHTransaction); +export_state_data_get!(rs_ssh_get_state_data, SSHState); #[no_mangle] pub extern "C" fn rs_ssh_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void { @@ -463,6 +466,7 @@ pub unsafe extern "C" fn rs_ssh_register_parser() { get_files: None, get_tx_iterator: None, get_tx_data: rs_ssh_get_tx_data, + get_state_data: rs_ssh_get_state_data, apply_tx_config: None, flags: 0, truncate: None, diff --git a/rust/src/telnet/telnet.rs b/rust/src/telnet/telnet.rs index 0fd2bb27ed..95c3704b8d 100644 --- a/rust/src/telnet/telnet.rs +++ b/rust/src/telnet/telnet.rs @@ -66,6 +66,7 @@ pub enum TelnetProtocolState { } pub struct TelnetState { + state_data: AppLayerStateData, tx_id: u64, transactions: Vec, request_gap: bool, @@ -94,6 +95,7 @@ impl State for TelnetState { impl TelnetState { pub fn new() -> Self { Self { + state_data: AppLayerStateData::new(), tx_id: 0, transactions: Vec::new(), request_gap: false, @@ -518,6 +520,7 @@ pub unsafe extern "C" fn rs_telnet_tx_get_alstate_progress( } export_tx_data_get!(rs_telnet_get_tx_data, TelnetTransaction); +export_state_data_get!(rs_telnet_get_state_data, TelnetState); // Parser name as a C style string. const PARSER_NAME: &'static [u8] = b"telnet\0"; @@ -550,6 +553,7 @@ pub unsafe extern "C" fn rs_telnet_register_parser() { get_files: None, get_tx_iterator: Some(applayer::state_get_tx_iterator::), get_tx_data: rs_telnet_get_tx_data, + get_state_data: rs_telnet_get_state_data, apply_tx_config: None, flags: APP_LAYER_PARSER_OPT_ACCEPT_GAPS, truncate: None, diff --git a/rust/src/tftp/tftp.rs b/rust/src/tftp/tftp.rs index 4aa3f25ecb..232e47102d 100644 --- a/rust/src/tftp/tftp.rs +++ b/rust/src/tftp/tftp.rs @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2020 Open Information Security Foundation +/* Copyright (C) 2017-2021 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 @@ -24,7 +24,7 @@ use nom7::combinator::map_res; use nom7::bytes::streaming::{tag, take_while}; use nom7::number::streaming::be_u8; -use crate::applayer::AppLayerTxData; +use crate::applayer::{AppLayerTxData,AppLayerStateData}; const READREQUEST: u8 = 1; const WRITEREQUEST: u8 = 2; @@ -42,6 +42,7 @@ pub struct TFTPTransaction { } pub struct TFTPState { + state_data: AppLayerStateData, pub transactions : Vec, /// tx counter for assigning incrementing id's to tx's tx_id: u64, @@ -87,7 +88,7 @@ impl TFTPTransaction { #[no_mangle] pub extern "C" fn rs_tftp_state_alloc() -> *mut std::os::raw::c_void { - let state = TFTPState { transactions : Vec::new(), tx_id: 0, }; + let state = TFTPState { state_data: AppLayerStateData::new(), transactions : Vec::new(), tx_id: 0, }; let boxed = Box::new(state); return Box::into_raw(boxed) as *mut _; } @@ -180,6 +181,15 @@ pub unsafe extern "C" fn rs_tftp_get_tx_data( return &mut tx.tx_data; } +#[no_mangle] +pub unsafe extern "C" fn rs_tftp_get_state_data( + state: *mut std::os::raw::c_void) + -> *mut AppLayerStateData +{ + let state = cast_pointer!(state, TFTPState); + return &mut state.state_data; +} + #[cfg(test)] mod test { use super::*; diff --git a/src/app-layer-dnp3.c b/src/app-layer-dnp3.c index 76e664f503..b985e57616 100644 --- a/src/app-layer-dnp3.c +++ b/src/app-layer-dnp3.c @@ -1543,6 +1543,12 @@ static AppLayerTxData *DNP3GetTxData(void *vtx) return &tx->tx_data; } +static AppLayerStateData *DNP3GetStateData(void *vstate) +{ + DNP3State *state = (DNP3State *)vstate; + return &state->state_data; +} + /** * \brief Check if the prefix code is a size prefix. * @@ -1619,6 +1625,7 @@ void RegisterDNP3Parsers(void) AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetTxData); + AppLayerParserRegisterStateDataFunc(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetStateData); } else { SCLogConfig("Parser disabled for protocol %s. " diff --git a/src/app-layer-dnp3.h b/src/app-layer-dnp3.h index 220ef10160..94220c91c3 100644 --- a/src/app-layer-dnp3.h +++ b/src/app-layer-dnp3.h @@ -249,6 +249,7 @@ TAILQ_HEAD(TxListHead, DNP3Transaction_); * \brief Per flow DNP3 state. */ typedef struct DNP3State_ { + AppLayerStateData state_data; TAILQ_HEAD(, DNP3Transaction_) tx_list; DNP3Transaction *curr; /**< Current transaction. */ uint64_t transaction_max; diff --git a/src/app-layer-enip-common.h b/src/app-layer-enip-common.h index 7cfd8d9785..330b263b60 100644 --- a/src/app-layer-enip-common.h +++ b/src/app-layer-enip-common.h @@ -210,6 +210,7 @@ typedef struct ENIPTransaction_ /** \brief Per flow ENIP state container */ typedef struct ENIPState_ { + AppLayerStateData state_data; TAILQ_HEAD(, ENIPTransaction_) tx_list; /**< transaction list */ ENIPTransaction *curr; /**< ptr to current tx */ ENIPTransaction *iter; diff --git a/src/app-layer-enip.c b/src/app-layer-enip.c index 25322ab1a9..87f4d5a396 100644 --- a/src/app-layer-enip.c +++ b/src/app-layer-enip.c @@ -73,6 +73,12 @@ static AppLayerTxData *ENIPGetTxData(void *vtx) return &tx->tx_data; } +static AppLayerStateData *ENIPGetStateData(void *vstate) +{ + ENIPState *state = (ENIPState *)vstate; + return &state->state_data; +} + static void *ENIPGetTx(void *alstate, uint64_t tx_id) { ENIPState *enip = (ENIPState *) alstate; @@ -493,6 +499,7 @@ void RegisterENIPUDPParsers(void) AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetTx); AppLayerParserRegisterTxDataFunc(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetTxData); + AppLayerParserRegisterStateDataFunc(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetStateData); AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetTxCnt); AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_ENIP, ENIPStateTransactionFree); @@ -566,6 +573,7 @@ void RegisterENIPTCPParsers(void) AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetTx); AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetTxData); + AppLayerParserRegisterStateDataFunc(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetStateData); AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetTxCnt); AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_ENIP, ENIPStateTransactionFree); diff --git a/src/app-layer-ftp.c b/src/app-layer-ftp.c index c4ec9e212e..57e15a4238 100644 --- a/src/app-layer-ftp.c +++ b/src/app-layer-ftp.c @@ -999,6 +999,12 @@ static AppLayerTxData *FTPGetTxData(void *vtx) return &tx->tx_data; } +static AppLayerStateData *FTPGetStateData(void *vstate) +{ + FtpState *s = (FtpState *)vstate; + return &s->state_data; +} + static void FTPStateTransactionFree(void *state, uint64_t tx_id) { FtpState *ftp_state = state; @@ -1261,6 +1267,12 @@ static AppLayerTxData *FTPDataGetTxData(void *vtx) return &ftp_state->tx_data; } +static AppLayerStateData *FTPDataGetStateData(void *vstate) +{ + FtpDataState *ftp_state = (FtpDataState *)vstate; + return &ftp_state->state_data; +} + static void FTPDataStateTransactionFree(void *state, uint64_t tx_id) { /* do nothing */ @@ -1396,6 +1408,7 @@ void RegisterFTPParsers(void) AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_FTP, FTPGetTx); AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_FTP, FTPGetTxData); AppLayerParserRegisterGetTxIterator(IPPROTO_TCP, ALPROTO_FTP, FTPGetTxIterator); + AppLayerParserRegisterStateDataFunc(IPPROTO_TCP, ALPROTO_FTP, FTPGetStateData); AppLayerParserRegisterLocalStorageFunc(IPPROTO_TCP, ALPROTO_FTP, FTPLocalStorageAlloc, FTPLocalStorageFree); @@ -1419,6 +1432,7 @@ void RegisterFTPParsers(void) AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_FTPDATA, FTPDataGetTx); AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_FTPDATA, FTPDataGetTxData); + AppLayerParserRegisterStateDataFunc(IPPROTO_TCP, ALPROTO_FTPDATA, FTPDataGetStateData); AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_FTPDATA, FTPDataGetTxCnt); diff --git a/src/app-layer-ftp.h b/src/app-layer-ftp.h index 7e8b4ad553..5e33c81a0a 100644 --- a/src/app-layer-ftp.h +++ b/src/app-layer-ftp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2020 Open Information Security Foundation +/* Copyright (C) 2007-2021 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 @@ -187,6 +187,7 @@ typedef struct FtpState_ { /* specifies which loggers are done logging */ uint32_t logged; + AppLayerStateData state_data; } FtpState; enum { @@ -205,6 +206,7 @@ typedef struct FtpDataState_ { uint8_t state; uint8_t direction; AppLayerTxData tx_data; + AppLayerStateData state_data; } FtpDataState; void RegisterFTPParsers(void); diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index cf8123b9a7..a8eac56eff 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -3110,6 +3110,12 @@ static AppLayerTxData *HTPGetTxData(void *vtx) return NULL; } +static AppLayerStateData *HTPGetStateData(void *vstate) +{ + HtpState *s = vstate; + return &s->state_data; +} + static int HTPRegisterPatternsForProtocolDetection(void) { const char *methods[] = { "GET", "PUT", "POST", "HEAD", "TRACE", "OPTIONS", @@ -3196,6 +3202,7 @@ void RegisterHTPParsers(void) AppLayerParserRegisterTruncateFunc(IPPROTO_TCP, ALPROTO_HTTP1, HTPStateTruncate); AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_HTTP1, HTPGetTxData); + AppLayerParserRegisterStateDataFunc(IPPROTO_TCP, ALPROTO_HTTP1, HTPGetStateData); AppLayerParserRegisterSetStreamDepthFlag( IPPROTO_TCP, ALPROTO_HTTP1, AppLayerHtpSetStreamDepthFlag); diff --git a/src/app-layer-htp.h b/src/app-layer-htp.h index c8ad371765..dc94d49551 100644 --- a/src/app-layer-htp.h +++ b/src/app-layer-htp.h @@ -264,6 +264,7 @@ typedef struct HtpState_ { StreamSlice *slice; FrameId request_frame_id; FrameId response_frame_id; + AppLayerStateData state_data; } HtpState; /** part of the engine needs the request body (e.g. http_client_body keyword) */ diff --git a/src/app-layer-nfs-tcp.c b/src/app-layer-nfs-tcp.c index 657db59c70..e02dd13788 100644 --- a/src/app-layer-nfs-tcp.c +++ b/src/app-layer-nfs-tcp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2020 Open Information Security Foundation +/* Copyright (C) 2015-2021 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 diff --git a/src/app-layer-nfs-udp.c b/src/app-layer-nfs-udp.c index b972803034..af90c11a75 100644 --- a/src/app-layer-nfs-udp.c +++ b/src/app-layer-nfs-udp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2020 Open Information Security Foundation +/* Copyright (C) 2015-2021 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 diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index daa535c7e7..6843b22ff8 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -125,6 +125,7 @@ typedef struct AppLayerParserProtoCtx_ int (*StateGetEventInfo)(const char *event_name, int *event_id, AppLayerEventType *event_type); + AppLayerStateData *(*GetStateData)(void *state); AppLayerTxData *(*GetTxData)(void *tx); bool (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig); @@ -618,6 +619,16 @@ void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto, SCReturn; } +void AppLayerParserRegisterStateDataFunc( + uint8_t ipproto, AppProto alproto, AppLayerStateData *(*GetStateData)(void *state)) +{ + SCEnter(); + + alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetStateData = GetStateData; + + SCReturn; +} + void AppLayerParserRegisterApplyTxConfigFunc(uint8_t ipproto, AppProto alproto, bool (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig)) { @@ -1199,6 +1210,17 @@ AppLayerTxData *AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void SCReturnPtr(d, "AppLayerTxData"); } +AppLayerStateData *AppLayerParserGetStateData(uint8_t ipproto, AppProto alproto, void *state) +{ + SCEnter(); + if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetStateData) { + AppLayerStateData *d = + alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetStateData(state); + SCReturnPtr(d, "AppLayerStateData"); + } + SCReturnPtr(NULL, "AppLayerStateData"); +} + void AppLayerParserApplyTxConfig(uint8_t ipproto, AppProto alproto, void *state, void *tx, enum ConfigAction mode, AppLayerTxConfig config) { @@ -1593,6 +1615,7 @@ static void ValidateParserProtoDump(AppProto alproto, uint8_t ipproto) printf("- StateGetTx %p StateGetTxCnt %p StateTransactionFree %p\n", ctx->StateGetTx, ctx->StateGetTxCnt, ctx->StateTransactionFree); printf("- GetTxData %p\n", ctx->GetTxData); + printf("- GetStateData %p\n", ctx->GetStateData); printf("- StateGetProgress %p\n", ctx->StateGetProgress); printf("Optional:\n"); printf("- LocalStorageAlloc %p LocalStorageFree %p\n", ctx->LocalStorageAlloc, ctx->LocalStorageFree); @@ -1632,6 +1655,9 @@ static void ValidateParserProto(AppProto alproto, uint8_t ipproto) if (ctx->GetTxData == NULL) { goto bad; } + if (ctx->GetStateData == NULL) { + goto bad; + } return; bad: ValidateParserProtoDump(alproto, ipproto); diff --git a/src/app-layer-parser.h b/src/app-layer-parser.h index e470517532..aede85bf80 100644 --- a/src/app-layer-parser.h +++ b/src/app-layer-parser.h @@ -216,6 +216,8 @@ void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto, AppLayerTxData *(*GetTxData)(void *tx)); void AppLayerParserRegisterApplyTxConfigFunc(uint8_t ipproto, AppProto alproto, bool (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig)); +void AppLayerParserRegisterStateDataFunc( + uint8_t ipproto, AppProto alproto, AppLayerStateData *(*GetStateData)(void *state)); /***** Get and transaction functions *****/ @@ -256,6 +258,7 @@ uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto); int AppLayerParserSupportsFiles(uint8_t ipproto, AppProto alproto); AppLayerTxData *AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void *tx); +AppLayerStateData *AppLayerParserGetStateData(uint8_t ipproto, AppProto alproto, void *state); void AppLayerParserApplyTxConfig(uint8_t ipproto, AppProto alproto, void *state, void *tx, enum ConfigAction mode, AppLayerTxConfig); diff --git a/src/app-layer-register.c b/src/app-layer-register.c index 12fd2bb31c..6e28eb1316 100644 --- a/src/app-layer-register.c +++ b/src/app-layer-register.c @@ -165,6 +165,10 @@ int AppLayerRegisterParser(const struct AppLayerParser *p, AppProto alproto) p->GetTxData); } + if (p->GetStateData) { + AppLayerParserRegisterStateDataFunc(p->ip_proto, alproto, p->GetStateData); + } + if (p->ApplyTxConfig) { AppLayerParserRegisterApplyTxConfigFunc(p->ip_proto, alproto, p->ApplyTxConfig); diff --git a/src/app-layer-register.h b/src/app-layer-register.h index 2c104fe76a..311a6e78d8 100644 --- a/src/app-layer-register.h +++ b/src/app-layer-register.h @@ -65,6 +65,7 @@ typedef struct AppLayerParser { const AppProto alproto, void *alstate, uint64_t min_tx_id, uint64_t max_tx_id, AppLayerGetTxIterState *istate); + AppLayerStateData *(*GetStateData)(void *state); AppLayerTxData *(*GetTxData)(void *tx); bool (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig); diff --git a/src/app-layer-smtp.c b/src/app-layer-smtp.c index 437691ceb0..9ae4da56e6 100644 --- a/src/app-layer-smtp.c +++ b/src/app-layer-smtp.c @@ -1738,6 +1738,12 @@ static AppLayerTxData *SMTPGetTxData(void *vtx) return &tx->tx_data; } +static AppLayerStateData *SMTPGetStateData(void *vstate) +{ + SMTPState *state = (SMTPState *)vstate; + return &state->state_data; +} + /** * \brief Register the SMTP Protocol parser. */ @@ -1775,6 +1781,7 @@ void RegisterSMTPParsers(void) AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateGetTxCnt); AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateGetTx); AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_SMTP, SMTPGetTxData); + AppLayerParserRegisterStateDataFunc(IPPROTO_TCP, ALPROTO_SMTP, SMTPGetStateData); AppLayerParserRegisterStateProgressCompletionStatus(ALPROTO_SMTP, 1, 1); AppLayerParserRegisterTruncateFunc(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateTruncate); } else { diff --git a/src/app-layer-smtp.h b/src/app-layer-smtp.h index f7f983b7ee..3aeb892d77 100644 --- a/src/app-layer-smtp.h +++ b/src/app-layer-smtp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation +/* Copyright (C) 2007-2021 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 @@ -103,6 +103,7 @@ typedef struct SMTPConfig { } SMTPConfig; typedef struct SMTPState_ { + AppLayerStateData state_data; SMTPTransaction *curr_tx; TAILQ_HEAD(, SMTPTransaction_) tx_list; /**< transaction list */ uint64_t tx_cnt; diff --git a/src/app-layer-ssl.c b/src/app-layer-ssl.c index b8cecdcb77..80c5382aef 100644 --- a/src/app-layer-ssl.c +++ b/src/app-layer-ssl.c @@ -331,6 +331,12 @@ static AppLayerTxData *SSLGetTxData(void *vtx) return &ssl_state->tx_data; } +static AppLayerStateData *SSLGetStateData(void *vstate) +{ + SSLState *ssl_state = (SSLState *)vstate; + return &ssl_state->state_data; +} + void SSLVersionToString(uint16_t version, char *buffer) { buffer[0] = '\0'; @@ -3007,6 +3013,7 @@ void RegisterSSLParsers(void) AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_TLS, SSLGetTx); AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_TLS, SSLGetTxData); + AppLayerParserRegisterStateDataFunc(IPPROTO_TCP, ALPROTO_TLS, SSLGetStateData); AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_TLS, SSLGetTxCnt); diff --git a/src/app-layer-ssl.h b/src/app-layer-ssl.h index 5febf4185b..5bd703d15e 100644 --- a/src/app-layer-ssl.h +++ b/src/app-layer-ssl.h @@ -288,6 +288,7 @@ typedef struct SSLStateConnp_ { typedef struct SSLState_ { Flow *f; + AppLayerStateData state_data; AppLayerTxData tx_data; /* holds some state flags we need */ diff --git a/src/app-layer-template.c b/src/app-layer-template.c index d53a0e6cf7..5803cacac0 100644 --- a/src/app-layer-template.c +++ b/src/app-layer-template.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2020 Open Information Security Foundation +/* Copyright (C) 2015-2021 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 @@ -446,6 +446,15 @@ static AppLayerTxData *TemplateGetTxData(void *vtx) return &tx->tx_data; } +/** + * \brief retrieve the state data + */ +static AppLayerStateData *TemplateGetStateData(void *vstate) +{ + TemplateState *state = vstate; + return &state->state_data; +} + void RegisterTemplateParsers(void) { const char *proto_name = "template"; @@ -523,6 +532,7 @@ void RegisterTemplateParsers(void) TemplateGetTx); AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_TEMPLATE, TemplateGetTxData); + AppLayerParserRegisterStateDataFunc(IPPROTO_TCP, ALPROTO_TEMPLATE, TemplateGetStateData); AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_TEMPLATE, TemplateStateGetEventInfo); diff --git a/src/app-layer-template.h b/src/app-layer-template.h index 3c28278426..f468005c84 100644 --- a/src/app-layer-template.h +++ b/src/app-layer-template.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2018 Open Information Security Foundation +/* Copyright (C) 2015-2021 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 @@ -52,6 +52,7 @@ typedef struct TemplateTransaction } TemplateTransaction; typedef struct TemplateState { + AppLayerStateData state_data; /** List of Template transactions associated with this * state. */ diff --git a/src/app-layer-tftp.c b/src/app-layer-tftp.c index 37b1846bbb..73dc52a59e 100644 --- a/src/app-layer-tftp.c +++ b/src/app-layer-tftp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2020 Open Information Security Foundation +/* Copyright (C) 2017-2021 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 @@ -234,6 +234,7 @@ void RegisterTFTPParsers(void) AppLayerParserRegisterTxDataFunc(IPPROTO_UDP, ALPROTO_TFTP, rs_tftp_get_tx_data); + AppLayerParserRegisterStateDataFunc(IPPROTO_UDP, ALPROTO_TFTP, rs_tftp_get_state_data); } else { SCLogDebug("TFTP protocol parsing disabled.");