From 58ac9b0f38bc94d235a78a61dc581604261578cd Mon Sep 17 00:00:00 2001 From: Shivani Bhardwaj Date: Thu, 24 Jun 2021 16:12:55 +0530 Subject: [PATCH] nfs: Add rust registration function Get rid of the C glue code and move registration completely to Rust. --- rust/src/nfs/nfs.rs | 159 +++++++++++++++++++++- src/app-layer-nfs-tcp.c | 292 +--------------------------------------- src/app-layer-nfs-udp.c | 264 +----------------------------------- 3 files changed, 160 insertions(+), 555 deletions(-) diff --git a/rust/src/nfs/nfs.rs b/rust/src/nfs/nfs.rs index acd6a13784..49c022a041 100644 --- a/rust/src/nfs/nfs.rs +++ b/rust/src/nfs/nfs.rs @@ -21,13 +21,14 @@ use std; use std::cmp; use std::mem::transmute; use std::collections::{HashMap}; -use std::ffi::CStr; +use std::ffi::{CStr, CString}; use nom; use crate::applayer; -use crate::applayer::{AppLayerResult, AppLayerTxData}; +use crate::applayer::*; use crate::core::*; +use crate::conf::*; use crate::filetracker::*; use crate::filecontainer::*; @@ -39,6 +40,8 @@ use crate::nfs::nfs3_records::*; pub static mut SURICATA_NFS_FILE_CONFIG: Option<&'static SuricataFileContext> = None; +pub const NFS_MIN_FRAME_LEN: u16 = 32; + static mut ALPROTO_NFS: AppProto = ALPROTO_UNKNOWN; /* * Record parsing. @@ -1926,3 +1929,155 @@ pub extern "C" fn rs_nfs_setfileflags(direction: u8, ptr: *mut NFSState, flags: parser.setfileflags(direction, flags) } +// Parser name as a C style string. +const PARSER_NAME: &'static [u8] = b"nfs\0"; + +#[no_mangle] +pub unsafe extern "C" fn rs_nfs_register_parser() { + let default_port = CString::new("[2049]").unwrap(); + let parser = RustParser { + name: PARSER_NAME.as_ptr() as *const std::os::raw::c_char, + default_port: default_port.as_ptr(), + ipproto: IPPROTO_TCP, + probe_ts: None, + probe_tc: None, + min_depth: 0, + max_depth: 16, + state_new: rs_nfs_state_new, + state_free: rs_nfs_state_free, + tx_free: rs_nfs_state_tx_free, + parse_ts: rs_nfs_parse_request, + parse_tc: rs_nfs_parse_response, + get_tx_count: rs_nfs_state_get_tx_count, + get_tx: rs_nfs_state_get_tx, + tx_comp_st_ts: 1, + tx_comp_st_tc: 1, + tx_get_progress: rs_nfs_tx_get_alstate_progress, + get_de_state: rs_nfs_state_get_tx_detect_state, + set_de_state: rs_nfs_state_set_tx_detect_state, + get_events: Some(rs_nfs_state_get_events), + get_eventinfo: Some(rs_nfs_state_get_event_info), + get_eventinfo_byid : Some(rs_nfs_state_get_event_info_by_id), + localstorage_new: None, + localstorage_free: None, + get_files: Some(rs_nfs_getfiles), + get_tx_iterator: Some(rs_nfs_state_get_tx_iterator), + get_tx_data: rs_nfs_get_tx_data, + apply_tx_config: None, + flags: APP_LAYER_PARSER_OPT_ACCEPT_GAPS, + truncate: None, + }; + + let ip_proto_str = CString::new("tcp").unwrap(); + + if AppLayerProtoDetectConfProtoDetectionEnabled( + ip_proto_str.as_ptr(), + parser.name, + ) != 0 + { + let alproto = AppLayerRegisterProtocolDetection(&parser, 1); + ALPROTO_NFS = alproto; + + let midstream = conf_get_bool("stream.midstream"); + if midstream == true { + if AppLayerProtoDetectPPParseConfPorts(ip_proto_str.as_ptr(), IPPROTO_TCP as u8, + parser.name, ALPROTO_NFS, 0, NFS_MIN_FRAME_LEN, + rs_nfs_probe_ms, rs_nfs_probe_ms) == 0 { + SCLogDebug!("No NFSTCP app-layer configuration, enabling NFSTCP + detection TCP detection on port {:?}.", + default_port); + /* register 'midstream' probing parsers if midstream is enabled. */ + AppLayerProtoDetectPPRegister(IPPROTO_TCP as u8, + default_port.as_ptr(), ALPROTO_NFS, 0, + NFS_MIN_FRAME_LEN, STREAM_TOSERVER, + rs_nfs_probe_ms, rs_nfs_probe_ms); + } + } else { + AppLayerProtoDetectPPRegister(IPPROTO_TCP as u8, + default_port.as_ptr(), ALPROTO_NFS, 0, + NFS_MIN_FRAME_LEN, STREAM_TOSERVER, + rs_nfs_probe, rs_nfs_probe); + } + if AppLayerParserConfParserEnabled( + ip_proto_str.as_ptr(), + parser.name, + ) != 0 + { + let _ = AppLayerRegisterParser(&parser, alproto); + } + SCLogDebug!("Rust nfs parser registered."); + } else { + SCLogDebug!("Protocol detector and parser disabled for nfs."); + } +} + +#[no_mangle] +pub unsafe extern "C" fn rs_nfs_udp_register_parser() { + let default_port = CString::new("[2049]").unwrap(); + let parser = RustParser { + name: PARSER_NAME.as_ptr() as *const std::os::raw::c_char, + default_port: default_port.as_ptr(), + ipproto: IPPROTO_UDP, + probe_ts: None, + probe_tc: None, + min_depth: 0, + max_depth: 16, + state_new: rs_nfs_state_new, + state_free: rs_nfs_state_free, + tx_free: rs_nfs_state_tx_free, + parse_ts: rs_nfs_parse_request_udp, + parse_tc: rs_nfs_parse_response_udp, + get_tx_count: rs_nfs_state_get_tx_count, + get_tx: rs_nfs_state_get_tx, + tx_comp_st_ts: 1, + tx_comp_st_tc: 1, + tx_get_progress: rs_nfs_tx_get_alstate_progress, + get_de_state: rs_nfs_state_get_tx_detect_state, + set_de_state: rs_nfs_state_set_tx_detect_state, + get_events: Some(rs_nfs_state_get_events), + get_eventinfo: Some(rs_nfs_state_get_event_info), + get_eventinfo_byid : None, + localstorage_new: None, + localstorage_free: None, + get_files: Some(rs_nfs_getfiles), + get_tx_iterator: Some(rs_nfs_state_get_tx_iterator), + get_tx_data: rs_nfs_get_tx_data, + apply_tx_config: None, + flags: APP_LAYER_PARSER_OPT_UNIDIR_TXS, + truncate: None, + }; + + let ip_proto_str = CString::new("udp").unwrap(); + + if AppLayerProtoDetectConfProtoDetectionEnabled( + ip_proto_str.as_ptr(), + parser.name, + ) != 0 + { + let alproto = AppLayerRegisterProtocolDetection(&parser, 1); + ALPROTO_NFS = alproto; + + if AppLayerProtoDetectPPParseConfPorts(ip_proto_str.as_ptr(), IPPROTO_UDP as u8, + parser.name, ALPROTO_NFS, 0, NFS_MIN_FRAME_LEN, + rs_nfs_probe_udp_ts, rs_nfs_probe_udp_tc) == 0 { + SCLogDebug!("No NFSUDP app-layer configuration, enabling NFSUDP + detection UDP detection on port {:?}.", + default_port); + AppLayerProtoDetectPPRegister(IPPROTO_UDP as u8, + default_port.as_ptr(), ALPROTO_NFS, 0, + NFS_MIN_FRAME_LEN, STREAM_TOSERVER, + rs_nfs_probe_udp_ts, rs_nfs_probe_udp_tc); + } + if AppLayerParserConfParserEnabled( + ip_proto_str.as_ptr(), + parser.name, + ) != 0 + { + let _ = AppLayerRegisterParser(&parser, alproto); + } + SCLogDebug!("Rust nfs parser registered."); + } else { + SCLogDebug!("Protocol detector and parser disabled for nfs."); + } +} + diff --git a/src/app-layer-nfs-tcp.c b/src/app-layer-nfs-tcp.c index 8599e04922..657db59c70 100644 --- a/src/app-layer-nfs-tcp.c +++ b/src/app-layer-nfs-tcp.c @@ -39,196 +39,6 @@ #include "rust.h" -/* The default port to probe for echo traffic if not provided in the - * configuration file. */ -#define NFSTCP_DEFAULT_PORT "2049" - -/* The minimum size for a RFC message. For some protocols this might - * be the size of a header. TODO actual min size is likely larger */ -#define NFSTCP_MIN_FRAME_LEN 32 - -static void *NFSTCPStateAlloc(void *orig_state, AppProto proto_orig) -{ - return rs_nfs_state_new(orig_state, proto_orig); -} - -static void NFSTCPStateFree(void *state) -{ - rs_nfs_state_free(state); -} - -/** - * \brief Callback from the application layer to have a transaction freed. - * - * \param state a void pointer to the NFSTCPState object. - * \param tx_id the transaction ID to free. - */ -static void NFSTCPStateTxFree(void *state, uint64_t tx_id) -{ - rs_nfs_state_tx_free(state, tx_id); -} - -static int NFSTCPStateGetEventInfo(const char *event_name, int *event_id, - AppLayerEventType *event_type) -{ - return rs_nfs_state_get_event_info(event_name, event_id, event_type); -} - -static int NFSTCPStateGetEventInfoById(int event_id, const char **event_name, - AppLayerEventType *event_type) -{ - return rs_nfs_state_get_event_info_by_id(event_id, event_name, event_type); -} - -static AppLayerDecoderEvents *NFSTCPGetEvents(void *tx) -{ - return rs_nfs_state_get_events(tx); -} - -/** - * \brief Probe the input to see if it looks like echo. - * - * \retval ALPROTO_NFS if it looks like echo, otherwise - * ALPROTO_UNKNOWN. - */ -static AppProto NFSTCPProbingParserMidstream(Flow *f, - uint8_t direction, - const 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_ms(f, 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, - const 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(f, 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; -} - -static AppLayerResult NFSTCPParseRequest(Flow *f, void *state, - AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len, - void *local_data, const uint8_t flags) -{ - uint16_t file_flags = FileFlowToFlags(f, STREAM_TOSERVER); - rs_nfs_setfileflags(0, state, file_flags); - - if (input == NULL && input_len > 0) { - 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, flags); - SCReturnStruct(res); - } -} - -static AppLayerResult NFSTCPParseResponse(Flow *f, void *state, AppLayerParserState *pstate, - const uint8_t *input, uint32_t input_len, void *local_data, - const uint8_t flags) -{ - uint16_t file_flags = FileFlowToFlags(f, STREAM_TOCLIENT); - rs_nfs_setfileflags(1, state, file_flags); - - if (input == NULL && input_len > 0) { - 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, flags); - SCReturnStruct(res); - } -} - -static uint64_t NFSTCPGetTxCnt(void *state) -{ - return rs_nfs_state_get_tx_count(state); -} - -static void *NFSTCPGetTx(void *state, uint64_t tx_id) -{ - return rs_nfs_state_get_tx(state, tx_id); -} - -static AppLayerGetTxIterTuple RustNFSTCPGetTxIterator( - const uint8_t ipproto, const AppProto alproto, - void *alstate, uint64_t min_tx_id, uint64_t max_tx_id, - AppLayerGetTxIterState *istate) -{ - return rs_nfs_state_get_tx_iterator( - ipproto, alproto, alstate, min_tx_id, max_tx_id, (uint64_t *)istate); -} - -/** - * \brief Return the state of a transaction in a given direction. - * - * In the case of the echo protocol, the existence of a transaction - * means that the request is done. However, some protocols that may - * need multiple chunks of data to complete the request may need more - * than just the existence of a transaction for the request to be - * considered complete. - * - * For the response to be considered done, the response for a request - * needs to be seen. The response_done flag is set on response for - * checking here. - */ -static int NFSTCPGetStateProgress(void *tx, uint8_t direction) -{ - return rs_nfs_tx_get_alstate_progress(tx, direction); -} - -/** - * \brief get stored tx detect state - */ -static DetectEngineState *NFSTCPGetTxDetectState(void *vtx) -{ - return rs_nfs_state_get_tx_detect_state(vtx); -} - -/** - * \brief set store tx detect state - */ -static int NFSTCPSetTxDetectState(void *vtx, DetectEngineState *s) -{ - rs_nfs_state_set_tx_detect_state(vtx, s); - return 0; -} - -static FileContainer *NFSTCPGetFiles(void *state, uint8_t direction) -{ - return rs_nfs_getfiles(state, direction); -} static StreamingBufferConfig sbcfg = STREAMING_BUFFER_CONFIG_INITIALIZER; static SuricataFileContext sfc = { &sbcfg }; @@ -242,106 +52,6 @@ void RegisterNFSTCPParsers(void) if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { rs_nfs_init(&sfc); - - SCLogDebug("NFSTCP TCP protocol detection enabled."); - - AppLayerProtoDetectRegisterProtocol(ALPROTO_NFS, proto_name); - - if (RunmodeIsUnittests()) { - - SCLogDebug("Unittest mode, registering default configuration."); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, NFSTCP_DEFAULT_PORT, - ALPROTO_NFS, 0, NFSTCP_MIN_FRAME_LEN, STREAM_TOSERVER, - NFSTCPProbingParser, NFSTCPProbingParser); - - } - 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, - FuncPtr, FuncPtr)) { - SCLogDebug("No NFSTCP app-layer configuration, enabling NFSTCP" - " detection TCP detection on port %s.", - NFSTCP_DEFAULT_PORT); - /* register 'midstream' probing parsers if midstream is enabled. */ - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - NFSTCP_DEFAULT_PORT, ALPROTO_NFS, 0, - NFSTCP_MIN_FRAME_LEN, STREAM_TOSERVER, - FuncPtr, FuncPtr); - } - - } - - } - - else { - SCLogDebug("Protocol detecter and parser disabled for NFSTCP."); - return; - } - - if (AppLayerParserConfParserEnabled("tcp", proto_name)) - { - SCLogDebug("Registering NFSTCP protocol parser."); - - /* Register functions for state allocation and freeing. A - * state is allocated for every new NFSTCP flow. */ - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_NFS, - NFSTCPStateAlloc, NFSTCPStateFree); - - /* Register request parser for parsing frame from server to client. */ - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_NFS, - STREAM_TOSERVER, NFSTCPParseRequest); - - /* Register response parser for parsing frames from server to client. */ - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_NFS, - STREAM_TOCLIENT, NFSTCPParseResponse); - - /* Register a function to be called by the application layer - * when a transaction is to be freed. */ - AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_NFS, - NFSTCPStateTxFree); - - /* Register a function to return the current transaction count. */ - AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_NFS, - NFSTCPGetTxCnt); - - /* Transaction handling. */ - AppLayerParserRegisterStateProgressCompletionStatus(ALPROTO_NFS, 1, 1); - AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, - ALPROTO_NFS, NFSTCPGetStateProgress); - AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_NFS, - NFSTCPGetTx); - AppLayerParserRegisterGetTxIterator(IPPROTO_TCP, ALPROTO_NFS, - RustNFSTCPGetTxIterator); - - AppLayerParserRegisterGetFilesFunc(IPPROTO_TCP, ALPROTO_NFS, NFSTCPGetFiles); - - /* What is this being registered for? */ - AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_NFS, - NFSTCPGetTxDetectState, NFSTCPSetTxDetectState); - - AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_NFS, - NFSTCPStateGetEventInfo); - - AppLayerParserRegisterGetEventInfoById(IPPROTO_TCP, ALPROTO_NFS, - NFSTCPStateGetEventInfoById); - - AppLayerParserRegisterGetEventsFunc(IPPROTO_TCP, ALPROTO_NFS, - NFSTCPGetEvents); - - AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_NFS, - rs_nfs_get_tx_data); - - /* This parser accepts gaps. */ - AppLayerParserRegisterOptionFlags(IPPROTO_TCP, ALPROTO_NFS, - APP_LAYER_PARSER_OPT_ACCEPT_GAPS); - } - else { - SCLogDebug("NFSTCP protocol parsing disabled."); + rs_nfs_register_parser(); } } diff --git a/src/app-layer-nfs-udp.c b/src/app-layer-nfs-udp.c index 88a72b8579..5bfddeb963 100644 --- a/src/app-layer-nfs-udp.c +++ b/src/app-layer-nfs-udp.c @@ -36,14 +36,6 @@ #include "rust.h" -/* The default port to probe for echo traffic if not provided in the - * configuration file. */ -#define NFS_DEFAULT_PORT "2049" - -/* The minimum size for a RFC message. For some protocols this might - * be the size of a header. TODO actual min size is likely larger */ -#define NFS_MIN_FRAME_LEN 32 - /* Enum of app-layer events for an echo protocol. Normally you might * have events for errors in parsing data, like unexpected data being * received. For echo we'll make something up, and log an app-layer @@ -63,266 +55,14 @@ SCEnumCharMap nfs_udp_decoder_event_table[] = { { NULL, 0 } }; -static void *NFSStateAlloc(void *orig_state, AppProto proto_orig) -{ - return rs_nfs_state_new(orig_state, proto_orig); -} - -static void NFSStateFree(void *state) -{ - rs_nfs_state_free(state); -} - -/** - * \brief Callback from the application layer to have a transaction freed. - * - * \param state a void pointer to the NFSState object. - * \param tx_id the transaction ID to free. - */ -static void NFSStateTxFree(void *state, uint64_t tx_id) -{ - rs_nfs_state_tx_free(state, tx_id); -} - -static int NFSStateGetEventInfo(const char *event_name, int *event_id, - AppLayerEventType *event_type) -{ - return rs_nfs_state_get_event_info(event_name, event_id, event_type); -} - -static int NFSStateGetEventInfoById(int event_id, const char **event_name, - AppLayerEventType *event_type) -{ - *event_name = "NFS UDP event name (generic)"; - *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION; - return 0; -} - -static AppLayerDecoderEvents *NFSGetEvents(void *tx) -{ - return rs_nfs_state_get_events(tx); -} - -/** - * \brief Probe the input to see if it looks like echo. - * - * \retval ALPROTO_NFS if it looks like echo, otherwise - * ALPROTO_UNKNOWN. - */ -static AppProto NFSProbingParser(Flow *f, uint8_t direction, - const uint8_t *input, uint32_t input_len, uint8_t *rdir) -{ - SCLogDebug("probing"); - if (input_len < NFS_MIN_FRAME_LEN) { - SCLogDebug("unknown"); - return ALPROTO_UNKNOWN; - } - - int8_t r = 0; - if (direction & STREAM_TOSERVER) - r = rs_nfs_probe_udp_ts(f, direction, input, input_len, rdir); - else - r = rs_nfs_probe_udp_tc(f, direction, input, input_len, rdir); - - if (r == 1) { - SCLogDebug("nfs"); - return ALPROTO_NFS; - } else if (r == -1) { - SCLogDebug("failed"); - return ALPROTO_FAILED; - } - - SCLogDebug("Protocol not detected as ALPROTO_NFS."); - return ALPROTO_UNKNOWN; -} - -static AppLayerResult NFSParseRequest(Flow *f, void *state, - AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len, - void *local_data, const uint8_t flags) -{ - 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, flags); - SCReturnStruct(res); -} - -static AppLayerResult NFSParseResponse(Flow *f, void *state, AppLayerParserState *pstate, - const uint8_t *input, uint32_t input_len, void *local_data, - const uint8_t flags) -{ - 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, flags); - SCReturnStruct(res); -} - -static uint64_t NFSGetTxCnt(void *state) -{ - return rs_nfs_state_get_tx_count(state); -} - -static void *NFSGetTx(void *state, uint64_t tx_id) -{ - return rs_nfs_state_get_tx(state, tx_id); -} - -static AppLayerGetTxIterTuple RustNFSGetTxIterator( - const uint8_t ipproto, const AppProto alproto, - void *alstate, uint64_t min_tx_id, uint64_t max_tx_id, - AppLayerGetTxIterState *istate) -{ - return rs_nfs_state_get_tx_iterator( - ipproto, alproto, alstate, min_tx_id, max_tx_id, (uint64_t *)istate); -} - -/** - * \brief Return the state of a transaction in a given direction. - * - * In the case of the echo protocol, the existence of a transaction - * means that the request is done. However, some protocols that may - * need multiple chunks of data to complete the request may need more - * than just the existence of a transaction for the request to be - * considered complete. - * - * For the response to be considered done, the response for a request - * needs to be seen. The response_done flag is set on response for - * checking here. - */ -static int NFSGetStateProgress(void *tx, uint8_t direction) -{ - return rs_nfs_tx_get_alstate_progress(tx, direction); -} - -/** - * \brief get stored tx detect state - */ -static DetectEngineState *NFSGetTxDetectState(void *vtx) -{ - return rs_nfs_state_get_tx_detect_state(vtx); -} - -/** - * \brief set store tx detect state - */ -static int NFSSetTxDetectState(void *vtx, DetectEngineState *s) -{ - rs_nfs_state_set_tx_detect_state(vtx, s); - return 0; -} - -static FileContainer *NFSGetFiles(void *state, uint8_t direction) -{ - return rs_nfs_getfiles(state, direction); -} static StreamingBufferConfig sbcfg = STREAMING_BUFFER_CONFIG_INITIALIZER; static SuricataFileContext sfc = { &sbcfg }; void RegisterNFSUDPParsers(void) { - const char *proto_name = "nfs"; - - /* Check if NFS TCP detection is enabled. If it does not exist in - * the configuration file then it will be enabled by default. */ - if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name)) { - - rs_nfs_init(&sfc); - - SCLogDebug("NFS UDP protocol detection enabled."); - - AppLayerProtoDetectRegisterProtocol(ALPROTO_NFS, proto_name); - - if (RunmodeIsUnittests()) { - - SCLogDebug("Unittest mode, registering default configuration."); - AppLayerProtoDetectPPRegister(IPPROTO_UDP, NFS_DEFAULT_PORT, - ALPROTO_NFS, 0, NFS_MIN_FRAME_LEN, STREAM_TOSERVER, - NFSProbingParser, NFSProbingParser); - - } - else { - - if (!AppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP, - proto_name, ALPROTO_NFS, 0, NFS_MIN_FRAME_LEN, - NFSProbingParser, NFSProbingParser)) { - SCLogDebug("No NFS app-layer configuration, enabling NFS" - " detection TCP detection on port %s.", - NFS_DEFAULT_PORT); - AppLayerProtoDetectPPRegister(IPPROTO_UDP, - NFS_DEFAULT_PORT, ALPROTO_NFS, 0, - NFS_MIN_FRAME_LEN, STREAM_TOSERVER, - NFSProbingParser, NFSProbingParser); - } - - } - - } - - else { - SCLogDebug("Protocol detecter and parser disabled for NFS."); - return; - } - - if (AppLayerParserConfParserEnabled("udp", proto_name)) - { - SCLogDebug("Registering NFS protocol parser."); - - /* Register functions for state allocation and freeing. A - * state is allocated for every new NFS flow. */ - AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_NFS, - NFSStateAlloc, NFSStateFree); - - /* Register request parser for parsing frame from server to client. */ - AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_NFS, - STREAM_TOSERVER, NFSParseRequest); - - /* Register response parser for parsing frames from server to client. */ - AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_NFS, - STREAM_TOCLIENT, NFSParseResponse); - - /* Register a function to be called by the application layer - * when a transaction is to be freed. */ - AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_NFS, - NFSStateTxFree); - - /* Register a function to return the current transaction count. */ - AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_NFS, - NFSGetTxCnt); - - /* Transaction handling. */ - AppLayerParserRegisterStateProgressCompletionStatus(ALPROTO_NFS, 1, 1); - AppLayerParserRegisterGetStateProgressFunc(IPPROTO_UDP, - ALPROTO_NFS, NFSGetStateProgress); - AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_NFS, - NFSGetTx); - AppLayerParserRegisterGetTxIterator(IPPROTO_UDP, ALPROTO_NFS, - RustNFSGetTxIterator); - - AppLayerParserRegisterGetFilesFunc(IPPROTO_UDP, ALPROTO_NFS, NFSGetFiles); - - /* What is this being registered for? */ - AppLayerParserRegisterDetectStateFuncs(IPPROTO_UDP, ALPROTO_NFS, - NFSGetTxDetectState, NFSSetTxDetectState); - - AppLayerParserRegisterGetEventInfo(IPPROTO_UDP, ALPROTO_NFS, - NFSStateGetEventInfo); - - AppLayerParserRegisterGetEventInfoById(IPPROTO_UDP, ALPROTO_NFS, - NFSStateGetEventInfoById); - - AppLayerParserRegisterGetEventsFunc(IPPROTO_UDP, ALPROTO_NFS, - NFSGetEvents); - - AppLayerParserRegisterTxDataFunc(IPPROTO_UDP, ALPROTO_NFS, - rs_nfs_get_tx_data); - } - else { - SCLogNotice("NFS protocol parsing disabled."); - } + rs_nfs_init(&sfc); + rs_nfs_udp_register_parser(); #ifdef UNITTESTS AppLayerParserRegisterProtocolUnittests(IPPROTO_UDP, ALPROTO_NFS,