nfs: Add rust registration function

Get rid of the C glue code and move registration completely to Rust.
pull/6285/head
Shivani Bhardwaj 4 years ago
parent 61fca4e9db
commit 58ac9b0f38

@ -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.");
}
}

@ -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();
}
}

@ -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,

Loading…
Cancel
Save