Add NTP parser (rust-experimental)

pull/2814/head
Pierre Chifflier 9 years ago committed by Victor Julien
parent 4f677fd157
commit efe11dc37e

@ -10,8 +10,11 @@ debug = true
[features]
lua = []
experimental = ["ntp-parser"]
[dependencies]
nom = "~3.0"
libc = "~0.2.0"
crc = "~1.4.0"
ntp-parser = { version = "^0", optional = true }

@ -59,6 +59,7 @@ type_map = {
"libc::c_void": "void",
"libc::c_char": "char",
"libc::c_int": "int",
"c_int": "int",
"libc::int8_t": "int8_t",
@ -77,10 +78,13 @@ type_map = {
"DNSTransaction": "RSDNSTransaction",
"NFSState": "NFSState",
"NFSTransaction": "NFSTransaction",
"NTPState": "NTPState",
"NTPTransaction": "NTPTransaction",
"JsonT": "json_t",
"DetectEngineState": "DetectEngineState",
"core::DetectEngineState": "DetectEngineState",
"core::AppLayerDecoderEvents": "AppLayerDecoderEvents",
"core::AppLayerEventType": "AppLayerEventType",
"CLuaState": "lua_State",
"Store": "Store",
}

@ -26,6 +26,11 @@ pub enum Flow {}
pub enum DetectEngineState {}
pub enum AppLayerDecoderEvents {}
// From app-layer-events.h
pub type AppLayerEventType = libc::c_int;
pub const APP_LAYER_EVENT_TYPE_TRANSACTION : i32 = 1;
pub const APP_LAYER_EVENT_TYPE_PACKET : i32 = 2;
// From stream.h.
pub const STREAM_TOSERVER: u8 = 0x04;
pub const STREAM_TOCLIENT: u8 = 0x08;

@ -39,3 +39,6 @@ pub mod lua;
pub mod dns;
pub mod nfs;
#[cfg(feature = "experimental")]
pub mod ntp;

@ -0,0 +1,20 @@
/* Copyright (C) 2017 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
// written by Pierre Chifflier <chifflier@wzdftpd.net>
pub mod ntp;

@ -0,0 +1,369 @@
/* Copyright (C) 2017 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
// written by Pierre Chifflier <chifflier@wzdftpd.net>
extern crate ntp_parser;
use self::ntp_parser::*;
use core;
use applayer;
use libc;
use std;
use std::ffi::CStr;
use log::*;
use nom::IResult;
#[repr(u32)]
pub enum NTPEvent {
UnsolicitedResponse = 0,
MalformedData,
NotRequest,
NotResponse,
}
pub struct NTPState {
/// List of transactions for this session
transactions: Vec<NTPTransaction>,
/// Detection engine states counter
de_state_count: u64,
/// Events counter
events: u16,
/// tx counter for assigning incrementing id's to tx's
tx_id: u64,
}
#[derive(Debug)]
pub struct NTPTransaction {
/// The NTP reference ID
pub xid: u32,
/// The internal transaction id
id: u64,
/// The detection engine state, if present
de_state: Option<*mut core::DetectEngineState>,
/// The events associated with this transaction
events: *mut core::AppLayerDecoderEvents,
logged: applayer::LoggerFlags,
}
impl NTPState {
pub fn new() -> NTPState {
NTPState{
transactions: Vec::new(),
de_state_count: 0,
events: 0,
tx_id: 0,
}
}
}
impl NTPState {
fn parse(&mut self, i: &[u8], _direction: u8) -> i8 {
match parse_ntp(i) {
IResult::Done(_,ref msg) => {
// SCLogDebug!("parse_ntp: {:?}",msg);
if msg.mode == 1 || msg.mode == 3 {
let mut tx = self.new_tx();
// use the reference id as identifier
tx.xid = msg.ref_id;
self.transactions.push(tx);
}
0
},
IResult::Incomplete(_) => {
SCLogDebug!("Insufficient data while parsing NTP data");
self.set_event(NTPEvent::MalformedData);
-1
},
IResult::Error(_) => {
SCLogDebug!("Error while parsing NTP data");
self.set_event(NTPEvent::MalformedData);
-1
},
}
}
fn free(&mut self) {
// All transactions are freed when the `transactions` object is freed.
// But let's be explicit
self.transactions.clear();
}
fn new_tx(&mut self) -> NTPTransaction {
self.tx_id += 1;
NTPTransaction::new(self.tx_id)
}
pub fn get_tx_by_id(&mut self, tx_id: u64) -> Option<&NTPTransaction> {
self.transactions.iter().find(|&tx| tx.id == tx_id + 1)
}
fn free_tx(&mut self, tx_id: u64) {
let tx = self.transactions.iter().position(|ref tx| tx.id == tx_id + 1);
debug_assert!(tx != None);
if let Some(idx) = tx {
let _ = self.transactions.remove(idx);
}
}
/// Set an event. The event is set on the most recent transaction.
pub fn set_event(&mut self, event: NTPEvent) {
if let Some(tx) = self.transactions.last_mut() {
let ev = event as u8;
core::sc_app_layer_decoder_events_set_event_raw(&mut tx.events, ev);
self.events += 1;
}
}
}
impl NTPTransaction {
pub fn new(id: u64) -> NTPTransaction {
NTPTransaction {
xid: 0,
id: id,
de_state: None,
events: std::ptr::null_mut(),
logged: applayer::LoggerFlags::new(),
}
}
fn free(&mut self) {
if self.events != std::ptr::null_mut() {
core::sc_app_layer_decoder_events_free_events(&mut self.events);
}
}
}
impl Drop for NTPTransaction {
fn drop(&mut self) {
self.free();
}
}
/// TOSERVER probe function
#[no_mangle]
pub extern "C" fn rs_ntp_probe(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)
};
match parse_ntp(slice) {
IResult::Done(_, ref msg) => {
if msg.version == 3 || msg.version == 4 {
return 1;
} else {
return -1;
}
},
IResult::Incomplete(_) => {
return 0;
},
IResult::Error(_) => {
return -1;
},
}
}
/// Returns *mut NTPState
#[no_mangle]
pub extern "C" fn rs_ntp_state_new() -> *mut libc::c_void {
let state = NTPState::new();
let boxed = Box::new(state);
return unsafe{std::mem::transmute(boxed)};
}
/// Params:
/// - state: *mut NTPState as void pointer
#[no_mangle]
pub extern "C" fn rs_ntp_state_free(state: *mut libc::c_void) {
// Just unbox...
let mut ntp_state: Box<NTPState> = unsafe{std::mem::transmute(state)};
ntp_state.free();
}
#[no_mangle]
pub extern "C" fn rs_ntp_parse_request(_flow: *const core::Flow,
state: &mut NTPState,
_pstate: *const libc::c_void,
input: *const libc::uint8_t,
input_len: u32,
_data: *const libc::c_void) -> i8 {
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
state.parse(buf, 0)
}
#[no_mangle]
pub extern "C" fn rs_ntp_parse_response(_flow: *const core::Flow,
state: &mut NTPState,
_pstate: *const libc::c_void,
input: *const libc::uint8_t,
input_len: u32,
_data: *const libc::c_void) -> i8 {
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
state.parse(buf, 1)
}
#[no_mangle]
pub extern "C" fn rs_ntp_state_get_tx(state: &mut NTPState,
tx_id: libc::uint64_t)
-> *mut NTPTransaction
{
match state.get_tx_by_id(tx_id) {
Some(tx) => unsafe{std::mem::transmute(tx)},
None => std::ptr::null_mut(),
}
}
#[no_mangle]
pub extern "C" fn rs_ntp_state_get_tx_count(state: &mut NTPState)
-> libc::uint64_t
{
state.tx_id
}
#[no_mangle]
pub extern "C" fn rs_ntp_state_tx_free(state: &mut NTPState,
tx_id: libc::uint64_t)
{
state.free_tx(tx_id);
}
#[no_mangle]
pub extern "C" fn rs_ntp_state_progress_completion_status(
_direction: libc::uint8_t)
-> libc::c_int
{
return 1;
}
#[no_mangle]
pub extern "C" fn rs_ntp_tx_get_alstate_progress(_tx: &mut NTPTransaction,
_direction: libc::uint8_t)
-> libc::uint8_t
{
1
}
#[no_mangle]
pub extern "C" fn rs_ntp_tx_set_logged(_state: &mut NTPState,
tx: &mut NTPTransaction,
logger: libc::uint32_t)
{
tx.logged.set_logged(logger);
}
#[no_mangle]
pub extern "C" fn rs_ntp_tx_get_logged(_state: &mut NTPState,
tx: &mut NTPTransaction,
logger: libc::uint32_t)
-> i8
{
if tx.logged.is_logged(logger) {
return 1;
}
return 0;
}
#[no_mangle]
pub extern "C" fn rs_ntp_state_set_tx_detect_state(
state: &mut NTPState,
tx: &mut NTPTransaction,
de_state: &mut core::DetectEngineState)
{
state.de_state_count += 1;
tx.de_state = Some(de_state);
}
#[no_mangle]
pub extern "C" fn rs_ntp_state_get_tx_detect_state(
tx: &mut NTPTransaction)
-> *mut core::DetectEngineState
{
match tx.de_state {
Some(ds) => ds,
None => std::ptr::null_mut(),
}
}
#[no_mangle]
pub extern "C" fn rs_ntp_state_has_events(state: &mut NTPState) -> u8 {
if state.events > 0 {
return 1;
}
return 0;
}
#[no_mangle]
pub extern "C" fn rs_ntp_state_get_events(state: &mut NTPState,
tx_id: libc::uint64_t)
-> *mut core::AppLayerDecoderEvents
{
match state.get_tx_by_id(tx_id) {
Some(tx) => tx.events,
_ => std::ptr::null_mut(),
}
}
#[no_mangle]
pub extern "C" fn rs_ntp_state_get_event_info(event_name: *const libc::c_char,
event_id: *mut libc::c_int,
event_type: *mut core::AppLayerEventType)
-> i8
{
if event_name == std::ptr::null() { return -1; }
let c_event_name: &CStr = unsafe { CStr::from_ptr(event_name) };
let event = match c_event_name.to_str() {
Ok(s) => {
match s {
"malformed_data" => NTPEvent::MalformedData as i32,
_ => -1, // unknown event
}
},
Err(_) => -1, // UTF-8 conversion failed
};
unsafe{
*event_type = core::APP_LAYER_EVENT_TYPE_TRANSACTION;
*event_id = event as libc::c_int;
};
0
}

@ -41,6 +41,7 @@ app-layer-smb.c app-layer-smb.h \
app-layer-smtp.c app-layer-smtp.h \
app-layer-nfs-tcp.c app-layer-nfs-tcp.h \
app-layer-nfs-udp.c app-layer-nfs-udp.h \
app-layer-ntp.c app-layer-ntp.h \
app-layer-template.c app-layer-template.h \
app-layer-ssh.c app-layer-ssh.h \
app-layer-ssl.c app-layer-ssl.h \

@ -698,6 +698,8 @@ static void AppLayerProtoDetectPrintProbingParsers(AppLayerProtoDetectProbingPar
printf(" alproto: ALPROTO_ENIP\n");
else if (pp_pe->alproto == ALPROTO_NFS)
printf(" alproto: ALPROTO_NFS\n");
else if (pp_pe->alproto == ALPROTO_NTP)
printf(" alproto: ALPROTO_NTP\n");
else if (pp_pe->alproto == ALPROTO_TEMPLATE)
printf(" alproto: ALPROTO_TEMPLATE\n");
else if (pp_pe->alproto == ALPROTO_DNP3)
@ -757,6 +759,8 @@ static void AppLayerProtoDetectPrintProbingParsers(AppLayerProtoDetectProbingPar
printf(" alproto: ALPROTO_ENIP\n");
else if (pp_pe->alproto == ALPROTO_NFS)
printf(" alproto: ALPROTO_NFS\n");
else if (pp_pe->alproto == ALPROTO_NTP)
printf(" alproto: ALPROTO_NTP\n");
else if (pp_pe->alproto == ALPROTO_TEMPLATE)
printf(" alproto: ALPROTO_TEMPLATE\n");
else if (pp_pe->alproto == ALPROTO_DNP3)

@ -0,0 +1,307 @@
/* Copyright (C) 2017 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Pierre Chifflier <chifflier@wzdftpd.net>
*
* Parser for NTP application layer running on UDP port 123.
*/
#include "suricata-common.h"
#include "stream.h"
#include "conf.h"
#include "util-unittest.h"
#include "app-layer-detect-proto.h"
#include "app-layer-parser.h"
#include "app-layer-ntp.h"
#if defined(HAVE_RUST) && defined(HAVE_RUST_EXTERNAL)
#include "rust-ntp-ntp-gen.h"
/* The default port to probe for NTP traffic if not provided in the
* configuration file. */
#define NTP_DEFAULT_PORT "123"
/* The minimum size for an NTP message. */
#define NTP_MIN_FRAME_LEN 2
static void *NTPStateAlloc(void)
{
return rs_ntp_state_new();
}
static void NTPStateFree(void *state)
{
rs_ntp_state_free(state);
}
/**
* \brief Callback from the application layer to have a transaction freed.
*
* \param state a void pointer to the NTPState object.
* \param tx_id the transaction ID to free.
*/
static void NTPStateTxFree(void *state, uint64_t tx_id)
{
rs_ntp_state_tx_free(state, tx_id);
}
static int NTPStateGetEventInfo(const char *event_name, int *event_id,
AppLayerEventType *event_type)
{
return rs_ntp_state_get_event_info(event_name, event_id, event_type);
}
static AppLayerDecoderEvents *NTPGetEvents(void *state, uint64_t tx_id)
{
return rs_ntp_state_get_events(state, tx_id);
}
static int NTPHasEvents(void *state)
{
return rs_ntp_state_has_events(state);
}
/**
* \brief Probe the input to see if it looks like NTP.
*
* \retval ALPROTO_NTP if it looks like NTP, otherwise
* ALPROTO_UNKNOWN.
*/
static AppProto NTPProbingParser(uint8_t *input, uint32_t input_len,
uint32_t *offset)
{
if (input_len < NTP_MIN_FRAME_LEN) {
return ALPROTO_UNKNOWN;
}
int8_t r = rs_ntp_probe(input, input_len);
if (r == 1) {
return ALPROTO_NTP;
} else if (r == -1) {
return ALPROTO_FAILED;
}
SCLogDebug("Protocol not detected as ALPROTO_NTP.");
return ALPROTO_UNKNOWN;
}
static int RustNTPParseRequest(Flow *f, void *state,
AppLayerParserState *pstate, uint8_t *input, uint32_t input_len,
void *local_data)
{
SCLogDebug("RustNTPParseRequest");
return rs_ntp_parse_request(f, state, pstate, input, input_len,
local_data);
}
static int RustNTPParseResponse(Flow *f, void *state,
AppLayerParserState *pstate, uint8_t *input, uint32_t input_len,
void *local_data)
{
SCLogDebug("RustNTPParseResponse");
return rs_ntp_parse_response(f, state, pstate, input, input_len,
local_data);
}
static uint64_t NTPGetTxCnt(void *state)
{
return rs_ntp_state_get_tx_count(state);
}
static void *NTPGetTx(void *state, uint64_t tx_id)
{
return rs_ntp_state_get_tx(state, tx_id);
}
// static void NTPSetTxLogged(void *state, void *vtx, uint32_t logger)
// {
// rs_ntp_tx_set_logged(state, vtx, logger);
// }
//
// static int NTPGetTxLogged(void *state, void *vtx, uint32_t logger)
// {
// return rs_ntp_tx_get_logged(state, vtx, logger);
// }
/**
* \brief Called by the application layer.
*
* In most cases 1 can be returned here.
*/
static int NTPGetAlstateProgressCompletionStatus(uint8_t direction) {
return rs_ntp_state_progress_completion_status(direction);
}
/**
* \brief Return the state of a transaction in a given direction.
*/
static int NTPGetStateProgress(void *tx, uint8_t direction)
{
return rs_ntp_tx_get_alstate_progress(tx, direction);
}
/**
* \brief Get stored Tx detect state
*/
static DetectEngineState *NTPGetTxDetectState(void *vtx)
{
return rs_ntp_state_get_tx_detect_state(vtx);
}
/**
* \brief Set stored Tx detect state
*/
static int NTPSetTxDetectState(void *state, void *vtx,
DetectEngineState *s)
{
rs_ntp_state_set_tx_detect_state(state, vtx, s);
return 0;
}
void RegisterNTPParsers(void)
{
const char *proto_name = "ntp";
/* Check if NTP UDP detection is enabled. If it does not exist in
* the configuration file then it will be enabled by default. */
if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name)) {
SCLogDebug("NTP UDP protocol detection enabled.");
AppLayerProtoDetectRegisterProtocol(ALPROTO_NTP, proto_name);
if (RunmodeIsUnittests()) {
SCLogDebug("Unittest mode, registeringd default configuration.");
AppLayerProtoDetectPPRegister(IPPROTO_UDP, NTP_DEFAULT_PORT,
ALPROTO_NTP, 0, NTP_MIN_FRAME_LEN, STREAM_TOSERVER,
NTPProbingParser, NULL);
}
else {
if (!AppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP,
proto_name, ALPROTO_NTP, 0, NTP_MIN_FRAME_LEN,
NTPProbingParser, NULL)) {
SCLogDebug("No NTP app-layer configuration, enabling NTP"
" detection UDP detection on port %s.",
NTP_DEFAULT_PORT);
AppLayerProtoDetectPPRegister(IPPROTO_UDP,
NTP_DEFAULT_PORT, ALPROTO_NTP, 0,
NTP_MIN_FRAME_LEN, STREAM_TOSERVER,
NTPProbingParser, NULL);
}
}
}
else {
SCLogDebug("Protocol detecter and parser disabled for NTP.");
return;
}
if (AppLayerParserConfParserEnabled("udp", proto_name)) {
SCLogDebug("Registering NTP protocol parser.");
/* Register functions for state allocation and freeing. A
* state is allocated for every new NTP flow. */
AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_NTP,
NTPStateAlloc, NTPStateFree);
/* Register request parser for parsing frame from server to client. */
AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_NTP,
STREAM_TOSERVER, RustNTPParseRequest);
/* Register response parser for parsing frames from server to client. */
AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_NTP,
STREAM_TOCLIENT, RustNTPParseResponse);
/* Register a function to be called by the application layer
* when a transaction is to be freed. */
AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_NTP,
NTPStateTxFree);
// AppLayerParserRegisterLoggerFuncs(IPPROTO_UDP, ALPROTO_NTP,
// NTPGetTxLogged, NTPSetTxLogged);
/* Register a function to return the current transaction count. */
AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_NTP,
NTPGetTxCnt);
/* Transaction handling. */
AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_NTP,
NTPGetAlstateProgressCompletionStatus);
AppLayerParserRegisterGetStateProgressFunc(IPPROTO_UDP,
ALPROTO_NTP, NTPGetStateProgress);
AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_NTP,
NTPGetTx);
/* Application layer event handling. */
AppLayerParserRegisterHasEventsFunc(IPPROTO_UDP, ALPROTO_NTP,
NTPHasEvents);
/* What is this being registered for? */
AppLayerParserRegisterDetectStateFuncs(IPPROTO_UDP, ALPROTO_NTP,
NULL, NTPGetTxDetectState, NTPSetTxDetectState);
AppLayerParserRegisterGetEventInfo(IPPROTO_UDP, ALPROTO_NTP,
NTPStateGetEventInfo);
AppLayerParserRegisterGetEventsFunc(IPPROTO_UDP, ALPROTO_NTP,
NTPGetEvents);
}
else {
SCLogDebug("NTP protocol parsing disabled.");
}
#ifdef UNITTESTS
AppLayerParserRegisterProtocolUnittests(IPPROTO_UDP, ALPROTO_NTP,
NTPParserRegisterTests);
#endif
}
#ifdef UNITTESTS
#endif
void NTPParserRegisterTests(void)
{
#ifdef UNITTESTS
#endif
}
#else /* HAVE_RUST */
void RegisterNTPParsers(void)
{
}
#endif /* HAVE_RUST */

@ -0,0 +1,34 @@
/* Copyright (C) 2017 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Pierre Chifflier <chifflier@wzdftpd.net>
*/
#ifndef __APP_LAYER_NTP_H__
#define __APP_LAYER_NTP_H__
void RegisterNTPParsers(void);
void NTPParserRegisterTests(void);
/** Opaque Rust types. */
typedef struct NTPState_ NTPState;
typedef struct NTPTransaction_ NTPTransaction;
#endif /* __APP_LAYER_NTP_H__ */

@ -62,6 +62,7 @@
#include "app-layer-dnp3.h"
#include "app-layer-nfs-tcp.h"
#include "app-layer-nfs-udp.h"
#include "app-layer-ntp.h"
#include "app-layer-template.h"
#include "conf.h"
@ -1386,6 +1387,7 @@ void AppLayerParserRegisterProtocolParsers(void)
RegisterDNP3Parsers();
RegisterNFSTCPParsers();
RegisterNFSUDPParsers();
RegisterNTPParsers();
RegisterTemplateParsers();
/** IMAP */

@ -84,6 +84,9 @@ const char *AppProtoToString(AppProto alproto)
case ALPROTO_NFS:
proto_name = "nfs";
break;
case ALPROTO_NTP:
proto_name = "ntp";
break;
case ALPROTO_TEMPLATE:
proto_name = "template";
break;

@ -45,6 +45,7 @@ enum AppProtoEnum {
ALPROTO_ENIP,
ALPROTO_DNP3,
ALPROTO_NFS,
ALPROTO_NTP,
ALPROTO_TEMPLATE,
/* used by the probing parser when alproto detection fails

@ -680,6 +680,8 @@ pcap-file:
# "detection-only" enables protocol detection only (parser disabled).
app-layer:
protocols:
ntp:
enabled: yes
nfs:
enabled: yes
tls:

Loading…
Cancel
Save