nfs: implement midstream reverse flow support

Register special midstream version of protocol detection that
can indicate the flow is the wrong direction based on the record
properties.
pull/3765/head
Victor Julien 7 years ago
parent bb78d48c0a
commit 822a434036

@ -1794,18 +1794,26 @@ pub fn nfs_probe_udp(i: &[u8], direction: u8) -> i8 {
/// MIDSTREAM
#[no_mangle]
pub extern "C" fn rs_nfs_probe_ms(input: *const libc::uint8_t,
pub extern "C" fn rs_nfs_probe_ms(
direction: libc::uint8_t, input: *const libc::uint8_t,
len: libc::uint32_t, rdir: *mut u8) -> libc::int8_t
{
let slice: &[u8] = unsafe {
std::slice::from_raw_parts(input as *mut u8, len as usize)
};
let mut direction : u8 = 0;
match nfs_probe_dir(slice, &mut direction) {
let slice: &[u8] = build_slice!(input, len as usize);
SCLogDebug!("rs_nfs_probe_ms: probing direction {:02x}", direction);
let mut adirection : u8 = 0;
match nfs_probe_dir(slice, &mut adirection) {
1 => {
let r = nfs_probe(slice, direction);
if adirection == STREAM_TOSERVER {
SCLogDebug!("nfs_probe_dir said STREAM_TOSERVER");
} else {
SCLogDebug!("nfs_probe_dir said STREAM_TOCLIENT");
}
let r = nfs_probe(slice, adirection);
if r == 1 {
unsafe { *rdir = direction; }
SCLogDebug!("nfs_probe success: dir {:02x} adir {:02x}", direction, adirection);
if (direction & (STREAM_TOSERVER|STREAM_TOCLIENT)) != adirection {
unsafe { *rdir = adirection; }
}
return 1;
}
return r;
@ -1819,26 +1827,16 @@ pub extern "C" fn rs_nfs_probe_ms(input: *const libc::uint8_t,
}
}
/// TOSERVER probe function
#[no_mangle]
pub extern "C" fn rs_nfs_probe_ts(input: *const libc::uint8_t, len: libc::uint32_t)
-> libc::int8_t
{
let slice: &[u8] = unsafe {
std::slice::from_raw_parts(input as *mut u8, len as usize)
};
return nfs_probe(slice, STREAM_TOSERVER);
}
/// TOCLIENT probe function
#[no_mangle]
pub extern "C" fn rs_nfs_probe_tc(input: *const libc::uint8_t, len: libc::uint32_t)
-> libc::int8_t
pub extern "C" fn rs_nfs_probe(direction: libc::uint8_t,
input: *const libc::uint8_t, len: libc::uint32_t)
-> libc::int8_t
{
let slice: &[u8] = unsafe {
std::slice::from_raw_parts(input as *mut u8, len as usize)
};
return nfs_probe(slice, STREAM_TOCLIENT);
SCLogDebug!("rs_nfs_probe: running probe");
return nfs_probe(slice, direction);
}
/// TOSERVER probe function

@ -112,7 +112,7 @@ static AppLayerDecoderEvents *NFSTCPGetEvents(void *state, uint64_t id)
* \retval ALPROTO_NFS if it looks like echo, otherwise
* ALPROTO_UNKNOWN.
*/
static AppProto NFSTCPProbingParser(Flow *f,
static AppProto NFSTCPProbingParserMidstream(Flow *f,
uint8_t direction,
uint8_t *input, uint32_t input_len,
uint8_t *rdir)
@ -121,12 +121,33 @@ static AppProto NFSTCPProbingParser(Flow *f,
return ALPROTO_UNKNOWN;
}
int8_t r = 0;
if (direction & STREAM_TOSERVER) {
r = rs_nfs_probe_ts(input, input_len);
} else {
r = rs_nfs_probe_tc(input, input_len);
int8_t r = rs_nfs_probe_ms(direction, input, input_len, rdir);
if (r == 1) {
return ALPROTO_NFS;
} else if (r == -1) {
return ALPROTO_FAILED;
}
SCLogDebug("Protocol not detected as ALPROTO_NFS.");
return ALPROTO_UNKNOWN;
}
/**
* \brief Probe the input to see if it looks like echo.
*
* \retval ALPROTO_NFS if it looks like echo, otherwise
* ALPROTO_UNKNOWN.
*/
static AppProto NFSTCPProbingParser(Flow *f,
uint8_t direction,
uint8_t *input, uint32_t input_len,
uint8_t *rdir)
{
if (input_len < NFSTCP_MIN_FRAME_LEN) {
return ALPROTO_UNKNOWN;
}
int8_t r = rs_nfs_probe(direction, input, input_len);
if (r == 1) {
return ALPROTO_NFS;
} else if (r == -1) {
@ -282,10 +303,15 @@ void RegisterNFSTCPParsers(void)
}
else {
int midstream = 0;
ConfGetBool("stream.midstream", &midstream);
ProbingParserFPtr FuncPtr = NFSTCPProbingParser;
if (midstream)
FuncPtr = NFSTCPProbingParserMidstream;
if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_NFS, 0, NFSTCP_MIN_FRAME_LEN,
NFSTCPProbingParser, NFSTCPProbingParser)) {
FuncPtr, FuncPtr)) {
SCLogDebug("No NFSTCP app-layer configuration, enabling NFSTCP"
" detection TCP detection on port %s.",
NFSTCP_DEFAULT_PORT);
@ -293,7 +319,7 @@ void RegisterNFSTCPParsers(void)
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
NFSTCP_DEFAULT_PORT, ALPROTO_NFS, 0,
NFSTCP_MIN_FRAME_LEN, STREAM_TOSERVER,
NFSTCPProbingParser, NFSTCPProbingParser);
FuncPtr, FuncPtr);
}
}

Loading…
Cancel
Save