dns/eve: convert to jsonbuilder

pull/5012/head
Jason Ish 5 years ago committed by Victor Julien
parent 6a70d6bb6e
commit 03cf3dcd6d

@ -19,7 +19,7 @@ use std;
use std::string::String; use std::string::String;
use std::collections::HashMap; use std::collections::HashMap;
use crate::json::*; use crate::jsonbuilder::{JsonBuilder, JsonError};
use crate::dns::dns::*; use crate::dns::dns::*;
pub const LOG_QUERIES : u64 = BIT_U64!(0); pub const LOG_QUERIES : u64 = BIT_U64!(0);
@ -396,89 +396,90 @@ pub fn dns_print_addr(addr: &Vec<u8>) -> std::string::String {
} }
/// Log the SSHPF in an DNSAnswerEntry. /// Log the SSHPF in an DNSAnswerEntry.
fn dns_log_sshfp(answer: &DNSAnswerEntry) -> Option<Json> fn dns_log_sshfp(answer: &DNSAnswerEntry) -> Result<Option<JsonBuilder>, JsonError>
{ {
// Need at least 3 bytes - TODO: log something if we don't? // Need at least 3 bytes - TODO: log something if we don't?
if answer.data.len() < 3 { if answer.data.len() < 3 {
return None return Ok(None)
} }
let sshfp = Json::object(); let mut sshfp = JsonBuilder::new_object();
let mut hex = Vec::new(); let mut hex = Vec::new();
for byte in &answer.data[2..] { for byte in &answer.data[2..] {
hex.push(format!("{:02x}", byte)); hex.push(format!("{:02x}", byte));
} }
sshfp.set_string("fingerprint", &hex.join(":")); sshfp.set_string("fingerprint", &hex.join(":"))?;
sshfp.set_integer("algo", answer.data[0] as u64); sshfp.set_uint("algo", answer.data[0] as u64)?;
sshfp.set_integer("type", answer.data[1] as u64); sshfp.set_uint("type", answer.data[1] as u64)?;
return Some(sshfp); return Ok(Some(sshfp));
} }
fn dns_log_json_answer_detail(answer: &DNSAnswerEntry) -> Json fn dns_log_json_answer_detail(answer: &DNSAnswerEntry) -> Result<JsonBuilder, JsonError>
{ {
let jsa = Json::object(); let mut jsa = JsonBuilder::new_object();
jsa.set_string_from_bytes("rrname", &answer.name); jsa.set_string_from_bytes("rrname", &answer.name)?;
jsa.set_string("rrtype", &dns_rrtype_string(answer.rrtype)); jsa.set_string("rrtype", &dns_rrtype_string(answer.rrtype))?;
jsa.set_integer("ttl", answer.ttl as u64); jsa.set_uint("ttl", answer.ttl as u64)?;
match answer.rrtype { match answer.rrtype {
DNS_RECORD_TYPE_A | DNS_RECORD_TYPE_AAAA => { DNS_RECORD_TYPE_A | DNS_RECORD_TYPE_AAAA => {
jsa.set_string("rdata", &dns_print_addr(&answer.data)); jsa.set_string("rdata", &dns_print_addr(&answer.data))?;
} }
DNS_RECORD_TYPE_CNAME | DNS_RECORD_TYPE_CNAME |
DNS_RECORD_TYPE_MX | DNS_RECORD_TYPE_MX |
DNS_RECORD_TYPE_TXT | DNS_RECORD_TYPE_TXT |
DNS_RECORD_TYPE_PTR => { DNS_RECORD_TYPE_PTR => {
jsa.set_string_from_bytes("rdata", &answer.data); jsa.set_string_from_bytes("rdata", &answer.data)?;
}, },
DNS_RECORD_TYPE_SSHFP => { DNS_RECORD_TYPE_SSHFP => {
for sshfp in dns_log_sshfp(&answer) { if let Some(sshfp) = dns_log_sshfp(answer)? {
jsa.set("sshfp", sshfp); jsa.set_object("sshfp", &sshfp)?;
} }
}, },
_ => {} _ => {}
} }
return jsa; jsa.close()?;
return Ok(jsa);
} }
fn dns_log_json_answer(response: &DNSResponse, flags: u64) -> Json fn dns_log_json_answer(js: &mut JsonBuilder, response: &DNSResponse, flags: u64)
-> Result<(), JsonError>
{ {
let header = &response.header; let header = &response.header;
let js = Json::object();
js.set_integer("version", 2); js.set_uint("version", 2)?;
js.set_string("type", "answer"); js.set_string("type", "answer")?;
js.set_integer("id", header.tx_id as u64); js.set_uint("id", header.tx_id as u64)?;
js.set_string("flags", format!("{:x}", header.flags).as_str()); js.set_string("flags", format!("{:x}", header.flags).as_str())?;
if header.flags & 0x8000 != 0 { if header.flags & 0x8000 != 0 {
js.set_boolean("qr", true); js.set_bool("qr", true)?;
} }
if header.flags & 0x0400 != 0 { if header.flags & 0x0400 != 0 {
js.set_boolean("aa", true); js.set_bool("aa", true)?;
} }
if header.flags & 0x0200 != 0 { if header.flags & 0x0200 != 0 {
js.set_boolean("tc", true); js.set_bool("tc", true)?;
} }
if header.flags & 0x0100 != 0 { if header.flags & 0x0100 != 0 {
js.set_boolean("rd", true); js.set_bool("rd", true)?;
} }
if header.flags & 0x0080 != 0 { if header.flags & 0x0080 != 0 {
js.set_boolean("ra", true); js.set_bool("ra", true)?;
} }
for query in &response.queries { for query in &response.queries {
js.set_string_from_bytes("rrname", &query.name); js.set_string_from_bytes("rrname", &query.name)?;
js.set_string("rrtype", &dns_rrtype_string(query.rrtype)); js.set_string("rrtype", &dns_rrtype_string(query.rrtype))?;
break; break;
} }
js.set_string("rcode", &dns_rcode_string(header.flags)); js.set_string("rcode", &dns_rcode_string(header.flags))?;
if response.answers.len() > 0 { if response.answers.len() > 0 {
let js_answers = Json::array(); let mut js_answers = JsonBuilder::new_array();
// For grouped answers we use a HashMap keyed by the rrtype. // For grouped answers we use a HashMap keyed by the rrtype.
let mut answer_types = HashMap::new(); let mut answer_types = HashMap::new();
@ -491,11 +492,10 @@ fn dns_log_json_answer(response: &DNSResponse, flags: u64) -> Json
DNS_RECORD_TYPE_A | DNS_RECORD_TYPE_AAAA => { DNS_RECORD_TYPE_A | DNS_RECORD_TYPE_AAAA => {
if !answer_types.contains_key(&type_string) { if !answer_types.contains_key(&type_string) {
answer_types.insert(type_string.to_string(), answer_types.insert(type_string.to_string(),
Json::array()); JsonBuilder::new_array());
} }
for a in &answer_types.get(&type_string) { if let Some(a) = answer_types.get_mut(&type_string) {
a.array_append( a.append_string(&dns_print_addr(&answer.data))?;
Json::string(&dns_print_addr(&answer.data)));
} }
} }
DNS_RECORD_TYPE_CNAME | DNS_RECORD_TYPE_CNAME |
@ -504,21 +504,20 @@ fn dns_log_json_answer(response: &DNSResponse, flags: u64) -> Json
DNS_RECORD_TYPE_PTR => { DNS_RECORD_TYPE_PTR => {
if !answer_types.contains_key(&type_string) { if !answer_types.contains_key(&type_string) {
answer_types.insert(type_string.to_string(), answer_types.insert(type_string.to_string(),
Json::array()); JsonBuilder::new_array());
} }
for a in &answer_types.get(&type_string) { if let Some(a) = answer_types.get_mut(&type_string) {
a.array_append( a.append_string_from_bytes(&answer.data)?;
Json::string_from_bytes(&answer.data));
} }
}, },
DNS_RECORD_TYPE_SSHFP => { DNS_RECORD_TYPE_SSHFP => {
if !answer_types.contains_key(&type_string) { if !answer_types.contains_key(&type_string) {
answer_types.insert(type_string.to_string(), answer_types.insert(type_string.to_string(),
Json::array()); JsonBuilder::new_array());
} }
for a in &answer_types.get(&type_string) { if let Some(a) = answer_types.get_mut(&type_string) {
for sshfp in dns_log_sshfp(&answer) { if let Some(sshfp) = dns_log_sshfp(&answer)? {
a.array_append(sshfp); a.append_object(&sshfp)?;
} }
} }
}, },
@ -527,155 +526,191 @@ fn dns_log_json_answer(response: &DNSResponse, flags: u64) -> Json
} }
if flags & LOG_FORMAT_DETAILED != 0 { if flags & LOG_FORMAT_DETAILED != 0 {
js_answers.array_append(dns_log_json_answer_detail(answer)); js_answers.append_object(&dns_log_json_answer_detail(answer)?)?;
} }
} }
js_answers.close()?;
if flags & LOG_FORMAT_DETAILED != 0 { if flags & LOG_FORMAT_DETAILED != 0 {
js.set("answers", js_answers); js.set_object("answers", &js_answers)?;
} }
if flags & LOG_FORMAT_GROUPED != 0 { if flags & LOG_FORMAT_GROUPED != 0 {
let grouped = Json::object(); js.open_object("grouped")?;
for (k, v) in answer_types.drain() { for (k, mut v) in answer_types.drain() {
grouped.set(&k, v); v.close()?;
js.set_object(&k, &v)?;
} }
js.set("grouped", grouped); js.close()?;
} }
} }
if response.authorities.len() > 0 { if response.authorities.len() > 0 {
let js_auth = Json::array(); js.open_array("authorities")?;
for auth in &response.authorities { for auth in &response.authorities {
js_auth.array_append(dns_log_json_answer_detail(auth)); let auth_detail = dns_log_json_answer_detail(auth)?;
js.append_object(&auth_detail)?;
} }
js.set("authorities", js_auth); js.close()?;
} }
return js; Ok(())
} }
#[no_mangle] fn dns_log_query(tx: &mut DNSTransaction,
pub extern "C" fn rs_dns_log_json_query(tx: &mut DNSTransaction, i: u16,
i: u16, flags: u64,
flags: u64) jb: &mut JsonBuilder)
-> *mut JsonT -> Result<bool, JsonError>
{ {
let index = i as usize; let index = i as usize;
if let &Some(ref request) = &tx.request { if let &Some(ref request) = &tx.request {
if index < request.queries.len() { if index < request.queries.len() {
let query = &request.queries[index]; let query = &request.queries[index];
if dns_log_rrtype_enabled(query.rrtype, flags) { if dns_log_rrtype_enabled(query.rrtype, flags) {
let js = Json::object(); jb.set_string("type", "query")?;
js.set_string("type", "query"); jb.set_uint("id", request.header.tx_id as u64)?;
js.set_integer("id", request.header.tx_id as u64); jb.set_string_from_bytes("rrname", &query.name)?;
js.set_string_from_bytes("rrname", &query.name); jb.set_string("rrtype", &dns_rrtype_string(query.rrtype))?;
js.set_string("rrtype", &dns_rrtype_string(query.rrtype)); jb.set_uint("tx_id", tx.id - 1)?;
js.set_integer("tx_id", tx.id - 1); return Ok(true);
return js.unwrap();
} }
} }
} }
return std::ptr::null_mut(); return Ok(false);
}
#[no_mangle]
pub extern "C" fn rs_dns_log_json_query(tx: &mut DNSTransaction,
i: u16,
flags: u64,
jb: &mut JsonBuilder)
-> bool
{
match dns_log_query(tx, i, flags, jb) {
Ok(false) | Err(_) => {
return false;
}
Ok(true) => {
return true;
}
}
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_dns_log_json_answer(tx: &mut DNSTransaction, pub extern "C" fn rs_dns_log_json_answer(tx: &mut DNSTransaction,
flags: u64) flags: u64, mut js: &mut JsonBuilder)
-> *mut JsonT -> bool
{ {
if let &Some(ref response) = &tx.response { if let &Some(ref response) = &tx.response {
for query in &response.queries { for query in &response.queries {
if dns_log_rrtype_enabled(query.rrtype, flags) { if dns_log_rrtype_enabled(query.rrtype, flags) {
let js = dns_log_json_answer(response, flags as u64); return dns_log_json_answer(&mut js, response, flags as u64).is_ok();
return js.unwrap();
} }
} }
} }
return false;
}
return std::ptr::null_mut(); #[no_mangle]
pub extern "C" fn rs_dns_do_log_answer(tx: &mut DNSTransaction,
flags: u64) -> bool
{
if let &Some(ref response) = &tx.response {
for query in &response.queries {
if dns_log_rrtype_enabled(query.rrtype, flags) {
return true;
}
}
}
return false;
} }
// Version 1 logging support. // Version 1 logging support.
fn dns_log_json_answer_v1(header: &DNSHeader, answer: &DNSAnswerEntry) fn dns_log_json_answer_v1(header: &DNSHeader, answer: &DNSAnswerEntry)
-> Json -> Result<JsonBuilder, JsonError>
{ {
let js = Json::object(); let mut js = JsonBuilder::new_object();
js.set_string("type", "answer"); js.set_string("type", "answer")?;
js.set_integer("id", header.tx_id as u64); js.set_uint("id", header.tx_id as u64)?;
js.set_string("flags", format!("{:x}", header.flags).as_str()); js.set_string("flags", format!("{:x}", header.flags).as_str())?;
if header.flags & 0x8000 != 0 { if header.flags & 0x8000 != 0 {
js.set_boolean("qr", true); js.set_bool("qr", true)?;
} }
if header.flags & 0x0400 != 0 { if header.flags & 0x0400 != 0 {
js.set_boolean("aa", true); js.set_bool("aa", true)?;
} }
if header.flags & 0x0200 != 0 { if header.flags & 0x0200 != 0 {
js.set_boolean("tc", true); js.set_bool("tc", true)?;
} }
if header.flags & 0x0100 != 0 { if header.flags & 0x0100 != 0 {
js.set_boolean("rd", true); js.set_bool("rd", true)?;
} }
if header.flags & 0x0080 != 0 { if header.flags & 0x0080 != 0 {
js.set_boolean("ra", true); js.set_bool("ra", true)?;
} }
js.set_string("rcode", &dns_rcode_string(header.flags)); js.set_string("rcode", &dns_rcode_string(header.flags))?;
js.set_string_from_bytes("rrname", &answer.name); js.set_string_from_bytes("rrname", &answer.name)?;
js.set_string("rrtype", &dns_rrtype_string(answer.rrtype)); js.set_string("rrtype", &dns_rrtype_string(answer.rrtype))?;
js.set_integer("ttl", answer.ttl as u64); js.set_uint("ttl", answer.ttl as u64)?;
match answer.rrtype { match answer.rrtype {
DNS_RECORD_TYPE_A | DNS_RECORD_TYPE_AAAA => { DNS_RECORD_TYPE_A | DNS_RECORD_TYPE_AAAA => {
js.set_string("rdata", &dns_print_addr(&answer.data)); js.set_string("rdata", &dns_print_addr(&answer.data))?;
} }
DNS_RECORD_TYPE_CNAME | DNS_RECORD_TYPE_CNAME |
DNS_RECORD_TYPE_MX | DNS_RECORD_TYPE_MX |
DNS_RECORD_TYPE_TXT | DNS_RECORD_TYPE_TXT |
DNS_RECORD_TYPE_PTR => { DNS_RECORD_TYPE_PTR => {
js.set_string_from_bytes("rdata", &answer.data); js.set_string_from_bytes("rdata", &answer.data)?;
}, },
DNS_RECORD_TYPE_SSHFP => { DNS_RECORD_TYPE_SSHFP => {
if let Some(sshfp) = dns_log_sshfp(&answer) { if let Some(sshfp) = dns_log_sshfp(&answer)? {
js.set("sshfp", sshfp); js.set_object("sshfp", &sshfp)?;
} }
}, },
_ => {} _ => {}
} }
return js; js.close()?;
return Ok(js);
} }
fn dns_log_json_failure_v1(r: &DNSResponse, index: usize, flags: u64) fn dns_log_json_failure_v1(r: &DNSResponse, index: usize, flags: u64)
-> * mut JsonT { -> Result<Option<JsonBuilder>, JsonError> {
if index >= r.queries.len() { if index >= r.queries.len() {
return std::ptr::null_mut(); return Ok(None);
} }
let ref query = r.queries[index]; let ref query = r.queries[index];
if !dns_log_rrtype_enabled(query.rrtype, flags) { if !dns_log_rrtype_enabled(query.rrtype, flags) {
return std::ptr::null_mut(); return Ok(None);
} }
let js = Json::object(); let mut js = JsonBuilder::new_object();
js.set_string("type", "answer")?;
js.set_uint("id", r.header.tx_id as u64)?;
js.set_string("rcode", &dns_rcode_string(r.header.flags))?;
js.set_string_from_bytes("rrname", &query.name)?;
js.set_string("type", "answer"); js.close()?;
js.set_integer("id", r.header.tx_id as u64);
js.set_string("rcode", &dns_rcode_string(r.header.flags));
js.set_string_from_bytes("rrname", &query.name);
return js.unwrap(); return Ok(Some(js));
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn rs_dns_log_json_answer_v1(tx: &mut DNSTransaction, pub extern "C" fn rs_dns_log_json_answer_v1(tx: &mut DNSTransaction,
i: u16, i: u16,
flags: u64) flags: u64)
-> *mut JsonT -> *mut JsonBuilder
{ {
let index = i as usize; let index = i as usize;
// Note for loop over Option for easier break out to default // Note for loop over Option for easier break out to default
@ -683,7 +718,9 @@ pub extern "C" fn rs_dns_log_json_answer_v1(tx: &mut DNSTransaction,
for response in &tx.response { for response in &tx.response {
if response.header.flags & 0x000f > 0 { if response.header.flags & 0x000f > 0 {
if index == 0 { if index == 0 {
return dns_log_json_failure_v1(response, index, flags); if let Ok(Some(js)) = dns_log_json_failure_v1(response, index, flags) {
return Box::into_raw(Box::new(js));
}
} }
break; break;
} }
@ -692,8 +729,10 @@ pub extern "C" fn rs_dns_log_json_answer_v1(tx: &mut DNSTransaction,
} }
let answer = &response.answers[index]; let answer = &response.answers[index];
if dns_log_rrtype_enabled(answer.rrtype, flags) { if dns_log_rrtype_enabled(answer.rrtype, flags) {
let js = dns_log_json_answer_v1(&response.header, answer); if let Ok(js) = dns_log_json_answer_v1(&response.header, answer) {
return js.unwrap(); return Box::into_raw(Box::new(js));
}
break;
} }
} }
return std::ptr::null_mut(); return std::ptr::null_mut();
@ -703,15 +742,16 @@ pub extern "C" fn rs_dns_log_json_answer_v1(tx: &mut DNSTransaction,
pub extern "C" fn rs_dns_log_json_authority_v1(tx: &mut DNSTransaction, pub extern "C" fn rs_dns_log_json_authority_v1(tx: &mut DNSTransaction,
i: u16, i: u16,
flags: u64) flags: u64)
-> *mut JsonT -> *mut JsonBuilder
{ {
let index = i as usize; let index = i as usize;
if let &Some(ref response) = &tx.response { if let &Some(ref response) = &tx.response {
if index < response.authorities.len() { if index < response.authorities.len() {
let answer = &response.authorities[index]; let answer = &response.authorities[index];
if dns_log_rrtype_enabled(answer.rrtype, flags) { if dns_log_rrtype_enabled(answer.rrtype, flags) {
let js = dns_log_json_answer_v1(&response.header, answer); if let Ok(js) = dns_log_json_answer_v1(&response.header, answer) {
return js.unwrap(); return Box::into_raw(Box::new(js));
}
} }
} }
} }

@ -198,20 +198,18 @@ static void AlertJsonDns(const Flow *f, const uint64_t tx_id, JsonBuilder *js)
void *txptr = AppLayerParserGetTx(f->proto, ALPROTO_DNS, void *txptr = AppLayerParserGetTx(f->proto, ALPROTO_DNS,
dns_state, tx_id); dns_state, tx_id);
if (txptr) { if (txptr) {
json_t *dnsjs = json_object(); jb_open_object(js, "dns");
if (unlikely(dnsjs == NULL)) { JsonBuilder *qjs = JsonDNSLogQuery(txptr, tx_id);
return;
}
json_t *qjs = JsonDNSLogQuery(txptr, tx_id);
if (qjs != NULL) { if (qjs != NULL) {
json_object_set_new(dnsjs, "query", qjs); jb_set_object(js, "query", qjs);
jb_free(qjs);
} }
json_t *ajs = JsonDNSLogAnswer(txptr, tx_id); JsonBuilder *ajs = JsonDNSLogAnswer(txptr, tx_id);
if (ajs != NULL) { if (ajs != NULL) {
json_object_set_new(dnsjs, "answer", ajs); jb_set_object(js, "answer", ajs);
jb_free(ajs);
} }
jb_set_jsont(js, "dns", dnsjs); jb_close(js);
json_decref(dnsjs);
} }
} }
return; return;

@ -271,26 +271,38 @@ typedef struct LogDnsLogThread_ {
MemBuffer *buffer; MemBuffer *buffer;
} LogDnsLogThread; } LogDnsLogThread;
json_t *JsonDNSLogQuery(void *txptr, uint64_t tx_id) JsonBuilder *JsonDNSLogQuery(void *txptr, uint64_t tx_id)
{ {
json_t *queryjs = json_array(); JsonBuilder *queryjb = jb_new_array();
if (queryjs == NULL) if (queryjb == NULL) {
return NULL; return NULL;
}
for (uint16_t i = 0; i < UINT16_MAX; i++) { for (uint16_t i = 0; i < UINT16_MAX; i++) {
json_t *dns = rs_dns_log_json_query((void *)txptr, i, LOG_ALL_RRTYPES); JsonBuilder *js = jb_new_object();
if (unlikely(dns == NULL)) { if (!rs_dns_log_json_query((void *)txptr, i, LOG_ALL_RRTYPES, js)) {
jb_free(js);
break; break;
} }
json_array_append_new(queryjs, dns); jb_close(js);
jb_append_object(queryjb, js);
jb_free(js);
} }
return queryjs; jb_close(queryjb);
return queryjb;
} }
json_t *JsonDNSLogAnswer(void *txptr, uint64_t tx_id) JsonBuilder *JsonDNSLogAnswer(void *txptr, uint64_t tx_id)
{ {
return rs_dns_log_json_answer(txptr, LOG_ALL_RRTYPES); if (!rs_dns_do_log_answer(txptr, LOG_ALL_RRTYPES)) {
return NULL;
} else {
JsonBuilder *js = jb_new_object();
rs_dns_log_json_answer(txptr, LOG_ALL_RRTYPES, js);
jb_close(js);
return js;
}
} }
static int JsonDnsLoggerToServer(ThreadVars *tv, void *thread_data, static int JsonDnsLoggerToServer(ThreadVars *tv, void *thread_data,
@ -300,28 +312,28 @@ static int JsonDnsLoggerToServer(ThreadVars *tv, void *thread_data,
LogDnsLogThread *td = (LogDnsLogThread *)thread_data; LogDnsLogThread *td = (LogDnsLogThread *)thread_data;
LogDnsFileCtx *dnslog_ctx = td->dnslog_ctx; LogDnsFileCtx *dnslog_ctx = td->dnslog_ctx;
json_t *js;
if (unlikely(dnslog_ctx->flags & LOG_QUERIES) == 0) { if (unlikely(dnslog_ctx->flags & LOG_QUERIES) == 0) {
return TM_ECODE_OK; return TM_ECODE_OK;
} }
for (uint16_t i = 0; i < 0xffff; i++) { for (uint16_t i = 0; i < 0xffff; i++) {
js = CreateJSONHeader(p, LOG_DIR_FLOW, "dns", NULL); JsonBuilder *jb = CreateEveHeader(p, LOG_DIR_FLOW, "dns", NULL);
if (unlikely(js == NULL)) { if (unlikely(jb == NULL)) {
return TM_ECODE_OK; return TM_ECODE_OK;
} }
JsonAddCommonOptions(&dnslog_ctx->cfg, p, f, js); EveAddCommonOptions(&dnslog_ctx->cfg, p, f, jb);
json_t *dns = rs_dns_log_json_query(txptr, i, td->dnslog_ctx->flags); jb_open_object(jb, "dns");
if (unlikely(dns == NULL)) { if (!rs_dns_log_json_query(txptr, i, td->dnslog_ctx->flags, jb)) {
json_decref(js); jb_free(jb);
break; break;
} }
json_object_set_new(js, "dns", dns); jb_close(jb);
MemBufferReset(td->buffer); MemBufferReset(td->buffer);
OutputJSONBuffer(js, td->dnslog_ctx->file_ctx, &td->buffer); OutputJsonBuilderBuffer(jb, td->dnslog_ctx->file_ctx, &td->buffer);
json_decref(js); jb_free(jb);
} }
SCReturnInt(TM_ECODE_OK); SCReturnInt(TM_ECODE_OK);
@ -339,49 +351,64 @@ static int JsonDnsLoggerToClient(ThreadVars *tv, void *thread_data,
return TM_ECODE_OK; return TM_ECODE_OK;
} }
json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "dns", NULL);
if (unlikely(js == NULL))
return TM_ECODE_OK;
JsonAddCommonOptions(&dnslog_ctx->cfg, p, f, js);
if (td->dnslog_ctx->version == DNS_VERSION_2) { if (td->dnslog_ctx->version == DNS_VERSION_2) {
json_t *answer = rs_dns_log_json_answer(txptr, if (rs_dns_do_log_answer(txptr, td->dnslog_ctx->flags)) {
td->dnslog_ctx->flags); JsonBuilder *jb = CreateEveHeader(p, LOG_DIR_FLOW, "dns", NULL);
if (answer != NULL) { if (unlikely(jb == NULL)) {
json_object_set_new(js, "dns", answer); return TM_ECODE_OK;
}
EveAddCommonOptions(&dnslog_ctx->cfg, p, f, jb);
jb_open_object(jb, "dns");
rs_dns_log_json_answer(txptr, td->dnslog_ctx->flags, jb);
jb_close(jb);
MemBufferReset(td->buffer); MemBufferReset(td->buffer);
OutputJSONBuffer(js, td->dnslog_ctx->file_ctx, &td->buffer); OutputJsonBuilderBuffer(jb, td->dnslog_ctx->file_ctx, &td->buffer);
jb_free(jb);
} }
} else { } else {
/* Log answers. */ /* Log answers. */
for (uint16_t i = 0; i < UINT16_MAX; i++) { for (uint16_t i = 0; i < UINT16_MAX; i++) {
json_t *answer = rs_dns_log_json_answer_v1(txptr, i, JsonBuilder *jb = CreateEveHeader(p, LOG_DIR_FLOW, "dns", NULL);
if (unlikely(jb == NULL)) {
return TM_ECODE_OK;
}
EveAddCommonOptions(&dnslog_ctx->cfg, p, f, jb);
JsonBuilder *answer = rs_dns_log_json_answer_v1(txptr, i,
td->dnslog_ctx->flags); td->dnslog_ctx->flags);
if (answer == NULL) { if (answer == NULL) {
jb_free(jb);
break; break;
} }
json_object_set_new(js, "dns", answer); jb_set_object(jb, "dns", answer);
MemBufferReset(td->buffer); MemBufferReset(td->buffer);
OutputJSONBuffer(js, td->dnslog_ctx->file_ctx, &td->buffer); OutputJsonBuilderBuffer(jb, td->dnslog_ctx->file_ctx, &td->buffer);
json_object_del(js, "dns"); jb_free(jb);
} }
/* Log authorities. */ /* Log authorities. */
for (uint16_t i = 0; i < UINT16_MAX; i++) { for (uint16_t i = 0; i < UINT16_MAX; i++) {
json_t *answer = rs_dns_log_json_authority_v1(txptr, i, JsonBuilder *jb = CreateEveHeader(p, LOG_DIR_FLOW, "dns", NULL);
if (unlikely(jb == NULL)) {
return TM_ECODE_OK;
}
EveAddCommonOptions(&dnslog_ctx->cfg, p, f, jb);
JsonBuilder *answer = rs_dns_log_json_authority_v1(txptr, i,
td->dnslog_ctx->flags); td->dnslog_ctx->flags);
if (answer == NULL) { if (answer == NULL) {
jb_free(jb);
break; break;
} }
json_object_set_new(js, "dns", answer); jb_set_object(jb, "dns", answer);
MemBufferReset(td->buffer); MemBufferReset(td->buffer);
OutputJSONBuffer(js, td->dnslog_ctx->file_ctx, &td->buffer); OutputJsonBuilderBuffer(jb, td->dnslog_ctx->file_ctx, &td->buffer);
json_object_del(js, "dns"); jb_free(jb);
} }
} }
json_decref(js);
SCReturnInt(TM_ECODE_OK); SCReturnInt(TM_ECODE_OK);
} }

@ -26,7 +26,7 @@
void JsonDnsLogRegister(void); void JsonDnsLogRegister(void);
json_t *JsonDNSLogQuery(void *txptr, uint64_t tx_id) __attribute__((nonnull)); JsonBuilder *JsonDNSLogQuery(void *txptr, uint64_t tx_id) __attribute__((nonnull));
json_t *JsonDNSLogAnswer(void *txptr, uint64_t tx_id) __attribute__((nonnull)); JsonBuilder *JsonDNSLogAnswer(void *txptr, uint64_t tx_id) __attribute__((nonnull));
#endif /* __OUTPUT_JSON_DNS_H__ */ #endif /* __OUTPUT_JSON_DNS_H__ */

Loading…
Cancel
Save