diff --git a/rust/src/dns/log.rs b/rust/src/dns/log.rs index c3c5f3a370..0ebbeb241a 100644 --- a/rust/src/dns/log.rs +++ b/rust/src/dns/log.rs @@ -598,3 +598,122 @@ pub extern "C" fn rs_dns_log_json_answer(tx: &mut DNSTransaction, return std::ptr::null_mut(); } + +// Version 1 logging support. + +fn dns_log_json_answer_v1(header: &DNSHeader, answer: &DNSAnswerEntry) + -> Json +{ + let js = Json::object(); + + js.set_string("type", "answer"); + js.set_integer("id", header.tx_id as u64); + js.set_string("flags", format!("{:x}", header.flags).as_str()); + if header.flags & 0x8000 != 0 { + js.set_boolean("qr", true); + } + if header.flags & 0x0400 != 0 { + js.set_boolean("aa", true); + } + if header.flags & 0x0200 != 0 { + js.set_boolean("tc", true); + } + if header.flags & 0x0100 != 0 { + js.set_boolean("rd", true); + } + if header.flags & 0x0080 != 0 { + js.set_boolean("ra", true); + } + js.set_string("rcode", &dns_rcode_string(header.flags)); + js.set_string_from_bytes("rrname", &answer.name); + js.set_string("rrtype", &dns_rrtype_string(answer.rrtype)); + js.set_integer("ttl", answer.ttl as u64); + + match answer.rrtype { + DNS_RECORD_TYPE_A | DNS_RECORD_TYPE_AAAA => { + js.set_string("rdata", &dns_print_addr(&answer.data)); + } + DNS_RECORD_TYPE_CNAME | + DNS_RECORD_TYPE_MX | + DNS_RECORD_TYPE_TXT | + DNS_RECORD_TYPE_PTR => { + js.set_string_from_bytes("rdata", &answer.data); + }, + DNS_RECORD_TYPE_SSHFP => { + if let Some(sshfp) = dns_log_sshfp(&answer) { + js.set("sshfp", sshfp); + } + }, + _ => {} + } + + return js; +} + +fn dns_log_json_failure_v1(r: &DNSResponse, index: usize, flags: u64) + -> * mut JsonT { + if index >= r.queries.len() { + return std::ptr::null_mut(); + } + + let ref query = r.queries[index]; + + if !dns_log_rrtype_enabled(query.rrtype, flags) { + return std::ptr::null_mut(); + } + + let js = Json::object(); + + js.set_string("type", "answer"); + 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(); +} + +#[no_mangle] +pub extern "C" fn rs_dns_log_json_answer_v1(tx: &mut DNSTransaction, + i: libc::uint16_t, + flags: libc::uint64_t) + -> *mut JsonT +{ + let index = i as usize; + for response in &tx.response { + if response.header.flags & 0x000f > 0 { + if index == 0 { + return dns_log_json_failure_v1(response, index, flags); + } + break; + } + if index >= response.answers.len() { + break; + } + let answer = &response.answers[index]; + if dns_log_rrtype_enabled(answer.rrtype, flags) { + let js = dns_log_json_answer_v1(&response.header, answer); + return js.unwrap(); + } + } + return std::ptr::null_mut(); +} + +#[no_mangle] +pub extern "C" fn rs_dns_log_json_authority_v1(tx: &mut DNSTransaction, + i: libc::uint16_t, + flags: libc::uint64_t) + -> *mut JsonT +{ + let index = i as usize; + for response in &tx.response { + if index >= response.authorities.len() { + break; + } + let answer = &response.authorities[index]; + if dns_log_rrtype_enabled(answer.rrtype, flags) { + let js = dns_log_json_answer_v1(&response.header, answer); + return js.unwrap(); + } + } + return std::ptr::null_mut(); +} diff --git a/src/output-json-dns.c b/src/output-json-dns.c index c5314e983f..e70a7f2632 100644 --- a/src/output-json-dns.c +++ b/src/output-json-dns.c @@ -1087,6 +1087,31 @@ static int JsonDnsLoggerToClient(ThreadVars *tv, void *thread_data, MemBufferReset(td->buffer); OutputJSONBuffer(js, td->dnslog_ctx->file_ctx, &td->buffer); } + } else { + /* Log answers. */ + for (uint16_t i = 0; i < UINT16_MAX; i++) { + json_t *answer = rs_dns_log_json_answer_v1(txptr, i, + td->dnslog_ctx->flags); + if (answer == NULL) { + break; + } + json_object_set_new(js, "dns", answer); + MemBufferReset(td->buffer); + OutputJSONBuffer(js, td->dnslog_ctx->file_ctx, &td->buffer); + json_object_del(js, "dns"); + } + /* Log authorities. */ + for (uint16_t i = 0; i < UINT16_MAX; i++) { + json_t *answer = rs_dns_log_json_authority_v1(txptr, i, + td->dnslog_ctx->flags); + if (answer == NULL) { + break; + } + json_object_set_new(js, "dns", answer); + MemBufferReset(td->buffer); + OutputJSONBuffer(js, td->dnslog_ctx->file_ctx, &td->buffer); + json_object_del(js, "dns"); + } } #else DNSTransaction *tx = txptr; @@ -1245,12 +1270,6 @@ static DnsVersion JsonDnsParseVersion(ConfNode *conf) DNS_VERSION_DEFAULT); version = DNS_VERSION_DEFAULT; } -#ifdef HAVE_RUST - if (version != DNS_VERSION_2) { - FatalError(SC_ERR_NOT_SUPPORTED, "EVE/DNS version %d not support with " - "by Rust builds.", version); - } -#endif return version; } @@ -1342,13 +1361,6 @@ static OutputInitResult JsonDnsLogInitCtx(ConfNode *conf) } DnsVersion version = JsonDnsParseVersion(conf); -#ifdef HAVE_RUST - if (version != 2) { - SCLogError(SC_ERR_NOT_SUPPORTED, "EVE/DNS version %d not support with " - "by Rust builds.", version); - exit(1); - } -#endif LogFileCtx *file_ctx = LogFileNewCtx(); diff --git a/suricata.yaml.in b/suricata.yaml.in index ccaf5fe5a3..f7fd199bcf 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -164,7 +164,6 @@ outputs: # rather than an event for each of it. # Without setting a version the version # will fallback to 1 for backwards compatibility. - # Note: version 1 is not available with rust enabled version: 2 # Enable/disable this logger. Default: enabled.