nfs: Change fn sign as per rust registration requirement

Registering parsers in Rust requires signatures to be a certain way and
compatible with C. Change signatures of all the functions.
Probe fn has also been changed to return AppProto as required by the new
fn signature.
pull/6285/head
Shivani Bhardwaj 5 years ago
parent e5c948df87
commit de50ac631e

@ -39,6 +39,7 @@ use crate::nfs::nfs3_records::*;
pub static mut SURICATA_NFS_FILE_CONFIG: Option<&'static SuricataFileContext> = None; pub static mut SURICATA_NFS_FILE_CONFIG: Option<&'static SuricataFileContext> = None;
static mut ALPROTO_NFS: AppProto = ALPROTO_UNKNOWN;
/* /*
* Record parsing. * Record parsing.
* *
@ -1387,14 +1388,17 @@ pub extern "C" fn rs_nfs_state_free(state: *mut std::os::raw::c_void) {
/// C binding parse a NFS TCP request. Returns 1 on success, -1 on failure. /// C binding parse a NFS TCP request. Returns 1 on success, -1 on failure.
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_parse_request(flow: &mut Flow, pub extern "C" fn rs_nfs_parse_request(flow: *const Flow,
state: &mut NFSState, state: *mut std::os::raw::c_void,
_pstate: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
input: *const u8, input: *const u8,
input_len: u32, input_len: u32,
_data: *mut std::os::raw::c_void) _data: *const std::os::raw::c_void,
-> AppLayerResult _flags: u8,
) -> AppLayerResult
{ {
let state = cast_pointer!(state, NFSState);
let flow = cast_pointer!(flow, Flow);
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)}; let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
SCLogDebug!("parsing {} bytes of request data", input_len); SCLogDebug!("parsing {} bytes of request data", input_len);
@ -1412,14 +1416,17 @@ pub extern "C" fn rs_nfs_parse_request_tcp_gap(
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_parse_response(flow: &mut Flow, pub extern "C" fn rs_nfs_parse_response(flow: *const Flow,
state: &mut NFSState, state: *mut std::os::raw::c_void,
_pstate: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
input: *const u8, input: *const u8,
input_len: u32, input_len: u32,
_data: *mut std::os::raw::c_void) _data: *const std::os::raw::c_void,
-> AppLayerResult _flags: u8,
) -> AppLayerResult
{ {
let state = cast_pointer!(state, NFSState);
let flow = cast_pointer!(flow, Flow);
SCLogDebug!("parsing {} bytes of response data", input_len); SCLogDebug!("parsing {} bytes of response data", input_len);
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)}; let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
@ -1438,46 +1445,52 @@ pub extern "C" fn rs_nfs_parse_response_tcp_gap(
/// C binding parse a DNS request. Returns 1 on success, -1 on failure. /// C binding parse a DNS request. Returns 1 on success, -1 on failure.
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_parse_request_udp(_flow: *mut Flow, pub extern "C" fn rs_nfs_parse_request_udp(_f: *const Flow,
state: &mut NFSState, state: *mut std::os::raw::c_void,
_pstate: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
input: *const u8, input: *const u8,
input_len: u32, input_len: u32,
_data: *mut std::os::raw::c_void) _data: *const std::os::raw::c_void,
-> AppLayerResult _flags: u8) -> AppLayerResult
{ {
let state = cast_pointer!(state, NFSState);
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)}; let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
SCLogDebug!("parsing {} bytes of request data", input_len); SCLogDebug!("parsing {} bytes of request data", input_len);
state.parse_udp_ts(buf) state.parse_udp_ts(buf)
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_parse_response_udp(_flow: *mut Flow, pub extern "C" fn rs_nfs_parse_response_udp(_f: *const Flow,
state: &mut NFSState, state: *mut std::os::raw::c_void,
_pstate: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
input: *const u8, input: *const u8,
input_len: u32, input_len: u32,
_data: *mut std::os::raw::c_void) _data: *const std::os::raw::c_void,
-> AppLayerResult _flags: u8) -> AppLayerResult
{ {
let state = cast_pointer!(state, NFSState);
SCLogDebug!("parsing {} bytes of response data", input_len); SCLogDebug!("parsing {} bytes of response data", input_len);
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)}; let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
state.parse_udp_tc(buf) state.parse_udp_tc(buf)
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_state_get_tx_count(state: &mut NFSState) pub extern "C" fn rs_nfs_state_get_tx_count(state: *mut std::os::raw::c_void)
-> u64 -> u64
{ {
let state = cast_pointer!(state, NFSState);
SCLogDebug!("rs_nfs_state_get_tx_count: returning {}", state.tx_id); SCLogDebug!("rs_nfs_state_get_tx_count: returning {}", state.tx_id);
return state.tx_id; return state.tx_id;
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_state_get_tx(state: &mut NFSState, pub extern "C" fn rs_nfs_state_get_tx(state: *mut std::os::raw::c_void,
tx_id: u64) tx_id: u64)
-> *mut NFSTransaction -> *mut std::os::raw::c_void
{ {
let state = cast_pointer!(state, NFSState);
match state.get_tx_by_id(tx_id) { match state.get_tx_by_id(tx_id) {
Some(tx) => { Some(tx) => {
return unsafe{transmute(tx)}; return unsafe{transmute(tx)};
@ -1491,11 +1504,15 @@ pub extern "C" fn rs_nfs_state_get_tx(state: &mut NFSState,
// for use with the C API call StateGetTxIterator // for use with the C API call StateGetTxIterator
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_state_get_tx_iterator( pub extern "C" fn rs_nfs_state_get_tx_iterator(
state: &mut NFSState, _ipproto: u8,
_alproto: AppProto,
state: *mut std::os::raw::c_void,
min_tx_id: u64, min_tx_id: u64,
_max_tx_id: u64,
istate: &mut u64) istate: &mut u64)
-> applayer::AppLayerGetTxIterTuple -> applayer::AppLayerGetTxIterTuple
{ {
let state = cast_pointer!(state, NFSState);
match state.get_tx_iterator(min_tx_id, istate) { match state.get_tx_iterator(min_tx_id, istate) {
Some((tx, out_tx_id, has_next)) => { Some((tx, out_tx_id, has_next)) => {
let c_tx = unsafe { transmute(tx) }; let c_tx = unsafe { transmute(tx) };
@ -1509,17 +1526,19 @@ pub extern "C" fn rs_nfs_state_get_tx_iterator(
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_state_tx_free(state: &mut NFSState, pub extern "C" fn rs_nfs_state_tx_free(state: *mut std::os::raw::c_void,
tx_id: u64) tx_id: u64)
{ {
let state = cast_pointer!(state, NFSState);
state.free_tx(tx_id); state.free_tx(tx_id);
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_tx_get_alstate_progress(tx: &mut NFSTransaction, pub extern "C" fn rs_nfs_tx_get_alstate_progress(tx: *mut std::os::raw::c_void,
direction: u8) direction: u8)
-> u8 -> std::os::raw::c_int
{ {
let tx = cast_pointer!(tx, NFSTransaction);
if direction == STREAM_TOSERVER && tx.request_done { if direction == STREAM_TOSERVER && tx.request_done {
//SCLogNotice!("TOSERVER progress 1"); //SCLogNotice!("TOSERVER progress 1");
return 1; return 1;
@ -1543,17 +1562,20 @@ pub extern "C" fn rs_nfs_get_tx_data(
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_state_set_tx_detect_state( pub extern "C" fn rs_nfs_state_set_tx_detect_state(
tx: &mut NFSTransaction, tx: *mut std::os::raw::c_void,
de_state: &mut DetectEngineState) de_state: &mut DetectEngineState) -> i32
{ {
let tx = cast_pointer!(tx, NFSTransaction);
tx.de_state = Some(de_state); tx.de_state = Some(de_state);
0
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_state_get_tx_detect_state( pub extern "C" fn rs_nfs_state_get_tx_detect_state(
tx: &mut NFSTransaction) tx: *mut std::os::raw::c_void)
-> *mut DetectEngineState -> *mut DetectEngineState
{ {
let tx = cast_pointer!(tx, NFSTransaction);
match tx.de_state { match tx.de_state {
Some(ds) => { Some(ds) => {
SCLogDebug!("{}: getting de_state", tx.id); SCLogDebug!("{}: getting de_state", tx.id);
@ -1595,11 +1617,13 @@ pub extern "C" fn rs_nfs_state_get_event_info_by_id(event_id: std::os::raw::c_in
-1 -1
} }
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_state_get_event_info(event_name: *const std::os::raw::c_char, pub extern "C" fn rs_nfs_state_get_event_info(event_name: *const std::os::raw::c_char,
event_id: *mut std::os::raw::c_int, event_id: *mut std::os::raw::c_int,
event_type: *mut AppLayerEventType) event_type: *mut AppLayerEventType)
-> i8 -> std::os::raw::c_int
{ {
if event_name == std::ptr::null() { if event_name == std::ptr::null() {
return -1; return -1;
@ -1693,7 +1717,7 @@ fn nfs_probe_dir(i: &[u8], rdir: *mut u8) -> i8 {
} }
} }
pub fn nfs_probe(i: &[u8], direction: u8) -> i8 { pub fn nfs_probe(i: &[u8], direction: u8) -> i32 {
if direction == STREAM_TOCLIENT { if direction == STREAM_TOCLIENT {
match parse_rpc_reply(i) { match parse_rpc_reply(i) {
Ok((_, ref rpc)) => { Ok((_, ref rpc)) => {
@ -1734,7 +1758,7 @@ pub fn nfs_probe(i: &[u8], direction: u8) -> i8 {
rpc.program == 100003 && rpc.program == 100003 &&
rpc.procedure <= NFSPROC3_COMMIT rpc.procedure <= NFSPROC3_COMMIT
{ {
return rpc_auth_type_known(rpc.creds_flavor); return rpc_auth_type_known(rpc.creds_flavor) as i32;
} else { } else {
return -1; return -1;
} }
@ -1749,7 +1773,7 @@ pub fn nfs_probe(i: &[u8], direction: u8) -> i8 {
} }
} }
pub fn nfs_probe_udp(i: &[u8], direction: u8) -> i8 { pub fn nfs_probe_udp(i: &[u8], direction: u8) -> i32 {
if direction == STREAM_TOCLIENT { if direction == STREAM_TOCLIENT {
match parse_rpc_udp_reply(i) { match parse_rpc_udp_reply(i) {
Ok((_, ref rpc)) => { Ok((_, ref rpc)) => {
@ -1786,8 +1810,9 @@ pub fn nfs_probe_udp(i: &[u8], direction: u8) -> i8 {
/// MIDSTREAM /// MIDSTREAM
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_probe_ms( pub extern "C" fn rs_nfs_probe_ms(
_flow: *const Flow,
direction: u8, input: *const u8, direction: u8, input: *const u8,
len: u32, rdir: *mut u8) -> i8 len: u32, rdir: *mut u8) -> AppProto
{ {
let slice: &[u8] = build_slice!(input, len as usize); let slice: &[u8] = build_slice!(input, len as usize);
SCLogDebug!("rs_nfs_probe_ms: probing direction {:02x}", direction); SCLogDebug!("rs_nfs_probe_ms: probing direction {:02x}", direction);
@ -1799,57 +1824,83 @@ pub extern "C" fn rs_nfs_probe_ms(
} else { } else {
SCLogDebug!("nfs_probe_dir said STREAM_TOCLIENT"); SCLogDebug!("nfs_probe_dir said STREAM_TOCLIENT");
} }
let r = nfs_probe(slice, adirection); match nfs_probe(slice, adirection) {
if r == 1 { 1 => {
SCLogDebug!("nfs_probe success: dir {:02x} adir {:02x}", direction, adirection); SCLogDebug!("nfs_probe success: dir {:02x} adir {:02x}", direction, adirection);
if (direction & (STREAM_TOSERVER|STREAM_TOCLIENT)) != adirection { if (direction & (STREAM_TOSERVER|STREAM_TOCLIENT)) != adirection {
unsafe { *rdir = adirection; } unsafe { *rdir = adirection; }
} }
return 1; unsafe { ALPROTO_NFS }
},
0 => { ALPROTO_UNKNOWN },
_ => { unsafe { ALPROTO_FAILED } },
} }
return r;
}, },
0 => { 0 => {
return 0; ALPROTO_UNKNOWN
}, },
_ => { _ => {
return -1; unsafe { ALPROTO_FAILED }
} }
} }
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_probe(direction: u8, pub extern "C" fn rs_nfs_probe(_f: *const Flow,
input: *const u8, len: u32) direction: u8,
-> i8 input: *const u8,
len: u32,
_rdir: *mut u8)
-> AppProto
{ {
let slice: &[u8] = build_slice!(input, len as usize); let slice: &[u8] = build_slice!(input, len as usize);
SCLogDebug!("rs_nfs_probe: running probe"); SCLogDebug!("rs_nfs_probe: running probe");
return nfs_probe(slice, direction); match nfs_probe(slice, direction) {
1 => { unsafe { ALPROTO_NFS } },
-1 => { unsafe { ALPROTO_FAILED } },
_ => { ALPROTO_UNKNOWN },
}
} }
/// TOSERVER probe function /// TOSERVER probe function
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_probe_udp_ts(input: *const u8, len: u32) pub extern "C" fn rs_nfs_probe_udp_ts(_f: *const Flow,
-> i8 _direction: u8,
input: *const u8,
len: u32,
_rdir: *mut u8)
-> AppProto
{ {
let slice: &[u8] = build_slice!(input, len as usize); let slice: &[u8] = build_slice!(input, len as usize);
return nfs_probe_udp(slice, STREAM_TOSERVER); match nfs_probe_udp(slice, STREAM_TOSERVER) {
1 => { unsafe { ALPROTO_NFS } },
-1 => { unsafe { ALPROTO_FAILED } },
_ => { ALPROTO_UNKNOWN },
}
} }
/// TOCLIENT probe function /// TOCLIENT probe function
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_probe_udp_tc(input: *const u8, len: u32) pub extern "C" fn rs_nfs_probe_udp_tc(_f: *const Flow,
-> i8 _direction: u8,
input: *const u8,
len: u32,
_rdir: *mut u8)
-> AppProto
{ {
let slice: &[u8] = build_slice!(input, len as usize); let slice: &[u8] = build_slice!(input, len as usize);
return nfs_probe_udp(slice, STREAM_TOCLIENT); match nfs_probe_udp(slice, STREAM_TOCLIENT) {
1 => { unsafe { ALPROTO_NFS } },
-1 => { unsafe { ALPROTO_FAILED } },
_ => { ALPROTO_UNKNOWN },
}
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_nfs_getfiles(direction: u8, ptr: *mut NFSState) -> * mut FileContainer { pub extern "C" fn rs_nfs_getfiles(ptr: *mut std::ffi::c_void, direction: u8) -> * mut FileContainer {
if ptr.is_null() { panic!("NULL ptr"); }; if ptr.is_null() { panic!("NULL ptr"); };
let parser = unsafe { &mut *ptr }; let ptr = cast_pointer!(ptr, NFSState);
let parser = &mut *ptr;
parser.getfiles(direction) parser.getfiles(direction)
} }
#[no_mangle] #[no_mangle]
@ -1859,3 +1910,4 @@ pub extern "C" fn rs_nfs_setfileflags(direction: u8, ptr: *mut NFSState, flags:
SCLogDebug!("direction {} flags {}", direction, flags); SCLogDebug!("direction {} flags {}", direction, flags);
parser.setfileflags(direction, flags) parser.setfileflags(direction, flags)
} }

@ -100,7 +100,7 @@ static AppProto NFSTCPProbingParserMidstream(Flow *f,
return ALPROTO_UNKNOWN; return ALPROTO_UNKNOWN;
} }
int8_t r = rs_nfs_probe_ms(direction, input, input_len, rdir); int8_t r = rs_nfs_probe_ms(f, direction, input, input_len, rdir);
if (r == 1) { if (r == 1) {
return ALPROTO_NFS; return ALPROTO_NFS;
} else if (r == -1) { } else if (r == -1) {
@ -126,7 +126,7 @@ static AppProto NFSTCPProbingParser(Flow *f,
return ALPROTO_UNKNOWN; return ALPROTO_UNKNOWN;
} }
int8_t r = rs_nfs_probe(direction, input, input_len); int8_t r = rs_nfs_probe(f, direction, input, input_len, rdir);
if (r == 1) { if (r == 1) {
return ALPROTO_NFS; return ALPROTO_NFS;
} else if (r == -1) { } else if (r == -1) {
@ -148,8 +148,8 @@ static AppLayerResult NFSTCPParseRequest(Flow *f, void *state,
AppLayerResult res = rs_nfs_parse_request_tcp_gap(state, input_len); AppLayerResult res = rs_nfs_parse_request_tcp_gap(state, input_len);
SCReturnStruct(res); SCReturnStruct(res);
} else { } else {
AppLayerResult res = rs_nfs_parse_request(f, state, pstate, AppLayerResult res =
input, input_len, local_data); rs_nfs_parse_request(f, state, pstate, input, input_len, local_data, flags);
SCReturnStruct(res); SCReturnStruct(res);
} }
} }
@ -165,8 +165,8 @@ static AppLayerResult NFSTCPParseResponse(Flow *f, void *state, AppLayerParserSt
AppLayerResult res = rs_nfs_parse_response_tcp_gap(state, input_len); AppLayerResult res = rs_nfs_parse_response_tcp_gap(state, input_len);
SCReturnStruct(res); SCReturnStruct(res);
} else { } else {
AppLayerResult res = rs_nfs_parse_response(f, state, pstate, AppLayerResult res =
input, input_len, local_data); rs_nfs_parse_response(f, state, pstate, input, input_len, local_data, flags);
SCReturnStruct(res); SCReturnStruct(res);
} }
} }
@ -186,7 +186,8 @@ static AppLayerGetTxIterTuple RustNFSTCPGetTxIterator(
void *alstate, uint64_t min_tx_id, uint64_t max_tx_id, void *alstate, uint64_t min_tx_id, uint64_t max_tx_id,
AppLayerGetTxIterState *istate) AppLayerGetTxIterState *istate)
{ {
return rs_nfs_state_get_tx_iterator(alstate, min_tx_id, (uint64_t *)istate); return rs_nfs_state_get_tx_iterator(
ipproto, alproto, alstate, min_tx_id, max_tx_id, (uint64_t *)istate);
} }
/** /**
@ -226,7 +227,7 @@ static int NFSTCPSetTxDetectState(void *vtx, DetectEngineState *s)
static FileContainer *NFSTCPGetFiles(void *state, uint8_t direction) static FileContainer *NFSTCPGetFiles(void *state, uint8_t direction)
{ {
return rs_nfs_getfiles(direction, state); return rs_nfs_getfiles(state, direction);
} }
static StreamingBufferConfig sbcfg = STREAMING_BUFFER_CONFIG_INITIALIZER; static StreamingBufferConfig sbcfg = STREAMING_BUFFER_CONFIG_INITIALIZER;

@ -120,9 +120,9 @@ static AppProto NFSProbingParser(Flow *f, uint8_t direction,
int8_t r = 0; int8_t r = 0;
if (direction & STREAM_TOSERVER) if (direction & STREAM_TOSERVER)
r = rs_nfs_probe_udp_ts(input, input_len); r = rs_nfs_probe_udp_ts(f, direction, input, input_len, rdir);
else else
r = rs_nfs_probe_udp_tc(input, input_len); r = rs_nfs_probe_udp_tc(f, direction, input, input_len, rdir);
if (r == 1) { if (r == 1) {
SCLogDebug("nfs"); SCLogDebug("nfs");
@ -143,8 +143,8 @@ static AppLayerResult NFSParseRequest(Flow *f, void *state,
uint16_t file_flags = FileFlowToFlags(f, STREAM_TOSERVER); uint16_t file_flags = FileFlowToFlags(f, STREAM_TOSERVER);
rs_nfs_setfileflags(0, state, file_flags); rs_nfs_setfileflags(0, state, file_flags);
AppLayerResult res = rs_nfs_parse_request_udp(f, state, pstate, AppLayerResult res =
input, input_len, local_data); rs_nfs_parse_request_udp(f, state, pstate, input, input_len, local_data, flags);
SCReturnStruct(res); SCReturnStruct(res);
} }
@ -155,8 +155,8 @@ static AppLayerResult NFSParseResponse(Flow *f, void *state, AppLayerParserState
uint16_t file_flags = FileFlowToFlags(f, STREAM_TOCLIENT); uint16_t file_flags = FileFlowToFlags(f, STREAM_TOCLIENT);
rs_nfs_setfileflags(1, state, file_flags); rs_nfs_setfileflags(1, state, file_flags);
AppLayerResult res = rs_nfs_parse_response_udp(f, state, pstate, AppLayerResult res =
input, input_len, local_data); rs_nfs_parse_response_udp(f, state, pstate, input, input_len, local_data, flags);
SCReturnStruct(res); SCReturnStruct(res);
} }
@ -175,7 +175,8 @@ static AppLayerGetTxIterTuple RustNFSGetTxIterator(
void *alstate, uint64_t min_tx_id, uint64_t max_tx_id, void *alstate, uint64_t min_tx_id, uint64_t max_tx_id,
AppLayerGetTxIterState *istate) AppLayerGetTxIterState *istate)
{ {
return rs_nfs_state_get_tx_iterator(alstate, min_tx_id, (uint64_t *)istate); return rs_nfs_state_get_tx_iterator(
ipproto, alproto, alstate, min_tx_id, max_tx_id, (uint64_t *)istate);
} }
/** /**
@ -215,7 +216,7 @@ static int NFSSetTxDetectState(void *vtx, DetectEngineState *s)
static FileContainer *NFSGetFiles(void *state, uint8_t direction) static FileContainer *NFSGetFiles(void *state, uint8_t direction)
{ {
return rs_nfs_getfiles(direction, state); return rs_nfs_getfiles(state, direction);
} }
static StreamingBufferConfig sbcfg = STREAMING_BUFFER_CONFIG_INITIALIZER; static StreamingBufferConfig sbcfg = STREAMING_BUFFER_CONFIG_INITIALIZER;

Loading…
Cancel
Save