|
|
|
|
@ -28,6 +28,7 @@ use nom;
|
|
|
|
|
use crate::log::*;
|
|
|
|
|
use crate::applayer;
|
|
|
|
|
use crate::applayer::LoggerFlags;
|
|
|
|
|
use crate::parser::AppLayerResult;
|
|
|
|
|
use crate::core::*;
|
|
|
|
|
use crate::filetracker::*;
|
|
|
|
|
use crate::filecontainer::*;
|
|
|
|
|
@ -589,7 +590,7 @@ impl NFSState {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 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());
|
|
|
|
|
|
|
|
|
|
@ -603,7 +604,7 @@ impl NFSState {
|
|
|
|
|
2 => {
|
|
|
|
|
self.process_request_record_v2(r)
|
|
|
|
|
},
|
|
|
|
|
_ => { 0 },
|
|
|
|
|
_ => { },
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -744,15 +745,18 @@ impl NFSState {
|
|
|
|
|
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");
|
|
|
|
|
@ -1006,7 +1010,7 @@ impl NFSState {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
@ -1015,15 +1019,15 @@ impl NFSState {
|
|
|
|
|
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();
|
|
|
|
|
@ -1032,18 +1036,17 @@ impl NFSState {
|
|
|
|
|
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
|
|
|
|
|
@ -1055,7 +1058,7 @@ impl NFSState {
|
|
|
|
|
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()
|
|
|
|
|
@ -1065,12 +1068,15 @@ impl NFSState {
|
|
|
|
|
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 {
|
|
|
|
|
@ -1088,7 +1094,7 @@ impl NFSState {
|
|
|
|
|
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..];
|
|
|
|
|
@ -1096,7 +1102,9 @@ impl NFSState {
|
|
|
|
|
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());
|
|
|
|
|
@ -1126,7 +1134,7 @@ impl NFSState {
|
|
|
|
|
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
|
|
|
|
|
},
|
|
|
|
|
_ => {
|
|
|
|
|
@ -1145,7 +1153,7 @@ impl NFSState {
|
|
|
|
|
Err(nom::Err::Failure(_e)) => {
|
|
|
|
|
self.set_event(NFSEvent::MalformedData);
|
|
|
|
|
SCLogDebug!("Parsing failed: {:?}", _e);
|
|
|
|
|
return 1;
|
|
|
|
|
return AppLayerResult::err();
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -1159,7 +1167,7 @@ impl NFSState {
|
|
|
|
|
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
|
|
|
|
|
@ -1168,14 +1176,12 @@ impl NFSState {
|
|
|
|
|
// 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();
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
@ -1188,7 +1194,7 @@ impl NFSState {
|
|
|
|
|
Err(nom::Err::Failure(_e)) => {
|
|
|
|
|
self.set_event(NFSEvent::MalformedData);
|
|
|
|
|
SCLogDebug!("Parsing failed: {:?}", _e);
|
|
|
|
|
return 1;
|
|
|
|
|
return AppLayerResult::err();
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
@ -1198,13 +1204,12 @@ impl NFSState {
|
|
|
|
|
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
|
|
|
|
|
@ -1215,7 +1220,7 @@ impl NFSState {
|
|
|
|
|
// 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);
|
|
|
|
|
@ -1233,7 +1238,9 @@ impl NFSState {
|
|
|
|
|
// 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 {
|
|
|
|
|
@ -1251,7 +1258,7 @@ impl NFSState {
|
|
|
|
|
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..];
|
|
|
|
|
@ -1259,7 +1266,9 @@ impl NFSState {
|
|
|
|
|
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());
|
|
|
|
|
@ -1287,7 +1296,7 @@ impl NFSState {
|
|
|
|
|
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(_)) => {
|
|
|
|
|
@ -1297,7 +1306,7 @@ impl NFSState {
|
|
|
|
|
Err(nom::Err::Failure(_e)) => {
|
|
|
|
|
self.set_event(NFSEvent::MalformedData);
|
|
|
|
|
SCLogDebug!("Parsing failed: {:?}", _e);
|
|
|
|
|
return 1;
|
|
|
|
|
return AppLayerResult::err();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
@ -1310,7 +1319,7 @@ impl NFSState {
|
|
|
|
|
Err(nom::Err::Failure(_e)) => {
|
|
|
|
|
self.set_event(NFSEvent::MalformedData);
|
|
|
|
|
SCLogDebug!("Parsing failed: {:?}", _e);
|
|
|
|
|
return 1;
|
|
|
|
|
return AppLayerResult::err();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -1323,7 +1332,7 @@ impl NFSState {
|
|
|
|
|
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
|
|
|
|
|
@ -1332,14 +1341,12 @@ impl NFSState {
|
|
|
|
|
// 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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
@ -1352,7 +1359,7 @@ impl NFSState {
|
|
|
|
|
Err(nom::Err::Failure(_e)) => {
|
|
|
|
|
self.set_event(NFSEvent::MalformedData);
|
|
|
|
|
SCLogDebug!("Parsing failed: {:?}", _e);
|
|
|
|
|
return 1;
|
|
|
|
|
return AppLayerResult::err();
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
@ -1360,11 +1367,10 @@ impl NFSState {
|
|
|
|
|
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) {
|
|
|
|
|
@ -1372,42 +1378,45 @@ impl NFSState {
|
|
|
|
|
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 {
|
|
|
|
|
@ -1453,29 +1462,22 @@ pub extern "C" fn rs_nfs_parse_request(flow: &mut Flow,
|
|
|
|
|
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]
|
|
|
|
|
@ -1485,29 +1487,22 @@ pub extern "C" fn rs_nfs_parse_response(flow: &mut Flow,
|
|
|
|
|
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.
|
|
|
|
|
@ -1518,16 +1513,11 @@ pub extern "C" fn rs_nfs_parse_request_udp(_flow: *mut Flow,
|
|
|
|
|
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]
|
|
|
|
|
@ -1537,16 +1527,11 @@ pub extern "C" fn rs_nfs_parse_response_udp(_flow: *mut Flow,
|
|
|
|
|
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]
|
|
|
|
|
|