From: Victor Julien Date: Sun, 5 Dec 2021 10:16:06 +0000 (+0100) Subject: app-layer: add StreamSlice to pass data to parsers X-Git-Tag: suricata-7.0.0-beta1~1088 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6466296b32d07f44e83da282b82a888ab0520734;p=thirdparty%2Fsuricata.git app-layer: add StreamSlice to pass data to parsers Since object to contain relevant pointer, length, offset, flags to make it easy to pass these to the parsers. --- diff --git a/rust/cbindgen.toml b/rust/cbindgen.toml index 2be76398b2..4f2355fb2f 100644 --- a/rust/cbindgen.toml +++ b/rust/cbindgen.toml @@ -72,6 +72,7 @@ documentation_style = "doxy" # # default: [] include = [ + "StreamSlice", "AppLayerGetTxIterTuple", "RdpState", "SIPState", diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index 88eff7fff3..6129f6703b 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -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, diff --git a/rust/src/applayertemplate/template.rs b/rust/src/applayertemplate/template.rs index 8db24866e2..065d5f5c4a 100644 --- a/rust/src/applayertemplate/template.rs +++ b/rust/src/applayertemplate/template.rs @@ -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, diff --git a/rust/src/dcerpc/dcerpc.rs b/rust/src/dcerpc/dcerpc.rs index 20ead2529b..ce36f882a4 100644 --- a/rust/src/dcerpc/dcerpc.rs +++ b/rust/src/dcerpc/dcerpc.rs @@ -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); diff --git a/rust/src/dcerpc/dcerpc_udp.rs b/rust/src/dcerpc/dcerpc_udp.rs index 276361cb44..156a8db7b6 100644 --- a/rust/src/dcerpc/dcerpc_udp.rs +++ b/rust/src/dcerpc/dcerpc_udp.rs @@ -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); diff --git a/rust/src/dhcp/dhcp.rs b/rust/src/dhcp/dhcp.rs index 45e5fb2c30..076b601797 100644 --- a/rust/src/dhcp/dhcp.rs +++ b/rust/src/dhcp/dhcp.rs @@ -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, diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index 9d47a68a27..69e98a3225 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -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, diff --git a/rust/src/http2/http2.rs b/rust/src/http2/http2.rs index 291bd3b377..45d799ea83 100644 --- a/rust/src/http2/http2.rs +++ b/rust/src/http2/http2.rs @@ -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); diff --git a/rust/src/ike/ike.rs b/rust/src/ike/ike.rs index 89cb3a0886..e0a368255e 100644 --- a/rust/src/ike/ike.rs +++ b/rust/src/ike/ike.rs @@ -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); diff --git a/rust/src/krb/krb5.rs b/rust/src/krb/krb5.rs index 61e8ee642a..f96e99b77f 100644 --- a/rust/src/krb/krb5.rs +++ b/rust/src/krb/krb5.rs @@ -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, diff --git a/rust/src/modbus/modbus.rs b/rust/src/modbus/modbus.rs index 514cdd0263..094db4fce8 100644 --- a/rust/src/modbus/modbus.rs +++ b/rust/src/modbus/modbus.rs @@ -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 { diff --git a/rust/src/mqtt/mqtt.rs b/rust/src/mqtt/mqtt.rs index f377afab23..1b688ed72a 100644 --- a/rust/src/mqtt/mqtt.rs +++ b/rust/src/mqtt/mqtt.rs @@ -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, diff --git a/rust/src/nfs/nfs.rs b/rust/src/nfs/nfs.rs index 299325bd61..1cc2a567fc 100644 --- a/rust/src/nfs/nfs.rs +++ b/rust/src/nfs/nfs.rs @@ -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, diff --git a/rust/src/ntp/ntp.rs b/rust/src/ntp/ntp.rs index 7de4187397..fd3571e128 100644 --- a/rust/src/ntp/ntp.rs +++ b/rust/src/ntp/ntp.rs @@ -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, diff --git a/rust/src/rdp/rdp.rs b/rust/src/rdp/rdp.rs index 1b78c5996a..bc28c8a142 100644 --- a/rust/src/rdp/rdp.rs +++ b/rust/src/rdp/rdp.rs @@ -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); diff --git a/rust/src/rfb/rfb.rs b/rust/src/rfb/rfb.rs index 5594a094a4..d84720b4da 100644 --- a/rust/src/rfb/rfb.rs +++ b/rust/src/rfb/rfb.rs @@ -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, diff --git a/rust/src/sip/sip.rs b/rust/src/sip/sip.rs index 4125198a8a..a85ce5d0dd 100755 --- a/rust/src/sip/sip.rs +++ b/rust/src/sip/sip.rs @@ -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, diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index e9fa49b252..1bcf92d651 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -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, diff --git a/rust/src/snmp/snmp.rs b/rust/src/snmp/snmp.rs index 33a42890a5..386c7db4d6 100644 --- a/rust/src/snmp/snmp.rs +++ b/rust/src/snmp/snmp.rs @@ -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, diff --git a/rust/src/ssh/ssh.rs b/rust/src/ssh/ssh.rs index 4a286d09bf..5c8ec34e27 100644 --- a/rust/src/ssh/ssh.rs +++ b/rust/src/ssh/ssh.rs @@ -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); diff --git a/src/app-layer-dnp3.c b/src/app-layer-dnp3.c index 7f75d9f1ed..1be6fa4536 100644 --- a/src/app-layer-dnp3.c +++ b/src/app-layer-dnp3.c @@ -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(); diff --git a/src/app-layer-enip.c b/src/app-layer-enip.c index e77624bd4c..2ad0e326f9 100644 --- a/src/app-layer-enip.c +++ b/src/app-layer-enip.c @@ -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(); diff --git a/src/app-layer-ftp.c b/src/app-layer-ftp.c index ae1b42d581..e017fa9dc8 100644 --- a/src/app-layer-ftp.c +++ b/src/app-layer-ftp.c @@ -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); diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index 4153ecdee1..dbe0b5658d 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -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; diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index af5ca0726f..54633abff5 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -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); diff --git a/src/app-layer-parser.h b/src/app-layer-parser.h index a51f10cb16..78dc457319 100644 --- a/src/app-layer-parser.h +++ b/src/app-layer-parser.h @@ -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 { diff --git a/src/app-layer-smtp.c b/src/app-layer-smtp.c index f2a809bf36..3f74a935fa 100644 --- a/src/app-layer-smtp.c +++ b/src/app-layer-smtp.c @@ -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(); diff --git a/src/app-layer-ssl.c b/src/app-layer-ssl.c index 3fa5bb0550..2f52bdb0fe 100644 --- a/src/app-layer-ssl.c +++ b/src/app-layer-ssl.c @@ -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); } diff --git a/src/app-layer-template.c b/src/app-layer-template.c index 84812848f6..f091599267 100644 --- a/src/app-layer-template.c +++ b/src/app-layer-template.c @@ -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; diff --git a/src/app-layer-tftp.c b/src/app-layer-tftp.c index 8721a02165..ba560ea820 100644 --- a/src/app-layer-tftp.c +++ b/src/app-layer-tftp.c @@ -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); } diff --git a/src/app-layer.h b/src/app-layer.h index ca7a632a02..76b40cf9c1 100644 --- a/src/app-layer.h +++ b/src/app-layer.h @@ -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