]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
app-layer: add StreamSlice to pass data to parsers
authorVictor Julien <vjulien@oisf.net>
Sun, 5 Dec 2021 10:16:06 +0000 (11:16 +0100)
committerVictor Julien <vjulien@oisf.net>
Tue, 4 Jan 2022 14:24:12 +0000 (15:24 +0100)
Since object to contain relevant pointer, length, offset, flags to make
it easy to pass these to the parsers.

31 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/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
src/app-layer-dnp3.c
src/app-layer-enip.c
src/app-layer-ftp.c
src/app-layer-htp.c
src/app-layer-parser.c
src/app-layer-parser.h
src/app-layer-smtp.c
src/app-layer-ssl.c
src/app-layer-template.c
src/app-layer-tftp.c
src/app-layer.h

index 2be76398b264f69dc92de4904218f9d46a05d387..4f2355fb2fdeda4a4f6830c0358b4d525695e708 100644 (file)
@@ -72,6 +72,7 @@ documentation_style = "doxy"
 #
 # default: []
 include = [
+    "StreamSlice",
     "AppLayerGetTxIterTuple",
     "RdpState",
     "SIPState",
index 88eff7fff385d9f592fe1b3db0501a64b3b343be..6129f6703b4a04403c8eeda23a490190adfe667e 100644 (file)
@@ -25,6 +25,36 @@ use std::os::raw::{c_void,c_char,c_int};
 use crate::core::SC;
 use std::ffi::CStr;
 
+#[repr(C)]
+pub struct StreamSlice {
+    input: *const u8,
+    input_len: u32,
+    /// STREAM_* flags
+    flags: u8,
+    offset: u64,
+}
+
+impl StreamSlice {
+    pub fn is_gap(&self) -> bool {
+        self.input.is_null() && self.input_len > 0
+    }
+    pub fn gap_size(&self) -> u32 {
+        self.input_len
+    }
+    pub fn as_slice(&self) -> &[u8] {
+        unsafe { std::slice::from_raw_parts(self.input, self.input_len as usize) }
+    }
+    pub fn len(&self) -> u32 {
+        self.input_len
+    }
+    pub fn offset_from(&self, slice: &[u8]) -> u32 {
+        self.len() - slice.len() as u32
+    }
+    pub fn flags(&self) -> u8 {
+        self.flags
+    }
+}
+
 #[repr(C)]
 #[derive(Default, Debug,PartialEq)]
 pub struct AppLayerTxConfig {
@@ -286,6 +316,7 @@ macro_rules! cast_pointer {
 pub type ParseFn      = unsafe extern "C" fn (flow: *const Flow,
                                        state: *mut c_void,
                                        pstate: *mut c_void,
+                                       stream_slice: StreamSlice,
                                        input: *const u8,
                                        input_len: u32,
                                        data: *const c_void,
index 8db24866e2c469616bb2fd8a00f6059b4ef3fa6d..065d5f5c4afd4e2f7afc0a603b5fb0d55b81dd4a 100644 (file)
@@ -285,6 +285,7 @@ pub unsafe extern "C" fn rs_template_parse_request(
     _flow: *const Flow,
     state: *mut std::os::raw::c_void,
     pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8,
     input_len: u32,
     _data: *const std::os::raw::c_void,
@@ -319,6 +320,7 @@ pub unsafe extern "C" fn rs_template_parse_response(
     _flow: *const Flow,
     state: *mut std::os::raw::c_void,
     pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8,
     input_len: u32,
     _data: *const std::os::raw::c_void,
index 20ead2529b405496fea497d48c8e934f9ee9bced..ce36f882a4dce448ffa45d92cd8cd6c116019f4e 100644 (file)
@@ -1129,6 +1129,7 @@ pub extern "C" fn rs_parse_dcerpc_response_gap(
 #[no_mangle]
 pub unsafe extern "C" fn rs_dcerpc_parse_request(
     flow: *const core::Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8, input_len: u32, _data: *const std::os::raw::c_void, flags: u8,
 ) -> AppLayerResult {
     let state = cast_pointer!(state, DCERPCState);
@@ -1152,6 +1153,7 @@ pub unsafe extern "C" fn rs_dcerpc_parse_request(
 #[no_mangle]
 pub unsafe extern "C" fn rs_dcerpc_parse_response(
     flow: *const core::Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8, input_len: u32, _data: *const std::os::raw::c_void, flags: u8,
 ) -> AppLayerResult {
     let state = cast_pointer!(state, DCERPCState);
index 276361cb449c56ebe3e7fac0018308760cdf8b7d..156a8db7b6268e48a04193312a5db9637f3c796a 100644 (file)
@@ -207,6 +207,7 @@ impl DCERPCUDPState {
 #[no_mangle]
 pub unsafe extern "C" fn rs_dcerpc_udp_parse(
     _flow: *const core::Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8, input_len: u32, _data: *const std::os::raw::c_void, _flags: u8,
 ) -> AppLayerResult {
     let state = cast_pointer!(state, DCERPCUDPState);
index 45e5fb2c30a9ab8351aae10f2804f2524115812c..076b6017979f0966288e039e92e573330246c109 100644 (file)
@@ -228,6 +228,7 @@ pub unsafe extern "C" fn rs_dhcp_state_get_tx_count(state: *mut std::os::raw::c_
 pub unsafe extern "C" fn rs_dhcp_parse(_flow: *const core::Flow,
                                 state: *mut std::os::raw::c_void,
                                 _pstate: *mut std::os::raw::c_void,
+                                _stream_slice: StreamSlice,
                                 input: *const u8,
                                 input_len: u32,
                                 _data: *const std::os::raw::c_void,
index 9d47a68a27d771f675b6644b641536da3c324590..69e98a3225ff0cb516e6f9721de6be8ea7cd40af 100644 (file)
@@ -668,6 +668,7 @@ pub unsafe extern "C" fn rs_dns_state_tx_free(state: *mut std::os::raw::c_void,
 pub unsafe extern "C" fn rs_dns_parse_request(_flow: *const core::Flow,
                                         state: *mut std::os::raw::c_void,
                                        _pstate: *mut std::os::raw::c_void,
+                                       _stream_slice: StreamSlice,
                                        input: *const u8,
                                        input_len: u32,
                                        _data: *const std::os::raw::c_void,
@@ -686,6 +687,7 @@ pub unsafe extern "C" fn rs_dns_parse_request(_flow: *const core::Flow,
 pub unsafe extern "C" fn rs_dns_parse_response(_flow: *const core::Flow,
                                         state: *mut std::os::raw::c_void,
                                         _pstate: *mut std::os::raw::c_void,
+                                        _stream_slice: StreamSlice,
                                         input: *const u8,
                                         input_len: u32,
                                         _data: *const std::os::raw::c_void,
@@ -705,6 +707,7 @@ pub unsafe extern "C" fn rs_dns_parse_response(_flow: *const core::Flow,
 pub unsafe extern "C" fn rs_dns_parse_request_tcp(_flow: *const core::Flow,
                                            state: *mut std::os::raw::c_void,
                                            _pstate: *mut std::os::raw::c_void,
+                                           _stream_slice: StreamSlice,
                                            input: *const u8,
                                            input_len: u32,
                                            _data: *const std::os::raw::c_void,
@@ -725,6 +728,7 @@ pub unsafe extern "C" fn rs_dns_parse_request_tcp(_flow: *const core::Flow,
 pub unsafe extern "C" fn rs_dns_parse_response_tcp(_flow: *const core::Flow,
                                             state: *mut std::os::raw::c_void,
                                             _pstate: *mut std::os::raw::c_void,
+                                            _stream_slice: StreamSlice,
                                             input: *const u8,
                                             input_len: u32,
                                             _data: *const std::os::raw::c_void,
index 291bd3b377602ef437d01282328e0da380d44c20..45d799ea83ce8e57c3a045643f5043b5cc0ae0fa 100644 (file)
@@ -1087,6 +1087,7 @@ pub unsafe extern "C" fn rs_http2_state_tx_free(state: *mut std::os::raw::c_void
 #[no_mangle]
 pub unsafe extern "C" fn rs_http2_parse_ts(
     flow: *const Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8, input_len: u32, _data: *const std::os::raw::c_void, _flags: u8,
 ) -> AppLayerResult {
     let state = cast_pointer!(state, HTTP2State);
@@ -1100,6 +1101,7 @@ pub unsafe extern "C" fn rs_http2_parse_ts(
 #[no_mangle]
 pub unsafe extern "C" fn rs_http2_parse_tc(
     flow: *const Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8, input_len: u32, _data: *const std::os::raw::c_void, _flags: u8,
 ) -> AppLayerResult {
     let state = cast_pointer!(state, HTTP2State);
index 89cb3a08862c18a71e6679d12fbc8455f6dac732..e0a368255e1b2eadc97e7048dc4284009e495d8e 100644 (file)
@@ -316,6 +316,7 @@ pub unsafe extern "C" fn rs_ike_state_tx_free(state: *mut std::os::raw::c_void,
 #[no_mangle]
 pub unsafe extern "C" fn rs_ike_parse_request(
     _flow: *const Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8, input_len: u32, _data: *const std::os::raw::c_void, _flags: u8,
 ) -> AppLayerResult {
     let state = cast_pointer!(state, IKEState);
@@ -327,6 +328,7 @@ pub unsafe extern "C" fn rs_ike_parse_request(
 #[no_mangle]
 pub unsafe extern "C" fn rs_ike_parse_response(
     _flow: *const Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8, input_len: u32, _data: *const std::os::raw::c_void, _flags: u8,
 ) -> AppLayerResult {
     let state = cast_pointer!(state, IKEState);
index 61e8ee642a4f189a36c5e9b069c6c40521d4f2fb..f96e99b77ff24dcc554fa29e8cfa1afc7b1dc172 100644 (file)
@@ -373,6 +373,7 @@ pub unsafe extern "C" fn rs_krb5_probing_parser_tcp(_flow: *const Flow,
 pub unsafe extern "C" fn rs_krb5_parse_request(_flow: *const core::Flow,
                                        state: *mut std::os::raw::c_void,
                                        _pstate: *mut std::os::raw::c_void,
+                                       _stream_slice: StreamSlice,
                                        input: *const u8,
                                        input_len: u32,
                                        _data: *const std::os::raw::c_void,
@@ -389,6 +390,7 @@ pub unsafe extern "C" fn rs_krb5_parse_request(_flow: *const core::Flow,
 pub unsafe extern "C" fn rs_krb5_parse_response(_flow: *const core::Flow,
                                        state: *mut std::os::raw::c_void,
                                        _pstate: *mut std::os::raw::c_void,
+                                       _stream_slice: StreamSlice,
                                        input: *const u8,
                                        input_len: u32,
                                        _data: *const std::os::raw::c_void,
@@ -405,6 +407,7 @@ pub unsafe extern "C" fn rs_krb5_parse_response(_flow: *const core::Flow,
 pub unsafe extern "C" fn rs_krb5_parse_request_tcp(_flow: *const core::Flow,
                                        state: *mut std::os::raw::c_void,
                                        _pstate: *mut std::os::raw::c_void,
+                                       _stream_slice: StreamSlice,
                                        input: *const u8,
                                        input_len: u32,
                                        _data: *const std::os::raw::c_void,
@@ -464,6 +467,7 @@ pub unsafe extern "C" fn rs_krb5_parse_request_tcp(_flow: *const core::Flow,
 pub unsafe extern "C" fn rs_krb5_parse_response_tcp(_flow: *const core::Flow,
                                        state: *mut std::os::raw::c_void,
                                        _pstate: *mut std::os::raw::c_void,
+                                       _stream_slice: StreamSlice,
                                        input: *const u8,
                                        input_len: u32,
                                        _data: *const std::os::raw::c_void,
index 514cdd0263d8becf0f983158f1c8becc9ca37fc6..094db4fce8065888639cc364ca7be25b6870e4c3 100644 (file)
@@ -306,6 +306,7 @@ pub unsafe extern "C" fn rs_modbus_state_tx_free(state: *mut std::os::raw::c_voi
 #[no_mangle]
 pub unsafe extern "C" fn rs_modbus_parse_request(
     _flow: *const core::Flow, state: *mut std::os::raw::c_void, pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8, input_len: u32, _data: *const std::os::raw::c_void, _flags: u8,
 ) -> AppLayerResult {
     if input_len == 0 {
@@ -325,6 +326,7 @@ pub unsafe extern "C" fn rs_modbus_parse_request(
 #[no_mangle]
 pub unsafe extern "C" fn rs_modbus_parse_response(
     _flow: *const core::Flow, state: *mut std::os::raw::c_void, pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8, input_len: u32, _data: *const std::os::raw::c_void, _flags: u8,
 ) -> AppLayerResult {
     if input_len == 0 {
index f377afab23b1b9d4b4c1b24240e666764124df93..1b688ed72af0e3c3105d73c5c6ffdd6489537a1f 100644 (file)
@@ -565,6 +565,7 @@ pub unsafe extern "C" fn rs_mqtt_parse_request(
     _flow: *const Flow,
     state: *mut std::os::raw::c_void,
     _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8,
     input_len: u32,
     _data: *const std::os::raw::c_void,
@@ -580,6 +581,7 @@ pub unsafe extern "C" fn rs_mqtt_parse_response(
     _flow: *const Flow,
     state: *mut std::os::raw::c_void,
     _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8,
     input_len: u32,
     _data: *const std::os::raw::c_void,
index 299325bd612a8a639df444503846d94581eefeaa..1cc2a567fc3c3d67a3e61e7e5ebe7ff591fe9105 100644 (file)
@@ -1377,6 +1377,7 @@ pub extern "C" fn rs_nfs_state_free(state: *mut std::os::raw::c_void) {
 pub unsafe extern "C" fn rs_nfs_parse_request(flow: *const Flow,
                                        state: *mut std::os::raw::c_void,
                                        _pstate: *mut std::os::raw::c_void,
+                                       _stream_slice: StreamSlice,
                                        input: *const u8,
                                        input_len: u32,
                                        _data: *const std::os::raw::c_void,
@@ -1411,6 +1412,7 @@ pub extern "C" fn rs_nfs_parse_request_tcp_gap(
 pub unsafe extern "C" fn rs_nfs_parse_response(flow: *const Flow,
                                         state: *mut std::os::raw::c_void,
                                         _pstate: *mut std::os::raw::c_void,
+                                        _stream_slice: StreamSlice,
                                         input: *const u8,
                                         input_len: u32,
                                         _data: *const std::os::raw::c_void,
@@ -1446,6 +1448,7 @@ pub extern "C" fn rs_nfs_parse_response_tcp_gap(
 pub unsafe extern "C" fn rs_nfs_parse_request_udp(f: *const Flow,
                                        state: *mut std::os::raw::c_void,
                                        _pstate: *mut std::os::raw::c_void,
+                                       _stream_slice: StreamSlice,
                                        input: *const u8,
                                        input_len: u32,
                                        _data: *const std::os::raw::c_void,
@@ -1464,6 +1467,7 @@ pub unsafe extern "C" fn rs_nfs_parse_request_udp(f: *const Flow,
 pub unsafe extern "C" fn rs_nfs_parse_response_udp(f: *const Flow,
                                         state: *mut std::os::raw::c_void,
                                         _pstate: *mut std::os::raw::c_void,
+                                        _stream_slice: StreamSlice,
                                         input: *const u8,
                                         input_len: u32,
                                         _data: *const std::os::raw::c_void,
index 7de41873971b467cf61dd93afab3e82569e4e55e..fd3571e128f1b6b7f4b08aed9b80faf06a6f419a 100644 (file)
@@ -170,6 +170,7 @@ pub extern "C" fn rs_ntp_state_free(state: *mut std::os::raw::c_void) {
 pub unsafe extern "C" fn rs_ntp_parse_request(_flow: *const core::Flow,
                                        state: *mut std::os::raw::c_void,
                                        _pstate: *mut std::os::raw::c_void,
+                                       _stream_slice: StreamSlice,
                                        input: *const u8,
                                        input_len: u32,
                                        _data: *const std::os::raw::c_void,
@@ -186,6 +187,7 @@ pub unsafe extern "C" fn rs_ntp_parse_request(_flow: *const core::Flow,
 pub unsafe extern "C" fn rs_ntp_parse_response(_flow: *const core::Flow,
                                        state: *mut std::os::raw::c_void,
                                        _pstate: *mut std::os::raw::c_void,
+                                       _stream_slice: StreamSlice,
                                        input: *const u8,
                                        input_len: u32,
                                        _data: *const std::os::raw::c_void,
index 1b78c5996a4265d9604bd8571fb4304859e03d3c..bc28c8a142f03e4a53cb852f03566e8de98d3b32 100644 (file)
@@ -427,6 +427,7 @@ fn probe_tls_handshake(input: &[u8]) -> bool {
 #[no_mangle]
 pub unsafe extern "C" fn rs_rdp_parse_ts(
     _flow: *const Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8, input_len: u32, _data: *const std::os::raw::c_void, _flags: u8,
 ) -> AppLayerResult {
     let state = cast_pointer!(state, RdpState);
@@ -438,6 +439,7 @@ pub unsafe extern "C" fn rs_rdp_parse_ts(
 #[no_mangle]
 pub unsafe extern "C" fn rs_rdp_parse_tc(
     _flow: *const Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8, input_len: u32, _data: *const std::os::raw::c_void, _flags: u8,
 ) -> AppLayerResult {
     let state = cast_pointer!(state, RdpState);
index 5594a094a4344be46d3579aa70dc3a7293e15bde..d84720b4daf2f2df153e929731efbf7b3dcee8c9 100644 (file)
@@ -506,6 +506,7 @@ pub unsafe extern "C" fn rs_rfb_parse_request(
     _flow: *const Flow,
     state: *mut std::os::raw::c_void,
     _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8,
     input_len: u32,
     _data: *const std::os::raw::c_void,
@@ -521,6 +522,7 @@ pub unsafe extern "C" fn rs_rfb_parse_response(
     _flow: *const Flow,
     state: *mut std::os::raw::c_void,
     _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8,
     input_len: u32,
     _data: *const std::os::raw::c_void,
index 4125198a8a1beccb30c3a736450adfa06da69224..a85ce5d0dd1707dfcd58e84c67b253830868ff66 100755 (executable)
@@ -235,6 +235,7 @@ pub unsafe extern "C" fn rs_sip_parse_request(
     _flow: *const core::Flow,
     state: *mut std::os::raw::c_void,
     _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8,
     input_len: u32,
     _data: *const std::os::raw::c_void,
@@ -250,6 +251,7 @@ pub unsafe extern "C" fn rs_sip_parse_response(
     _flow: *const core::Flow,
     state: *mut std::os::raw::c_void,
     _pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8,
     input_len: u32,
     _data: *const std::os::raw::c_void,
index e9fa49b2524e7e27a1309937c8ba8900f79e8717..1bcf92d651c412ac5bb07a706702fa55b8b6187c 100644 (file)
@@ -1793,6 +1793,7 @@ pub extern "C" fn rs_smb_state_free(state: *mut std::os::raw::c_void) {
 pub unsafe extern "C" fn rs_smb_parse_request_tcp(flow: *const Flow,
                                        state: *mut ffi::c_void,
                                        _pstate: *mut std::os::raw::c_void,
+                                       _stream_slice: StreamSlice,
                                        input: *const u8,
                                        input_len: u32,
                                        _data: *const std::os::raw::c_void,
@@ -1832,6 +1833,7 @@ pub extern "C" fn rs_smb_parse_request_tcp_gap(
 pub unsafe extern "C" fn rs_smb_parse_response_tcp(flow: *const Flow,
                                         state: *mut ffi::c_void,
                                         _pstate: *mut std::os::raw::c_void,
+                                        _stream_slice: StreamSlice,
                                         input: *const u8,
                                         input_len: u32,
                                         _data: *const ffi::c_void,
index 33a42890a58883693622d60c75210c32c0896bba..386c7db4d6727e05111cb92b11531d23437a2d11 100644 (file)
@@ -265,6 +265,7 @@ pub extern "C" fn rs_snmp_state_free(state: *mut std::os::raw::c_void) {
 pub unsafe extern "C" fn rs_snmp_parse_request(_flow: *const core::Flow,
                                        state: *mut std::os::raw::c_void,
                                        _pstate: *mut std::os::raw::c_void,
+                                       _stream_slice: StreamSlice,
                                        input: *const u8,
                                        input_len: u32,
                                        _data: *const std::os::raw::c_void,
@@ -278,6 +279,7 @@ pub unsafe extern "C" fn rs_snmp_parse_request(_flow: *const core::Flow,
 pub unsafe extern "C" fn rs_snmp_parse_response(_flow: *const core::Flow,
                                        state: *mut std::os::raw::c_void,
                                        _pstate: *mut std::os::raw::c_void,
+                                       _stream_slice: StreamSlice,
                                        input: *const u8,
                                        input_len: u32,
                                        _data: *const std::os::raw::c_void,
index 4a286d09bf2679598446836bd1f2fc025e25f667..5c8ec34e27d6e754434c173428056831efe24f10 100644 (file)
@@ -353,6 +353,7 @@ pub extern "C" fn rs_ssh_state_tx_free(_state: *mut std::os::raw::c_void, _tx_id
 #[no_mangle]
 pub unsafe extern "C" fn rs_ssh_parse_request(
     _flow: *const Flow, state: *mut std::os::raw::c_void, pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8, input_len: u32, _data: *const std::os::raw::c_void, _flags: u8,
 ) -> AppLayerResult {
     let state = &mut cast_pointer!(state, SSHState);
@@ -368,6 +369,7 @@ pub unsafe extern "C" fn rs_ssh_parse_request(
 #[no_mangle]
 pub unsafe extern "C" fn rs_ssh_parse_response(
     _flow: *const Flow, state: *mut std::os::raw::c_void, pstate: *mut std::os::raw::c_void,
+    _stream_slice: StreamSlice,
     input: *const u8, input_len: u32, _data: *const std::os::raw::c_void, _flags: u8,
 ) -> AppLayerResult {
     let state = &mut cast_pointer!(state, SSHState);
index 7f75d9f1edd367b01f71de30d84c81f961a16598..1be6fa45362412502d301d45fff32a7b1dfb3d25 100644 (file)
@@ -1131,8 +1131,8 @@ error:
  * multiple frames, but not the complete final frame).
  */
 static AppLayerResult DNP3ParseRequest(Flow *f, void *state, AppLayerParserState *pstate,
-    const uint8_t *input, uint32_t input_len, void *local_data,
-    const uint8_t flags)
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     SCEnter();
     DNP3State *dnp3 = (DNP3State *)state;
@@ -1271,8 +1271,8 @@ error:
  * See DNP3ParseResponsePDUs for DNP3 frame handling.
  */
 static AppLayerResult DNP3ParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
-    const uint8_t *input, uint32_t input_len, void *local_data,
-    const uint8_t flags)
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     SCEnter();
 
index e77624bd4cc6c12389668351b3c66c44dd311708..2ad0e326f99bc177b6beadea9f6c39b5c926f415 100644 (file)
@@ -290,7 +290,7 @@ static void ENIPStateTransactionFree(void *state, uint64_t tx_id)
  * \retval 1 when the command is parsed, 0 otherwise
  */
 static AppLayerResult ENIPParse(Flow *f, void *state, AppLayerParserState *pstate,
-        const uint8_t *input, uint32_t input_len, void *local_data,
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
         const uint8_t flags)
 {
     SCEnter();
index ae1b42d5816ad1b0c8bd80ca71b69b8e41af7b7b..e017fa9dc8cd1af6bae86cccd295a4ce4e95d582 100644 (file)
@@ -546,10 +546,9 @@ static uint32_t CopyCommandLine(uint8_t **dest, const uint8_t *src, uint32_t len
  * \retval APP_LAYER_OK when input was process successfully
  * \retval APP_LAYER_ERROR when a unrecoverable error was encountered
  */
-static AppLayerResult FTPParseRequest(Flow *f, void *ftp_state,
-                           AppLayerParserState *pstate,
-                           const uint8_t *input, uint32_t input_len,
-                           void *local_data, const uint8_t flags)
+static AppLayerResult FTPParseRequest(Flow *f, void *ftp_state, AppLayerParserState *pstate,
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     FTPThreadCtx *thread_data = local_data;
 
@@ -733,8 +732,8 @@ static inline bool FTPIsPPR(const uint8_t *input, uint32_t input_len)
  * \retval 1 when the command is parsed, 0 otherwise
  */
 static AppLayerResult FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstate,
-                            const uint8_t *input, uint32_t input_len,
-                            void *local_data, const uint8_t flags)
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     FtpState *state = (FtpState *)ftp_state;
 
@@ -1113,19 +1112,17 @@ out:
     SCReturnStruct(APP_LAYER_OK);
 }
 
-static AppLayerResult FTPDataParseRequest(Flow *f, void *ftp_state,
-        AppLayerParserState *pstate,
-        const uint8_t *input, uint32_t input_len,
-        void *local_data, const uint8_t flags)
+static AppLayerResult FTPDataParseRequest(Flow *f, void *ftp_state, AppLayerParserState *pstate,
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     return FTPDataParse(f, ftp_state, pstate, input, input_len,
                                local_data, STREAM_TOSERVER);
 }
 
-static AppLayerResult FTPDataParseResponse(Flow *f, void *ftp_state,
-        AppLayerParserState *pstate,
-        const uint8_t *input, uint32_t input_len,
-        void *local_data, const uint8_t flags)
+static AppLayerResult FTPDataParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstate,
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     return FTPDataParse(f, ftp_state, pstate, input, input_len,
                                local_data, STREAM_TOCLIENT);
index 4153ecdee158a55b9cc01db3d6a6e47ecf55243f..dbe0b5658dd0b438fa798051f6e11019a1eeb30f 100644 (file)
@@ -814,10 +814,9 @@ error:
  *
  *  \retval On success returns 1 or on failure returns -1.
  */
-static AppLayerResult HTPHandleRequestData(Flow *f, void *htp_state,
-                                AppLayerParserState *pstate,
-                                const uint8_t *input, uint32_t input_len,
-                                void *local_data, const uint8_t flags)
+static AppLayerResult HTPHandleRequestData(Flow *f, void *htp_state, AppLayerParserState *pstate,
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     SCEnter();
     int ret = 0;
@@ -878,10 +877,9 @@ static AppLayerResult HTPHandleRequestData(Flow *f, void *htp_state,
  *
  *  \retval On success returns 1 or on failure returns -1
  */
-static AppLayerResult HTPHandleResponseData(Flow *f, void *htp_state,
-                                 AppLayerParserState *pstate,
-                                 const uint8_t *input, uint32_t input_len,
-                                 void *local_data, const uint8_t flags)
+static AppLayerResult HTPHandleResponseData(Flow *f, void *htp_state, AppLayerParserState *pstate,
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     SCEnter();
     int ret = 0;
index af5ca0726f73f0c62edca72ca9aa77b471159f2c..54633abff5ee1c8dc568b8be29013b5524403487 100644 (file)
@@ -1162,6 +1162,21 @@ static inline void SetEOFFlags(AppLayerParserState *pstate, const uint8_t flags)
     }
 }
 
+static void Setup(Flow *f, const uint8_t direction, const uint8_t *input, uint32_t input_len,
+        const uint8_t flags, StreamSlice *as)
+{
+    memset(as, 0, sizeof(*as));
+    as->input = input;
+    as->input_len = input_len;
+    as->flags = flags;
+
+    if (f->proto == IPPROTO_TCP && f->protoctx != NULL) {
+        TcpSession *ssn = f->protoctx;
+        TcpStream *stream = (direction & STREAM_TOSERVER) ? &ssn->client : &ssn->server;
+        as->offset = STREAM_APP_PROGRESS(stream);
+    }
+}
+
 /** \retval int -1 in case of unrecoverable error. App-layer tracking stops for this flow.
  *  \retval int 0 ok: we did not update app_progress
  *  \retval int 1 ok: we updated app_progress */
@@ -1174,6 +1189,7 @@ int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow
 #endif
     AppLayerParserState *pstate = f->alparser;
     AppLayerParserProtoCtx *p = &alp_ctx.ctxs[f->protomap][alproto];
+    StreamSlice stream_slice;
     void *alstate = NULL;
     uint64_t p_tx_cnt = 0;
     uint32_t consumed = input_len;
@@ -1219,11 +1235,11 @@ int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow
 
     /* invoke the recursive parser, but only on data. We may get empty msgs on EOF */
     if (input_len > 0 || (flags & STREAM_EOF)) {
+        Setup(f, flags & (STREAM_TOSERVER | STREAM_TOCLIENT), input, input_len, flags,
+                &stream_slice);
         /* invoke the parser */
-        AppLayerResult res = p->Parser[direction](f, alstate, pstate,
-                input, input_len,
-                alp_tctx->alproto_local_storage[f->protomap][alproto],
-                flags);
+        AppLayerResult res = p->Parser[direction](f, alstate, pstate, stream_slice, input,
+                input_len, alp_tctx->alproto_local_storage[f->protomap][alproto], flags);
         if (res.status < 0) {
             goto error;
         } else if (res.status > 0) {
@@ -1650,8 +1666,8 @@ typedef struct TestState_ {
  *          parser of occurence of an error.
  */
 static AppLayerResult TestProtocolParser(Flow *f, void *test_state, AppLayerParserState *pstate,
-                              const uint8_t *input, uint32_t input_len,
-                              void *local_data, const uint8_t flags)
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     SCEnter();
     SCReturnStruct(APP_LAYER_ERROR);
@@ -1736,8 +1752,7 @@ static int AppLayerParserTest01(void)
     memset(&ssn, 0, sizeof(ssn));
 
     /* Register the Test protocol state and parser functions */
-    AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TEST, STREAM_TOSERVER,
-                      TestProtocolParser);
+    AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TEST, STREAM_TOSERVER, TestProtocolParser);
     AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_TEST,
                           TestProtocolStateAlloc, TestProtocolStateFree);
     AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_TEST, TestStateTransactionFree);
index a51f10cb166a8e766f541878677c2f38c54dd2e0..78dc457319827dfbe2edbad75d0a04ca26ba400f 100644 (file)
@@ -137,8 +137,7 @@ int AppLayerParserConfParserEnabled(const char *ipproto,
 
 /** \brief Prototype for parsing functions */
 typedef AppLayerResult (*AppLayerParserFPtr)(Flow *f, void *protocol_state,
-        AppLayerParserState *pstate,
-        const uint8_t *buf, uint32_t buf_len,
+        AppLayerParserState *pstate, StreamSlice stream_slice, const uint8_t *buf, uint32_t buf_len,
         void *local_storage, const uint8_t flags);
 
 typedef struct AppLayerGetTxIterState {
index f2a809bf366960eb50e58c0cfb12d0848e2b6b69..3f74a935fa3c36308ace9b261ed6408b26c2e8d6 100644 (file)
@@ -1415,10 +1415,9 @@ static AppLayerResult SMTPParse(int direction, Flow *f, SMTPState *state,
     SCReturnStruct(APP_LAYER_OK);
 }
 
-static AppLayerResult SMTPParseClientRecord(Flow *f, void *alstate,
-                                 AppLayerParserState *pstate,
-                                 const uint8_t *input, uint32_t input_len,
-                                 void *local_data, const uint8_t flags)
+static AppLayerResult SMTPParseClientRecord(Flow *f, void *alstate, AppLayerParserState *pstate,
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     SCEnter();
 
@@ -1426,10 +1425,9 @@ static AppLayerResult SMTPParseClientRecord(Flow *f, void *alstate,
     return SMTPParse(0, f, alstate, pstate, input, input_len, local_data);
 }
 
-static AppLayerResult SMTPParseServerRecord(Flow *f, void *alstate,
-                                 AppLayerParserState *pstate,
-                                 const uint8_t *input, uint32_t input_len,
-                                 void *local_data, const uint8_t flags)
+static AppLayerResult SMTPParseServerRecord(Flow *f, void *alstate, AppLayerParserState *pstate,
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     SCEnter();
 
index 3fa5bb0550a7046ec91e3caf812d5639fe8b6093..2f52bdb0fe54efaa81c10d9289402aebfa5005a4 100644 (file)
@@ -2593,15 +2593,15 @@ static AppLayerResult SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLa
 }
 
 static AppLayerResult SSLParseClientRecord(Flow *f, void *alstate, AppLayerParserState *pstate,
-                         const uint8_t *input, uint32_t input_len,
-                         void *local_data, const uint8_t flags)
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     return SSLDecode(f, 0 /* toserver */, alstate, pstate, input, input_len);
 }
 
 static AppLayerResult SSLParseServerRecord(Flow *f, void *alstate, AppLayerParserState *pstate,
-                         const uint8_t *input, uint32_t input_len,
-                         void *local_data, const uint8_t flags)
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     return SSLDecode(f, 1 /* toclient */, alstate, pstate, input, input_len);
 }
index 84812848f6eff2f4538ffafd04d8578f87c71a3e..f09159926790ddb2a6e6280e61fecc7671acbbf1 100644 (file)
@@ -232,9 +232,9 @@ static AppProto TemplateProbingParserTc(Flow *f, uint8_t direction,
     return ALPROTO_UNKNOWN;
 }
 
-static AppLayerResult TemplateParseRequest(Flow *f, void *statev,
-    AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len,
-    void *local_data, const uint8_t flags)
+static AppLayerResult TemplateParseRequest(Flow *f, void *statev, AppLayerParserState *pstate,
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     TemplateState *state = statev;
 
@@ -306,8 +306,8 @@ end:
 }
 
 static AppLayerResult TemplateParseResponse(Flow *f, void *statev, AppLayerParserState *pstate,
-    const uint8_t *input, uint32_t input_len, void *local_data,
-    const uint8_t flags)
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     TemplateState *state = statev;
     TemplateTransaction *tx = NULL, *ttx;
index 8721a02165e0b918241d1bf06d45313b5fadabe8..ba560ea8208d3bfae837dd26fac15144b43e6289 100644 (file)
@@ -91,9 +91,9 @@ static AppProto TFTPProbingParser(Flow *f, uint8_t direction,
     return ALPROTO_UNKNOWN;
 }
 
-static AppLayerResult TFTPParseRequest(Flow *f, void *state,
-    AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len,
-    void *local_data, const uint8_t flags)
+static AppLayerResult TFTPParseRequest(Flow *f, void *state, AppLayerParserState *pstate,
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     SCLogDebug("Parsing tftp request: len=%" PRIu32, input_len);
 
@@ -120,8 +120,8 @@ static AppLayerResult TFTPParseRequest(Flow *f, void *state,
  * \brief Response parsing is not implemented
  */
 static AppLayerResult TFTPParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
-    const uint8_t *input, uint32_t input_len, void *local_data,
-    const uint8_t flags)
+        StreamSlice stream_slice, const uint8_t *input, uint32_t input_len, void *local_data,
+        const uint8_t flags)
 {
     SCReturnStruct(APP_LAYER_OK);
 }
index ca7a632a0226bb7d092d00bc462de5b7582accbf..76b40cf9c1d171c0567071799606512e8e6ed738 100644 (file)
@@ -33,6 +33,8 @@
 
 #include "util-profiling.h"
 
+#include "rust.h"
+
 #define APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER \
     (~STREAM_TOSERVER & ~STREAM_TOCLIENT)
 
@@ -145,4 +147,29 @@ void AppLayerUnittestsRegister(void);
 
 void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step);
 
+static inline uint8_t StreamSliceGetFlags(const StreamSlice *stream_slice)
+{
+    return stream_slice->flags;
+}
+
+static inline const uint8_t *StreamSliceGetData(const StreamSlice *stream_slice)
+{
+    return stream_slice->input;
+}
+
+static inline uint32_t StreamSliceGetDataLen(const StreamSlice *stream_slice)
+{
+    return stream_slice->input_len;
+}
+
+static inline bool StreamSliceIsGap(const StreamSlice *stream_slice)
+{
+    return stream_slice->input == NULL && stream_slice->input_len > 0;
+}
+
+static inline uint32_t StreamSliceGetGapSize(const StreamSlice *stream_slice)
+{
+    return StreamSliceGetDataLen(stream_slice);
+}
+
 #endif