use super::http2::{HTTP2Frame, HTTP2FrameTypeData, HTTP2Transaction};
use super::parser;
-use crate::dns::log::{SCDnsLogAnswerEnabled, SCDnsLogJsonAnswer, SCDnsLogJsonQuery};
use crate::jsonbuilder::{JsonBuilder, JsonError};
use std;
use std::collections::{HashMap, HashSet};
js.close()?; // http2
js.close()?; // http
- if let Some(doh) = &tx.doh {
- js.open_object("dns")?;
- if let Some(dtx) = &doh.dns_request_tx {
- let mark = js.get_mark();
- let mut has_dns_query = false;
- js.open_array("query")?;
- for i in 0..0xFFFF {
- let mut jsa = JsonBuilder::try_new_object()?;
- if !SCDnsLogJsonQuery(dtx, i, 0xFFFFFFFFFFFFFFFF, &mut jsa) {
- break;
- }
- jsa.close()?;
- js.append_object(&jsa)?;
- has_dns_query = true;
- }
- if has_dns_query {
- js.close()?; // query
- } else {
- js.restore_mark(&mark)?;
- }
- }
- if let Some(dtx) = &doh.dns_response_tx {
- if SCDnsLogAnswerEnabled(dtx, 0xFFFFFFFFFFFFFFFF) {
- // logging at root of dns object
- SCDnsLogJsonAnswer(dtx, 0xFFFFFFFFFFFFFFFF, js);
- }
- }
- js.close()?; // dns
- }
return Ok(has_request || has_response || has_headers);
}
txptr, LOG_FORMAT_DETAILED | LOG_QUERIES | LOG_ANSWERS | LOG_ALL_RRTYPES, js);
}
+bool AlertJsonDoh2(void *txptr, JsonBuilder *js)
+{
+ JsonBuilderMark mark = { 0, 0, 0 };
+
+ jb_get_mark(js, &mark);
+ // first log HTTP2 part
+ bool r = rs_http2_log_json(txptr, js);
+ if (!r) {
+ jb_restore_mark(js, &mark);
+ }
+ // then log one DNS tx if any, preferring the answer
+ void *tx_dns = DetectGetInnerTx(txptr, ALPROTO_DOH2, ALPROTO_DNS, STREAM_TOCLIENT);
+ if (tx_dns == NULL) {
+ tx_dns = DetectGetInnerTx(txptr, ALPROTO_DOH2, ALPROTO_DNS, STREAM_TOSERVER);
+ }
+ bool r2 = false;
+ if (tx_dns) {
+ jb_get_mark(js, &mark);
+ r2 = AlertJsonDns(tx_dns, js);
+ if (!r2) {
+ jb_restore_mark(js, &mark);
+ }
+ }
+ return r || r2;
+}
+
+static int JsonDoh2Logger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f,
+ void *alstate, void *txptr, uint64_t tx_id)
+{
+ LogDnsLogThread *td = (LogDnsLogThread *)thread_data;
+ LogDnsFileCtx *dnslog_ctx = td->dnslog_ctx;
+
+ JsonBuilder *jb = CreateEveHeader(p, LOG_DIR_FLOW, "dns", NULL, dnslog_ctx->eve_ctx);
+
+ if (unlikely(jb == NULL)) {
+ return TM_ECODE_OK;
+ }
+
+ JsonBuilderMark mark = { 0, 0, 0 };
+
+ jb_get_mark(jb, &mark);
+ // first log HTTP2 part
+ bool r = rs_http2_log_json(txptr, jb);
+ if (!r) {
+ jb_restore_mark(jb, &mark);
+ }
+
+ void *tx_dns = DetectGetInnerTx(txptr, ALPROTO_DOH2, ALPROTO_DNS, STREAM_TOCLIENT);
+ if (tx_dns == NULL) {
+ tx_dns = DetectGetInnerTx(txptr, ALPROTO_DOH2, ALPROTO_DNS, STREAM_TOSERVER);
+ }
+ bool r2 = false;
+ if (tx_dns) {
+ // mix of JsonDnsLogger
+ if (SCDnsTxIsRequest(tx_dns)) {
+ if (unlikely(dnslog_ctx->flags & LOG_QUERIES) == 0) {
+ goto out;
+ }
+ } else if (SCDnsTxIsResponse(tx_dns)) {
+ if (unlikely(dnslog_ctx->flags & LOG_ANSWERS) == 0) {
+ goto out;
+ }
+ }
+
+ if (!SCDnsLogEnabled(tx_dns, td->dnslog_ctx->flags)) {
+ goto out;
+ }
+
+ jb_get_mark(jb, &mark);
+ // log DOH2 with DNS config
+ r2 = SCDnsLogJson(tx_dns, td->dnslog_ctx->flags, jb);
+ if (!r2) {
+ jb_restore_mark(jb, &mark);
+ }
+ }
+out:
+ if (r || r2) {
+ OutputJsonBuilderBuffer(jb, td->ctx);
+ }
+ jb_free(jb);
+ return TM_ECODE_OK;
+}
+
static int JsonDnsLoggerToServer(ThreadVars *tv, void *thread_data,
const Packet *p, Flow *f, void *alstate, void *txptr, uint64_t tx_id)
{
JsonDnsLogInitCtxSub, ALPROTO_DNS, JsonDnsLogger, LogDnsLogThreadInit,
LogDnsLogThreadDeinit, NULL);
}
+
+void JsonDoh2LogRegister(void)
+{
+ OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonDoH2Log", "eve-log.doh2",
+ JsonDnsLogInitCtxSub, ALPROTO_DOH2, JsonDoh2Logger, LogDnsLogThreadInit,
+ LogDnsLogThreadDeinit, NULL);
+}
OutputJsonLogInitSub, ALPROTO_LDAP, JsonGenericDirPacketLogger, JsonLogThreadInit,
JsonLogThreadDeinit, NULL);
/* DoH2 JSON logger. */
- OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonDoH2Log", "eve-log.doh2",
- OutputJsonLogInitSub, ALPROTO_DOH2, JsonGenericDirFlowLogger, JsonLogThreadInit,
- JsonLogThreadDeinit, NULL);
+ JsonDoh2LogRegister();
/* Template JSON logger. */
OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonTemplateLog", "eve-log.template",
OutputJsonLogInitSub, ALPROTO_TEMPLATE, JsonGenericDirPacketLogger, JsonLogThreadInit,
{ ALPROTO_TELNET, NULL }, // no logging
{ ALPROTO_WEBSOCKET, rs_websocket_logger_log },
{ ALPROTO_LDAP, rs_ldap_logger_log },
- { ALPROTO_DOH2, rs_http2_log_json }, // http2 logger knows how to log dns
+ { ALPROTO_DOH2, AlertJsonDoh2 },
{ ALPROTO_TEMPLATE, rs_template_logger_log },
{ ALPROTO_RDP, (EveJsonSimpleTxLogFunc)rs_rdp_to_json },
{ ALPROTO_HTTP2, rs_http2_log_json },