]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
app-layer: introduce common AppLayerStateData API
authorVictor Julien <victor@inliniac.net>
Mon, 26 Apr 2021 12:36:32 +0000 (14:36 +0200)
committerVictor Julien <vjulien@oisf.net>
Fri, 30 Sep 2022 07:46:05 +0000 (09:46 +0200)
Add per state structure for storing flags and other variables.

45 files changed:
rust/cbindgen.toml
rust/src/applayer.rs
rust/src/applayertemplate/template.rs
rust/src/dcerpc/dcerpc.rs
rust/src/dcerpc/dcerpc_udp.rs
rust/src/dhcp/dhcp.rs
rust/src/dns/dns.rs
rust/src/http2/http2.rs
rust/src/ike/ike.rs
rust/src/krb/krb5.rs
rust/src/modbus/modbus.rs
rust/src/mqtt/mqtt.rs
rust/src/nfs/nfs.rs
rust/src/ntp/ntp.rs
rust/src/pgsql/pgsql.rs
rust/src/quic/quic.rs
rust/src/rdp/rdp.rs
rust/src/rfb/rfb.rs
rust/src/sip/sip.rs
rust/src/smb/smb.rs
rust/src/snmp/snmp.rs
rust/src/ssh/ssh.rs
rust/src/telnet/telnet.rs
rust/src/tftp/tftp.rs
src/app-layer-dnp3.c
src/app-layer-dnp3.h
src/app-layer-enip-common.h
src/app-layer-enip.c
src/app-layer-ftp.c
src/app-layer-ftp.h
src/app-layer-htp.c
src/app-layer-htp.h
src/app-layer-nfs-tcp.c
src/app-layer-nfs-udp.c
src/app-layer-parser.c
src/app-layer-parser.h
src/app-layer-register.c
src/app-layer-register.h
src/app-layer-smtp.c
src/app-layer-smtp.h
src/app-layer-ssl.c
src/app-layer-ssl.h
src/app-layer-template.c
src/app-layer-template.h
src/app-layer-tftp.c

index bccb19fd193d760622189332f6b4f7f6d0abd7da..635b972945fc4824a91e3aeb8db04cdf412080f5 100644 (file)
@@ -73,6 +73,7 @@ documentation_style = "doxy"
 # default: []
 include = [
     "StreamSlice",
+    "AppLayerStateData",
     "AppLayerGetTxIterTuple",
     "RdpState",
     "SIPState",
index a08741b02b4d0763de343daa706e5a40f30aaf9b..d6b08ad5a0444b987a85dcd965a478b0ea740f5a 100644 (file)
@@ -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<GetTxIteratorFn>,
 
+    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;
index 3db22ea3432f519c6e049fb64ef005f910747359..12719b5b65aea777cf8374f77074d6f29c7bf64c 100644 (file)
@@ -54,6 +54,7 @@ impl Transaction for TemplateTransaction {
 }
 
 pub struct TemplateState {
+    state_data: AppLayerStateData,
     tx_id: u64,
     transactions: VecDeque<TemplateTransaction>,
     request_gap: bool,
@@ -73,6 +74,7 @@ impl State<TemplateTransaction> 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::<TemplateState, TemplateTransaction>),
         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,
index a70bcb64f8667055d8b7cbbe967a0a603c378b83..91e698d90edb57ecc1fac28a6d500a23c559f80f 100644 (file)
@@ -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<DCERPCTransaction> 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::<DCERPCState, DCERPCTransaction>),
         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,
index 4648e9148e95b5402c2601ce66e852dc97b5f5ca..c66bfdea0416c7c74d802f9f44afee1abb35bd40 100644 (file)
@@ -55,6 +55,7 @@ pub struct DCERPCHdrUdp {
 
 #[derive(Default, Debug)]
 pub struct DCERPCUDPState {
+    state_data: AppLayerStateData,
     pub tx_id: u64,
     pub transactions: VecDeque<DCERPCTransaction>,
 }
@@ -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::<DCERPCUDPState, DCERPCTransaction>),
         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,
index 063f981f7ec9f2f40fcaaf20fc0825e703202e97..2365194299a7f7d617c2ce45c277e8d2980a6457 100644 (file)
@@ -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::<DHCPState, DHCPTransaction>),
         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,
index d6ba77e37ea62bef4f3bc6b4a2b6c9e3e60ab76f..5aafd73924c0dd82c1e96c510db292855ca3e0be 100644 (file)
@@ -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::<DNSState, DNSTransaction>),
         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::<DNSState, DNSTransaction>),
         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,
index 533ea491b0e562dc98efcf904055f212d4b8e9c1..b83c5de74b75bbd13d3b701e2d8b80d07f0ed1ed 100644 (file)
@@ -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<HTTP2Transaction> 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::<HTTP2State, HTTP2Transaction>),
         get_tx_data: rs_http2_get_tx_data,
+        get_state_data: rs_http2_get_state_data,
         apply_tx_config: None,
         flags: 0,
         truncate: None,
index 53b91bbd8b8d91a48f592889530a65aa3054d311..16f9866dcba6124c760e79cdd6a02266d646c07a 100644 (file)
@@ -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<IKETransaction>,
 
@@ -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::<IKEState, IKETransaction>),
         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,
index fdee89d3ca1914af304d4f3507ea8dee19536a62..293db1f864facf67ba1d1d8ce96682ab8cd6859d 100644 (file)
@@ -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::<KRB5State, KRB5Transaction>),
         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,
index 9d10d04ddc4caee5d904731faaee574d7c8ddb54..164d8d1a55b8cfc6069062b4af1caff3496fb13c 100644 (file)
@@ -90,6 +90,7 @@ impl ModbusTransaction {
 }
 
 pub struct ModbusState {
+    state_data: AppLayerStateData,
     pub transactions: Vec<ModbusTransaction>,
     tx_id: u64,
     givenup: bool, // Indicates flood
@@ -108,6 +109,7 @@ impl State<ModbusTransaction> 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::<ModbusState, ModbusTransaction>),
         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,
index 2d7b592973034d60b72a04e1a07ee0fb8fd509e3..2c310a9517ece2262b1c685e93d07090c6cfcbd8 100644 (file)
@@ -97,6 +97,7 @@ impl Transaction for MQTTTransaction {
 }
 
 pub struct MQTTState {
+    state_data: AppLayerStateData,
     tx_id: u64,
     pub protocol_version: u8,
     transactions: VecDeque<MQTTTransaction>,
@@ -120,6 +121,7 @@ impl State<MQTTTransaction> 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::<MQTTState, MQTTTransaction>),
         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,
index 25176d4bfee6c5b0e915115a8467fab0baf80066..bf6ec90a2732c9d050099e4f436cb631fffb8b0b 100644 (file)
@@ -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<u32, NFSRequestXidMap>,
 
@@ -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::<NFSState, NFSTransaction>),
         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::<NFSState, NFSTransaction>),
         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,
index 12ec8c40a3a979903eaafaf9027bcfec5a7dbee8..aad352e9684d7c70bed4d9f6dfb9b392fcc1ca05 100644 (file)
@@ -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<NTPTransaction>,
 
@@ -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::<NTPState, NTPTransaction>),
         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,
index daf61117425cf39e2b2dfa9040955e13a3124a22..56c09b9c29f4ae107895cb23ab7d6c0166b03222 100644 (file)
@@ -119,6 +119,7 @@ pub enum PgsqlStateProgress {
 
 #[derive(Debug)]
 pub struct PgsqlState {
+    state_data: AppLayerStateData,
     tx_id: u64,
     transactions: VecDeque<PgsqlTransaction>,
     request_gap: bool,
@@ -142,6 +143,7 @@ impl State<PgsqlTransaction> 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::<PgsqlState, PgsqlTransaction>,
         ),
         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,
index 01b46ad6c4bec954d0e281c41ec03e37fde8e5b3..6010b04e371332c781b9b922e0e2820190875a82 100644 (file)
@@ -86,6 +86,7 @@ impl QuicTransaction {
 }
 
 pub struct QuicState {
+    state_data: AppLayerStateData,
     max_tx_id: u64,
     keys: Option<QuicKeys>,
     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,
index 2e740daee06f1d6e8889784b6c1b32fe72205b44..e911712038ae8d73e80bfd7de7d00e1c6c927977 100644 (file)
@@ -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<RdpTransaction>,
     tls_parsing: bool,
@@ -126,6 +127,7 @@ impl State<RdpTransaction> 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::<RdpState, RdpTransaction>),
         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,
index f0e3a25c86228a221a23ccc7158a1423894b1093..ea858f406856f3cf842bde73e1183461424a1bb0 100644 (file)
@@ -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<RFBTransaction>,
     state: parser::RFBGlobalState
@@ -97,6 +98,7 @@ impl State<RFBTransaction> 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::<RFBState, RFBTransaction>),
         get_tx_data: rs_rfb_get_tx_data,
+        get_state_data: rs_rfb_get_state_data,
         apply_tx_config: None,
         flags: 0,
         truncate: None,
index 1c335dbcd94ce838732e8f709c2a017951c79965..d59098cf23d586901748a72481908057a812c60f 100755 (executable)
@@ -46,6 +46,7 @@ pub enum SIPEvent {
 }
 
 pub struct SIPState {
+    state_data: AppLayerStateData,
     transactions: Vec<SIPTransaction>,
     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::<SIPState, SIPTransaction>),
         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,
index e53f9417cb12383a9d6178618e6f90a38801e19a..2b429037fea5bb07821b7d6034798f8d3b206baa 100644 (file)
@@ -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<SMBCommonHdr, Vec<u8>>,
     /// 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::<SMBState, SMBTransaction>),
         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),
index e6a769820436f62bf7227f416c370e9421a86091..dc2d1bf26098cc368caf8888c3403366c4b7cd28 100644 (file)
@@ -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::<SNMPState, SNMPTransaction>),
         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,
index de716557d717cb163a72e1f80e0a8b5339f378e8..f77f3ea16c2dcadc0851d8b44c78ee5f927d94d5 100644 (file)
@@ -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,
index 0fd2bb27ed6dc6a8f6a12651bd26801cfd6dfa53..95c3704b8dea2c80e7d9f4fb5572614e01377ac7 100644 (file)
@@ -66,6 +66,7 @@ pub enum TelnetProtocolState {
 }
 
 pub struct TelnetState {
+    state_data: AppLayerStateData,
     tx_id: u64,
     transactions: Vec<TelnetTransaction>,
     request_gap: bool,
@@ -94,6 +95,7 @@ impl State<TelnetTransaction> 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::<TelnetState, TelnetTransaction>),
         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,
index 4aa3f25ecb155a6604e19be73b5e25591a5b3c37..232e47102de397ff3fd4b86e1e98b77600cd93ef 100644 (file)
@@ -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<TFTPTransaction>,
     /// 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::*;
index 76e664f5039388d738f860ffd9245492eb3552c1..b985e57616bf66fd2be730acb0fe212ac7cc7dfe 100644 (file)
@@ -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. "
index 220ef1016007fe076ea12f7524d4f8922da67de8..94220c91c39641524a2b07606a205dabce1ddac5 100644 (file)
@@ -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;
index 7cfd8d9785408a73f396839dbd5a4a6b59d22a46..330b263b6060cf17c62d8b3793a8b369e7d83f9b 100644 (file)
@@ -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;
index 25322ab1a9bd9d43725261e8ae2e17738fcc416e..87f4d5a396cbf4960bf79e4c9678818f561c309c 100644 (file)
@@ -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);
 
index c4ec9e212e01d104f78bbe29fa94b0707be99df5..57e15a4238c4b9d26e6a7124e9643c09fbf09cfa 100644 (file)
@@ -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);
 
index 7e8b4ad553a906d4a0f0fb06ace328a7eccd01b0..5e33c81a0abda2e10ff0f0e91bfcc55011d923c6 100644 (file)
@@ -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);
index cf8123b9a71c3d02e03463ddbd33a020cbcb9873..a8eac56eff5385ebde2d35a6e037c0eaafa3f41d 100644 (file)
@@ -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);
index c8ad3717651499f12c59b5b5c3050b1c346c0af6..dc94d495518282dabe76f6df5ac75e3d7e36667f 100644 (file)
@@ -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) */
index 657db59c705640f88154fac521a5bcd3aeb1b37e..e02dd13788f6847cf31a4924af0c0200a46cc526 100644 (file)
@@ -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
index b972803034c6590fbefafb5996de1c820ef66f49..af90c11a758f6425994836d2d2aa80d962674712 100644 (file)
@@ -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
index daa535c7e74cd96cad2d31c7da3cab2a293ee172..6843b22ff885f2db535be9e7d2284985cf09317d 100644 (file)
@@ -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);
index e47051753262a0c917181754e5ec5631abfc2ec8..aede85bf80464f497f93f3708c3dd26eb602177b 100644 (file)
@@ -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);
 
index 12fd2bb31c368d95ad0d269057150caa2438b152..6e28eb13162e0c034abba1485b1d1c9381f2c5ce 100644 (file)
@@ -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);
index 2c104fe76a67bd467bb42202a1789ea8bb07fdb5..311a6e78d86799ee1f149cfa3555a8080e717aa4 100644 (file)
@@ -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);
 
index 437691ceb050f7d3d548723d75da0a1016ca6159..9ae4da56e62b01d14bfacc1afc8b8419ab308e8c 100644 (file)
@@ -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 {
index f7f983b7ee08bb662179b54e763a862754a9cd37..3aeb892d772e38afaf009cc9948aac6d3a26f97b 100644 (file)
@@ -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;
index b8cecdcb77ef408a7e6d96cc94b92259e48ef404..80c5382aefc765f6089560b5894a82acbe849039 100644 (file)
@@ -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);
 
index 5febf4185b73a41186927678688edb7cefd23c8c..5bd703d15e10b660ab9387bcc3bf6b64c9bcc544 100644 (file)
@@ -288,6 +288,7 @@ typedef struct SSLStateConnp_ {
 typedef struct SSLState_ {
     Flow *f;
 
+    AppLayerStateData state_data;
     AppLayerTxData tx_data;
 
     /* holds some state flags we need */
index d53a0e6cf78607f9e26f972e8ce6e0c4ef336910..5803cacac0b06557ef05c1fcbba08ae2509ad2aa 100644 (file)
@@ -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);
index 3c28278426e5d54c7cad567b83dc7faaf1bf5e49..f468005c8497883456a80fdacf7819ffcbdcb1aa 100644 (file)
@@ -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. */
index 37b1846bbbb996db083f48f00c692d4db4e6b914..73dc52a59eac609ba04e8ec66c5156c595131386 100644 (file)
@@ -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.");