input_len: u32,
_data: *const std::os::raw::c_void,
_flags: u8,
-) -> i32 {
+) -> AppLayerResult {
let eof = unsafe {
if AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF) > 0 {
true
let state = cast_pointer!(state, TemplateState);
let buf = build_slice!(input, input_len as usize);
- if state.parse_request(buf) {
- return 1;
+ if !state.parse_request(buf) {
+ return AppLayerResult::err();
}
- return -1;
+ AppLayerResult::ok()
}
#[no_mangle]
input_len: u32,
_data: *const std::os::raw::c_void,
_flags: u8,
-) -> i32 {
+) -> AppLayerResult {
let _eof = unsafe {
if AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF) > 0 {
true
};
let state = cast_pointer!(state, TemplateState);
let buf = build_slice!(input, input_len as usize);
- if state.parse_response(buf) {
- return 1;
+ if !state.parse_response(buf) {
+ return AppLayerResult::err();
}
- return -1;
+ AppLayerResult::ok()
}
#[no_mangle]
input: *const u8,
input_len: u32,
_data: *const std::os::raw::c_void,
- _flags: u8) -> i32 {
+ _flags: u8) -> AppLayerResult {
let state = cast_pointer!(state, DHCPState);
let buf = build_slice!(input, input_len as usize);
if state.parse(buf) {
- return 0;
+ return AppLayerResult::ok();
}
- return -1;
+ return AppLayerResult::err();
}
#[no_mangle]
input_len: u32,
_data: *const std::os::raw::c_void,
_flags: u8)
- -> std::os::raw::c_int {
+ -> AppLayerResult {
let state = cast_pointer!(state, DNSState);
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
if state.parse_request(buf) {
- 0
+ AppLayerResult::ok()
} else {
- -1
+ AppLayerResult::err()
}
}
input_len: u32,
_data: *const std::os::raw::c_void,
_flags: u8)
- -> std::os::raw::c_int {
+ -> AppLayerResult {
let state = cast_pointer!(state, DNSState);
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
if state.parse_response(buf) {
- 0
+ AppLayerResult::ok()
} else {
- -1
+ AppLayerResult::err()
}
}
input_len: u32,
_data: *const std::os::raw::c_void,
_flags: u8)
- -> std::os::raw::c_int {
+ -> AppLayerResult {
let state = cast_pointer!(state, DNSState);
if input_len > 0 {
if input != std::ptr::null_mut() {
let buf = unsafe{
std::slice::from_raw_parts(input, input_len as usize)};
- return state.parse_request_tcp(buf) as std::os::raw::c_int;
+ let _ = state.parse_request_tcp(buf);
+ return AppLayerResult::ok();
}
state.request_gap(input_len);
}
- return 0;
+ AppLayerResult::ok()
}
#[no_mangle]
input_len: u32,
_data: *const std::os::raw::c_void,
_flags: u8)
- -> std::os::raw::c_int {
+ -> AppLayerResult {
let state = cast_pointer!(state, DNSState);
if input_len > 0 {
if input != std::ptr::null_mut() {
let buf = unsafe{
std::slice::from_raw_parts(input, input_len as usize)};
- return state.parse_response_tcp(buf) as std::os::raw::c_int;
+ let _ = state.parse_response_tcp(buf);
+ return AppLayerResult::ok();
}
state.response_gap(input_len);
}
- return 0;
+ AppLayerResult::ok()
}
#[no_mangle]
input: *const u8,
input_len: u32,
_data: *const std::os::raw::c_void,
- _flags: u8) -> i32 {
+ _flags: u8) -> AppLayerResult {
let buf = build_slice!(input,input_len as usize);
let state = cast_pointer!(state,IKEV2State);
- let res = state.parse(buf, STREAM_TOSERVER);
- if res < 0 {
- return res;
+ if state.parse(buf, STREAM_TOSERVER) < 0 {
+ return AppLayerResult::err();
}
- 0
+ return AppLayerResult::ok();
}
#[no_mangle]
input: *const u8,
input_len: u32,
_data: *const std::os::raw::c_void,
- _flags: u8) -> i32 {
+ _flags: u8) -> AppLayerResult {
let buf = build_slice!(input,input_len as usize);
let state = cast_pointer!(state,IKEV2State);
let res = state.parse(buf, STREAM_TOCLIENT);
};
}
if res < 0 {
- return res;
+ return AppLayerResult::err();
}
- 0
+ return AppLayerResult::ok();
}
#[no_mangle]
/// Parse a Kerberos request message
///
- /// Returns The number of messages parsed, or -1 on error
+ /// Returns 0 in case of success, or -1 on error
fn parse(&mut self, i: &[u8], _direction: u8) -> i32 {
match der_read_element_header(i) {
Ok((_rem,hdr)) => {
// Kerberos messages start with an APPLICATION header
- if hdr.class != 0b01 { return 1; }
+ if hdr.class != 0b01 { return 0; }
match hdr.tag.0 {
10 => {
self.req_id = 10;
input: *const u8,
input_len: u32,
_data: *const std::os::raw::c_void,
- _flags: u8) -> i32 {
+ _flags: u8) -> AppLayerResult {
let buf = build_slice!(input,input_len as usize);
let state = cast_pointer!(state,KRB5State);
- state.parse(buf, STREAM_TOSERVER)
+ if state.parse(buf, STREAM_TOSERVER) < 0 {
+ return AppLayerResult::err();
+ }
+ AppLayerResult::ok()
}
#[no_mangle]
input: *const u8,
input_len: u32,
_data: *const std::os::raw::c_void,
- _flags: u8) -> i32 {
+ _flags: u8) -> AppLayerResult {
let buf = build_slice!(input,input_len as usize);
let state = cast_pointer!(state,KRB5State);
- state.parse(buf, STREAM_TOCLIENT)
+ if state.parse(buf, STREAM_TOCLIENT) < 0 {
+ return AppLayerResult::err();
+ }
+ AppLayerResult::ok()
}
#[no_mangle]
input: *const u8,
input_len: u32,
_data: *const std::os::raw::c_void,
- _flags: u8) -> i32 {
+ _flags: u8) -> AppLayerResult {
let buf = build_slice!(input,input_len as usize);
let state = cast_pointer!(state,KRB5State);
let mut v : Vec<u8>;
- let mut status = 0;
let tcp_buffer = match state.record_ts {
0 => buf,
_ => {
if state.defrag_buf_ts.len() + buf.len() > 100000 {
SCLogDebug!("rs_krb5_parse_request_tcp: TCP buffer exploded {} {}",
state.defrag_buf_ts.len(), buf.len());
- return 1;
+ return AppLayerResult::err();
}
v = state.defrag_buf_ts.split_off(0);
v.extend_from_slice(buf);
},
Err(nom::Err::Incomplete(_)) => {
state.defrag_buf_ts.extend_from_slice(cur_i);
- return 0;
+ return AppLayerResult::ok();
}
_ => {
SCLogDebug!("rs_krb5_parse_request_tcp: reading record mark failed!");
- return 1;
+ return AppLayerResult::err();
}
}
}
if cur_i.len() >= state.record_ts {
- status = state.parse(cur_i, STREAM_TOSERVER);
- if status != 0 {
- return status;
+ if state.parse(cur_i, STREAM_TOSERVER) < 0 {
+ return AppLayerResult::err();
}
state.record_ts = 0;
cur_i = &cur_i[state.record_ts..];
} else {
// more fragments required
state.defrag_buf_ts.extend_from_slice(cur_i);
- return 0;
+ return AppLayerResult::ok();
}
}
- status
+ AppLayerResult::ok()
}
#[no_mangle]
input: *const u8,
input_len: u32,
_data: *const std::os::raw::c_void,
- _flags: u8) -> i32 {
+ _flags: u8) -> AppLayerResult {
let buf = build_slice!(input,input_len as usize);
let state = cast_pointer!(state,KRB5State);
let mut v : Vec<u8>;
- let mut status = 0;
let tcp_buffer = match state.record_tc {
0 => buf,
_ => {
if state.defrag_buf_tc.len() + buf.len() > 100000 {
SCLogDebug!("rs_krb5_parse_response_tcp: TCP buffer exploded {} {}",
state.defrag_buf_tc.len(), buf.len());
- return 1;
+ return AppLayerResult::err();
}
v = state.defrag_buf_tc.split_off(0);
v.extend_from_slice(buf);
},
Err(nom::Err::Incomplete(_)) => {
state.defrag_buf_tc.extend_from_slice(cur_i);
- return 0;
+ return AppLayerResult::ok();
}
_ => {
SCLogDebug!("reading record mark failed!");
- return 1;
+ return AppLayerResult::ok();
}
}
}
if cur_i.len() >= state.record_tc {
- status = state.parse(cur_i, STREAM_TOCLIENT);
- if status != 0 {
- return status;
+ if state.parse(cur_i, STREAM_TOCLIENT) < 0 {
+ return AppLayerResult::err();
}
state.record_tc = 0;
cur_i = &cur_i[state.record_tc..];
} else {
// more fragments required
state.defrag_buf_tc.extend_from_slice(cur_i);
- return 0;
+ return AppLayerResult::ok();
}
}
- status
+ AppLayerResult::ok()
}
export_tx_detect_flags_set!(rs_krb5_tx_detect_flags_set, KRB5Transaction);
impl NTPState {
/// Parse an NTP request message
///
- /// Returns The number of messages parsed, or -1 on error
+ /// Returns 0 if successful, or -1 on error
fn parse(&mut self, i: &[u8], _direction: u8) -> i32 {
match parse_ntp(i) {
Ok((_,ref msg)) => {
input: *const u8,
input_len: u32,
_data: *const std::os::raw::c_void,
- _flags: u8) -> i32 {
+ _flags: u8) -> AppLayerResult {
let buf = build_slice!(input,input_len as usize);
let state = cast_pointer!(state,NTPState);
- state.parse(buf, 0)
+ if state.parse(buf, 0) < 0 {
+ return AppLayerResult::err();
+ }
+ AppLayerResult::ok()
}
#[no_mangle]
input: *const u8,
input_len: u32,
_data: *const std::os::raw::c_void,
- _flags: u8) -> i32 {
+ _flags: u8) -> AppLayerResult {
let buf = build_slice!(input,input_len as usize);
let state = cast_pointer!(state,NTPState);
- state.parse(buf, 1)
+ if state.parse(buf, 1) < 0 {
+ return AppLayerResult::err();
+ }
+ AppLayerResult::ok()
}
#[no_mangle]
use std::os::raw::{c_void,c_char,c_int};
use crate::applayer::{AppLayerGetTxIterTuple};
+#[repr(C)]
+pub struct AppLayerResult {
+ pub status: i32,
+ pub consumed: u32,
+ pub needed: u32,
+}
+
+impl AppLayerResult {
+ pub fn ok() -> AppLayerResult {
+ return AppLayerResult {
+ status: 0,
+ consumed: 0,
+ needed: 0,
+ };
+ }
+ pub fn err() -> AppLayerResult {
+ return AppLayerResult {
+ status: -1,
+ consumed: 0,
+ needed: 0,
+ };
+ }
+}
+
/// Rust parser declaration
#[repr(C)]
pub struct RustParser {
input: *const u8,
input_len: u32,
data: *const c_void,
- flags: u8) -> i32;
+ flags: u8) -> AppLayerResult;
pub type ProbeFn = extern "C" fn (flow: *const Flow,direction: u8,input:*const u8, input_len: u32, rdir: *mut u8) -> AppProto;
pub type StateAllocFn = extern "C" fn () -> *mut c_void;
pub type StateFreeFn = extern "C" fn (*mut c_void);
input_len: u32,
_data: *const std::os::raw::c_void,
_flags: u8,
-) -> i32 {
+) -> AppLayerResult {
let state = cast_pointer!(state, RdpState);
let buf = build_slice!(input, input_len as usize);
// attempt to parse bytes as `rdp` protocol
if state.parse_ts(buf) {
- return 0;
+ AppLayerResult::ok()
+ } else {
+ // no need for further parsing
+ AppLayerResult::err()
}
- // no need for further parsing
- return -1;
}
#[no_mangle]
input_len: u32,
_data: *const std::os::raw::c_void,
_flags: u8,
-) -> i32 {
+) -> AppLayerResult {
let state = cast_pointer!(state, RdpState);
let buf = build_slice!(input, input_len as usize);
// attempt to parse bytes as `rdp` protocol
if state.parse_tc(buf) {
- return 0;
+ AppLayerResult::ok()
+ } else {
+ // no need for further parsing
+ AppLayerResult::err()
}
- // no need for further parsing
- return -1;
}
//
input_len: u32,
_data: *const std::os::raw::c_void,
_flags: u8,
-) -> i32 {
+) -> AppLayerResult {
let buf = build_slice!(input, input_len as usize);
let state = cast_pointer!(state, SIPState);
- if state.parse_request(buf) {
- 0
- } else {
- -1
+ if !state.parse_request(buf) {
+ return AppLayerResult::err();
}
+ AppLayerResult::ok()
}
#[no_mangle]
input_len: u32,
_data: *const std::os::raw::c_void,
_flags: u8,
-) -> i32 {
+) -> AppLayerResult {
let buf = build_slice!(input, input_len as usize);
let state = cast_pointer!(state, SIPState);
- if state.parse_response(buf) {
- 0
- } else {
- -1
+ if !state.parse_response(buf) {
+ return AppLayerResult::err();
}
+ AppLayerResult::ok()
}
const PARSER_NAME: &'static [u8] = b"sip\0";
/// Parse an SNMP request message
///
- /// Returns The number of messages parsed, or -1 on error
+ /// Returns 0 if successful, or -1 on error
fn parse(&mut self, i: &[u8], direction: u8) -> i32 {
if self.version == 0 {
match parse_pdu_enveloppe_version(i) {
input: *const u8,
input_len: u32,
_data: *const std::os::raw::c_void,
- _flags: u8) -> i32 {
+ _flags: u8) -> AppLayerResult {
let buf = build_slice!(input,input_len as usize);
let state = cast_pointer!(state,SNMPState);
- state.parse(buf, STREAM_TOSERVER)
+ if state.parse(buf, STREAM_TOSERVER) < 0 {
+ return AppLayerResult::err();
+ }
+ AppLayerResult::ok()
}
#[no_mangle]
input: *const u8,
input_len: u32,
_data: *const std::os::raw::c_void,
- _flags: u8) -> i32 {
+ _flags: u8) -> AppLayerResult {
let buf = build_slice!(input,input_len as usize);
let state = cast_pointer!(state,SNMPState);
- state.parse(buf, STREAM_TOCLIENT)
+ if state.parse(buf, STREAM_TOCLIENT) < 0 {
+ return AppLayerResult::err();
+ }
+ AppLayerResult::ok()
}
#[no_mangle]
SCReturnInt((p - input));
}
-static int DCERPCUDPParse(Flow *f, void *dcerpc_state,
+static AppLayerResult DCERPCUDPParse(Flow *f, void *dcerpc_state,
AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
{
SCEnter();
if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
DCERPCUDPState *sstate = (DCERPCUDPState *) dcerpc_state;
input_len);
if (hdrretval == -1 || hdrretval > (int32_t)input_len) {
sstate->bytesprocessed = 0;
- SCReturnInt(hdrretval);
+ SCReturnStruct(APP_LAYER_ERROR);
} else {
parsed += hdrretval;
input_len -= hdrretval;
sstate->bytesprocessed = 0;
}
if (pstate == NULL)
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
static void *DCERPCUDPStateAlloc(void)
SCReturnInt(parsed);
}
-static int DCERPCParse(Flow *f, void *dcerpc_state,
+static AppLayerResult DCERPCParse(Flow *f, void *dcerpc_state,
AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len,
void *local_data, int dir)
DCERPCState *sstate = (DCERPCState *) dcerpc_state;
if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
if (sstate->dcerpc.bytesprocessed != 0 && sstate->data_needed_for_dir != dir) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
retval = DCERPCParser(&sstate->dcerpc, input, input_len);
if (retval == -1) {
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
sstate->data_needed_for_dir = dir;
if (pstate == NULL)
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
-static int DCERPCParseRequest(Flow *f, void *dcerpc_state,
+static AppLayerResult DCERPCParseRequest(Flow *f, void *dcerpc_state,
AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
local_data, 0);
}
-static int DCERPCParseResponse(Flow *f, void *dcerpc_state,
+static AppLayerResult DCERPCParseResponse(Flow *f, void *dcerpc_state,
AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
* date if a segment does not contain a complete frame (or contains
* multiple frames, but not the complete final frame).
*/
-static int DNP3ParseRequest(Flow *f, void *state, AppLayerParserState *pstate,
+static AppLayerResult DNP3ParseRequest(Flow *f, void *state, AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len, void *local_data,
const uint8_t flags)
{
int processed = 0;
if (input_len == 0) {
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
if (buffer->len) {
}
}
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
error:
/* Reset the buffer. */
DNP3BufferReset(buffer);
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
/**
*
* See DNP3ParseResponsePDUs for DNP3 frame handling.
*/
-static int DNP3ParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
+static AppLayerResult DNP3ParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len, void *local_data,
const uint8_t flags)
{
}
done:
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
error:
/* An error occurred while processing DNP3 frames. Dump the
* buffer as we can't be assured that they are valid anymore. */
DNP3BufferReset(buffer);
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
static AppLayerDecoderEvents *DNP3GetEvents(void *tx)
*
* \retval 1 when the command is parsed, 0 otherwise
*/
-static int ENIPParse(Flow *f, void *state, AppLayerParserState *pstate,
+static AppLayerResult ENIPParse(Flow *f, void *state, AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len, void *local_data,
const uint8_t flags)
{
if (input == NULL && AppLayerParserStateIssetFlag(pstate,
APP_LAYER_PARSER_EOF))
{
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL && input_len != 0) {
// GAP
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0)
{
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
while (input_len > 0)
{
tx = ENIPTransactionAlloc(enip);
if (tx == NULL)
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
SCLogDebug("ENIPParse input len %d", input_len);
DecodeENIPPDU(input, input_len, tx);
}
}
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
* \retval APP_LAYER_OK when input was process successfully
* \retval APP_LAYER_ERROR when a unrecoverable error was encountered
*/
-static int FTPParseRequest(Flow *f, void *ftp_state,
+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)
void *ptmp;
if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
state->input = input;
FTPTransaction *tx = FTPTransactionCreate(state);
if (unlikely(tx == NULL))
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
state->curr_tx = tx;
tx->command_descriptor = cmd_descriptor;
state->port_line = NULL;
state->port_line_size = 0;
}
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
state->port_line = ptmp;
state->port_line_size = state->current_line_len;
* name -- need more than 5 chars: cmd [4], space, <filename>
*/
if (state->dyn_port == 0 || state->current_line_len < 6) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
struct FtpTransferCmd *data = FTPCalloc(1, sizeof(struct FtpTransferCmd));
if (data == NULL)
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
data->DFree = FtpTransferCmdFree;
/* Min size has been checked in FTPParseRequestCommand */
data->file_name = FTPCalloc(state->current_line_len - 4, sizeof(char));
if (data->file_name == NULL) {
FtpTransferCmdFree(data);
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
data->file_name[state->current_line_len - 5] = 0;
data->file_len = state->current_line_len - 5;
if (ret == -1) {
FtpTransferCmdFree(data);
SCLogDebug("No expectation created.");
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
} else {
SCLogDebug("Expectation created [direction: %s, dynamic port %"PRIu16"].",
state->active ? "to server" : "to client",
}
}
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
static int FTPParsePassiveResponse(Flow *f, FtpState *state, const uint8_t *input, uint32_t input_len)
*
* \retval 1 when the command is parsed, 0 otherwise
*/
-static int FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstate,
+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)
{
FtpState *state = (FtpState *)ftp_state;
if (unlikely(input_len == 0)) {
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
FTPTransaction *tx = FTPGetOldestTx(state);
tx = FTPTransactionCreate(state);
}
if (unlikely(tx == NULL)) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
if (state->command == FTP_COMMAND_UNKNOWN || tx->command_descriptor == NULL) {
/* unknown */
/* Handle preliminary replies -- keep tx open */
if (FTPIsPPR(input, input_len)) {
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
tx_complete:
tx->done = true;
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
*
* \retval 1 when the command is parsed, 0 otherwise
*/
-static int FTPDataParse(Flow *f, FtpDataState *ftpdata_state,
+static AppLayerResult FTPDataParse(Flow *f, FtpDataState *ftpdata_state,
AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len,
void *local_data, int direction)
if (ftpdata_state->files == NULL) {
struct FtpTransferCmd *data = (struct FtpTransferCmd *)FlowGetStorageById(f, AppLayerExpectationGetDataId());
if (data == NULL) {
- SCReturnInt(-1);
+ SCReturnStruct(APP_LAYER_ERROR);
}
ftpdata_state->files = FileContainerAlloc();
if (ftpdata_state->files == NULL) {
FlowFreeStorageById(f, AppLayerExpectationGetDataId());
- SCReturnInt(-1);
+ SCReturnStruct(APP_LAYER_ERROR);
}
ftpdata_state->file_name = data->file_name;
}
out:
- return ret;
+ if (ret < 0) {
+ SCReturnStruct(APP_LAYER_ERROR);
+ }
+ SCReturnStruct(APP_LAYER_OK);
}
static void FTPStateSetTxLogged(void *state, void *vtx, LoggerId logged)
FTPTransaction *tx = vtx;
return tx->logged;
}
-static int FTPDataParseRequest(Flow *f, void *ftp_state,
+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)
local_data, STREAM_TOSERVER);
}
-static int FTPDataParseResponse(Flow *f, void *ftp_state,
+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)
*
* \retval On success returns 1 or on failure returns -1.
*/
-static int HTPHandleRequestData(Flow *f, void *htp_state,
+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)
*/
if (NULL == hstate->conn) {
if (Setup(f, hstate) != 0) {
- goto error;
+ SCReturnStruct(APP_LAYER_ERROR);
}
}
DEBUG_VALIDATE_BUG_ON(hstate->connp == NULL);
}
SCLogDebug("hstate->connp %p", hstate->connp);
- SCReturnInt(ret);
-error:
- SCReturnInt(-1);
+ if (ret < 0) {
+ SCReturnStruct(APP_LAYER_ERROR);
+ }
+ SCReturnStruct(APP_LAYER_OK);
}
/**
*
* \retval On success returns 1 or on failure returns -1
*/
-static int HTPHandleResponseData(Flow *f, void *htp_state,
+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)
*/
if (NULL == hstate->conn) {
if (Setup(f, hstate) != 0) {
- goto error;
+ SCReturnStruct(APP_LAYER_ERROR);
}
}
DEBUG_VALIDATE_BUG_ON(hstate->connp == NULL);
}
SCLogDebug("hstate->connp %p", hstate->connp);
- SCReturnInt(ret);
-error:
- SCReturnInt(-1);
+
+ if (ret < 0) {
+ SCReturnStruct(APP_LAYER_ERROR);
+ }
+ SCReturnStruct(APP_LAYER_OK);
}
/**
* \param input Input line of the command
* \param input_len Length of the request
*
- * \retval 1 when the command is parsed, 0 otherwise
+ * \retval AppLayerResult APP_LAYER_OK or APP_LAYER_ERROR
*/
-static int ModbusParseRequest(Flow *f,
+static AppLayerResult ModbusParseRequest(Flow *f,
void *state,
AppLayerParserState *pstate,
const uint8_t *input,
ModbusHeader header;
if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
while (input_len > 0) {
/* Extract MODBUS Header */
if (ModbusParseHeader(modbus, &header, adu, adu_len))
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
/* Update ADU length with length in Modbus header. */
adu_len = (uint32_t) sizeof(ModbusHeader) + (uint32_t) header.length - 1;
if (adu_len > input_len)
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
/* Allocate a Transaction Context and add it to Transaction list */
tx = ModbusTxAlloc(modbus);
if (tx == NULL)
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
/* Check MODBUS Header */
ModbusCheckHeader(modbus, &header);
input_len -= adu_len;
}
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
/** \internal
* \param input Input line of the command
* \param input_len Length of the request
*
- * \retval 1 when the command is parsed, 0 otherwise
+ * \retval AppLayerResult APP_LAYER_OK or APP_LAYER_ERROR
*/
-static int ModbusParseResponse(Flow *f,
+static AppLayerResult ModbusParseResponse(Flow *f,
void *state,
AppLayerParserState *pstate,
const uint8_t *input,
ModbusTransaction *tx;
if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
while (input_len > 0) {
/* Extract MODBUS Header */
if (ModbusParseHeader(modbus, &header, adu, adu_len))
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
/* Update ADU length with length in Modbus header. */
adu_len = (uint32_t) sizeof(ModbusHeader) + (uint32_t) header.length - 1;
if (adu_len > input_len)
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
/* Find the transaction context thanks to transaction ID (and function code) */
tx = ModbusTxFindByTransaction(modbus, header.transactionId);
/* and add it to Transaction list */
tx = ModbusTxAlloc(modbus);
if (tx == NULL)
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
SCLogDebug("MODBUS_DECODER_EVENT_UNSOLICITED_RESPONSE");
ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_UNSOLICITED_RESPONSE);
input_len -= adu_len;
}
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
/** \internal
return ALPROTO_UNKNOWN;
}
-static int NFSTCPParseRequest(Flow *f, void *state,
+static AppLayerResult NFSTCPParseRequest(Flow *f, void *state,
AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
{
} else {
res = rs_nfs_parse_request(f, state, pstate, input, input_len, local_data);
}
- return res;
+ if (res < 0) {
+ SCReturnStruct(APP_LAYER_ERROR);
+ }
+ SCReturnStruct(APP_LAYER_OK);
}
-static int NFSTCPParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
+static AppLayerResult NFSTCPParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len, void *local_data,
const uint8_t flags)
{
} else {
res = rs_nfs_parse_response(f, state, pstate, input, input_len, local_data);
}
- return res;
+ if (res < 0) {
+ SCReturnStruct(APP_LAYER_ERROR);
+ }
+ SCReturnStruct(APP_LAYER_OK);
}
static uint64_t NFSTCPGetTxCnt(void *state)
return ALPROTO_UNKNOWN;
}
-static int NFSParseRequest(Flow *f, void *state,
+static AppLayerResult NFSParseRequest(Flow *f, void *state,
AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
{
uint16_t file_flags = FileFlowToFlags(f, STREAM_TOSERVER);
rs_nfs_setfileflags(0, state, file_flags);
- return rs_nfs_parse_request_udp(f, state, pstate, input, input_len, local_data);
+ int res = rs_nfs_parse_request_udp(f, state, pstate, input, input_len, local_data);
+ if (res < 0) {
+ SCReturnStruct(APP_LAYER_ERROR);
+ }
+ SCReturnStruct(APP_LAYER_OK);
}
-static int NFSParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
+static AppLayerResult NFSParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len, void *local_data,
const uint8_t flags)
{
uint16_t file_flags = FileFlowToFlags(f, STREAM_TOCLIENT);
rs_nfs_setfileflags(1, state, file_flags);
- return rs_nfs_parse_response_udp(f, state, pstate, input, input_len, local_data);
+ int res = rs_nfs_parse_response_udp(f, state, pstate, input, input_len, local_data);
+ if (res < 0) {
+ SCReturnStruct(APP_LAYER_ERROR);
+ }
+ SCReturnStruct(APP_LAYER_OK);
}
static uint64_t NFSGetTxCnt(void *state)
/* invoke the recursive parser, but only on data. We may get empty msgs on EOF */
if (input_len > 0 || (flags & STREAM_EOF)) {
/* invoke the parser */
- int parse_res = p->Parser[(flags & STREAM_TOSERVER) ? 0 : 1](f, alstate, pstate,
+ AppLayerResult res = p->Parser[(flags & STREAM_TOSERVER) ? 0 : 1](f, alstate, pstate,
input, input_len,
alp_tctx->alproto_local_storage[f->protomap][alproto],
flags);
- if (parse_res < 0)
+ if (res.status < 0)
{
goto error;
}
* \brief Test parser function to test the memory deallocation of app layer
* parser of occurence of an error.
*/
-static int TestProtocolParser(Flow *f, void *test_state, AppLayerParserState *pstate,
+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)
{
SCEnter();
- SCReturnInt(-1);
+ SCReturnStruct(APP_LAYER_ERROR);
}
/** \brief Function to allocates the Test protocol state memory
* completely inspected */
#define APP_LAYER_TX_PREFILTER_MASK ~APP_LAYER_TX_INSPECTED_FLAG
-#define APP_LAYER_OK 0
-#define APP_LAYER_ERROR -1
+#define APP_LAYER_OK (AppLayerResult) { 0, 0, 0 }
+#define APP_LAYER_ERROR (AppLayerResult) { -1, 0, 0 }
int AppLayerParserProtoIsRegistered(uint8_t ipproto, AppProto alproto);
const char *alproto_name);
/** \brief Prototype for parsing functions */
-typedef int (*AppLayerParserFPtr)(Flow *f, void *protocol_state,
+typedef AppLayerResult (*AppLayerParserFPtr)(Flow *f, void *protocol_state,
AppLayerParserState *pstate,
const uint8_t *buf, uint32_t buf_len,
void *local_storage, const uint8_t flags);
#define MIN_REC_SIZE 32+4 // SMB hdr + nbss hdr
-static int SMBTCPParseRequest(Flow *f, void *state,
+static AppLayerResult SMBTCPParseRequest(Flow *f, void *state,
AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
{
if (res != 0) {
SCLogDebug("SMB request%s of %u bytes, retval %d",
(input == NULL && input_len > 0) ? " is GAP" : "", input_len, res);
+ SCReturnStruct(APP_LAYER_ERROR);
}
- return res;
+ SCReturnStruct(APP_LAYER_OK);
}
-static int SMBTCPParseResponse(Flow *f, void *state,
+static AppLayerResult SMBTCPParseResponse(Flow *f, void *state,
AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
{
if (res != 0) {
SCLogDebug("SMB response%s of %u bytes, retval %d",
(input == NULL && input_len > 0) ? " is GAP" : "", input_len, res);
+ SCReturnStruct(APP_LAYER_ERROR);
}
- return res;
+ SCReturnStruct(APP_LAYER_OK);
}
static uint16_t SMBTCPProbe(Flow *f, uint8_t direction,
}
}
-static int SMTPParse(int direction, Flow *f, SMTPState *state,
+static AppLayerResult SMTPParse(int direction, Flow *f, SMTPState *state,
AppLayerParserState *pstate, const uint8_t *input,
uint32_t input_len,
SMTPThreadCtx *thread_data)
SCEnter();
if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
state->input = input;
if (direction == 0) {
while (SMTPGetLine(state) >= 0) {
if (SMTPProcessRequest(state, f, pstate) == -1)
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
/* toclient */
} else {
while (SMTPGetLine(state) >= 0) {
if (SMTPProcessReply(state, f, pstate, thread_data) == -1)
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
}
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
-static int SMTPParseClientRecord(Flow *f, void *alstate,
+static AppLayerResult SMTPParseClientRecord(Flow *f, void *alstate,
AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
return SMTPParse(0, f, alstate, pstate, input, input_len, local_data);
}
-static int SMTPParseServerRecord(Flow *f, void *alstate,
+static AppLayerResult SMTPParseServerRecord(Flow *f, void *alstate,
AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
return 0;
}
-static int SSHParseRequest(Flow *f, void *state, AppLayerParserState *pstate,
+static AppLayerResult SSHParseRequest(Flow *f, void *state, AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
{
SshHeader *ssh_header = &ssh_state->cli_hdr;
if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
int r = SSHParseData(ssh_state, ssh_header, input, input_len);
}
if (r < 0) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
-static int SSHParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
+static AppLayerResult SSHParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
{
SshHeader *ssh_header = &ssh_state->srv_hdr;
if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
int r = SSHParseData(ssh_state, ssh_header, input, input_len);
}
if (r < 0) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
}
/** \brief Function to allocates the SSH state memory
*
* \retval >=0 On success.
*/
-static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserState *pstate,
+static AppLayerResult SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserState *pstate,
const uint8_t *input, uint32_t ilen)
{
SSLState *ssl_state = (SSLState *)alstate;
AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
/* flag session as finished if APP_LAYER_PARSER_EOF is set */
ssl_state->flags |= SSL_AL_FLAG_STATE_FINISHED;
- SCReturnInt(APP_LAYER_OK);
+ SCReturnStruct(APP_LAYER_OK);
} else if (input == NULL || input_len == 0) {
- SCReturnInt(APP_LAYER_ERROR);
+ SCReturnStruct(APP_LAYER_ERROR);
}
if (direction == 0)
return APP_LAYER_OK;
}
-static int SSLParseClientRecord(Flow *f, void *alstate, AppLayerParserState *pstate,
+static AppLayerResult SSLParseClientRecord(Flow *f, void *alstate, AppLayerParserState *pstate,
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 int SSLParseServerRecord(Flow *f, void *alstate, AppLayerParserState *pstate,
+static AppLayerResult SSLParseServerRecord(Flow *f, void *alstate, AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
{
return ALPROTO_UNKNOWN;
}
-static int TemplateParseRequest(Flow *f, void *statev,
+static AppLayerResult TemplateParseRequest(Flow *f, void *statev,
AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
{
/* Likely connection closed, we can just return here. */
if ((input == NULL || input_len == 0) &&
AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
- return 0;
+ SCReturnStruct(APP_LAYER_OK);
}
/* Probably don't want to create a transaction in this case
* either. */
if (input == NULL || input_len == 0) {
- return 0;
+ SCReturnStruct(APP_LAYER_OK);
}
/* Normally you would parse out data here and store it in the
}
end:
- return 0;
+ SCReturnStruct(APP_LAYER_OK);
}
-static int TemplateParseResponse(Flow *f, void *statev, AppLayerParserState *pstate,
+static AppLayerResult TemplateParseResponse(Flow *f, void *statev, AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len, void *local_data,
const uint8_t flags)
{
/* Likely connection closed, we can just return here. */
if ((input == NULL || input_len == 0) &&
AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
- return 0;
+ SCReturnStruct(APP_LAYER_OK);
}
/* Probably don't want to create a transaction in this case
* either. */
if (input == NULL || input_len == 0) {
- return 0;
+ SCReturnStruct(APP_LAYER_OK);
}
/* Look up the existing transaction for this response. In the case
tx->response_done = 1;
end:
- return 0;
+ SCReturnStruct(APP_LAYER_OK);
}
static uint64_t TemplateGetTxCnt(void *statev)
return ALPROTO_UNKNOWN;
}
-static int TFTPParseRequest(Flow *f, void *state,
+static AppLayerResult TFTPParseRequest(Flow *f, void *state,
AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags)
{
/* Likely connection closed, we can just return here. */
if ((input == NULL || input_len == 0) &&
AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
- return 0;
+ SCReturnStruct(APP_LAYER_OK);
}
/* Probably don't want to create a transaction in this case
* either. */
if (input == NULL || input_len == 0) {
- return 0;
+ SCReturnStruct(APP_LAYER_OK);
}
- return rs_tftp_request(state, input, input_len);
+ int res = rs_tftp_request(state, input, input_len);
+ if (res < 0) {
+ SCReturnStruct(APP_LAYER_ERROR);
+ }
+ SCReturnStruct(APP_LAYER_OK);
}
/**
* \brief Response parsing is not implemented
*/
-static int TFTPParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
+static AppLayerResult TFTPParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len, void *local_data,
const uint8_t flags)
{
- return 0;
+ SCReturnStruct(APP_LAYER_OK);
}
static uint64_t TFTPGetTxCnt(void *state)
#define SCReturnBool(x) return x
+#define SCReturnStruct(x) return x
+
/* Please use it only for debugging purposes */
#else
return x; \
} while(0)
+#define SCReturnStruct(x) do { \
+ if (sc_log_global_log_level >= SC_LOG_DEBUG) { \
+ SCLogDebug("Returning: ... <<"); \
+ SCLogCheckFDFilterExit(__FUNCTION__); \
+ } \
+ return x; \
+ } while(0)
+
#endif /* DEBUG */
#define FatalError(x, ...) do { \