output/alert: rewrite code for app-layer properties

Especially fix setup-app-layer script to not forget this part

This allows, for simple loggers, to have a unique definition
of the actual logging function with the jsonbuilder.
This way, alerts, files, and app-layer event can share the code
to output the same data.

Ticket: #3827
pull/9851/head
Philippe Antoine 2 years ago
parent 90c17652a3
commit 0b6b015e26

@ -20,12 +20,14 @@ use crate::jsonbuilder::{JsonBuilder, JsonError};
use std;
fn log_template(tx: &TemplateTransaction, js: &mut JsonBuilder) -> Result<(), JsonError> {
js.open_object("template")?;
if let Some(ref request) = tx.request {
js.set_string("request", request)?;
}
if let Some(ref response) = tx.response {
js.set_string("response", response)?;
}
js.close()?;
Ok(())
}

@ -48,6 +48,7 @@ fn print_ip_addr(addr: &[u8]) -> std::string::String {
fn log_bittorrent_dht(
tx: &BitTorrentDHTTransaction, js: &mut JsonBuilder,
) -> Result<(), JsonError> {
js.open_object("bittorrent_dht")?;
js.set_hex("transaction_id", &tx.transaction_id)?;
if let Some(client_version) = &tx.client_version {
js.set_hex("client_version", client_version)?;
@ -125,6 +126,7 @@ fn log_bittorrent_dht(
}
js.close()?;
};
js.close()?;
Ok(())
}

@ -192,6 +192,7 @@ fn log_http2_frames(frames: &[HTTP2Frame], js: &mut JsonBuilder) -> Result<bool,
}
fn log_http2(tx: &HTTP2Transaction, js: &mut JsonBuilder) -> Result<bool, JsonError> {
js.open_object("http")?;
js.set_string("version", "2")?;
let mut common: HashMap<HeaderName, &Vec<u8>> = HashMap::new();
@ -261,8 +262,8 @@ fn log_http2(tx: &HTTP2Transaction, js: &mut JsonBuilder) -> Result<bool, JsonEr
let has_response = log_http2_frames(&tx.frames_tc, js)?;
js.close()?;
// Close http2.
js.close()?;
js.close()?; // http2
js.close()?; // http
return Ok(has_request || has_response || has_headers);
}

@ -88,7 +88,7 @@ fn quic_tls_extension_name(e: u16) -> Option<String> {
}
}
fn log_template(tx: &QuicTransaction, js: &mut JsonBuilder) -> Result<(), JsonError> {
fn log_quic(tx: &QuicTransaction, js: &mut JsonBuilder) -> Result<(), JsonError> {
js.open_object("quic")?;
if tx.header.ty != QuicType::Short {
js.set_string("version", String::from(tx.header.version).as_str())?;
@ -153,5 +153,5 @@ pub unsafe extern "C" fn rs_quic_to_json(
tx: *mut std::os::raw::c_void, js: &mut JsonBuilder,
) -> bool {
let tx = cast_pointer!(tx, QuicTransaction);
log_template(tx, js).is_ok()
log_quic(tx, js).is_ok()
}

@ -39,6 +39,7 @@ fn str_of_pdu_type(t:&PduType) -> Cow<str> {
fn snmp_log_response(jsb: &mut JsonBuilder, tx: &mut SNMPTransaction) -> Result<(), JsonError>
{
jsb.open_object("snmp")?;
jsb.set_uint("version", tx.version as u64)?;
if tx.encrypted {
jsb.set_string("pdu_type", "encrypted")?;
@ -71,11 +72,12 @@ fn snmp_log_response(jsb: &mut JsonBuilder, tx: &mut SNMPTransaction) -> Result<
}
}
jsb.close()?;
return Ok(());
}
#[no_mangle]
pub extern "C" fn rs_snmp_log_json_response(jsb: &mut JsonBuilder, tx: &mut SNMPTransaction) -> bool
pub extern "C" fn rs_snmp_log_json_response(tx: &mut SNMPTransaction, jsb: &mut JsonBuilder) -> bool
{
snmp_log_response(jsb, tx).is_ok()
}

@ -19,6 +19,7 @@ use super::ssh::SSHTransaction;
use crate::jsonbuilder::{JsonBuilder, JsonError};
fn log_ssh(tx: &SSHTransaction, js: &mut JsonBuilder) -> Result<bool, JsonError> {
js.open_object("ssh")?;
if tx.cli_hdr.protover.is_empty() && tx.srv_hdr.protover.is_empty() {
return Ok(false);
}
@ -58,6 +59,7 @@ fn log_ssh(tx: &SSHTransaction, js: &mut JsonBuilder) -> Result<bool, JsonError>
}
js.close()?;
}
js.close()?;
return Ok(true);
}

@ -200,6 +200,10 @@ def logger_patch_output_c(proto):
output = io.StringIO()
inlines = open(filename).readlines()
for i, line in enumerate(inlines):
if line.find("ALPROTO_TEMPLATE") > -1:
new_line = line.replace("TEMPLATE", proto.upper()).replace(
"template", proto.lower())
output.write(new_line)
if line.find("output-json-template.h") > -1:
output.write(line.replace("template", proto.lower()))
if line.find("/* Template JSON logger.") > -1:

@ -1405,13 +1405,10 @@ uint16_t JsonGetNextLineFromBuffer(const char *buffer, const uint16_t len)
return c == NULL ? len : (uint16_t)(c - buffer + 1);
}
void EveFTPDataAddMetadata(const Flow *f, JsonBuilder *jb)
bool EveFTPDataAddMetadata(void *vtx, JsonBuilder *jb)
{
const FtpDataState *ftp_state = NULL;
if (f->alstate == NULL)
return;
ftp_state = (FtpDataState *)f->alstate;
const FtpDataState *ftp_state = (FtpDataState *)vtx;
jb_open_object(jb, "ftp_data");
if (ftp_state->file_name) {
jb_set_string_from_bytes(jb, "filename", ftp_state->file_name, ftp_state->file_len);
@ -1426,6 +1423,8 @@ void EveFTPDataAddMetadata(const Flow *f, JsonBuilder *jb)
default:
break;
}
jb_close(jb);
return true;
}
/**

@ -190,7 +190,7 @@ uint64_t FTPMemuseGlobalCounter(void);
uint64_t FTPMemcapGlobalCounter(void);
uint16_t JsonGetNextLineFromBuffer(const char *buffer, const uint16_t len);
void EveFTPDataAddMetadata(const Flow *f, JsonBuilder *jb);
bool EveFTPDataAddMetadata(void *vtx, JsonBuilder *jb);
#endif /* __APP_LAYER_FTP_H__ */

@ -137,164 +137,6 @@ static int AlertJsonDumpStreamSegmentCallback(
return 1;
}
static void AlertJsonTls(const Flow *f, JsonBuilder *js)
{
SSLState *ssl_state = (SSLState *)FlowGetAppState(f);
if (ssl_state) {
jb_open_object(js, "tls");
JsonTlsLogJSONExtended(js, ssl_state);
jb_close(js);
}
return;
}
static void AlertJsonSsh(const Flow *f, JsonBuilder *js)
{
void *ssh_state = FlowGetAppState(f);
if (ssh_state) {
JsonBuilderMark mark = { 0, 0, 0 };
void *tx_ptr = rs_ssh_state_get_tx(ssh_state, 0);
jb_get_mark(js, &mark);
jb_open_object(js, "ssh");
if (rs_ssh_log_json(tx_ptr, js)) {
jb_close(js);
} else {
jb_restore_mark(js, &mark);
}
}
return;
}
static void AlertJsonHttp2(const Flow *f, const uint64_t tx_id, JsonBuilder *js)
{
void *h2_state = FlowGetAppState(f);
if (h2_state) {
void *tx_ptr = rs_http2_state_get_tx(h2_state, tx_id);
if (tx_ptr) {
JsonBuilderMark mark = { 0, 0, 0 };
jb_get_mark(js, &mark);
jb_open_object(js, "http");
if (rs_http2_log_json(tx_ptr, js)) {
jb_close(js);
} else {
jb_restore_mark(js, &mark);
}
}
}
return;
}
static void AlertJsonDnp3(const Flow *f, const uint64_t tx_id, JsonBuilder *js)
{
DNP3State *dnp3_state = (DNP3State *)FlowGetAppState(f);
if (dnp3_state) {
DNP3Transaction *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_DNP3,
dnp3_state, tx_id);
if (tx) {
JsonBuilderMark mark = { 0, 0, 0 };
jb_get_mark(js, &mark);
bool logged = false;
jb_open_object(js, "dnp3");
if (tx->is_request && tx->done) {
jb_open_object(js, "request");
JsonDNP3LogRequest(js, tx);
jb_close(js);
logged = true;
}
if (!tx->is_request && tx->done) {
jb_open_object(js, "response");
JsonDNP3LogResponse(js, tx);
jb_close(js);
logged = true;
}
if (logged) {
/* Close dnp3 object. */
jb_close(js);
} else {
jb_restore_mark(js, &mark);
}
}
}
}
static void AlertJsonDns(const Flow *f, const uint64_t tx_id, JsonBuilder *js)
{
void *dns_state = (void *)FlowGetAppState(f);
if (dns_state) {
void *txptr = AppLayerParserGetTx(f->proto, ALPROTO_DNS,
dns_state, tx_id);
if (txptr) {
jb_open_object(js, "dns");
JsonBuilder *qjs = JsonDNSLogQuery(txptr);
if (qjs != NULL) {
jb_set_object(js, "query", qjs);
jb_free(qjs);
}
JsonBuilder *ajs = JsonDNSLogAnswer(txptr);
if (ajs != NULL) {
jb_set_object(js, "answer", ajs);
jb_free(ajs);
}
jb_close(js);
}
}
return;
}
static void AlertJsonSNMP(const Flow *f, const uint64_t tx_id, JsonBuilder *js)
{
void *snmp_state = (void *)FlowGetAppState(f);
if (snmp_state != NULL) {
void *tx = AppLayerParserGetTx(f->proto, ALPROTO_SNMP, snmp_state,
tx_id);
if (tx != NULL) {
jb_open_object(js, "snmp");
rs_snmp_log_json_response(js, tx);
jb_close(js);
}
}
}
static void AlertJsonRDP(const Flow *f, const uint64_t tx_id, JsonBuilder *js)
{
void *rdp_state = (void *)FlowGetAppState(f);
if (rdp_state != NULL) {
void *tx = AppLayerParserGetTx(f->proto, ALPROTO_RDP, rdp_state,
tx_id);
if (tx != NULL) {
JsonBuilderMark mark = { 0, 0, 0 };
jb_get_mark(js, &mark);
if (!rs_rdp_to_json(tx, js)) {
jb_restore_mark(js, &mark);
}
}
}
}
static void AlertJsonBitTorrentDHT(const Flow *f, const uint64_t tx_id, JsonBuilder *js)
{
void *bittorrent_dht_state = (void *)FlowGetAppState(f);
if (bittorrent_dht_state != NULL) {
void *tx =
AppLayerParserGetTx(f->proto, ALPROTO_BITTORRENT_DHT, bittorrent_dht_state, tx_id);
if (tx != NULL) {
JsonBuilderMark mark = { 0, 0, 0 };
jb_get_mark(js, &mark);
jb_open_object(js, "bittorrent_dht");
if (rs_bittorrent_dht_logger_log(tx, js)) {
jb_close(js);
} else {
jb_restore_mark(js, &mark);
}
}
}
}
static void AlertJsonSourceTarget(const Packet *p, const PacketAlert *pa,
JsonBuilder *js, JsonAddrInfo *addr)
{
@ -471,7 +313,21 @@ static void AlertAddAppLayer(const Packet *p, JsonBuilder *jb,
const uint64_t tx_id, const uint16_t option_flags)
{
const AppProto proto = FlowGetAppProtocol(p->flow);
EveJsonSimpleAppLayerLogger *al = SCEveJsonSimpleGetLogger(proto);
JsonBuilderMark mark = { 0, 0, 0 };
if (al && al->LogTx) {
void *state = FlowGetAppState(p->flow);
if (state) {
void *tx = AppLayerParserGetTx(p->flow->proto, proto, state, tx_id);
if (tx) {
jb_get_mark(jb, &mark);
if (!al->LogTx(tx, jb)) {
jb_restore_mark(jb, &mark);
}
}
}
return;
}
switch (proto) {
case ALPROTO_HTTP1:
// TODO: Could result in an empty http object being logged.
@ -486,12 +342,6 @@ static void AlertAddAppLayer(const Packet *p, JsonBuilder *jb,
}
jb_close(jb);
break;
case ALPROTO_TLS:
AlertJsonTls(p->flow, jb);
break;
case ALPROTO_SSH:
AlertJsonSsh(p->flow, jb);
break;
case ALPROTO_SMTP:
jb_get_mark(jb, &mark);
jb_open_object(jb, "smtp");
@ -535,63 +385,12 @@ static void AlertAddAppLayer(const Packet *p, JsonBuilder *jb,
jb_restore_mark(jb, &mark);
}
break;
case ALPROTO_SIP:
JsonSIPAddMetadata(jb, p->flow, tx_id);
break;
case ALPROTO_RFB:
jb_get_mark(jb, &mark);
if (!JsonRFBAddMetadata(p->flow, tx_id, jb)) {
jb_restore_mark(jb, &mark);
}
break;
case ALPROTO_FTPDATA:
jb_get_mark(jb, &mark);
jb_open_object(jb, "ftp_data");
EveFTPDataAddMetadata(p->flow, jb);
jb_close(jb);
break;
case ALPROTO_DNP3:
AlertJsonDnp3(p->flow, tx_id, jb);
break;
case ALPROTO_HTTP2:
AlertJsonHttp2(p->flow, tx_id, jb);
break;
case ALPROTO_DNS:
AlertJsonDns(p->flow, tx_id, jb);
break;
case ALPROTO_IKE:
jb_get_mark(jb, &mark);
if (!EveIKEAddMetadata(p->flow, tx_id, jb)) {
jb_restore_mark(jb, &mark);
}
break;
case ALPROTO_MQTT:
jb_get_mark(jb, &mark);
if (!JsonMQTTAddMetadata(p->flow, tx_id, jb)) {
jb_restore_mark(jb, &mark);
}
break;
case ALPROTO_QUIC:
jb_get_mark(jb, &mark);
if (!JsonQuicAddMetadata(p->flow, tx_id, jb)) {
jb_restore_mark(jb, &mark);
}
break;
case ALPROTO_SNMP:
AlertJsonSNMP(p->flow, tx_id, jb);
break;
case ALPROTO_RDP:
AlertJsonRDP(p->flow, tx_id, jb);
break;
case ALPROTO_MODBUS:
jb_get_mark(jb, &mark);
if (!JsonModbusAddMetadata(p->flow, tx_id, jb)) {
jb_restore_mark(jb, &mark);
}
break;
case ALPROTO_BITTORRENT_DHT:
AlertJsonBitTorrentDHT(p->flow, tx_id, jb);
break;
default:
break;
}

@ -65,11 +65,9 @@ static int JsonBitTorrentDHTLogger(ThreadVars *tv, void *thread_data, const Pack
return TM_ECODE_FAILED;
}
jb_open_object(js, "bittorrent_dht");
if (!rs_bittorrent_dht_logger_log(tx, js)) {
goto error;
}
jb_close(js);
OutputJsonBuilderBuffer(js, thread->ctx);
jb_free(js);

@ -210,6 +210,27 @@ void JsonDNP3LogResponse(JsonBuilder *js, DNP3Transaction *dnp3tx)
jb_close(js);
}
bool AlertJsonDnp3(void *vtx, JsonBuilder *js)
{
DNP3Transaction *tx = (DNP3Transaction *)vtx;
bool logged = false;
jb_open_object(js, "dnp3");
if (tx->is_request && tx->done) {
jb_open_object(js, "request");
JsonDNP3LogRequest(js, tx);
jb_close(js);
logged = true;
}
if (!tx->is_request && tx->done) {
jb_open_object(js, "response");
JsonDNP3LogResponse(js, tx);
jb_close(js);
logged = true;
}
jb_close(js);
return logged;
}
static int JsonDNP3LoggerToServer(ThreadVars *tv, void *thread_data,
const Packet *p, Flow *f, void *state, void *vtx, uint64_t tx_id)
{

@ -24,5 +24,6 @@ void JsonDNP3LogRequest(JsonBuilder *js, DNP3Transaction *);
void JsonDNP3LogResponse(JsonBuilder *js, DNP3Transaction *);
void JsonDNP3LogRegister(void);
bool AlertJsonDnp3(void *vtx, JsonBuilder *js);
#endif /* __OUTPUT_JSON_DNP3_H__ */

@ -263,7 +263,7 @@ typedef struct LogDnsLogThread_ {
OutputJsonThreadCtx *ctx;
} LogDnsLogThread;
JsonBuilder *JsonDNSLogQuery(void *txptr)
static JsonBuilder *JsonDNSLogQuery(void *txptr)
{
JsonBuilder *queryjb = jb_new_array();
if (queryjb == NULL) {
@ -292,7 +292,7 @@ JsonBuilder *JsonDNSLogQuery(void *txptr)
return queryjb;
}
JsonBuilder *JsonDNSLogAnswer(void *txptr)
static JsonBuilder *JsonDNSLogAnswer(void *txptr)
{
if (!rs_dns_do_log_answer(txptr, LOG_ALL_RRTYPES)) {
return NULL;
@ -304,6 +304,23 @@ JsonBuilder *JsonDNSLogAnswer(void *txptr)
}
}
bool AlertJsonDns(void *txptr, JsonBuilder *js)
{
jb_open_object(js, "dns");
JsonBuilder *qjs = JsonDNSLogQuery(txptr);
if (qjs != NULL) {
jb_set_object(js, "query", qjs);
jb_free(qjs);
}
JsonBuilder *ajs = JsonDNSLogAnswer(txptr);
if (ajs != NULL) {
jb_set_object(js, "answer", ajs);
jb_free(ajs);
}
jb_close(js);
return true;
}
static int JsonDnsLoggerToServer(ThreadVars *tv, void *thread_data,
const Packet *p, Flow *f, void *alstate, void *txptr, uint64_t tx_id)
{

@ -26,7 +26,6 @@
void JsonDnsLogRegister(void);
JsonBuilder *JsonDNSLogQuery(void *txptr) __attribute__((nonnull));
JsonBuilder *JsonDNSLogAnswer(void *txptr) __attribute__((nonnull));
bool AlertJsonDns(void *vtx, JsonBuilder *js);
#endif /* __OUTPUT_JSON_DNS_H__ */

@ -123,6 +123,7 @@ JsonBuilder *JsonBuildFileInfoRecord(const Packet *p, const File *ff, void *tx,
return NULL;
JsonBuilderMark mark = { 0, 0, 0 };
EveJsonSimpleAppLayerLogger *al;
switch (p->flow->alproto) {
case ALPROTO_HTTP1:
jb_open_object(js, "http");
@ -172,14 +173,20 @@ JsonBuilder *JsonBuildFileInfoRecord(const Packet *p, const File *ff, void *tx,
jb_restore_mark(js, &mark);
}
break;
case ALPROTO_HTTP2:
default:
al = SCEveJsonSimpleGetLogger(p->flow->alproto);
if (al && al->LogTx) {
void *state = FlowGetAppState(p->flow);
if (state) {
tx = AppLayerParserGetTx(p->flow->proto, p->flow->alproto, state, tx_id);
if (tx) {
jb_get_mark(js, &mark);
jb_open_object(js, "http");
if (EveHTTP2AddMetadata(p->flow, tx_id, js)) {
jb_close(js);
} else {
if (!al->LogTx(tx, js)) {
jb_restore_mark(js, &mark);
}
}
}
}
break;
}

@ -57,6 +57,7 @@ static void EveFTPLogCommand(FTPTransaction *tx, JsonBuilder *jb)
return;
}
}
jb_open_object(jb, "ftp");
jb_set_string(jb, "command", tx->command_descriptor->command_name);
uint32_t min_length = tx->command_descriptor->command_length + 1; /* command + space */
if (tx->request_length > min_length) {
@ -149,6 +150,7 @@ static void EveFTPLogCommand(FTPTransaction *tx, JsonBuilder *jb)
} else {
JB_SET_FALSE(jb, "reply_truncated");
}
jb_close(jb);
}
@ -169,17 +171,14 @@ static int JsonFTPLogger(ThreadVars *tv, void *thread_data,
JsonBuilder *jb =
CreateEveHeaderWithTxId(p, LOG_DIR_FLOW, event_type, NULL, tx_id, thread->ctx);
if (likely(jb)) {
jb_open_object(jb, event_type);
if (f->alproto == ALPROTO_FTPDATA) {
EveFTPDataAddMetadata(f, jb);
if (!EveFTPDataAddMetadata(vtx, jb)) {
goto fail;
}
} else {
EveFTPLogCommand(tx, jb);
}
if (!jb_close(jb)) {
goto fail;
}
OutputJsonBuilderBuffer(jb, thread);
jb_free(jb);

@ -61,19 +61,6 @@ typedef struct JsonHttp2LogThread_ {
OutputJsonThreadCtx *ctx;
} JsonHttp2LogThread;
bool EveHTTP2AddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *jb)
{
void *state = FlowGetAppState(f);
if (state) {
void *tx = AppLayerParserGetTx(f->proto, ALPROTO_HTTP2, state, tx_id);
if (tx) {
return rs_http2_log_json(tx, jb);
}
}
return false;
}
static int JsonHttp2Logger(ThreadVars *tv, void *thread_data, const Packet *p,
Flow *f, void *state, void *txptr, uint64_t tx_id)
{
@ -88,11 +75,9 @@ static int JsonHttp2Logger(ThreadVars *tv, void *thread_data, const Packet *p,
if (unlikely(js == NULL))
return 0;
jb_open_object(js, "http");
if (!rs_http2_log_json(txptr, js)) {
goto end;
}
jb_close(js);
OutputJsonBuilderBuffer(js, aft->ctx);
end:
jb_free(js);

@ -25,6 +25,5 @@
#define __OUTPUT_JSON_HTTP2_H__
void JsonHttp2LogRegister(void);
bool EveHTTP2AddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *jb);
#endif /* __OUTPUT_JSON_HTTP2_H__ */

@ -136,19 +136,6 @@ static TmEcode JsonModbusLogThreadDeinit(ThreadVars *t, void *data)
return TM_ECODE_OK;
}
bool JsonModbusAddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *js)
{
void *state = FlowGetAppState(f);
if (state) {
void *tx = AppLayerParserGetTx(f->proto, ALPROTO_MODBUS, state, tx_id);
if (tx) {
return rs_modbus_to_json(tx, js);
}
}
return false;
}
void JsonModbusLogRegister(void)
{
/* Register as an eve sub-module. */

@ -19,6 +19,5 @@
#define __OUTPUT_JSON_MODBUS_H__
void JsonModbusLogRegister(void);
bool JsonModbusAddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *js);
#endif /* __OUTPUT_JSON_MODBUS_H__ */

@ -59,17 +59,9 @@ typedef struct LogMQTTLogThread_ {
OutputJsonThreadCtx *ctx;
} LogMQTTLogThread;
bool JsonMQTTAddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *js)
bool JsonMQTTAddMetadata(void *vtx, JsonBuilder *js)
{
MQTTState *state = FlowGetAppState(f);
if (state) {
MQTTTransaction *tx = AppLayerParserGetTx(f->proto, ALPROTO_MQTT, state, tx_id);
if (tx) {
return rs_mqtt_logger_log(tx, MQTT_DEFAULTS, js);
}
}
return false;
return rs_mqtt_logger_log(vtx, MQTT_DEFAULTS, js);
}
static int JsonMQTTLogger(ThreadVars *tv, void *thread_data,

@ -25,6 +25,6 @@
#define __OUTPUT_JSON_MQTT_H__
void JsonMQTTLogRegister(void);
bool JsonMQTTAddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *js);
bool JsonMQTTAddMetadata(void *vtx, JsonBuilder *js);
#endif /* __OUTPUT_JSON_MQTT_H__ */

@ -140,19 +140,6 @@ static TmEcode JsonQuicLogThreadDeinit(ThreadVars *t, void *data)
return TM_ECODE_OK;
}
bool JsonQuicAddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *js)
{
void *state = FlowGetAppState(f);
if (state) {
void *tx = AppLayerParserGetTx(f->proto, ALPROTO_QUIC, state, tx_id);
if (tx) {
return rs_quic_to_json(tx, js);
}
}
return false;
}
void JsonQuicLogRegister(void)
{
/* Register as an eve sub-module. */

@ -22,7 +22,6 @@
#ifndef __OUTPUT_JSON_QUIC_H__
#define __OUTPUT_JSON_QUIC_H__
bool JsonQuicAddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *js);
void JsonQuicLogRegister(void);
#endif /* __OUTPUT_JSON_QUIC_H__ */

@ -46,19 +46,6 @@
#include "rust-bindings.h"
bool JsonRFBAddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *js)
{
void *state = FlowGetAppState(f);
if (state) {
RFBTransaction *tx = AppLayerParserGetTx(f->proto, ALPROTO_RFB, state, tx_id);
if (tx) {
return rs_rfb_logger_log(tx, js);
}
}
return false;
}
static int JsonRFBLogger(ThreadVars *tv, void *thread_data,
const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id)
{

@ -26,6 +26,4 @@
void JsonRFBLogRegister(void);
bool JsonRFBAddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *js);
#endif /* __OUTPUT_JSON_RFB_H__ */

@ -48,17 +48,6 @@
#include "rust.h"
void JsonSIPAddMetadata(JsonBuilder *js, const Flow *f, uint64_t tx_id)
{
SIPState *state = FlowGetAppState(f);
if (state) {
SIPTransaction *tx = AppLayerParserGetTx(f->proto, ALPROTO_SIP, state, tx_id);
if (tx) {
rs_sip_log_json(tx, js);
}
}
}
static int JsonSIPLogger(ThreadVars *tv, void *thread_data,
const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id)
{

@ -26,6 +26,4 @@
void JsonSIPLogRegister(void);
void JsonSIPAddMetadata(JsonBuilder *js, const Flow *f, uint64_t tx_id);
#endif /* __OUTPUT_JSON_SIP_H__ */

@ -59,11 +59,9 @@ static int JsonSNMPLogger(ThreadVars *tv, void *thread_data,
return TM_ECODE_FAILED;
}
jb_open_object(jb, "snmp");
if (!rs_snmp_log_json_response(jb, snmptx)) {
if (!rs_snmp_log_json_response(snmptx, jb)) {
goto error;
}
jb_close(jb);
OutputJsonBuilderBuffer(jb, thread);

@ -64,11 +64,9 @@ static int JsonSshLogger(ThreadVars *tv, void *thread_data, const Packet *p,
if (unlikely(js == NULL))
return 0;
jb_open_object(js, "ssh");
if (!rs_ssh_log_json(txptr, js)) {
goto end;
}
jb_close(js);
OutputJsonBuilderBuffer(js, thread);
end:

@ -74,11 +74,9 @@ static int JsonTemplateLogger(ThreadVars *tv, void *thread_data, const Packet *p
return TM_ECODE_FAILED;
}
jb_open_object(js, "template");
if (!rs_template_logger_log(tx, js)) {
goto error;
}
jb_close(js);
OutputJsonBuilderBuffer(js, thread->ctx);
jb_free(js);

@ -392,8 +392,9 @@ static void JsonTlsLogJSONCustom(OutputTlsCtx *tls_ctx, JsonBuilder *js,
}
}
void JsonTlsLogJSONExtended(JsonBuilder *tjs, SSLState * state)
static bool JsonTlsLogJSONExtendedAux(void *vtx, JsonBuilder *tjs)
{
SSLState *state = (SSLState *)vtx;
JsonTlsLogJSONBasic(tjs, state);
/* tls serial */
@ -425,6 +426,15 @@ void JsonTlsLogJSONExtended(JsonBuilder *tjs, SSLState * state)
JsonTlsLogClientCert(tjs, &state->client_connp, false, false);
jb_close(tjs);
}
return true;
}
bool JsonTlsLogJSONExtended(void *vtx, JsonBuilder *tjs)
{
jb_open_object(tjs, "tls");
bool r = JsonTlsLogJSONExtendedAux(vtx, tjs);
jb_close(tjs);
return r;
}
static int JsonTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p,
@ -459,7 +469,7 @@ static int JsonTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p,
}
/* log extended */
else if (tls_ctx->flags & LOG_TLS_EXTENDED) {
JsonTlsLogJSONExtended(js, ssl_state);
JsonTlsLogJSONExtendedAux(ssl_state, js);
}
/* log basic */
else {

@ -29,6 +29,6 @@ void JsonTlsLogRegister(void);
#include "app-layer-ssl.h"
void JsonTlsLogJSONBasic(JsonBuilder *js, SSLState *ssl_state);
void JsonTlsLogJSONExtended(JsonBuilder *js, SSLState *ssl_state);
bool JsonTlsLogJSONExtended(void *vtx, JsonBuilder *js);
#endif /* __OUTPUT_JSON_TLS_H__ */

@ -67,6 +67,8 @@
#include "log-stats.h"
#include "output-json-nfs.h"
#include "output-json-ftp.h"
// for misplaced EveFTPDataAddMetadata
#include "app-layer-ftp.h"
#include "output-json-tftp.h"
#include "output-json-smb.h"
#include "output-json-ike.h"
@ -1126,3 +1128,53 @@ void OutputRegisterLoggers(void)
/* BitTorrent DHT JSON logger */
JsonBitTorrentDHTLogRegister();
}
static EveJsonSimpleAppLayerLogger simple_json_applayer_loggers[ALPROTO_MAX] = {
{ ALPROTO_UNKNOWN, NULL },
{ ALPROTO_HTTP1, NULL }, // special: uses some options flags
{ ALPROTO_FTP, NULL }, // TODO missing
{ ALPROTO_SMTP, NULL }, // special: uses state
{ ALPROTO_TLS, JsonTlsLogJSONExtended },
{ ALPROTO_SSH, rs_ssh_log_json },
{ ALPROTO_IMAP, NULL }, // protocol detection only
{ ALPROTO_JABBER, NULL }, // no parser, no logging
{ ALPROTO_SMB, NULL }, // special: uses state
{ ALPROTO_DCERPC, NULL }, // TODO missing
{ ALPROTO_IRC, NULL }, // no parser, no logging
{ ALPROTO_DNS, AlertJsonDns },
{ ALPROTO_MODBUS, (EveJsonSimpleTxLogFunc)rs_modbus_to_json },
{ ALPROTO_ENIP, NULL }, // no logging
{ ALPROTO_DNP3, AlertJsonDnp3 },
{ ALPROTO_NFS, NULL }, // special: uses state
{ ALPROTO_NTP, NULL }, // no logging
{ ALPROTO_FTPDATA, EveFTPDataAddMetadata },
{ ALPROTO_TFTP, NULL }, // TODO missing
{ ALPROTO_IKE, NULL }, // special: uses state
{ ALPROTO_KRB5, NULL }, // TODO missing
{ ALPROTO_QUIC, rs_quic_to_json },
{ ALPROTO_DHCP, NULL }, // TODO missing
{ ALPROTO_SNMP, (EveJsonSimpleTxLogFunc)rs_snmp_log_json_response },
{ ALPROTO_SIP, (EveJsonSimpleTxLogFunc)rs_sip_log_json },
{ ALPROTO_RFB, rs_rfb_logger_log },
{ ALPROTO_MQTT, JsonMQTTAddMetadata },
{ ALPROTO_PGSQL, NULL }, // TODO missing
{ ALPROTO_TELNET, NULL }, // no logging
{ ALPROTO_TEMPLATE, rs_template_logger_log },
{ ALPROTO_RDP, (EveJsonSimpleTxLogFunc)rs_rdp_to_json },
{ ALPROTO_HTTP2, rs_http2_log_json },
{ ALPROTO_BITTORRENT_DHT, rs_bittorrent_dht_logger_log },
{ ALPROTO_HTTP, NULL }, // signature protocol, not for app-layer logging
{ ALPROTO_FAILED, NULL },
#ifdef UNITTESTS
{ ALPROTO_TEST, NULL },
#endif /* UNITESTS */
};
EveJsonSimpleAppLayerLogger *SCEveJsonSimpleGetLogger(AppProto alproto)
{
if (alproto < ALPROTO_MAX) {
BUG_ON(simple_json_applayer_loggers[alproto].proto != alproto);
return &simple_json_applayer_loggers[alproto];
}
return NULL;
}

@ -208,4 +208,13 @@ void OutputLoggerExitPrintStats(ThreadVars *, void *);
void OutputSetupActiveLoggers(void);
void OutputClearActiveLoggers(void);
typedef bool (*EveJsonSimpleTxLogFunc)(void *, struct JsonBuilder *);
typedef struct EveJsonSimpleAppLayerLogger {
AppProto proto;
EveJsonSimpleTxLogFunc LogTx;
} EveJsonSimpleAppLayerLogger;
EveJsonSimpleAppLayerLogger *SCEveJsonSimpleGetLogger(AppProto alproto);
#endif /* ! __OUTPUT_H__ */

Loading…
Cancel
Save