diff --git a/rust/sys/src/sys.rs b/rust/sys/src/sys.rs index 90dd86c093..4823633b01 100644 --- a/rust/sys/src/sys.rs +++ b/rust/sys/src/sys.rs @@ -135,6 +135,43 @@ pub type SCAppLayerPlugin = SCAppLayerPlugin_; extern "C" { pub fn SCPluginRegisterAppLayer(arg1: *mut SCAppLayerPlugin) -> ::std::os::raw::c_int; } +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum SCOutputJsonLogDirection { + LOG_DIR_PACKET = 0, + LOG_DIR_FLOW = 1, + LOG_DIR_FLOW_TOCLIENT = 2, + LOG_DIR_FLOW_TOSERVER = 3, +} +pub type EveJsonSimpleTxLogFunc = ::std::option::Option< + unsafe extern "C" fn( + arg1: *const ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> bool, +>; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct EveJsonSimpleAppLayerLogger { + pub LogTx: EveJsonSimpleTxLogFunc, + pub name: *const ::std::os::raw::c_char, +} +extern "C" { + pub fn SCEveJsonSimpleGetLogger(alproto: AppProto) -> *mut EveJsonSimpleAppLayerLogger; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct EveJsonTxLoggerRegistrationData { + pub confname: *const ::std::os::raw::c_char, + pub logname: *const ::std::os::raw::c_char, + pub alproto: AppProto, + pub dir: u8, + pub LogTx: EveJsonSimpleTxLogFunc, +} +extern "C" { + pub fn SCOutputEvePreRegisterLogger( + reg_data: EveJsonTxLoggerRegistrationData, + ) -> ::std::os::raw::c_int; +} #[doc = " Structure of a configuration parameter."] #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/src/Makefile.am b/src/Makefile.am index 3591e11018..50eeb79c31 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -390,6 +390,7 @@ noinst_HEADERS = \ output-eve-syslog.h \ output-lua.h \ output-packet.h \ + output-eve-bindgen.h \ output-stats.h \ output-streaming.h \ output-tx.h \ diff --git a/src/bindgen.h b/src/bindgen.h index 9dccc75d96..a568685b2c 100644 --- a/src/bindgen.h +++ b/src/bindgen.h @@ -31,6 +31,7 @@ #include "app-layer-protos.h" #include "suricata-plugin.h" +#include "output-eve-bindgen.h" #include "conf.h" diff --git a/src/output-eve-bindgen.h b/src/output-eve-bindgen.h new file mode 100644 index 0000000000..0469d4cd88 --- /dev/null +++ b/src/output-eve-bindgen.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2025 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 + * + * This file contains definitions that should be made available + * to rust via bindgen. + * + */ + +#ifndef SURICATA_OUTPUT_PUBLIC_H +#define SURICATA_OUTPUT_PUBLIC_H + +#include "app-layer-protos.h" + +typedef enum SCOutputJsonLogDirection { + LOG_DIR_PACKET = 0, + LOG_DIR_FLOW, + LOG_DIR_FLOW_TOCLIENT, + LOG_DIR_FLOW_TOSERVER, +} SCOutputJsonLogDirection; + +typedef bool (*EveJsonSimpleTxLogFunc)(const void *, void *); + +typedef struct EveJsonSimpleAppLayerLogger { + EveJsonSimpleTxLogFunc LogTx; + const char *name; +} EveJsonSimpleAppLayerLogger; + +EveJsonSimpleAppLayerLogger *SCEveJsonSimpleGetLogger(AppProto alproto); + +typedef struct EveJsonTxLoggerRegistrationData { + const char *confname; + const char *logname; + AppProto alproto; + uint8_t dir; + EveJsonSimpleTxLogFunc LogTx; +} EveJsonTxLoggerRegistrationData; + +int SCOutputEvePreRegisterLogger(EveJsonTxLoggerRegistrationData reg_data); + +#endif /* ! SURICATA_OUTPUT_PUBLIC_H */ diff --git a/src/output-json-file.c b/src/output-json-file.c index c58f227653..3a678f4cf9 100644 --- a/src/output-json-file.c +++ b/src/output-json-file.c @@ -83,7 +83,7 @@ SCJsonBuilder *JsonBuildFileInfoRecord(const Packet *p, const File *ff, void *tx const uint64_t tx_id, const bool stored, uint8_t dir, HttpXFFCfg *xff_cfg, OutputJsonCtx *eve_ctx) { - enum OutputJsonLogDirection fdir = LOG_DIR_FLOW; + enum SCOutputJsonLogDirection fdir = LOG_DIR_FLOW; switch(dir) { case STREAM_TOCLIENT: diff --git a/src/output-json-mqtt.c b/src/output-json-mqtt.c index d619f31db8..2342f6323c 100644 --- a/src/output-json-mqtt.c +++ b/src/output-json-mqtt.c @@ -69,7 +69,7 @@ static int JsonMQTTLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id) { LogMQTTLogThread *thread = thread_data; - enum OutputJsonLogDirection dir; + enum SCOutputJsonLogDirection dir; if (SCMqttTxIsToClient((MQTTTransaction *)tx)) { dir = LOG_DIR_FLOW_TOCLIENT; diff --git a/src/output-json.c b/src/output-json.c index 17e1d9b112..4f8b3cad34 100644 --- a/src/output-json.c +++ b/src/output-json.c @@ -71,7 +71,7 @@ static void OutputJsonDeInitCtx(OutputCtx *); static void CreateEveCommunityFlowId(SCJsonBuilder *js, const Flow *f, const uint16_t seed); static int CreateJSONEther( - SCJsonBuilder *parent, const Packet *p, const Flow *f, enum OutputJsonLogDirection dir); + SCJsonBuilder *parent, const Packet *p, const Flow *f, enum SCOutputJsonLogDirection dir); static const char *TRAFFIC_ID_PREFIX = "traffic/id/"; static const char *TRAFFIC_LABEL_PREFIX = "traffic/label/"; @@ -396,7 +396,7 @@ void EveAddMetadata(const Packet *p, const Flow *f, SCJsonBuilder *js) } void EveAddCommonOptions(const OutputJsonCommonSettings *cfg, const Packet *p, const Flow *f, - SCJsonBuilder *js, enum OutputJsonLogDirection dir) + SCJsonBuilder *js, enum SCOutputJsonLogDirection dir) { if (cfg->include_metadata) { EveAddMetadata(p, f, js); @@ -464,7 +464,7 @@ void EveTcpFlags(const uint8_t flags, SCJsonBuilder *js) JB_SET_TRUE(js, "cwr"); } -void JsonAddrInfoInit(const Packet *p, enum OutputJsonLogDirection dir, JsonAddrInfo *addr) +void JsonAddrInfoInit(const Packet *p, enum SCOutputJsonLogDirection dir, JsonAddrInfo *addr) { char srcip[46] = {0}, dstip[46] = {0}; Port sp, dp; @@ -735,7 +735,7 @@ static int MacSetIterateToJSON(uint8_t *val, MacSetSide side, void *data) } static int CreateJSONEther( - SCJsonBuilder *js, const Packet *p, const Flow *f, enum OutputJsonLogDirection dir) + SCJsonBuilder *js, const Packet *p, const Flow *f, enum SCOutputJsonLogDirection dir) { if (p != NULL) { /* this is a packet context, so we need to add scalar fields */ @@ -828,7 +828,7 @@ static int CreateJSONEther( return 0; } -SCJsonBuilder *CreateEveHeader(const Packet *p, enum OutputJsonLogDirection dir, +SCJsonBuilder *CreateEveHeader(const Packet *p, enum SCOutputJsonLogDirection dir, const char *event_type, JsonAddrInfo *addr, OutputJsonCtx *eve_ctx) { char timebuf[64]; @@ -924,7 +924,7 @@ SCJsonBuilder *CreateEveHeader(const Packet *p, enum OutputJsonLogDirection dir, return js; } -SCJsonBuilder *CreateEveHeaderWithTxId(const Packet *p, enum OutputJsonLogDirection dir, +SCJsonBuilder *CreateEveHeaderWithTxId(const Packet *p, enum SCOutputJsonLogDirection dir, const char *event_type, JsonAddrInfo *addr, uint64_t tx_id, OutputJsonCtx *eve_ctx) { SCJsonBuilder *js = CreateEveHeader(p, dir, event_type, addr, eve_ctx); diff --git a/src/output-json.h b/src/output-json.h index 47c0e5b463..a126391f28 100644 --- a/src/output-json.h +++ b/src/output-json.h @@ -28,18 +28,12 @@ #include "util-buffer.h" #include "util-logopenfile.h" #include "output.h" +#include "output-eve-bindgen.h" #include "app-layer-htp-xff.h" 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 @@ -56,8 +50,7 @@ typedef struct JsonAddrInfo_ { extern const JsonAddrInfo json_addr_info_zero; -void JsonAddrInfoInit(const Packet *p, enum OutputJsonLogDirection dir, - JsonAddrInfo *addr); +void JsonAddrInfoInit(const Packet *p, enum SCOutputJsonLogDirection dir, JsonAddrInfo *addr); /* Suggested output buffer size */ #define JSON_OUTPUT_BUFFER_SIZE 65535 @@ -99,9 +92,9 @@ void CreateEveFlowId(SCJsonBuilder *js, const Flow *f); void EveFileInfo(SCJsonBuilder *js, const File *file, const uint64_t tx_id, const uint16_t flags); void EveTcpFlags(uint8_t flags, SCJsonBuilder *js); void EvePacket(const Packet *p, SCJsonBuilder *js, uint32_t max_length); -SCJsonBuilder *CreateEveHeader(const Packet *p, enum OutputJsonLogDirection dir, +SCJsonBuilder *CreateEveHeader(const Packet *p, enum SCOutputJsonLogDirection dir, const char *event_type, JsonAddrInfo *addr, OutputJsonCtx *eve_ctx); -SCJsonBuilder *CreateEveHeaderWithTxId(const Packet *p, enum OutputJsonLogDirection dir, +SCJsonBuilder *CreateEveHeaderWithTxId(const Packet *p, enum SCOutputJsonLogDirection dir, const char *event_type, JsonAddrInfo *addr, uint64_t tx_id, OutputJsonCtx *eve_ctx); int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer **buffer); void OutputJsonBuilderBuffer( @@ -113,7 +106,7 @@ TmEcode JsonLogThreadInit(ThreadVars *t, const void *initdata, void **data); TmEcode JsonLogThreadDeinit(ThreadVars *t, void *data); void EveAddCommonOptions(const OutputJsonCommonSettings *cfg, const Packet *p, const Flow *f, - SCJsonBuilder *js, enum OutputJsonLogDirection dir); + SCJsonBuilder *js, enum SCOutputJsonLogDirection dir); int OutputJsonLogFlush(ThreadVars *tv, void *thread_data, const Packet *p); void EveAddMetadata(const Packet *p, const Flow *f, SCJsonBuilder *js); diff --git a/src/output.c b/src/output.c index 2877353bcf..f16a1e8a9b 100644 --- a/src/output.c +++ b/src/output.c @@ -39,6 +39,7 @@ #include "util-error.h" #include "util-debug.h" #include "output.h" +#include "output-eve-bindgen.h" #include "alert-fastlog.h" #include "alert-debuglog.h" @@ -880,46 +881,53 @@ void OutputRegisterRootLoggers(void) FatalError("Failed to allocate simple_json_applayer_loggers"); } // ALPROTO_HTTP1 special: uses some options flags - RegisterSimpleJsonApplayerLogger(ALPROTO_FTP, EveFTPLogCommand, NULL); + RegisterSimpleJsonApplayerLogger(ALPROTO_FTP, (EveJsonSimpleTxLogFunc)EveFTPLogCommand, NULL); // ALPROTO_SMTP special: uses state - RegisterSimpleJsonApplayerLogger(ALPROTO_TLS, JsonTlsLogJSONExtended, NULL); + RegisterSimpleJsonApplayerLogger( + ALPROTO_TLS, (EveJsonSimpleTxLogFunc)JsonTlsLogJSONExtended, NULL); // no cast here but done in rust for SSHTransaction - RegisterSimpleJsonApplayerLogger(ALPROTO_SSH, SCSshLogJson, NULL); + RegisterSimpleJsonApplayerLogger(ALPROTO_SSH, (EveJsonSimpleTxLogFunc)SCSshLogJson, NULL); // ALPROTO_SMB special: uses state // ALPROTO_DCERPC special: uses state - RegisterSimpleJsonApplayerLogger(ALPROTO_DNS, AlertJsonDns, NULL); + RegisterSimpleJsonApplayerLogger(ALPROTO_DNS, (EveJsonSimpleTxLogFunc)AlertJsonDns, NULL); // either need a cast here or in rust for ModbusTransaction, done here RegisterSimpleJsonApplayerLogger( ALPROTO_MODBUS, (EveJsonSimpleTxLogFunc)rs_modbus_to_json, NULL); - RegisterSimpleJsonApplayerLogger(ALPROTO_ENIP, SCEnipLoggerLog, NULL); - RegisterSimpleJsonApplayerLogger(ALPROTO_DNP3, AlertJsonDnp3, NULL); + RegisterSimpleJsonApplayerLogger(ALPROTO_ENIP, (EveJsonSimpleTxLogFunc)SCEnipLoggerLog, NULL); + RegisterSimpleJsonApplayerLogger(ALPROTO_DNP3, (EveJsonSimpleTxLogFunc)AlertJsonDnp3, NULL); // ALPROTO_NFS special: uses state // underscore instead of dash for ftp_data - RegisterSimpleJsonApplayerLogger(ALPROTO_FTPDATA, EveFTPDataAddMetadata, "ftp_data"); + RegisterSimpleJsonApplayerLogger( + ALPROTO_FTPDATA, (EveJsonSimpleTxLogFunc)EveFTPDataAddMetadata, "ftp_data"); RegisterSimpleJsonApplayerLogger( ALPROTO_TFTP, (EveJsonSimpleTxLogFunc)rs_tftp_log_json_request, NULL); // ALPROTO_IKE special: uses state RegisterSimpleJsonApplayerLogger( ALPROTO_KRB5, (EveJsonSimpleTxLogFunc)rs_krb5_log_json_response, NULL); - RegisterSimpleJsonApplayerLogger(ALPROTO_QUIC, rs_quic_to_json, NULL); + RegisterSimpleJsonApplayerLogger(ALPROTO_QUIC, (EveJsonSimpleTxLogFunc)rs_quic_to_json, NULL); // ALPROTO_DHCP TODO missing RegisterSimpleJsonApplayerLogger( ALPROTO_SNMP, (EveJsonSimpleTxLogFunc)SCSnmpLogJsonResponse, NULL); RegisterSimpleJsonApplayerLogger(ALPROTO_SIP, (EveJsonSimpleTxLogFunc)rs_sip_log_json, NULL); - RegisterSimpleJsonApplayerLogger(ALPROTO_RFB, rs_rfb_logger_log, NULL); - RegisterSimpleJsonApplayerLogger(ALPROTO_MQTT, JsonMQTTAddMetadata, NULL); - RegisterSimpleJsonApplayerLogger(ALPROTO_PGSQL, JsonPgsqlAddMetadata, NULL); - RegisterSimpleJsonApplayerLogger(ALPROTO_WEBSOCKET, rs_websocket_logger_log, NULL); - RegisterSimpleJsonApplayerLogger(ALPROTO_LDAP, rs_ldap_logger_log, NULL); - RegisterSimpleJsonApplayerLogger(ALPROTO_DOH2, AlertJsonDoh2, NULL); + RegisterSimpleJsonApplayerLogger(ALPROTO_RFB, (EveJsonSimpleTxLogFunc)rs_rfb_logger_log, NULL); + RegisterSimpleJsonApplayerLogger( + ALPROTO_MQTT, (EveJsonSimpleTxLogFunc)JsonMQTTAddMetadata, NULL); + RegisterSimpleJsonApplayerLogger( + ALPROTO_PGSQL, (EveJsonSimpleTxLogFunc)JsonPgsqlAddMetadata, NULL); + RegisterSimpleJsonApplayerLogger( + ALPROTO_WEBSOCKET, (EveJsonSimpleTxLogFunc)rs_websocket_logger_log, NULL); + RegisterSimpleJsonApplayerLogger( + ALPROTO_LDAP, (EveJsonSimpleTxLogFunc)rs_ldap_logger_log, NULL); + RegisterSimpleJsonApplayerLogger(ALPROTO_DOH2, (EveJsonSimpleTxLogFunc)AlertJsonDoh2, NULL); RegisterSimpleJsonApplayerLogger( ALPROTO_TEMPLATE, (EveJsonSimpleTxLogFunc)rs_template_logger_log, NULL); RegisterSimpleJsonApplayerLogger(ALPROTO_RDP, (EveJsonSimpleTxLogFunc)SCRdpToJson, NULL); // special case : http2 is logged in http object - RegisterSimpleJsonApplayerLogger(ALPROTO_HTTP2, rs_http2_log_json, "http"); - // underscore instead of dash for bittorrent_dht RegisterSimpleJsonApplayerLogger( - ALPROTO_BITTORRENT_DHT, SCBittorrentDhtLogger, "bittorrent_dht"); + ALPROTO_HTTP2, (EveJsonSimpleTxLogFunc)rs_http2_log_json, "http"); + // underscore instead of dash for bittorrent_dht + RegisterSimpleJsonApplayerLogger(ALPROTO_BITTORRENT_DHT, + (EveJsonSimpleTxLogFunc)SCBittorrentDhtLogger, "bittorrent_dht"); OutputPacketLoggerRegister(); OutputFiledataLoggerRegister(); @@ -977,7 +985,7 @@ static size_t preregistered_loggers_cap = 0; // When an app-layer plugin is loaded, it wants to register its logger // But the plugin is loaded before loggers can register // The preregistration data will later be used by OutputRegisterLoggers -int OutputPreRegisterLogger(EveJsonTxLoggerRegistrationData reg_data) +int SCOutputEvePreRegisterLogger(EveJsonTxLoggerRegistrationData reg_data) { if (preregistered_loggers_nb == preregistered_loggers_cap) { void *tmp = SCRealloc( @@ -1167,7 +1175,7 @@ void OutputRegisterLoggers(void) 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 0720a459eb..64196716c9 100644 --- a/src/output.h +++ b/src/output.h @@ -172,23 +172,4 @@ void OutputLoggerExitPrintStats(ThreadVars *, void *); void OutputSetupActiveLoggers(void); void OutputClearActiveLoggers(void); -typedef bool (*EveJsonSimpleTxLogFunc)(void *, struct SCJsonBuilder *); - -typedef struct EveJsonSimpleAppLayerLogger { - EveJsonSimpleTxLogFunc LogTx; - const char *name; -} EveJsonSimpleAppLayerLogger; - -EveJsonSimpleAppLayerLogger *SCEveJsonSimpleGetLogger(AppProto alproto); - -typedef struct EveJsonTxLoggerRegistrationData { - const char *confname; - const char *logname; - AppProto alproto; - uint8_t dir; - EveJsonSimpleTxLogFunc LogTx; -} EveJsonTxLoggerRegistrationData; - -int OutputPreRegisterLogger(EveJsonTxLoggerRegistrationData reg_data); - #endif /* ! SURICATA_OUTPUT_H */ diff --git a/src/util-plugin.c b/src/util-plugin.c index 5254e6b275..564c1f5dba 100644 --- a/src/util-plugin.c +++ b/src/util-plugin.c @@ -29,6 +29,7 @@ #include "app-layer-parser.h" #include "detect-engine-register.h" #include "output.h" +#include "output-eve-bindgen.h" #include @@ -180,9 +181,9 @@ int SCPluginRegisterAppLayer(SCAppLayerPlugin *plugin) .logname = plugin->logname, .alproto = alproto, .dir = plugin->dir, - .LogTx = (EveJsonSimpleTxLogFunc)plugin->Logger, + .LogTx = plugin->Logger, }; - if (OutputPreRegisterLogger(reg_data) != 0) { + if (SCOutputEvePreRegisterLogger(reg_data) != 0) { return 1; } }