]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
nfs: Change fn sign as per rust registration requirement
authorShivani Bhardwaj <shivanib134@gmail.com>
Fri, 21 May 2021 10:01:16 +0000 (15:31 +0530)
committerShivani Bhardwaj <shivanib134@gmail.com>
Thu, 5 Aug 2021 15:33:36 +0000 (21:03 +0530)
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.

rust/src/nfs/nfs.rs
src/app-layer-nfs-tcp.c
src/app-layer-nfs-udp.c

index 5bbf8c82e44ba334899465b7bf676e76c1acfa9d..98aa5cf5a4e52b9c2016cd595a2e1040f255696e 100644 (file)
@@ -39,6 +39,7 @@ use crate::nfs::nfs3_records::*;
 
 pub static mut SURICATA_NFS_FILE_CONFIG: Option<&'static SuricataFileContext> = None;
 
+static mut ALPROTO_NFS: AppProto = ALPROTO_UNKNOWN;
 /*
  * 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.
 #[no_mangle]
-pub extern "C" fn rs_nfs_parse_request(flow: &mut Flow,
-                                       state: &mut NFSState,
+pub extern "C" fn rs_nfs_parse_request(flow: *const Flow,
+                                       state: *mut std::os::raw::c_void,
                                        _pstate: *mut std::os::raw::c_void,
                                        input: *const u8,
                                        input_len: u32,
-                                       _data: *mut std::os::raw::c_void)
-                                       -> AppLayerResult
+                                       _data: *const std::os::raw::c_void,
+                                       _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)};
     SCLogDebug!("parsing {} bytes of request data", input_len);
 
@@ -1412,14 +1416,17 @@ pub extern "C" fn rs_nfs_parse_request_tcp_gap(
 }
 
 #[no_mangle]
-pub extern "C" fn rs_nfs_parse_response(flow: &mut Flow,
-                                        state: &mut NFSState,
+pub extern "C" fn rs_nfs_parse_response(flow: *const Flow,
+                                        state: *mut std::os::raw::c_void,
                                         _pstate: *mut std::os::raw::c_void,
                                         input: *const u8,
                                         input_len: u32,
-                                        _data: *mut std::os::raw::c_void)
-                                        -> AppLayerResult
+                                        _data: *const std::os::raw::c_void,
+                                        _flags: u8,
+                                        ) -> AppLayerResult
 {
+    let state = cast_pointer!(state, NFSState);
+    let flow = cast_pointer!(flow, Flow);
     SCLogDebug!("parsing {} bytes of response data", input_len);
     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.
 #[no_mangle]
-pub extern "C" fn rs_nfs_parse_request_udp(_flow: *mut Flow,
-                                       state: &mut NFSState,
+pub extern "C" fn rs_nfs_parse_request_udp(_f: *const Flow,
+                                       state: *mut std::os::raw::c_void,
                                        _pstate: *mut std::os::raw::c_void,
                                        input: *const u8,
                                        input_len: u32,
-                                       _data: *mut std::os::raw::c_void)
-                                       -> AppLayerResult
+                                       _data: *const std::os::raw::c_void,
+                                       _flags: u8) -> AppLayerResult
 {
+    let state = cast_pointer!(state, NFSState);
+
     let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
     SCLogDebug!("parsing {} bytes of request data", input_len);
     state.parse_udp_ts(buf)
 }
 
 #[no_mangle]
-pub extern "C" fn rs_nfs_parse_response_udp(_flow: *mut Flow,
-                                        state: &mut NFSState,
+pub extern "C" fn rs_nfs_parse_response_udp(_f: *const Flow,
+                                        state: *mut std::os::raw::c_void,
                                         _pstate: *mut std::os::raw::c_void,
                                         input: *const u8,
                                         input_len: u32,
-                                        _data: *mut std::os::raw::c_void)
-                                        -> AppLayerResult
+                                        _data: *const std::os::raw::c_void,
+                                        _flags: u8) -> AppLayerResult
 {
+    let state = cast_pointer!(state, NFSState);
+
     SCLogDebug!("parsing {} bytes of response data", input_len);
     let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
     state.parse_udp_tc(buf)
 }
 
 #[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
 {
+    let state = cast_pointer!(state, NFSState);
     SCLogDebug!("rs_nfs_state_get_tx_count: returning {}", state.tx_id);
     return state.tx_id;
 }
 
 #[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)
-                                      -> *mut NFSTransaction
+                                      -> *mut std::os::raw::c_void
 {
+    let state = cast_pointer!(state, NFSState);
     match state.get_tx_by_id(tx_id) {
         Some(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
 #[no_mangle]
 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,
+                                      _max_tx_id: u64,
                                       istate: &mut u64)
                                       -> applayer::AppLayerGetTxIterTuple
 {
+    let state = cast_pointer!(state, NFSState);
     match state.get_tx_iterator(min_tx_id, istate) {
         Some((tx, out_tx_id, has_next)) => {
             let c_tx = unsafe { transmute(tx) };
@@ -1509,17 +1526,19 @@ pub extern "C" fn rs_nfs_state_get_tx_iterator(
 }
 
 #[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)
 {
+    let state = cast_pointer!(state, NFSState);
     state.free_tx(tx_id);
 }
 
 #[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)
-                                                  -> u8
+                                                  -> std::os::raw::c_int
 {
+    let tx = cast_pointer!(tx, NFSTransaction);
     if direction == STREAM_TOSERVER && tx.request_done {
         //SCLogNotice!("TOSERVER progress 1");
         return 1;
@@ -1543,17 +1562,20 @@ pub extern "C" fn rs_nfs_get_tx_data(
 
 #[no_mangle]
 pub extern "C" fn rs_nfs_state_set_tx_detect_state(
-    tx: &mut NFSTransaction,
-    de_state: &mut DetectEngineState)
+    tx: *mut std::os::raw::c_void,
+    de_state: &mut DetectEngineState) -> i32
 {
+    let tx = cast_pointer!(tx, NFSTransaction);
     tx.de_state = Some(de_state);
+    0
 }
 
 #[no_mangle]
 pub extern "C" fn rs_nfs_state_get_tx_detect_state(
-    tx: &mut NFSTransaction)
+    tx: *mut std::os::raw::c_void)
     -> *mut DetectEngineState
 {
+    let tx = cast_pointer!(tx, NFSTransaction);
     match tx.de_state {
         Some(ds) => {
             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
     }
 }
+
+
 #[no_mangle]
 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_type: *mut AppLayerEventType)
-                                              -> i8
+                                              -> std::os::raw::c_int
 {
     if event_name == std::ptr::null() {
         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 {
         match parse_rpc_reply(i) {
             Ok((_, ref rpc)) => {
@@ -1734,7 +1758,7 @@ pub fn nfs_probe(i: &[u8], direction: u8) -> i8 {
                    rpc.program == 100003 &&
                    rpc.procedure <= NFSPROC3_COMMIT
                 {
-                    return rpc_auth_type_known(rpc.creds_flavor);
+                    return rpc_auth_type_known(rpc.creds_flavor) as i32;
                 } else {
                     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 {
         match parse_rpc_udp_reply(i) {
             Ok((_, ref rpc)) => {
@@ -1786,8 +1810,9 @@ pub fn nfs_probe_udp(i: &[u8], direction: u8) -> i8 {
 /// MIDSTREAM
 #[no_mangle]
 pub extern "C" fn rs_nfs_probe_ms(
+        _flow: *const Flow,
         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);
     SCLogDebug!("rs_nfs_probe_ms: probing direction {:02x}", direction);
@@ -1799,57 +1824,83 @@ pub extern "C" fn rs_nfs_probe_ms(
             } else {
                 SCLogDebug!("nfs_probe_dir said STREAM_TOCLIENT");
             }
-            let r = nfs_probe(slice, adirection);
-            if r == 1 {
-                SCLogDebug!("nfs_probe success: dir {:02x} adir {:02x}", direction, adirection);
-                if (direction & (STREAM_TOSERVER|STREAM_TOCLIENT)) != adirection {
-                    unsafe { *rdir = adirection; }
-                }
-                return 1;
+            match nfs_probe(slice, adirection) {
+                1 => {
+                    SCLogDebug!("nfs_probe success: dir {:02x} adir {:02x}", direction, adirection);
+                    if (direction & (STREAM_TOSERVER|STREAM_TOCLIENT)) != adirection {
+                        unsafe { *rdir = adirection; }
+                    }
+                    unsafe { ALPROTO_NFS }
+                },
+                0 => { ALPROTO_UNKNOWN },
+                _ => { unsafe { ALPROTO_FAILED } },
             }
-            return r;
         },
         0 => {
-            return 0;
+            ALPROTO_UNKNOWN
         },
         _ => {
-            return -1;
+            unsafe { ALPROTO_FAILED }
         }
     }
 }
 
 #[no_mangle]
-pub extern "C" fn rs_nfs_probe(direction: u8,
-        input: *const u8, len: u32)
-    -> i8
+pub extern "C" fn rs_nfs_probe(_f: *const Flow,
+                               direction: u8,
+                               input: *const u8,
+                               len: u32,
+                               _rdir: *mut u8)
+    -> AppProto
 {
     let slice: &[u8] = build_slice!(input, len as usize);
     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
 #[no_mangle]
-pub extern "C" fn rs_nfs_probe_udp_ts(input: *const u8, len: u32)
-                               -> i8
+pub extern "C" fn rs_nfs_probe_udp_ts(_f: *const Flow,
+                               _direction: u8,
+                               input: *const u8,
+                               len: u32,
+                               _rdir: *mut u8)
+    -> AppProto
 {
     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
 #[no_mangle]
-pub extern "C" fn rs_nfs_probe_udp_tc(input: *const u8, len: u32)
-                               -> i8
+pub extern "C" fn rs_nfs_probe_udp_tc(_f: *const Flow,
+                               _direction: u8,
+                               input: *const u8,
+                               len: u32,
+                               _rdir: *mut u8)
+    -> AppProto
 {
     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]
-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"); };
-    let parser = unsafe { &mut *ptr };
+    let ptr = cast_pointer!(ptr, NFSState);
+    let parser = &mut *ptr;
     parser.getfiles(direction)
 }
 #[no_mangle]
@@ -1859,3 +1910,4 @@ pub extern "C" fn rs_nfs_setfileflags(direction: u8, ptr: *mut NFSState, flags:
     SCLogDebug!("direction {} flags {}", direction, flags);
     parser.setfileflags(direction, flags)
 }
+
index d921db5f98e05adce2fc8956f0a04be287da95d7..8599e04922878dca91cb59dc672c8b9b8ad2c9ec 100644 (file)
@@ -100,7 +100,7 @@ static AppProto NFSTCPProbingParserMidstream(Flow *f,
         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) {
         return ALPROTO_NFS;
     } else if (r == -1) {
@@ -126,7 +126,7 @@ static AppProto NFSTCPProbingParser(Flow *f,
         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) {
         return ALPROTO_NFS;
     } 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);
         SCReturnStruct(res);
     } else {
-        AppLayerResult res = rs_nfs_parse_request(f, state, pstate,
-                input, input_len, local_data);
+        AppLayerResult res =
+                rs_nfs_parse_request(f, state, pstate, input, input_len, local_data, flags);
         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);
         SCReturnStruct(res);
     } else {
-        AppLayerResult res = rs_nfs_parse_response(f, state, pstate,
-                input, input_len, local_data);
+        AppLayerResult res =
+                rs_nfs_parse_response(f, state, pstate, input, input_len, local_data, flags);
         SCReturnStruct(res);
     }
 }
@@ -186,7 +186,8 @@ static AppLayerGetTxIterTuple RustNFSTCPGetTxIterator(
         void *alstate, uint64_t min_tx_id, uint64_t max_tx_id,
         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)
 {
-    return rs_nfs_getfiles(direction, state);
+    return rs_nfs_getfiles(state, direction);
 }
 
 static StreamingBufferConfig sbcfg = STREAMING_BUFFER_CONFIG_INITIALIZER;
index 209de497b320e1d3817eaac37eef3fad2eaeb441..88a72b8579508fc53af3586d54fdb024912a3f06 100644 (file)
@@ -120,9 +120,9 @@ static AppProto NFSProbingParser(Flow *f, uint8_t direction,
 
     int8_t r = 0;
     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
-        r = rs_nfs_probe_udp_tc(input, input_len);
+        r = rs_nfs_probe_udp_tc(f, direction, input, input_len, rdir);
 
     if (r == 1) {
         SCLogDebug("nfs");
@@ -143,8 +143,8 @@ static AppLayerResult NFSParseRequest(Flow *f, void *state,
     uint16_t file_flags = FileFlowToFlags(f, STREAM_TOSERVER);
     rs_nfs_setfileflags(0, state, file_flags);
 
-    AppLayerResult res = rs_nfs_parse_request_udp(f, state, pstate,
-            input, input_len, local_data);
+    AppLayerResult res =
+            rs_nfs_parse_request_udp(f, state, pstate, input, input_len, local_data, flags);
     SCReturnStruct(res);
 }
 
@@ -155,8 +155,8 @@ static AppLayerResult NFSParseResponse(Flow *f, void *state, AppLayerParserState
     uint16_t file_flags = FileFlowToFlags(f, STREAM_TOCLIENT);
     rs_nfs_setfileflags(1, state, file_flags);
 
-    AppLayerResult res = rs_nfs_parse_response_udp(f, state, pstate,
-            input, input_len, local_data);
+    AppLayerResult res =
+            rs_nfs_parse_response_udp(f, state, pstate, input, input_len, local_data, flags);
     SCReturnStruct(res);
 }
 
@@ -175,7 +175,8 @@ static AppLayerGetTxIterTuple RustNFSGetTxIterator(
         void *alstate, uint64_t min_tx_id, uint64_t max_tx_id,
         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)
 {
-    return rs_nfs_getfiles(direction, state);
+    return rs_nfs_getfiles(state, direction);
 }
 
 static StreamingBufferConfig sbcfg = STREAMING_BUFFER_CONFIG_INITIALIZER;