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.
pull/6763/head
Victor Julien 3 years ago
parent 93842aa14a
commit 6466296b32

@ -72,6 +72,7 @@ documentation_style = "doxy"
#
# default: []
include = [
"StreamSlice",
"AppLayerGetTxIterTuple",
"RdpState",
"SIPState",

@ -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,

@ -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,

@ -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);

@ -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);

@ -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,

@ -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,

@ -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);

@ -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);

@ -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,

@ -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 {

@ -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,

@ -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,

@ -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,

@ -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);

@ -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,

@ -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,

@ -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,

@ -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,

@ -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);

@ -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();

@ -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();

@ -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);

@ -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;

@ -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);

@ -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 {

@ -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();

@ -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);
}

@ -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;

@ -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);
}

@ -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

Loading…
Cancel
Save