diff --git a/rust/cbindgen.toml b/rust/cbindgen.toml index 7e20a8411a40..2405450dd1ca 100644 --- a/rust/cbindgen.toml +++ b/rust/cbindgen.toml @@ -88,6 +88,8 @@ include = [ "SCSigTableElmt", "SCTransformTableElmt", "DataRepType", + "OutputJsonLogDirection", + "EveJsonTxLoggerRegistrationData", ] # A list of items to not include in the generated bindings diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index 4367825727ae..326d5df7d870 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -472,6 +472,38 @@ pub type ApplyTxConfigFn = unsafe extern "C" fn (*mut c_void, *mut c_void, c_int pub type GetFrameIdByName = unsafe extern "C" fn(*const c_char) -> c_int; pub type GetFrameNameById = unsafe extern "C" fn(u8) -> *const c_char; +#[repr(C)] +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[allow(non_camel_case_types)] +pub enum OutputJsonLogDirection { + LOG_DIR_PACKET = 0, + LOG_DIR_FLOW = 1, + LOG_DIR_FLOW_TOCLIENT = 2, + LOG_DIR_FLOW_TOSERVER = 3, +} + +#[repr(C)] +#[allow(non_snake_case)] +pub struct EveJsonTxLoggerRegistrationData { + pub confname: *const c_char, + pub logname: *const c_char, + pub alproto: AppProto, + pub dir: u8, + // EveJsonSimpleTxLogFunc, cannot use JsonBuilder as it is not #[repr(C)] + pub LogTx: unsafe extern "C" fn(*const c_void, *mut c_void) -> bool, +} + +// Defined in output.h +/// cbindgen:ignore +extern { + pub fn OutputPreRegisterLogger(reg_data: EveJsonTxLoggerRegistrationData) -> c_int; +} + +// Defined in detect-engine-register.h +/// cbindgen:ignore +extern { + pub fn SigTablePreRegister(cb: unsafe extern "C" fn ()); +} // Defined in app-layer-register.h /// cbindgen:ignore @@ -479,6 +511,7 @@ extern { pub fn AppLayerRegisterProtocolDetection(parser: *const RustParser, enable_default: c_int) -> AppProto; pub fn AppLayerRegisterParserAlias(parser_name: *const c_char, alias_name: *const c_char); pub fn AppLayerRegisterParser(parser: *const RustParser, alproto: AppProto) -> c_int; + pub fn AppProtoNewProtoFromString(name: *const c_char) -> AppProto; } diff --git a/rust/src/snmp/detect.rs b/rust/src/snmp/detect.rs index 0c07538c7fe2..fa1010c343d4 100644 --- a/rust/src/snmp/detect.rs +++ b/rust/src/snmp/detect.rs @@ -105,7 +105,7 @@ unsafe extern "C" fn snmp_detect_pdutype_free(_de: *mut c_void, ctx: *mut c_void rs_detect_u32_free(ctx); } -pub unsafe extern "C" fn snmp_detect_usm_setup( +unsafe extern "C" fn snmp_detect_usm_setup( de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, ) -> c_int { if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { @@ -117,7 +117,7 @@ pub unsafe extern "C" fn snmp_detect_usm_setup( return 0; } -pub unsafe extern "C" fn snmp_detect_usm_get( +unsafe extern "C" fn snmp_detect_usm_get( tx: *const c_void, _flow_flags: u8, buffer: *mut *const u8, buffer_len: *mut u32, ) -> bool { let tx = cast_pointer!(tx, SNMPTransaction); @@ -129,7 +129,7 @@ pub unsafe extern "C" fn snmp_detect_usm_get( return false; } -pub unsafe extern "C" fn snmp_detect_usm_get_data( +unsafe extern "C" fn snmp_detect_usm_get_data( de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, tx: *const c_void, list_id: c_int, ) -> *mut c_void { @@ -144,7 +144,7 @@ pub unsafe extern "C" fn snmp_detect_usm_get_data( ); } -pub unsafe extern "C" fn snmp_detect_community_setup( +unsafe extern "C" fn snmp_detect_community_setup( de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, ) -> c_int { if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { @@ -156,7 +156,7 @@ pub unsafe extern "C" fn snmp_detect_community_setup( return 0; } -pub unsafe extern "C" fn snmp_detect_community_get( +unsafe extern "C" fn snmp_detect_community_get( tx: *const c_void, _flow_flags: u8, buffer: *mut *const u8, buffer_len: *mut u32, ) -> bool { let tx = cast_pointer!(tx, SNMPTransaction); @@ -168,7 +168,7 @@ pub unsafe extern "C" fn snmp_detect_community_get( return false; } -pub unsafe extern "C" fn snmp_detect_community_get_data( +unsafe extern "C" fn snmp_detect_community_get_data( de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, tx: *const c_void, list_id: c_int, ) -> *mut c_void { @@ -182,8 +182,8 @@ pub unsafe extern "C" fn snmp_detect_community_get_data( snmp_detect_community_get, ); } -#[no_mangle] -pub unsafe extern "C" fn SCDetectSNMPRegister() { + +pub(super) unsafe extern "C" fn detect_snmp_register() { let kw = SCSigTableElmt { name: b"snmp.version\0".as_ptr() as *const libc::c_char, desc: b"match SNMP version\0".as_ptr() as *const libc::c_char, diff --git a/rust/src/snmp/log.rs b/rust/src/snmp/log.rs index 5707f30ccb4e..91e900f5da65 100644 --- a/rust/src/snmp/log.rs +++ b/rust/src/snmp/log.rs @@ -19,10 +19,10 @@ use crate::jsonbuilder::{JsonBuilder, JsonError}; use crate::snmp::snmp::SNMPTransaction; -use crate::snmp::snmp_parser::{NetworkAddress,PduType}; +use crate::snmp::snmp_parser::{NetworkAddress, PduType}; use std::borrow::Cow; -fn str_of_pdu_type(t:&PduType) -> Cow { +fn str_of_pdu_type(t: &PduType) -> Cow { match t { &PduType::GetRequest => Cow::Borrowed("get_request"), &PduType::GetNextRequest => Cow::Borrowed("get_next_request"), @@ -37,8 +37,7 @@ fn str_of_pdu_type(t:&PduType) -> Cow { } } -fn snmp_log_response(jsb: &mut JsonBuilder, tx: &mut SNMPTransaction) -> Result<(), JsonError> -{ +fn snmp_log_response(jsb: &mut JsonBuilder, tx: &SNMPTransaction) -> Result<(), JsonError> { jsb.open_object("snmp")?; jsb.set_uint("version", tx.version as u64)?; if tx.encrypted { @@ -53,7 +52,9 @@ fn snmp_log_response(jsb: &mut JsonBuilder, tx: &mut SNMPTransaction) -> Result< jsb.set_string("trap_type", &format!("{:?}", trap_type))?; jsb.set_string("trap_oid", &oid.to_string())?; match address { - NetworkAddress::IPv4(ip) => {jsb.set_string("trap_address", &ip.to_string())?;}, + NetworkAddress::IPv4(ip) => { + jsb.set_string("trap_address", &ip.to_string())?; + } } } if !info.vars.is_empty() { @@ -76,8 +77,10 @@ fn snmp_log_response(jsb: &mut JsonBuilder, tx: &mut SNMPTransaction) -> Result< return Ok(()); } -#[no_mangle] -pub extern "C" fn rs_snmp_log_json_response(tx: &mut SNMPTransaction, jsb: &mut JsonBuilder) -> bool -{ +pub(super) unsafe extern "C" fn rs_snmp_log_json_response( + tx: *const std::os::raw::c_void, jsb: *mut std::os::raw::c_void, +) -> bool { + let tx = cast_pointer!(tx, SNMPTransaction); + let jsb = cast_pointer!(jsb, JsonBuilder); snmp_log_response(jsb, tx).is_ok() } diff --git a/rust/src/snmp/snmp.rs b/rust/src/snmp/snmp.rs index aa4b0b3f60d2..10f6617d0222 100644 --- a/rust/src/snmp/snmp.rs +++ b/rust/src/snmp/snmp.rs @@ -22,6 +22,8 @@ use crate::flow::Flow; use crate::snmp::snmp_parser::*; use crate::core::{self, *}; use crate::applayer::{self, *}; +use super::log::rs_snmp_log_json_response; +use super::detect::detect_snmp_register; use std; use std::ffi::CString; @@ -33,18 +35,18 @@ use nom7::error::{ErrorKind, make_error}; use suricata_sys::sys::AppProto; #[derive(AppLayerEvent)] -pub enum SNMPEvent { +enum SNMPEvent { MalformedData, UnknownSecurityModel, VersionMismatch, } #[derive(Default)] -pub struct SNMPState<'a> { +struct SNMPState<'a> { state_data: AppLayerStateData, /// SNMP protocol version - pub version: u32, + version: u32, /// List of transactions for this session transactions: Vec>, @@ -53,7 +55,7 @@ pub struct SNMPState<'a> { tx_id: u64, } -pub struct SNMPPduInfo<'a> { +pub(super) struct SNMPPduInfo<'a> { pub pdu_type: PduType, pub err: ErrorStatus, @@ -63,7 +65,7 @@ pub struct SNMPPduInfo<'a> { pub vars: Vec>, } -pub struct SNMPTransaction<'a> { +pub(super) struct SNMPTransaction<'a> { /// PDU version pub version: u32, @@ -92,7 +94,7 @@ impl Transaction for SNMPTransaction<'_> { } impl<'a> SNMPState<'a> { - pub fn new() -> SNMPState<'a> { + fn new() -> SNMPState<'a> { Default::default() } } @@ -238,7 +240,7 @@ impl<'a> SNMPState<'a> { } impl<'a> SNMPTransaction<'a> { - pub fn new(direction: Direction, version: u32, id: u64) -> SNMPTransaction<'a> { + fn new(direction: Direction, version: u32, id: u64) -> SNMPTransaction<'a> { SNMPTransaction { version, info: None, @@ -252,8 +254,7 @@ impl<'a> SNMPTransaction<'a> { } /// Returns *mut SNMPState -#[no_mangle] -pub extern "C" fn rs_snmp_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void { +extern "C" fn rs_snmp_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void { let state = SNMPState::new(); let boxed = Box::new(state); return Box::into_raw(boxed) as *mut _; @@ -261,14 +262,12 @@ pub extern "C" fn rs_snmp_state_new(_orig_state: *mut std::os::raw::c_void, _ori /// Params: /// - state: *mut SNMPState as void pointer -#[no_mangle] -pub extern "C" fn rs_snmp_state_free(state: *mut std::os::raw::c_void) { +extern "C" fn rs_snmp_state_free(state: *mut std::os::raw::c_void) { let mut snmp_state = unsafe{ Box::from_raw(state as *mut SNMPState) }; snmp_state.free(); } -#[no_mangle] -pub unsafe extern "C" fn rs_snmp_parse_request(_flow: *const Flow, +unsafe extern "C" fn rs_snmp_parse_request(_flow: *const Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void, stream_slice: StreamSlice, @@ -278,8 +277,7 @@ pub unsafe extern "C" fn rs_snmp_parse_request(_flow: *const Flow, state.parse(stream_slice.as_slice(), Direction::ToServer).into() } -#[no_mangle] -pub unsafe extern "C" fn rs_snmp_parse_response(_flow: *const Flow, +unsafe extern "C" fn rs_snmp_parse_response(_flow: *const Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void, stream_slice: StreamSlice, @@ -289,8 +287,7 @@ pub unsafe extern "C" fn rs_snmp_parse_response(_flow: *const Flow, state.parse(stream_slice.as_slice(), Direction::ToClient).into() } -#[no_mangle] -pub unsafe extern "C" fn rs_snmp_state_get_tx(state: *mut std::os::raw::c_void, +unsafe extern "C" fn rs_snmp_state_get_tx(state: *mut std::os::raw::c_void, tx_id: u64) -> *mut std::os::raw::c_void { @@ -301,24 +298,21 @@ pub unsafe extern "C" fn rs_snmp_state_get_tx(state: *mut std::os::raw::c_void, } } -#[no_mangle] -pub unsafe extern "C" fn rs_snmp_state_get_tx_count(state: *mut std::os::raw::c_void) +unsafe extern "C" fn rs_snmp_state_get_tx_count(state: *mut std::os::raw::c_void) -> u64 { let state = cast_pointer!(state,SNMPState); state.tx_id } -#[no_mangle] -pub unsafe extern "C" fn rs_snmp_state_tx_free(state: *mut std::os::raw::c_void, +unsafe extern "C" fn rs_snmp_state_tx_free(state: *mut std::os::raw::c_void, tx_id: u64) { let state = cast_pointer!(state,SNMPState); state.free_tx(tx_id); } -#[no_mangle] -pub extern "C" fn rs_snmp_tx_get_alstate_progress(_tx: *mut std::os::raw::c_void, +extern "C" fn rs_snmp_tx_get_alstate_progress(_tx: *mut std::os::raw::c_void, _direction: u8) -> std::os::raw::c_int { @@ -355,7 +349,7 @@ fn parse_pdu_envelope_version(i:&[u8]) -> IResult<&[u8],u32> { } #[no_mangle] -pub unsafe extern "C" fn rs_snmp_probing_parser(_flow: *const Flow, +unsafe extern "C" fn rs_snmp_probing_parser(_flow: *const Flow, _direction: u8, input:*const u8, input_len: u32, @@ -413,20 +407,28 @@ pub unsafe extern "C" fn rs_register_snmp_parser() { get_frame_name_by_id: None, }; let ip_proto_str = CString::new("udp").unwrap(); + ALPROTO_SNMP = AppProtoNewProtoFromString(PARSER_NAME.as_ptr() as *const std::os::raw::c_char); + let reg_data = EveJsonTxLoggerRegistrationData { + confname: b"eve-log.snmp\0".as_ptr() as *const std::os::raw::c_char, + logname: b"JsonSNMPLog\0".as_ptr() as *const std::os::raw::c_char, + alproto: ALPROTO_SNMP, + dir: OutputJsonLogDirection::LOG_DIR_PACKET as u8, + LogTx: rs_snmp_log_json_response, + }; + OutputPreRegisterLogger(reg_data); + SigTablePreRegister(detect_snmp_register); if AppLayerProtoDetectConfProtoDetectionEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { // port 161 - let alproto = AppLayerRegisterProtocolDetection(&parser, 1); - // store the allocated ID for the probe function - ALPROTO_SNMP = alproto; + _ = AppLayerRegisterProtocolDetection(&parser, 1); if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { - let _ = AppLayerRegisterParser(&parser, alproto); + let _ = AppLayerRegisterParser(&parser, ALPROTO_SNMP); } // port 162 let default_port_traps = CString::new("162").unwrap(); parser.default_port = default_port_traps.as_ptr(); let _ = AppLayerRegisterProtocolDetection(&parser, 1); if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { - let _ = AppLayerRegisterParser(&parser, alproto); + let _ = AppLayerRegisterParser(&parser, ALPROTO_SNMP); } AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_SNMP); } else { diff --git a/rust/sys/src/sys.rs b/rust/sys/src/sys.rs index cf6f060a3e5d..a2ea59a9a508 100644 --- a/rust/sys/src/sys.rs +++ b/rust/sys/src/sys.rs @@ -27,28 +27,30 @@ pub enum AppProtoEnum { ALPROTO_KRB5 = 21, ALPROTO_QUIC = 22, ALPROTO_DHCP = 23, - ALPROTO_SNMP = 24, - ALPROTO_SIP = 25, - ALPROTO_RFB = 26, - ALPROTO_MQTT = 27, - ALPROTO_PGSQL = 28, - ALPROTO_TELNET = 29, - ALPROTO_WEBSOCKET = 30, - ALPROTO_LDAP = 31, - ALPROTO_DOH2 = 32, - ALPROTO_TEMPLATE = 33, - ALPROTO_RDP = 34, - ALPROTO_HTTP2 = 35, - ALPROTO_BITTORRENT_DHT = 36, - ALPROTO_POP3 = 37, - ALPROTO_HTTP = 38, - ALPROTO_MAX_STATIC = 39, + ALPROTO_SIP = 24, + ALPROTO_RFB = 25, + ALPROTO_MQTT = 26, + ALPROTO_PGSQL = 27, + ALPROTO_TELNET = 28, + ALPROTO_WEBSOCKET = 29, + ALPROTO_LDAP = 30, + ALPROTO_DOH2 = 31, + ALPROTO_TEMPLATE = 32, + ALPROTO_RDP = 33, + ALPROTO_HTTP2 = 34, + ALPROTO_BITTORRENT_DHT = 35, + ALPROTO_POP3 = 36, + ALPROTO_HTTP = 37, + ALPROTO_MAX_STATIC = 38, } pub type AppProto = u16; extern "C" { #[doc = " \\brief Maps the ALPROTO_*, to its string equivalent.\n\n \\param alproto App layer protocol id.\n\n \\retval String equivalent for the alproto."] pub fn AppProtoToString(alproto: AppProto) -> *const ::std::os::raw::c_char; } +extern "C" { + pub fn AppProtoNewProtoFromString(proto_name: *const ::std::os::raw::c_char) -> AppProto; +} extern "C" { pub fn AppProtoRegisterProtoString( alproto: AppProto, proto_name: *const ::std::os::raw::c_char, @@ -114,9 +116,10 @@ pub struct SCAppLayerPlugin_ { pub KeywordsRegister: ::std::option::Option, pub logname: *mut ::std::os::raw::c_char, pub confname: *mut ::std::os::raw::c_char, + pub dir: u8, pub Logger: ::std::option::Option< unsafe extern "C" fn( - tx: *mut ::std::os::raw::c_void, + tx: *const ::std::os::raw::c_void, jb: *mut ::std::os::raw::c_void, ) -> bool, >, diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index 1f931e3f2281..21ccc26b4d4c 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -161,12 +161,14 @@ typedef struct AppLayerProtoDetectCtx_ { * ipproto. It should be allocated to contain ALPROTO_MAX * protocols. */ const char **alproto_names; + size_t alproto_names_len; /* Protocol expectations, like ftp-data on tcp. * It should be allocated to contain ALPROTO_MAX * app-layer protocols. For each protocol, an iptype * is referenced (or 0 if there is no expectation). */ uint8_t *expectation_proto; + size_t expectation_proto_len; } AppLayerProtoDetectCtx; typedef struct AppLayerProtoDetectAliases_ { @@ -1714,11 +1716,13 @@ int AppLayerProtoDetectSetup(void) if (unlikely(alpd_ctx.alproto_names == NULL)) { FatalError("Unable to alloc alproto_names."); } + alpd_ctx.alproto_names_len = g_alproto_max; // to realloc when dynamic protos are added alpd_ctx.expectation_proto = SCCalloc(g_alproto_max, sizeof(uint8_t)); if (unlikely(alpd_ctx.expectation_proto == NULL)) { FatalError("Unable to alloc expectation_proto."); } + alpd_ctx.expectation_proto_len = g_alproto_max; AppLayerExpectationSetup(); SCReturnInt(0); @@ -1752,8 +1756,10 @@ int AppLayerProtoDetectDeSetup(void) SCFree(alpd_ctx.alproto_names); alpd_ctx.alproto_names = NULL; + alpd_ctx.alproto_names_len = 0; SCFree(alpd_ctx.expectation_proto); alpd_ctx.expectation_proto = NULL; + alpd_ctx.expectation_proto_len = 0; SpmDestroyGlobalThreadCtx(alpd_ctx.spm_global_thread_ctx); @@ -1768,7 +1774,16 @@ void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_n { SCEnter(); - // should have just been realloced when dynamic protos is added + if (alpd_ctx.alproto_names_len <= alproto && alproto < g_alproto_max) { + void *tmp = SCRealloc(alpd_ctx.alproto_names, sizeof(char *) * g_alproto_max); + if (unlikely(tmp == NULL)) { + FatalError("Unable to realloc alproto_names."); + } + alpd_ctx.alproto_names = tmp; + memset(&alpd_ctx.alproto_names[alpd_ctx.alproto_names_len], 0, + sizeof(char *) * (g_alproto_max - alpd_ctx.alproto_names_len)); + alpd_ctx.alproto_names_len = g_alproto_max; + } if (alpd_ctx.alproto_names[alproto] == NULL) alpd_ctx.alproto_names[alproto] = alproto_name; @@ -2121,6 +2136,9 @@ void AppLayerProtoDetectSupportedAppProtocols(AppProto *alprotos) static void AppLayerProtoDetectPEGetIpprotos(AppProto alproto, uint8_t *ipprotos) { + if (alproto >= alpd_ctx.expectation_proto_len) { + return; + } if (alpd_ctx.expectation_proto[alproto] == IPPROTO_TCP) { ipprotos[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8); } diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index c4d742f8b3d8..21c48f141b56 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -124,6 +124,7 @@ typedef struct AppLayerParserProtoCtx_ typedef struct AppLayerParserCtx_ { AppLayerParserProtoCtx (*ctxs)[FLOW_PROTO_MAX]; + size_t ctxs_len; } AppLayerParserCtx; struct AppLayerParserState_ { @@ -254,6 +255,7 @@ int AppLayerParserSetup(void) if (unlikely(alp_ctx.ctxs == NULL)) { FatalError("Unable to alloc alp_ctx.ctxs."); } + alp_ctx.ctxs_len = g_alproto_max; SCReturnInt(0); } @@ -426,6 +428,20 @@ void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto, { SCEnter(); + if (alp_ctx.ctxs_len <= alproto && alproto < g_alproto_max) { + // Realloc now as AppLayerParserRegisterStateFuncs is called first + void *tmp = SCRealloc( + alp_ctx.ctxs, sizeof(AppLayerParserProtoCtx[FLOW_PROTO_MAX]) * g_alproto_max); + if (unlikely(tmp == NULL)) { + FatalError("Unable to realloc alp_ctx.ctxs."); + } + alp_ctx.ctxs = tmp; + memset(&alp_ctx.ctxs[alp_ctx.ctxs_len], 0, + sizeof(AppLayerParserProtoCtx[FLOW_PROTO_MAX]) * + (g_alproto_max - alp_ctx.ctxs_len)); + alp_ctx.ctxs_len = g_alproto_max; + } + alp_ctx.ctxs[alproto][FlowGetProtoMapping(ipproto)].StateAlloc = StateAlloc; alp_ctx.ctxs[alproto][FlowGetProtoMapping(ipproto)].StateFree = StateFree; @@ -1684,7 +1700,6 @@ static void ValidateParserProto(AppProto alproto, uint8_t ipproto) } #undef BOTH_SET #undef BOTH_SET_OR_BOTH_UNSET -#undef THREE_SET_OR_THREE_UNSET #undef THREE_SET static void ValidateParser(AppProto alproto) diff --git a/src/app-layer-protos.c b/src/app-layer-protos.c index 3f991f35d404..19db07cd8477 100644 --- a/src/app-layer-protos.c +++ b/src/app-layer-protos.c @@ -71,6 +71,12 @@ AppProto StringToAppProto(const char *proto_name) return ALPROTO_UNKNOWN; } +AppProto AppProtoNewProtoFromString(const char *proto_name) +{ + AppProtoRegisterProtoString(g_alproto_max, proto_name); + return g_alproto_max - 1; +} + void AppProtoRegisterProtoString(AppProto alproto, const char *proto_name) { if (alproto < ALPROTO_MAX_STATIC) { diff --git a/src/app-layer-protos.h b/src/app-layer-protos.h index 813e58f13d3b..d3a1932fd017 100644 --- a/src/app-layer-protos.h +++ b/src/app-layer-protos.h @@ -56,7 +56,6 @@ enum AppProtoEnum { ALPROTO_KRB5, ALPROTO_QUIC, ALPROTO_DHCP, - ALPROTO_SNMP, ALPROTO_SIP, ALPROTO_RFB, ALPROTO_MQTT, @@ -78,6 +77,7 @@ enum AppProtoEnum { /* keep last */ ALPROTO_MAX_STATIC, // After this ALPROTO_MAX_STATIC can come dynamic alproto ids + // For example, ALPROTO_SNMP is now dynamic }; // NOTE: if ALPROTO's get >= 256, update SignatureNonPrefilterStore @@ -175,6 +175,8 @@ const char *AppProtoToString(AppProto alproto); */ AppProto StringToAppProto(const char *proto_name); +AppProto AppProtoNewProtoFromString(const char *proto_name); + void AppProtoRegisterProtoString(AppProto alproto, const char *proto_name); #endif /* SURICATA_APP_LAYER_PROTOS_H */ diff --git a/src/app-layer.c b/src/app-layer.c index e5efcdf361d1..a7397b85d542 100644 --- a/src/app-layer.c +++ b/src/app-layer.c @@ -1055,7 +1055,6 @@ static void AppLayerNamesSetup(void) AppProtoRegisterProtoString(ALPROTO_KRB5, "krb5"); AppProtoRegisterProtoString(ALPROTO_QUIC, "quic"); AppProtoRegisterProtoString(ALPROTO_DHCP, "dhcp"); - AppProtoRegisterProtoString(ALPROTO_SNMP, "snmp"); AppProtoRegisterProtoString(ALPROTO_SIP, "sip"); AppProtoRegisterProtoString(ALPROTO_RFB, "rfb"); AppProtoRegisterProtoString(ALPROTO_MQTT, "mqtt"); diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index 10af70b1d0f7..6759f08e4a1b 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -734,7 +734,6 @@ void SigTableSetup(void) DetectVlanLayersRegister(); SCDetectSMTPRegister(); - SCDetectSNMPRegister(); SCDetectDHCPRegister(); SCDetectWebsocketRegister(); SCDetectEnipRegister(); diff --git a/src/detect-parse.c b/src/detect-parse.c index 9c711d14c254..15c873e529b2 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -119,7 +119,9 @@ void DetectFileRegisterProto( al_protocols[i].direction = direction; al_protocols[i].to_client_progress = to_client_progress; al_protocols[i].to_server_progress = to_server_progress; - al_protocols[i + 1].alproto = ALPROTO_UNKNOWN; + if (i + 1 < ALPROTO_WITHFILES_MAX) { + al_protocols[i + 1].alproto = ALPROTO_UNKNOWN; + } } void DetectFileRegisterFileProtocols(DetectFileHandlerTableElmt *reg) diff --git a/src/output-json.h b/src/output-json.h index 82989a115639..ab94dd42cc4e 100644 --- a/src/output-json.h +++ b/src/output-json.h @@ -33,13 +33,6 @@ void OutputJsonRegister(void); -enum OutputJsonLogDirection { - LOG_DIR_PACKET = 0, - LOG_DIR_FLOW, - LOG_DIR_FLOW_TOCLIENT, - LOG_DIR_FLOW_TOSERVER, -}; - #define JSON_ADDR_LEN 46 #define JSON_PROTO_LEN 16 diff --git a/src/output.c b/src/output.c index 7a9c86a267b7..46b2c28216ca 100644 --- a/src/output.c +++ b/src/output.c @@ -903,8 +903,6 @@ void OutputRegisterRootLoggers(void) ALPROTO_KRB5, (EveJsonSimpleTxLogFunc)rs_krb5_log_json_response, NULL); RegisterSimpleJsonApplayerLogger(ALPROTO_QUIC, rs_quic_to_json, NULL); // ALPROTO_DHCP TODO missing - RegisterSimpleJsonApplayerLogger( - ALPROTO_SNMP, (EveJsonSimpleTxLogFunc)rs_snmp_log_json_response, NULL); RegisterSimpleJsonApplayerLogger(ALPROTO_SIP, (EveJsonSimpleTxLogFunc)rs_sip_log_json, NULL); RegisterSimpleJsonApplayerLogger(ALPROTO_RFB, rs_rfb_logger_log, NULL); RegisterSimpleJsonApplayerLogger(ALPROTO_MQTT, JsonMQTTAddMetadata, NULL); @@ -993,6 +991,15 @@ int OutputPreRegisterLogger(EveJsonTxLoggerRegistrationData reg_data) return 0; } +static TxLogger JsonLoggerFromDir(uint8_t dir) +{ + if (dir == LOG_DIR_PACKET) { + return JsonGenericDirPacketLogger; + } + BUG_ON(dir != LOG_DIR_FLOW); + return JsonGenericDirFlowLogger; +} + /** * \brief Register all non-root logging modules. */ @@ -1093,12 +1100,7 @@ void OutputRegisterLoggers(void) SCLogDebug("quic json logger registered."); /* DHCP JSON logger. */ JsonDHCPLogRegister(); - /* SNMP JSON logger. */ - OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonSNMPLog", "eve-log.snmp", - OutputJsonLogInitSub, ALPROTO_SNMP, JsonGenericDirPacketLogger, JsonLogThreadInit, - JsonLogThreadDeinit); - SCLogDebug("SNMP JSON logger registered."); /* SIP JSON logger. */ OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonSIPLog", "eve-log.sip", OutputJsonLogInitSub, ALPROTO_SIP, JsonGenericDirPacketLogger, JsonLogThreadInit, @@ -1153,11 +1155,11 @@ void OutputRegisterLoggers(void) for (size_t i = 0; i < preregistered_loggers_nb; i++) { OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", preregistered_loggers[i].logname, preregistered_loggers[i].confname, OutputJsonLogInitSub, - preregistered_loggers[i].alproto, JsonGenericDirFlowLogger, JsonLogThreadInit, - JsonLogThreadDeinit); + preregistered_loggers[i].alproto, JsonLoggerFromDir(preregistered_loggers[i].dir), + JsonLogThreadInit, JsonLogThreadDeinit); SCLogDebug( "%s JSON logger registered.", AppProtoToString(preregistered_loggers[i].alproto)); - RegisterSimpleJsonApplayerLogger( - preregistered_loggers[i].alproto, preregistered_loggers[i].LogTx, NULL); + RegisterSimpleJsonApplayerLogger(preregistered_loggers[i].alproto, + (EveJsonSimpleTxLogFunc)preregistered_loggers[i].LogTx, NULL); } } diff --git a/src/output.h b/src/output.h index bc8086fc4a82..56d9b888c9cf 100644 --- a/src/output.h +++ b/src/output.h @@ -26,6 +26,7 @@ #include "decode.h" #include "tm-modules.h" +#include "rust.h" #define DEFAULT_LOG_MODE_APPEND "yes" #define DEFAULT_LOG_FILETYPE "regular" @@ -181,13 +182,6 @@ typedef struct EveJsonSimpleAppLayerLogger { EveJsonSimpleAppLayerLogger *SCEveJsonSimpleGetLogger(AppProto alproto); -typedef struct EveJsonTxLoggerRegistrationData { - const char *confname; - const char *logname; - AppProto alproto; - EveJsonSimpleTxLogFunc LogTx; -} EveJsonTxLoggerRegistrationData; - int OutputPreRegisterLogger(EveJsonTxLoggerRegistrationData reg_data); #endif /* ! SURICATA_OUTPUT_H */ diff --git a/src/suricata-plugin.h b/src/suricata-plugin.h index 8bc2183d70fd..139113380743 100644 --- a/src/suricata-plugin.h +++ b/src/suricata-plugin.h @@ -63,7 +63,8 @@ typedef struct SCAppLayerPlugin_ { void (*KeywordsRegister)(void); char *logname; char *confname; - bool (*Logger)(void *tx, void *jb); + uint8_t dir; + bool (*Logger)(const void *tx, void *jb); } SCAppLayerPlugin; int SCPluginRegisterAppLayer(SCAppLayerPlugin *); diff --git a/src/util-plugin.c b/src/util-plugin.c index eb2ce7647e66..9ed97872a90e 100644 --- a/src/util-plugin.c +++ b/src/util-plugin.c @@ -159,8 +159,7 @@ int SCPluginRegisterAppLayer(SCAppLayerPlugin *plugin) if (plugin->version != SC_PLUGIN_API_VERSION) { return 1; } - AppProto alproto = g_alproto_max; - AppProtoRegisterProtoString(alproto, plugin->name); + AppProto alproto = AppProtoNewProtoFromString(plugin->name); if (plugin->Register) { if (AppLayerParserPreRegister(plugin->Register) != 0) { return 1; @@ -176,7 +175,8 @@ int SCPluginRegisterAppLayer(SCAppLayerPlugin *plugin) .confname = plugin->confname, .logname = plugin->logname, .alproto = alproto, - .LogTx = (EveJsonSimpleTxLogFunc)plugin->Logger, + .dir = plugin->dir, + .LogTx = plugin->Logger, }; if (OutputPreRegisterLogger(reg_data) != 0) { return 1;