use crate::log::*;
use crate::applayer;
use crate::applayer::LoggerFlags;
+use crate::parser::AppLayerResult;
use crate::core::*;
use crate::filetracker::*;
use crate::filecontainer::*;
}
/// complete request record
- fn process_request_record<'b>(&mut self, r: &RpcPacket<'b>) -> u32 {
+ fn process_request_record<'b>(&mut self, r: &RpcPacket<'b>) {
SCLogDebug!("REQUEST {} procedure {} ({}) blob size {}",
r.hdr.xid, r.procedure, self.requestmap.len(), r.prog_data.len());
2 => {
self.process_request_record_v2(r)
},
- _ => { 0 },
+ _ => { },
}
}
match xidmap.progver {
2 => {
SCLogDebug!("NFSv2 reply record");
- return self.process_reply_record_v2(r, &xidmap);
+ self.process_reply_record_v2(r, &xidmap);
+ return 0;
},
3 => {
SCLogDebug!("NFSv3 reply record");
- return self.process_reply_record_v3(r, &mut xidmap);
+ self.process_reply_record_v3(r, &mut xidmap);
+ return 0;
},
4 => {
SCLogDebug!("NFSv4 reply record");
- return self.process_reply_record_v4(r, &mut xidmap);
+ self.process_reply_record_v4(r, &mut xidmap);
+ return 0;
},
_ => {
SCLogDebug!("Invalid NFS version");
}
}
- pub fn parse_tcp_data_ts_gap<'b>(&mut self, gap_size: u32) -> u32 {
+ pub fn parse_tcp_data_ts_gap<'b>(&mut self, gap_size: u32) -> AppLayerResult {
SCLogDebug!("parse_tcp_data_ts_gap ({})", gap_size);
if self.tcp_buffer_ts.len() > 0 {
self.tcp_buffer_ts.clear();
let consumed = self.filetracker_update(STREAM_TOSERVER, &gap, gap_size);
if consumed > gap_size {
SCLogDebug!("consumed more than GAP size: {} > {}", consumed, gap_size);
- return 0;
+ return AppLayerResult::ok();
}
self.ts_ssn_gap = true;
self.ts_gap = true;
SCLogDebug!("parse_tcp_data_ts_gap ({}) done", gap_size);
- return 0
+ return AppLayerResult::ok();
}
- pub fn parse_tcp_data_tc_gap<'b>(&mut self, gap_size: u32) -> u32 {
+ pub fn parse_tcp_data_tc_gap<'b>(&mut self, gap_size: u32) -> AppLayerResult {
SCLogDebug!("parse_tcp_data_tc_gap ({})", gap_size);
if self.tcp_buffer_tc.len() > 0 {
self.tcp_buffer_tc.clear();
let consumed = self.filetracker_update(STREAM_TOCLIENT, &gap, gap_size);
if consumed > gap_size {
SCLogDebug!("consumed more than GAP size: {} > {}", consumed, gap_size);
- return 0;
+ return AppLayerResult::ok();
}
self.tc_ssn_gap = true;
self.tc_gap = true;
SCLogDebug!("parse_tcp_data_tc_gap ({}) done", gap_size);
- return 0
+ return AppLayerResult::ok();
}
/// Parsing function, handling TCP chunks fragmentation
- pub fn parse_tcp_data_ts<'b>(&mut self, i: &'b[u8]) -> u32 {
+ pub fn parse_tcp_data_ts<'b>(&mut self, i: &'b[u8]) -> AppLayerResult {
let mut v : Vec<u8>;
- let mut status = 0;
SCLogDebug!("parse_tcp_data_ts ({})",i.len());
//SCLogDebug!("{:?}",i);
// Check if TCP data is being defragmented
if self.tcp_buffer_ts.len() + i.len() > 1000000 {
SCLogDebug!("parse_tcp_data_ts: TS buffer exploded {} {}",
self.tcp_buffer_ts.len(), i.len());
- return 1;
+ return AppLayerResult::err();
};
v.extend_from_slice(i);
v.as_slice()
let mut cur_i = tcp_buffer;
if cur_i.len() > 1000000 {
SCLogDebug!("BUG buffer exploded: {}", cur_i.len());
+ return AppLayerResult::err();
}
// take care of in progress file chunk transfers
// and skip buffer beyond it
let consumed = self.filetracker_update(STREAM_TOSERVER, cur_i, 0);
if consumed > 0 {
- if consumed > cur_i.len() as u32 { return 1; }
+ if consumed > cur_i.len() as u32 {
+ return AppLayerResult::err();
+ }
cur_i = &cur_i[consumed as usize..];
}
if self.ts_gap {
0 => {
SCLogDebug!("incomplete, queue and retry with the next block (input {}). Looped {} times.", cur_i.len(), cnt);
self.tcp_buffer_tc.extend_from_slice(cur_i);
- return 0;
+ return AppLayerResult::ok();
},
-1 => {
cur_i = &cur_i[1..];
SCLogDebug!("all post-GAP data in this chunk was bad. Looped {} times.", cnt);
}
},
- _ => { return 1; },
+ _ => {
+ return AppLayerResult::err();
+ },
}
}
SCLogDebug!("TS GAP handling done (input {})", cur_i.len());
match parse_nfs3_request_write(rpc_record.prog_data) {
Ok((_, ref nfs_request_write)) => {
// deal with the partial nfs write data
- status |= self.process_partial_write_request_record(rpc_record, nfs_request_write);
+ self.process_partial_write_request_record(rpc_record, nfs_request_write);
cur_i = remaining; // progress input past parsed record
},
_ => {
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
- return 1;
+ return AppLayerResult::err();
},
}
}
match parse_rpc(&cur_i[..rec_size]) {
Ok((_, ref rpc_record)) => {
cur_i = &cur_i[rec_size..];
- status |= self.process_request_record(rpc_record);
+ self.process_request_record(rpc_record);
},
Err(nom::Err::Incomplete(_)) => {
cur_i = &cur_i[rec_size..]; // progress input past parsed record
// so if we got incomplete anyway it's the data that is
// bad.
self.set_event(NFSEvent::MalformedData);
-
- status = 0;
},
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
- return 1;
+ return AppLayerResult::err();
},
}
},
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
- return 1;
+ return AppLayerResult::err();
},
}
};
self.post_gap_housekeeping_for_files();
}
- status
+ AppLayerResult::ok()
}
/// Parsing function, handling TCP chunks fragmentation
- pub fn parse_tcp_data_tc<'b>(&mut self, i: &'b[u8]) -> u32 {
+ pub fn parse_tcp_data_tc<'b>(&mut self, i: &'b[u8]) -> AppLayerResult {
let mut v : Vec<u8>;
- let mut status = 0;
SCLogDebug!("parse_tcp_data_tc ({})",i.len());
//SCLogDebug!("{:?}",i);
// Check if TCP data is being defragmented
// sanity check vector length to avoid memory exhaustion
if self.tcp_buffer_tc.len() + i.len() > 100000 {
SCLogDebug!("TC buffer exploded");
- return 1;
+ return AppLayerResult::err();
};
v.extend_from_slice(i);
// and skip buffer beyond it
let consumed = self.filetracker_update(STREAM_TOCLIENT, cur_i, 0);
if consumed > 0 {
- if consumed > cur_i.len() as u32 { return 1; }
+ if consumed > cur_i.len() as u32 {
+ return AppLayerResult::err();
+ }
cur_i = &cur_i[consumed as usize..];
}
if self.tc_gap {
0 => {
SCLogDebug!("incomplete, queue and retry with the next block (input {}). Looped {} times.", cur_i.len(), cnt);
self.tcp_buffer_tc.extend_from_slice(cur_i);
- return 0;
+ return AppLayerResult::ok();
},
-1 => {
cur_i = &cur_i[1..];
SCLogDebug!("all post-GAP data in this chunk was bad. Looped {} times.", cnt);
}
},
- _ => { return 1; },
+ _ => {
+ return AppLayerResult::err();
+ }
}
}
SCLogDebug!("TC GAP handling done (input {})", cur_i.len());
match parse_nfs3_reply_read(rpc_record.prog_data) {
Ok((_, ref nfs_reply_read)) => {
// deal with the partial nfs read data
- status |= self.process_partial_read_reply_record(rpc_record, nfs_reply_read);
+ self.process_partial_read_reply_record(rpc_record, nfs_reply_read);
cur_i = remaining; // progress input past parsed record
},
Err(nom::Err::Incomplete(_)) => {
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
- return 1;
+ return AppLayerResult::err();
}
}
},
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
- return 1;
+ return AppLayerResult::err();
}
}
}
match parse_rpc_reply(&cur_i[..rec_size]) {
Ok((_, ref rpc_record)) => {
cur_i = &cur_i[rec_size..]; // progress input past parsed record
- status |= self.process_reply_record(rpc_record);
+ self.process_reply_record(rpc_record);
},
Err(nom::Err::Incomplete(_)) => {
cur_i = &cur_i[rec_size..]; // progress input past parsed record
// so if we got incomplete anyway it's the data that is
// bad.
self.set_event(NFSEvent::MalformedData);
-
- status = 0;
},
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
- return 1;
+ return AppLayerResult::err();
}
}
},
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
- return 1;
+ return AppLayerResult::err();
},
}
};
if self.check_post_gap_file_txs {
self.post_gap_housekeeping_for_files();
}
- status
+ AppLayerResult::ok()
}
/// Parsing function
- pub fn parse_udp_ts<'b>(&mut self, input: &'b[u8]) -> u32 {
- let mut status = 0;
+ pub fn parse_udp_ts<'b>(&mut self, input: &'b[u8]) -> AppLayerResult {
SCLogDebug!("parse_udp_ts ({})", input.len());
if input.len() > 0 {
match parse_rpc_udp_request(input) {
self.is_udp = true;
match rpc_record.progver {
3 => {
- status |= self.process_request_record(rpc_record);
+ self.process_request_record(rpc_record);
},
2 => {
- status |= self.process_request_record_v2(rpc_record);
+ self.process_request_record_v2(rpc_record);
},
- _ => { status = 0; },
+ _ => { },
}
},
Err(nom::Err::Incomplete(_)) => {
},
Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => { SCLogDebug!("Parsing failed: {:?}", _e); }
+ Err(nom::Err::Failure(_e)) => {
+ SCLogDebug!("Parsing failed: {:?}", _e);
+ }
}
}
- SCLogDebug!("status {}", status);
- status
+ AppLayerResult::ok()
}
/// Parsing function
- pub fn parse_udp_tc<'b>(&mut self, input: &'b[u8]) -> u32 {
- let mut status = 0;
+ pub fn parse_udp_tc<'b>(&mut self, input: &'b[u8]) -> AppLayerResult {
SCLogDebug!("parse_udp_tc ({})", input.len());
if input.len() > 0 {
match parse_rpc_udp_reply(input) {
Ok((_, ref rpc_record)) => {
self.is_udp = true;
- status |= self.process_reply_record(rpc_record);
+ self.process_reply_record(rpc_record);
},
Err(nom::Err::Incomplete(_)) => {
},
Err(nom::Err::Error(_e)) |
- Err(nom::Err::Failure(_e)) => { SCLogDebug!("Parsing failed: {:?}", _e); }
+ Err(nom::Err::Failure(_e)) => {
+ SCLogDebug!("Parsing failed: {:?}", _e);
+ }
}
- };
- status
+ }
+ AppLayerResult::ok()
}
+
fn getfiles(&mut self, direction: u8) -> * mut FileContainer {
//SCLogDebug!("direction: {}", direction);
if direction == STREAM_TOCLIENT {
input: *const u8,
input_len: u32,
_data: *mut std::os::raw::c_void)
- -> i8
+ -> AppLayerResult
{
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
SCLogDebug!("parsing {} bytes of request data", input_len);
state.ts = flow.get_last_time().as_secs();
- if state.parse_tcp_data_ts(buf) == 0 {
- 0
- } else {
- -1
- }
+ state.parse_tcp_data_ts(buf)
}
#[no_mangle]
pub extern "C" fn rs_nfs_parse_request_tcp_gap(
state: &mut NFSState,
input_len: u32)
- -> i8
+ -> AppLayerResult
{
- if state.parse_tcp_data_ts_gap(input_len as u32) == 0 {
- return 0;
- }
- return -1;
+ state.parse_tcp_data_ts_gap(input_len as u32)
}
#[no_mangle]
input: *const u8,
input_len: u32,
_data: *mut std::os::raw::c_void)
- -> i8
+ -> AppLayerResult
{
SCLogDebug!("parsing {} bytes of response data", input_len);
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
state.ts = flow.get_last_time().as_secs();
- if state.parse_tcp_data_tc(buf) == 0 {
- 0
- } else {
- -1
- }
+ state.parse_tcp_data_tc(buf)
}
#[no_mangle]
pub extern "C" fn rs_nfs_parse_response_tcp_gap(
state: &mut NFSState,
input_len: u32)
- -> i8
+ -> AppLayerResult
{
- if state.parse_tcp_data_tc_gap(input_len as u32) == 0 {
- return 0;
- }
- return -1;
+ state.parse_tcp_data_tc_gap(input_len as u32)
}
/// C binding parse a DNS request. Returns 1 on success, -1 on failure.
input: *const u8,
input_len: u32,
_data: *mut std::os::raw::c_void)
- -> i8
+ -> AppLayerResult
{
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
SCLogDebug!("parsing {} bytes of request data", input_len);
-
- if state.parse_udp_ts(buf) == 0 {
- 0
- } else {
- -1
- }
+ state.parse_udp_ts(buf)
}
#[no_mangle]
input: *const u8,
input_len: u32,
_data: *mut std::os::raw::c_void)
- -> i8
+ -> AppLayerResult
{
SCLogDebug!("parsing {} bytes of response data", input_len);
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
-
- if state.parse_udp_tc(buf) == 0 {
- 0
- } else {
- -1
- }
+ state.parse_udp_tc(buf)
}
#[no_mangle]