]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
dns-json: turn logger to tx api
authorVictor Julien <victor@inliniac.net>
Wed, 29 Jan 2014 14:29:15 +0000 (15:29 +0100)
committerVictor Julien <victor@inliniac.net>
Thu, 30 Jan 2014 07:32:49 +0000 (08:32 +0100)
Convert Json DNS logger into a Tx Logger API logger.

src/output-dnslog.c
src/output-dnslog.h
src/output-json.c
src/suricata.c
src/tm-threads-common.h

index ea2b352e7c7419f5e48ebe04f412f8738ad897a0..b9bab570502d92ef59e097bc04a6c154788f2960 100644 (file)
  * TX id handling doesn't expect it */
 #define QUERY 0
 
+typedef struct LogDnsFileCtx_ {
+    LogFileCtx *file_ctx;
+    uint32_t flags; /** Store mode */
+} LogDnsFileCtx;
+
+typedef struct LogDnsLogThread_ {
+    LogDnsFileCtx *dnslog_ctx;
+    /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */
+    uint32_t dns_cnt;
+
+    MemBuffer *buffer;
+} LogDnsLogThread;
+
 static void CreateTypeString(uint16_t type, char *str, size_t str_size) {
     if (type == DNS_RECORD_TYPE_A) {
         snprintf(str, str_size, "A");
@@ -86,7 +99,7 @@ static void CreateTypeString(uint16_t type, char *str, size_t str_size) {
     }
 }
 
-static void LogQuery(AlertJsonThread *aft, json_t *js, DNSTransaction *tx, DNSQueryEntry *entry) {
+static void LogQuery(LogDnsLogThread *aft, json_t *js, DNSTransaction *tx, DNSQueryEntry *entry) {
     MemBuffer *buffer = (MemBuffer *)aft->buffer;
 
     SCLogDebug("got a DNS request and now logging !!");
@@ -119,7 +132,7 @@ static void LogQuery(AlertJsonThread *aft, json_t *js, DNSTransaction *tx, DNSQu
 
     /* dns */
     json_object_set_new(js, "dns", djs);
-    OutputJSON(js, aft, &aft->dns_cnt);
+    OutputJSONBuffer(js, aft->dnslog_ctx->file_ctx, buffer);
     json_object_del(js, "dns");
 }
 
@@ -170,7 +183,7 @@ static void AppendAnswer(json_t *djs, DNSTransaction *tx, DNSAnswerEntry *entry)
     json_array_append_new(djs, js);
 }
 
-static void LogAnswers(AlertJsonThread *aft, json_t *js, DNSTransaction *tx) {
+static void LogAnswers(LogDnsLogThread *aft, json_t *js, DNSTransaction *tx) {
     MemBuffer *buffer = (MemBuffer *)aft->buffer;
 
     SCLogDebug("got a DNS response and now logging !!");
@@ -199,92 +212,164 @@ static void LogAnswers(AlertJsonThread *aft, json_t *js, DNSTransaction *tx) {
 
     /* dns */
     json_object_set_new(js, "dns", djs);
-    OutputJSON(js, aft, &aft->dns_cnt);
+    OutputJSONBuffer(js, aft->dnslog_ctx->file_ctx, buffer);
     json_object_del(js, "dns");
 }
 
-static TmEcode DnsJsonIPWrapper(ThreadVars *tv, Packet *p, void *data,
-                                int ipproto)
+static int JsonDnsLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *alstate, void *txptr, uint64_t tx_id)
 {
     SCEnter();
 
-    AlertJsonThread *aft = (AlertJsonThread *)data;
-
-    /* check if we have DNS state or not */
-    FLOWLOCK_WRLOCK(p->flow); /* WRITE lock before we updated flow logged id */
-    uint16_t proto = FlowGetAppProtocol(p->flow);
-    if (proto != ALPROTO_DNS) {
-        SCLogDebug("proto not ALPROTO_DNS: %u", proto);
-        goto end;
-    }
-
-    DNSState *dns_state = (DNSState *)FlowGetAppState(p->flow);
-    if (dns_state == NULL) {
-        SCLogDebug("no dns state, so no request logging");
-        goto end;
-    }
+    LogDnsLogThread *td = (LogDnsLogThread *)thread_data;
+    DNSTransaction *tx = txptr;
 
-    uint64_t total_txs = AppLayerParserGetTxCnt(p->proto, proto, dns_state);
-    uint64_t tx_id = AppLayerParserGetTransactionLogId(p->flow->alparser);
-    //int tx_progress_done_value_ts = AppLayerGetAlstateProgressCompletionStatus(proto, 0);
-    //int tx_progress_done_value_tc = AppLayerGetAlstateProgressCompletionStatus(proto, 1);
-
-    json_t *js = CreateJSONHeader(p, 1);
+    json_t *js = CreateJSONHeader((Packet *)p, 1);//TODO const
     if (unlikely(js == NULL))
         return TM_ECODE_OK;
 
 #if QUERY
     if (PKT_IS_TOSERVER(p)) {
-        DNSTransaction *tx = NULL;
-        TAILQ_FOREACH(tx, &dns_state->tx_list, next) {
-            DNSQueryEntry *entry = NULL;
-            TAILQ_FOREACH(entry, &tx->query_list, next) {
-                LogQuery(aft, timebuf, srcip, dstip, sp, dp, tx, proto_s, entry);
-            }
+        DNSQueryEntry *entry = NULL;
+        TAILQ_FOREACH(entry, &tx->query_list, next) {
+            LogQuery(aft, timebuf, srcip, dstip, sp, dp, tx, proto_s, entry);
         }
     } else
 #endif
     if ((PKT_IS_TOCLIENT(p))) {
-        DNSTransaction *tx = NULL;
-        for (; tx_id < total_txs; tx_id++)
-        {
-            tx = AppLayerParserGetTx(p->proto, proto, dns_state, tx_id);
-            if (tx == NULL)
-                continue;
-
-            DNSQueryEntry *query = NULL;
-            TAILQ_FOREACH(query, &tx->query_list, next) {
-                LogQuery(aft, js, tx, query);
-            }
-
-            LogAnswers(aft, js, tx);
-
-            SCLogDebug("calling AppLayerTransactionUpdateLoggedId");
-            AppLayerParserSetTransactionLogId(p->flow->alparser);
+        DNSQueryEntry *query = NULL;
+        TAILQ_FOREACH(query, &tx->query_list, next) {
+            LogQuery(td, js, tx, query);
         }
+
+        LogAnswers(td, js, tx);
     }
     json_decref(js);
 
-end:
-    FLOWLOCK_UNLOCK(p->flow);
     SCReturnInt(TM_ECODE_OK);
 }
 
-TmEcode OutputDnsLog(ThreadVars *tv, Packet *p, void *data)
+#define OUTPUT_BUFFER_SIZE 65536
+static TmEcode LogDnsLogThreadInit(ThreadVars *t, void *initdata, void **data)
 {
-    SCEnter();
+    LogDnsLogThread *aft = SCMalloc(sizeof(LogDnsLogThread));
+    if (unlikely(aft == NULL))
+        return TM_ECODE_FAILED;
+    memset(aft, 0, sizeof(LogDnsLogThread));
+
+    if(initdata == NULL)
+    {
+        SCLogDebug("Error getting context for DNSLog.  \"initdata\" argument NULL");
+        SCFree(aft);
+        return TM_ECODE_FAILED;
+    }
 
-    /* no flow, no htp state */
-    if (p->flow == NULL) {
-        SCReturnInt(TM_ECODE_OK);
+    aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE);
+    if (aft->buffer == NULL) {
+        SCFree(aft);
+        return TM_ECODE_FAILED;
     }
 
-    if (!(PKT_IS_UDP(p)) && !(PKT_IS_TCP(p))) {
-        SCReturnInt(TM_ECODE_OK);
+    /* Use the Ouptut Context (file pointer and mutex) */
+    aft->dnslog_ctx= ((OutputCtx *)initdata)->data;
+
+    *data = (void *)aft;
+    return TM_ECODE_OK;
+}
+
+static TmEcode LogDnsLogThreadDeinit(ThreadVars *t, void *data)
+{
+    LogDnsLogThread *aft = (LogDnsLogThread *)data;
+    if (aft == NULL) {
+        return TM_ECODE_OK;
     }
 
-    DnsJsonIPWrapper(tv, p, data, AF_INET);
+    MemBufferFree(aft->buffer);
+    /* clear memory */
+    memset(aft, 0, sizeof(LogDnsLogThread));
 
-    SCReturnInt(TM_ECODE_OK);
+    SCFree(aft);
+    return TM_ECODE_OK;
+}
+
+static void LogDnsLogDeInitCtx(OutputCtx *output_ctx)
+{
+    LogDnsFileCtx *dnslog_ctx = (LogDnsFileCtx *)output_ctx->data;
+    LogFileFreeCtx(dnslog_ctx->file_ctx);
+    SCFree(dnslog_ctx);
+    SCFree(output_ctx);
+}
+
+#define DEFAULT_LOG_FILENAME "dns.json"
+/** \brief Create a new dns log LogFileCtx.
+ *  \param conf Pointer to ConfNode containing this loggers configuration.
+ *  \return NULL if failure, LogFileCtx* to the file_ctx if succesful
+ * */
+static OutputCtx *JsonDnsLogInitCtx(ConfNode *conf)
+{
+    LogFileCtx *file_ctx = LogFileNewCtx();
+
+    if(file_ctx == NULL) {
+        SCLogError(SC_ERR_DNS_LOG_GENERIC, "couldn't create new file_ctx");
+        return NULL;
+    }
+
+    if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME) < 0) {
+        LogFileFreeCtx(file_ctx);
+        return NULL;
+    }
+
+    LogDnsFileCtx *dnslog_ctx = SCMalloc(sizeof(LogDnsFileCtx));
+    if (unlikely(dnslog_ctx == NULL)) {
+        LogFileFreeCtx(file_ctx);
+        return NULL;
+    }
+    memset(dnslog_ctx, 0x00, sizeof(LogDnsFileCtx));
+
+    dnslog_ctx->file_ctx = file_ctx;
+
+    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
+    if (unlikely(output_ctx == NULL)) {
+        LogFileFreeCtx(file_ctx);
+        SCFree(dnslog_ctx);
+        return NULL;
+    }
+
+    output_ctx->data = dnslog_ctx;
+    output_ctx->DeInit = LogDnsLogDeInitCtx;
+
+    SCLogDebug("DNS log output initialized");
+
+    AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_DNS);
+    AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_DNS);
+
+    return output_ctx;
 }
+
+
+#define MODULE_NAME "JsonDnsLog"
+void TmModuleJsonDnsLogRegister (void) {
+    tmm_modules[TMM_JSONDNSLOG].name = MODULE_NAME;
+    tmm_modules[TMM_JSONDNSLOG].ThreadInit = LogDnsLogThreadInit;
+    tmm_modules[TMM_JSONDNSLOG].ThreadDeinit = LogDnsLogThreadDeinit;
+    tmm_modules[TMM_JSONDNSLOG].RegisterTests = NULL;
+    tmm_modules[TMM_JSONDNSLOG].cap_flags = 0;
+
+    OutputRegisterTxModule(MODULE_NAME, "dns-json-log", JsonDnsLogInitCtx,
+            ALPROTO_DNS, JsonDnsLogger);
+}
+
+#else
+
+static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data)
+{
+    SCLogInfo("Can't init JSON output - JSON support was disabled during build.");
+    return TM_ECODE_FAILED;
+}
+
+void TmModuleJsonDnsLogRegister (void)
+{
+    tmm_modules[TMM_JSONDNSLOG].name = "JsonDnsLog";
+    tmm_modules[TMM_JSONDNSLOG].ThreadInit = OutputJsonThreadInit;
+}
+
 #endif
index 3708f9d8974a92a75219eb99b7377e1915b95a6f..3c08b0f4bd6ffcaf287c7063f73e96def5f73b27 100644 (file)
@@ -24,7 +24,8 @@
 #ifndef __OUTPUT_DNSLOG_H__
 #define __OUTPUT_DNSLOG_H__
 
-TmEcode OutputDnsLog(ThreadVars *tv, Packet *p, void *data);
+//TmEcode OutputDnsLog(ThreadVars *tv, Packet *p, void *data);
 OutputCtx *DnsJsonInitCtx(ConfNode *);
+void TmModuleJsonDnsLogRegister (void);
 
 #endif /* __OUTPUT_DNSLOG_H__ */
index ba4bc51b4183ef2736325c36b8443cb8b53bd3c3..2024e891ac49b12ebf9e72cf86bf40906f086bf9 100644 (file)
@@ -494,7 +494,7 @@ TmEcode OutputJson (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, Pack
     }
 
     if (output_flags & OUTPUT_DNS) {
-        OutputDnsLog(tv, p, data);
+//        OutputDnsLog(tv, p, data);
     }
 
     if (output_flags & OUTPUT_DROP) {
index e0f11a7ccbbace93d1db08a5981b11abc0e46ced..f2165f972734b3bccb752518c5d98df2a2e093f1 100644 (file)
@@ -83,6 +83,7 @@
 #include "log-httplog.h"
 #include "output-httplog.h"
 #include "log-dnslog.h"
+#include "output-dnslog.h"
 #include "log-tlslog.h"
 #include "log-pcap.h"
 #include "log-file.h"
@@ -807,6 +808,7 @@ void RegisterAllModules()
     TmModuleLogFilestoreRegister();
     /* dns log */
     TmModuleLogDnsLogRegister();
+    TmModuleJsonDnsLogRegister();
     TmModulePacketLoggerRegister();
     TmModuleTxLoggerRegister();
     TmModuleFileLoggerRegister();
index 716ad9573bbb014e8754c2630d6aa2d5655e1957..8b9712605ccf0e92dc0a545caaede77205152c99 100644 (file)
@@ -85,6 +85,7 @@ typedef enum {
     TMM_FILELOGGER,
     TMM_FILEDATALOGGER,
     TMM_JSONHTTPLOG,
+    TMM_JSONDNSLOG,
     TMM_SIZE,
 } TmmId;