From 93a84180dc904c75c087fef06ddb800e0c54e87f Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Fri, 31 Jan 2014 10:58:35 +0100 Subject: [PATCH] json dns: do not use array to output answer Without this patch DNS answers for a single query are stored in a single json event. The result is an array in the object like this one: {"type":"answer","id":45084,"rrname":"s-static.ak.facebook.com","rrtype":"CNAME","ttl":734}, {"type":"answer","id":45084,"rrname":"s-static.ak.facebook.com.edgekey.net","rrtype":"CNAME","ttl":1710}, This type of output is not well supported in logstash. It is displayed as it is written above and it is not possible to query the fields. I think the reason is that this is not logical if we consider search query. For example if we search for "rrname" equal "s-static.ak.facebook.com" we got one entry with two values in it. That's against the logic of event. Furthermore, if we want to get a complete query, we can used the id. This patch splits the answer part in mulitple message. The result is then accepted by logstash and fields can be queried easily. --- src/output-json-dns.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/output-json-dns.c b/src/output-json-dns.c index 149a412be6..7f34f96e8c 100644 --- a/src/output-json-dns.c +++ b/src/output-json-dns.c @@ -135,7 +135,8 @@ static void LogQuery(LogDnsLogThread *aft, json_t *js, DNSTransaction *tx, DNSQu json_object_del(js, "dns"); } -static void AppendAnswer(json_t *djs, DNSTransaction *tx, DNSAnswerEntry *entry) { +static void OutputAnswer(LogDnsLogThread *aft, json_t *djs, DNSTransaction *tx, DNSAnswerEntry *entry) { + MemBuffer *buffer = (MemBuffer *)aft->buffer; json_t *js = json_object(); if (js == NULL) return; @@ -179,40 +180,34 @@ static void AppendAnswer(json_t *djs, DNSTransaction *tx, DNSAnswerEntry *entry) json_object_set_new(js, "rdata", json_string("")); } } - json_array_append_new(djs, js); + + /* reset */ + MemBufferReset(buffer); + json_object_set_new(djs, "dns", js); + OutputJSONBuffer(djs, aft->dnslog_ctx->file_ctx, buffer); + json_object_del(djs, "dns"); + + return; } static void LogAnswers(LogDnsLogThread *aft, json_t *js, DNSTransaction *tx) { - MemBuffer *buffer = (MemBuffer *)aft->buffer; SCLogDebug("got a DNS response and now logging !!"); - json_t *djs = json_array(); - if (djs == NULL) { - return; - } - - /* reset */ - MemBufferReset(buffer); - if (tx->no_such_name) { - AppendAnswer(djs, tx, NULL); + OutputAnswer(aft, js, tx, NULL); } DNSAnswerEntry *entry = NULL; TAILQ_FOREACH(entry, &tx->answer_list, next) { - AppendAnswer(djs, tx, entry); + OutputAnswer(aft, js, tx, entry); } entry = NULL; TAILQ_FOREACH(entry, &tx->authority_list, next) { - AppendAnswer(djs, tx, entry); + OutputAnswer(aft, js, tx, entry); } - /* dns */ - json_object_set_new(js, "dns", djs); - OutputJSONBuffer(js, aft->dnslog_ctx->file_ctx, buffer); - json_object_del(js, "dns"); } static int JsonDnsLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *alstate, void *txptr, uint64_t tx_id)