From: Jason Ish Date: Wed, 10 May 2017 13:24:02 +0000 (-0600) Subject: rust: dns: add log filtering on rrtype X-Git-Tag: suricata-4.0.0-beta1~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ba1a67e2cb11016a617e1074bc5789a66a15309e;p=thirdparty%2Fsuricata.git rust: dns: add log filtering on rrtype While the filtering is still configured in C, the filtering flags are passed into Rust so it can determine if a record should be logged or not. --- diff --git a/rust/src/core.rs b/rust/src/core.rs index f92f3f0b01..8388da2733 100644 --- a/rust/src/core.rs +++ b/rust/src/core.rs @@ -28,6 +28,10 @@ pub enum AppLayerDecoderEvents {} pub const STREAM_TOSERVER: u8 = 0x04; pub const STREAM_TOCLIENT: u8 = 0x08; +macro_rules!BIT_U64 { + ($x:expr) => (1 << $x); +} + // // Function types for calls into C. // diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index 5aadf148aa..bccef87c4f 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -36,6 +36,66 @@ pub const DNS_RTYPE_AAAA: u16 = 28; pub const DNS_RTYPE_SSHFP: u16 = 44; pub const DNS_RTYPE_RRSIG: u16 = 46; +/// DNS record types. +pub const DNS_RECORD_TYPE_A : u16 = 1; +pub const DNS_RECORD_TYPE_NS : u16 = 2; +pub const DNS_RECORD_TYPE_MD : u16 = 3; // Obsolete +pub const DNS_RECORD_TYPE_MF : u16 = 4; // Obsolete +pub const DNS_RECORD_TYPE_CNAME : u16 = 5; +pub const DNS_RECORD_TYPE_SOA : u16 = 6; +pub const DNS_RECORD_TYPE_MB : u16 = 7; // Experimental +pub const DNS_RECORD_TYPE_MG : u16 = 8; // Experimental +pub const DNS_RECORD_TYPE_MR : u16 = 9; // Experimental +pub const DNS_RECORD_TYPE_NULL : u16 = 10; // Experimental +pub const DNS_RECORD_TYPE_WKS : u16 = 11; +pub const DNS_RECORD_TYPE_PTR : u16 = 12; +pub const DNS_RECORD_TYPE_HINFO : u16 = 13; +pub const DNS_RECORD_TYPE_MINFO : u16 = 14; +pub const DNS_RECORD_TYPE_MX : u16 = 15; +pub const DNS_RECORD_TYPE_TXT : u16 = 16; +pub const DNS_RECORD_TYPE_RP : u16 = 17; +pub const DNS_RECORD_TYPE_AFSDB : u16 = 18; +pub const DNS_RECORD_TYPE_X25 : u16 = 19; +pub const DNS_RECORD_TYPE_ISDN : u16 = 20; +pub const DNS_RECORD_TYPE_RT : u16 = 21; +pub const DNS_RECORD_TYPE_NSAP : u16 = 22; +pub const DNS_RECORD_TYPE_NSAPPTR : u16 = 23; +pub const DNS_RECORD_TYPE_SIG : u16 = 24; +pub const DNS_RECORD_TYPE_KEY : u16 = 25; +pub const DNS_RECORD_TYPE_PX : u16 = 26; +pub const DNS_RECORD_TYPE_GPOS : u16 = 27; +pub const DNS_RECORD_TYPE_AAAA : u16 = 28; +pub const DNS_RECORD_TYPE_LOC : u16 = 29; +pub const DNS_RECORD_TYPE_NXT : u16 = 30; // Obosolete +pub const DNS_RECORD_TYPE_SRV : u16 = 33; +pub const DNS_RECORD_TYPE_ATMA : u16 = 34; +pub const DNS_RECORD_TYPE_NAPTR : u16 = 35; +pub const DNS_RECORD_TYPE_KX : u16 = 36; +pub const DNS_RECORD_TYPE_CERT : u16 = 37; +pub const DNS_RECORD_TYPE_A6 : u16 = 38; // Obsolete +pub const DNS_RECORD_TYPE_DNAME : u16 = 39; +pub const DNS_RECORD_TYPE_OPT : u16 = 41; +pub const DNS_RECORD_TYPE_APL : u16 = 42; +pub const DNS_RECORD_TYPE_DS : u16 = 43; +pub const DNS_RECORD_TYPE_SSHFP : u16 = 44; +pub const DNS_RECORD_TYPE_IPSECKEY : u16 = 45; +pub const DNS_RECORD_TYPE_RRSIG : u16 = 46; +pub const DNS_RECORD_TYPE_NSEC : u16 = 47; +pub const DNS_RECORD_TYPE_DNSKEY : u16 = 48; +pub const DNS_RECORD_TYPE_DHCID : u16 = 49; +pub const DNS_RECORD_TYPE_NSEC3 : u16 = 50; +pub const DNS_RECORD_TYPE_NSEC3PARAM : u16 = 51; +pub const DNS_RECORD_TYPE_TLSA : u16 = 52; +pub const DNS_RECORD_TYPE_HIP : u16 = 55; +pub const DNS_RECORD_TYPE_CDS : u16 = 59; +pub const DNS_RECORD_TYPE_CDNSKEY : u16 = 60; +pub const DNS_RECORD_TYPE_SPF : u16 = 99; // Obsolete +pub const DNS_RECORD_TYPE_TKEY : u16 = 249; +pub const DNS_RECORD_TYPE_TSIG : u16 = 250; +pub const DNS_RECORD_TYPE_MAILA : u16 = 254; // Obsolete +pub const DNS_RECORD_TYPE_ANY : u16 = 255; +pub const DNS_RECORD_TYPE_URI : u16 = 256; + /// DNS error codes. pub const DNS_RCODE_NOERROR: u16 = 0; pub const DNS_RCODE_FORMERR: u16 = 1; diff --git a/rust/src/dns/log.rs b/rust/src/dns/log.rs index e2440cc243..da18ac44e0 100644 --- a/rust/src/dns/log.rs +++ b/rust/src/dns/log.rs @@ -22,7 +22,252 @@ use std::string::String; use json::*; use dns::dns::*; -use log::*; + +pub const LOG_A : u64 = BIT_U64!(2); +pub const LOG_NS : u64 = BIT_U64!(3); +pub const LOG_MD : u64 = BIT_U64!(4); +pub const LOG_MF : u64 = BIT_U64!(5); +pub const LOG_CNAME : u64 = BIT_U64!(6); +pub const LOG_SOA : u64 = BIT_U64!(7); +pub const LOG_MB : u64 = BIT_U64!(8); +pub const LOG_MG : u64 = BIT_U64!(9); +pub const LOG_MR : u64 = BIT_U64!(10); +pub const LOG_NULL : u64 = BIT_U64!(11); +pub const LOG_WKS : u64 = BIT_U64!(12); +pub const LOG_PTR : u64 = BIT_U64!(13); +pub const LOG_HINFO : u64 = BIT_U64!(14); +pub const LOG_MINFO : u64 = BIT_U64!(15); +pub const LOG_MX : u64 = BIT_U64!(16); +pub const LOG_TXT : u64 = BIT_U64!(17); +pub const LOG_RP : u64 = BIT_U64!(18); +pub const LOG_AFSDB : u64 = BIT_U64!(19); +pub const LOG_X25 : u64 = BIT_U64!(20); +pub const LOG_ISDN : u64 = BIT_U64!(21); +pub const LOG_RT : u64 = BIT_U64!(22); +pub const LOG_NSAP : u64 = BIT_U64!(23); +pub const LOG_NSAPPTR : u64 = BIT_U64!(24); +pub const LOG_SIG : u64 = BIT_U64!(25); +pub const LOG_KEY : u64 = BIT_U64!(26); +pub const LOG_PX : u64 = BIT_U64!(27); +pub const LOG_GPOS : u64 = BIT_U64!(28); +pub const LOG_AAAA : u64 = BIT_U64!(29); +pub const LOG_LOC : u64 = BIT_U64!(30); +pub const LOG_NXT : u64 = BIT_U64!(31); +pub const LOG_SRV : u64 = BIT_U64!(32); +pub const LOG_ATMA : u64 = BIT_U64!(33); +pub const LOG_NAPTR : u64 = BIT_U64!(34); +pub const LOG_KX : u64 = BIT_U64!(35); +pub const LOG_CERT : u64 = BIT_U64!(36); +pub const LOG_A6 : u64 = BIT_U64!(37); +pub const LOG_DNAME : u64 = BIT_U64!(38); +pub const LOG_OPT : u64 = BIT_U64!(39); +pub const LOG_APL : u64 = BIT_U64!(40); +pub const LOG_DS : u64 = BIT_U64!(41); +pub const LOG_SSHFP : u64 = BIT_U64!(42); +pub const LOG_IPSECKEY : u64 = BIT_U64!(43); +pub const LOG_RRSIG : u64 = BIT_U64!(44); +pub const LOG_NSEC : u64 = BIT_U64!(45); +pub const LOG_DNSKEY : u64 = BIT_U64!(46); +pub const LOG_DHCID : u64 = BIT_U64!(47); +pub const LOG_NSEC3 : u64 = BIT_U64!(48); +pub const LOG_NSEC3PARAM : u64 = BIT_U64!(49); +pub const LOG_TLSA : u64 = BIT_U64!(50); +pub const LOG_HIP : u64 = BIT_U64!(51); +pub const LOG_CDS : u64 = BIT_U64!(52); +pub const LOG_CDNSKEY : u64 = BIT_U64!(53); +pub const LOG_SPF : u64 = BIT_U64!(54); +pub const LOG_TKEY : u64 = BIT_U64!(55); +pub const LOG_TSIG : u64 = BIT_U64!(56); +pub const LOG_MAILA : u64 = BIT_U64!(57); +pub const LOG_ANY : u64 = BIT_U64!(58); +pub const LOG_URI : u64 = BIT_U64!(59); + +fn dns_log_rrtype_enabled(rtype: u16, flags: u64) -> bool +{ + if flags == !0 { + return true; + } + + match rtype { + DNS_RECORD_TYPE_A => { + return flags & LOG_A != 0; + } + DNS_RECORD_TYPE_NS => { + return flags & LOG_NS != 0; + } + DNS_RECORD_TYPE_MD => { + return flags & LOG_MD != 0; + } + DNS_RECORD_TYPE_MF => { + return flags & LOG_MF != 0; + } + DNS_RECORD_TYPE_CNAME => { + return flags & LOG_CNAME != 0; + } + DNS_RECORD_TYPE_SOA => { + return flags & LOG_SOA != 0; + } + DNS_RECORD_TYPE_MB => { + return flags & LOG_MB != 0; + } + DNS_RECORD_TYPE_MG => { + return flags & LOG_MG != 0; + } + DNS_RECORD_TYPE_MR => { + return flags & LOG_MR != 0; + } + DNS_RECORD_TYPE_NULL => { + return flags & LOG_NULL != 0; + } + DNS_RECORD_TYPE_WKS => { + return flags & LOG_WKS != 0; + } + DNS_RECORD_TYPE_PTR => { + return flags & LOG_PTR != 0; + } + DNS_RECORD_TYPE_HINFO => { + return flags & LOG_HINFO != 0; + } + DNS_RECORD_TYPE_MINFO => { + return flags & LOG_MINFO != 0; + } + DNS_RECORD_TYPE_MX => { + return flags & LOG_MX != 0; + } + DNS_RECORD_TYPE_TXT => { + return flags & LOG_TXT != 0; + } + DNS_RECORD_TYPE_RP => { + return flags & LOG_RP != 0; + } + DNS_RECORD_TYPE_AFSDB => { + return flags & LOG_AFSDB != 0; + } + DNS_RECORD_TYPE_X25 => { + return flags & LOG_X25 != 0; + } + DNS_RECORD_TYPE_ISDN => { + return flags & LOG_ISDN != 0; + } + DNS_RECORD_TYPE_RT => { + return flags & LOG_RT != 0; + } + DNS_RECORD_TYPE_NSAP => { + return flags & LOG_NSAP != 0; + } + DNS_RECORD_TYPE_NSAPPTR => { + return flags & LOG_NSAPPTR != 0; + } + DNS_RECORD_TYPE_SIG => { + return flags & LOG_SIG != 0; + } + DNS_RECORD_TYPE_KEY => { + return flags & LOG_KEY != 0; + } + DNS_RECORD_TYPE_PX => { + return flags & LOG_PX != 0; + } + DNS_RECORD_TYPE_GPOS => { + return flags & LOG_GPOS != 0; + } + DNS_RECORD_TYPE_AAAA => { + return flags & LOG_AAAA != 0; + } + DNS_RECORD_TYPE_LOC => { + return flags & LOG_LOC != 0; + } + DNS_RECORD_TYPE_NXT => { + return flags & LOG_NXT != 0; + } + DNS_RECORD_TYPE_SRV => { + return flags & LOG_SRV != 0; + } + DNS_RECORD_TYPE_ATMA => { + return flags & LOG_ATMA != 0; + } + DNS_RECORD_TYPE_NAPTR => { + return flags & LOG_NAPTR != 0; + } + DNS_RECORD_TYPE_KX => { + return flags & LOG_KX != 0; + } + DNS_RECORD_TYPE_CERT => { + return flags & LOG_CERT != 0; + } + DNS_RECORD_TYPE_A6 => { + return flags & LOG_A6 != 0; + } + DNS_RECORD_TYPE_DNAME => { + return flags & LOG_DNAME != 0; + } + DNS_RECORD_TYPE_OPT => { + return flags & LOG_OPT != 0; + } + DNS_RECORD_TYPE_APL => { + return flags & LOG_APL != 0; + } + DNS_RECORD_TYPE_DS => { + return flags & LOG_DS != 0; + } + DNS_RECORD_TYPE_SSHFP => { + return flags & LOG_SSHFP != 0; + } + DNS_RECORD_TYPE_IPSECKEY => { + return flags & LOG_IPSECKEY != 0; + } + DNS_RECORD_TYPE_RRSIG => { + return flags & LOG_RRSIG != 0; + } + DNS_RECORD_TYPE_NSEC => { + return flags & LOG_NSEC != 0; + } + DNS_RECORD_TYPE_DNSKEY => { + return flags & LOG_DNSKEY != 0; + } + DNS_RECORD_TYPE_DHCID => { + return flags & LOG_DHCID != 0; + } + DNS_RECORD_TYPE_NSEC3 => { + return flags & LOG_NSEC3 != 0 + } + DNS_RECORD_TYPE_NSEC3PARAM => { + return flags & LOG_NSEC3PARAM != 0; + } + DNS_RECORD_TYPE_TLSA => { + return flags & LOG_TLSA != 0; + } + DNS_RECORD_TYPE_HIP => { + return flags & LOG_HIP != 0; + } + DNS_RECORD_TYPE_CDS => { + return flags & LOG_CDS != 0; + } + DNS_RECORD_TYPE_CDNSKEY => { + return flags & LOG_CDNSKEY != 0; + } + DNS_RECORD_TYPE_SPF => { + return flags & LOG_SPF != 0; + } + DNS_RECORD_TYPE_TKEY => { + return flags & LOG_TKEY != 0; + } + DNS_RECORD_TYPE_TSIG => { + return flags & LOG_TSIG != 0; + } + DNS_RECORD_TYPE_MAILA => { + return flags & LOG_MAILA != 0; + } + DNS_RECORD_TYPE_ANY => { + return flags & LOG_ANY != 0; + } + DNS_RECORD_TYPE_URI => { + return flags & LOG_URI != 0; + } + _ => { + return false; + } + } +} pub fn dns_rrtype_string(rrtype: u16) -> String { match rrtype { @@ -31,6 +276,7 @@ pub fn dns_rrtype_string(rrtype: u16) -> String { DNS_RTYPE_SOA => "SOA", DNS_RTYPE_PTR => "PTR", DNS_RTYPE_MX => "MX", + DNS_RTYPE_AAAA => "AAAA", DNS_RTYPE_SSHFP => "SSHFP", DNS_RTYPE_RRSIG => "RRSIG", _ => { @@ -56,7 +302,7 @@ pub fn dns_print_addr(addr: &Vec) -> std::string::String { return format!("{}.{}.{}.{}", addr[0], addr[1], addr[2], addr[3]); } else if addr.len() == 16 { - return format!("{}{}:{}{}:{}{}:{}{}:{}{}:{}{}:{}{}:{}{}", + return format!("{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}", addr[0], addr[1], addr[2], @@ -102,21 +348,23 @@ fn dns_log_sshfp(js: &Json, answer: &DNSAnswerEntry) #[no_mangle] pub extern "C" fn rs_dns_log_json_query(tx: &mut DNSTransaction, - i: libc::uint16_t) + i: libc::uint16_t, + flags: libc::uint64_t) -> *mut JsonT { - SCLogDebug!("rs_dns_log_json_query: tx_id={}, i={}", tx.id, i); let index = i as usize; for request in &tx.request { if index < request.queries.len() { let query = &request.queries[index]; - let js = Json::object(); - js.set_string("type", "query"); - js.set_integer("id", request.header.tx_id as u64); - js.set_string("rrname", query.name()); - js.set_string("rrtype", &dns_rrtype_string(query.rrtype)); - js.set_integer("tx_id", tx.id - 1); - return js.unwrap(); + if dns_log_rrtype_enabled(query.rrtype, flags) { + let js = Json::object(); + js.set_string("type", "query"); + js.set_integer("id", request.header.tx_id as u64); + js.set_string("rrname", query.name()); + js.set_string("rrtype", &dns_rrtype_string(query.rrtype)); + js.set_integer("tx_id", tx.id - 1); + return js.unwrap(); + } } } @@ -153,13 +401,18 @@ fn dns_log_json_answer(header: &DNSHeader, answer: &DNSAnswerEntry) return js; } -fn dns_log_json_failure(r: &DNSResponse, index: usize) -> * mut JsonT { +fn dns_log_json_failure(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"); @@ -172,14 +425,15 @@ fn dns_log_json_failure(r: &DNSResponse, index: usize) -> * mut JsonT { #[no_mangle] pub extern "C" fn rs_dns_log_json_answer(tx: &mut DNSTransaction, - i: libc::uint16_t) + 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(response, index); + return dns_log_json_failure(response, index, flags); } break; } @@ -187,15 +441,18 @@ pub extern "C" fn rs_dns_log_json_answer(tx: &mut DNSTransaction, break; } let answer = &response.answers[index]; - let js = dns_log_json_answer(&response.header, answer); - return js.unwrap(); + if dns_log_rrtype_enabled(answer.rrtype, flags) { + let js = dns_log_json_answer(&response.header, answer); + return js.unwrap(); + } } return std::ptr::null_mut(); } #[no_mangle] pub extern "C" fn rs_dns_log_json_authority(tx: &mut DNSTransaction, - i: libc::uint16_t) + i: libc::uint16_t, + flags: libc::uint64_t) -> *mut JsonT { let index = i as usize; @@ -204,8 +461,10 @@ pub extern "C" fn rs_dns_log_json_authority(tx: &mut DNSTransaction, break; } let answer = &response.authorities[index]; - let js = dns_log_json_answer(&response.header, answer); - return js.unwrap(); + if dns_log_rrtype_enabled(answer.rrtype, flags) { + let js = dns_log_json_answer(&response.header, answer); + return js.unwrap(); + } } return std::ptr::null_mut(); } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 15c7c0735e..aa214304d6 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -21,7 +21,9 @@ extern crate nom; #[macro_use] pub mod log; +#[macro_use] pub mod core; + pub mod conf; pub mod json; pub mod applayer; diff --git a/src/output-json-dns.c b/src/output-json-dns.c index 98b10129ca..74840fdcca 100644 --- a/src/output-json-dns.c +++ b/src/output-json-dns.c @@ -650,7 +650,7 @@ static int JsonDnsLoggerToServer(ThreadVars *tv, void *thread_data, if (unlikely(js == NULL)) { return TM_ECODE_OK; } - json_t *dns = rs_dns_log_json_query(txptr, i); + json_t *dns = rs_dns_log_json_query(txptr, i, td->dnslog_ctx->flags); if (unlikely(dns == NULL)) { json_decref(js); break; @@ -662,17 +662,15 @@ static int JsonDnsLoggerToServer(ThreadVars *tv, void *thread_data, } #else DNSTransaction *tx = txptr; - if (likely(dnslog_ctx->flags & LOG_QUERIES) != 0) { - DNSQueryEntry *query = NULL; - TAILQ_FOREACH(query, &tx->query_list, next) { - js = CreateJSONHeader((Packet *)p, 1, "dns"); - if (unlikely(js == NULL)) - return TM_ECODE_OK; + DNSQueryEntry *query = NULL; + TAILQ_FOREACH(query, &tx->query_list, next) { + js = CreateJSONHeader((Packet *)p, 1, "dns"); + if (unlikely(js == NULL)) + return TM_ECODE_OK; - LogQuery(td, js, tx, tx_id, query); + LogQuery(td, js, tx, tx_id, query); - json_decref(js); - } + json_decref(js); } #endif @@ -697,7 +695,8 @@ static int JsonDnsLoggerToClient(ThreadVars *tv, void *thread_data, #if HAVE_RUST /* Log answers. */ for (uint16_t i = 0; i < 0xffff; i++) { - json_t *answer = rs_dns_log_json_answer(txptr, i); + json_t *answer = rs_dns_log_json_answer(txptr, i, + td->dnslog_ctx->flags); if (answer == NULL) { break; } @@ -709,7 +708,8 @@ static int JsonDnsLoggerToClient(ThreadVars *tv, void *thread_data, /* Log authorities. */ for (uint16_t i = 0; i < 0xffff; i++) { - json_t *answer = rs_dns_log_json_authority(txptr, i); + json_t *answer = rs_dns_log_json_authority(txptr, i, + td->dnslog_ctx->flags); if (answer == NULL) { break; }