From: Philippe Antoine Date: Sun, 26 Jan 2025 14:46:34 +0000 (+0100) Subject: detect/dns: support string for dns.rrtype X-Git-Tag: suricata-8.0.0-rc1~445 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8757ad5fd302666d6259659d0fdce51c8edd7ed1;p=thirdparty%2Fsuricata.git detect/dns: support string for dns.rrtype Ticket: 6723 --- diff --git a/doc/userguide/rules/dns-keywords.rst b/doc/userguide/rules/dns-keywords.rst index e343517742..49d10a52b3 100644 --- a/doc/userguide/rules/dns-keywords.rst +++ b/doc/userguide/rules/dns-keywords.rst @@ -82,6 +82,8 @@ This keyword matches on the **rrtype** (integer) found in the DNS message. dns.rrtype uses an :ref:`unsigned 16-bit integer `. +It can also be specified by text from the enumeration. + Syntax ~~~~~~ diff --git a/rust/src/dns/detect.rs b/rust/src/dns/detect.rs index bfbc9b95df..615772a1f8 100644 --- a/rust/src/dns/detect.rs +++ b/rust/src/dns/detect.rs @@ -15,10 +15,10 @@ * 02110-1301, USA. */ -use super::dns::{DNSRcode, DNSTransaction, ALPROTO_DNS}; +use super::dns::{DNSRcode, DNSRecordType, DNSTransaction, ALPROTO_DNS}; use crate::detect::uint::{ - detect_match_uint, detect_parse_uint_enum, SCDetectU16Free, SCDetectU16Parse, - SCDetectU8Free, SCDetectU8Parse, DetectUintData, + detect_match_uint, detect_parse_uint_enum, DetectUintData, SCDetectU16Free, SCDetectU8Free, + SCDetectU8Parse, }; use crate::detect::{ DetectBufferSetActiveList, DetectHelperBufferRegister, DetectHelperGetMultiData, @@ -188,13 +188,26 @@ unsafe extern "C" fn dns_rcode_free(_de: *mut c_void, ctx: *mut c_void) { SCDetectU16Free(ctx); } +unsafe extern "C" fn dns_rrtype_parse( + ustr: *const std::os::raw::c_char, +) -> *mut DetectUintData { + let ft_name: &CStr = CStr::from_ptr(ustr); //unsafe + if let Ok(s) = ft_name.to_str() { + if let Some(ctx) = detect_parse_uint_enum::(s) { + let boxed = Box::new(ctx); + return Box::into_raw(boxed) as *mut _; + } + } + return std::ptr::null_mut(); +} + unsafe extern "C" fn dns_rrtype_setup( de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, ) -> c_int { if DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0 { return -1; } - let ctx = SCDetectU16Parse(raw) as *mut c_void; + let ctx = dns_rrtype_parse(raw) as *mut c_void; if ctx.is_null() { return -1; } @@ -634,7 +647,7 @@ mod test { #[test] fn parse_rrtype_good() { assert_eq!( - detect_parse_uint::("1").unwrap().1, + detect_parse_uint_enum::("1").unwrap(), DetectUintData { mode: DetectUintMode::DetectUintModeEqual, arg1: 1, @@ -642,7 +655,7 @@ mod test { } ); assert_eq!( - detect_parse_uint::("123").unwrap().1, + detect_parse_uint_enum::("123").unwrap(), DetectUintData { mode: DetectUintMode::DetectUintModeEqual, arg1: 123, @@ -650,7 +663,7 @@ mod test { } ); assert_eq!( - detect_parse_uint::("!123").unwrap().1, + detect_parse_uint_enum::("!123").unwrap(), DetectUintData { mode: DetectUintMode::DetectUintModeNe, arg1: 123, @@ -658,17 +671,25 @@ mod test { } ); assert_eq!( - detect_parse_uint::("7-15").unwrap().1, + detect_parse_uint_enum::("7-15").unwrap(), DetectUintData { mode: DetectUintMode::DetectUintModeRange, arg1: 7, arg2: 15, } ); - assert!(detect_parse_uint::("").is_err()); - assert!(detect_parse_uint::("!").is_err()); - assert!(detect_parse_uint::("! ").is_err()); - assert!(detect_parse_uint::("!asdf").is_err()); + assert_eq!( + detect_parse_uint_enum::("a").unwrap(), + DetectUintData { + mode: DetectUintMode::DetectUintModeEqual, + arg1: DNSRecordType::A as u16, + arg2: 0, + } + ); + assert!(detect_parse_uint_enum::("").is_none()); + assert!(detect_parse_uint_enum::("!").is_none()); + assert!(detect_parse_uint_enum::("! ").is_none()); + assert!(detect_parse_uint_enum::("!asdf").is_none()); } #[test] diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index ab10bd15a7..1b2acaca6a 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -33,65 +33,69 @@ use nom7::{Err, IResult}; use suricata_sys::sys::AppProto; /// 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; // Obsolete -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_HTTPS: u16 = 65; -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. +#[derive(Clone, Debug, EnumStringU16)] +pub enum DNSRecordType { + A = 1, + NS = 2, + MD = 3, // Obsolete + MF = 4, // Obsolete + CNAME = 5, + SOA = 6, + MB = 7, // Experimental + MG = 8, // Experimental + MR = 9, // Experimental + NULL = 10, // Experimental + WKS = 11, + PTR = 12, + HINFO = 13, + MINFO = 14, + MX = 15, + TXT = 16, + RP = 17, + AFSDB = 18, + X25 = 19, + ISDN = 20, + RT = 21, + NSAP = 22, + NSAPPTR = 23, + SIG = 24, + KEY = 25, + PX = 26, + GPOS = 27, + AAAA = 28, + LOC = 29, + NXT = 30, // Obsolete + SRV = 33, + ATMA = 34, + NAPTR = 35, + KX = 36, + CERT = 37, + A6 = 38, // Obsolete + DNAME = 39, + OPT = 41, + APL = 42, + DS = 43, + SSHFP = 44, + IPSECKEY = 45, + RRSIG = 46, + NSEC = 47, + DNSKEY = 48, + DHCID = 49, + NSEC3 = 50, + NSEC3PARAM = 51, + TLSA = 52, + HIP = 55, + CDS = 59, + CDNSKEY = 60, + HTTPS = 65, + SPF = 99, // Obsolete + TKEY = 249, + TSIG = 250, + MAILA = 254, // Obsolete + ANY = 255, + URI = 256, +} /// DNS error codes. #[derive(Clone, Debug, EnumStringU16)] diff --git a/rust/src/dns/log.rs b/rust/src/dns/log.rs index 6647ac88e6..447dda1b23 100644 --- a/rust/src/dns/log.rs +++ b/rust/src/dns/log.rs @@ -96,180 +96,180 @@ fn dns_log_rrtype_enabled(rtype: u16, flags: u64) -> bool { return true; } - match rtype { - DNS_RECORD_TYPE_A => { + match DNSRecordType::from_u(rtype) { + Some(DNSRecordType::A) => { return flags & LOG_A != 0; } - DNS_RECORD_TYPE_NS => { + Some(DNSRecordType::NS) => { return flags & LOG_NS != 0; } - DNS_RECORD_TYPE_MD => { + Some(DNSRecordType::MD) => { return flags & LOG_MD != 0; } - DNS_RECORD_TYPE_MF => { + Some(DNSRecordType::MF) => { return flags & LOG_MF != 0; } - DNS_RECORD_TYPE_CNAME => { + Some(DNSRecordType::CNAME) => { return flags & LOG_CNAME != 0; } - DNS_RECORD_TYPE_SOA => { + Some(DNSRecordType::SOA) => { return flags & LOG_SOA != 0; } - DNS_RECORD_TYPE_MB => { + Some(DNSRecordType::MB) => { return flags & LOG_MB != 0; } - DNS_RECORD_TYPE_MG => { + Some(DNSRecordType::MG) => { return flags & LOG_MG != 0; } - DNS_RECORD_TYPE_MR => { + Some(DNSRecordType::MR) => { return flags & LOG_MR != 0; } - DNS_RECORD_TYPE_NULL => { + Some(DNSRecordType::NULL) => { return flags & LOG_NULL != 0; } - DNS_RECORD_TYPE_WKS => { + Some(DNSRecordType::WKS) => { return flags & LOG_WKS != 0; } - DNS_RECORD_TYPE_PTR => { + Some(DNSRecordType::PTR) => { return flags & LOG_PTR != 0; } - DNS_RECORD_TYPE_HINFO => { + Some(DNSRecordType::HINFO) => { return flags & LOG_HINFO != 0; } - DNS_RECORD_TYPE_MINFO => { + Some(DNSRecordType::MINFO) => { return flags & LOG_MINFO != 0; } - DNS_RECORD_TYPE_MX => { + Some(DNSRecordType::MX) => { return flags & LOG_MX != 0; } - DNS_RECORD_TYPE_TXT => { + Some(DNSRecordType::TXT) => { return flags & LOG_TXT != 0; } - DNS_RECORD_TYPE_RP => { + Some(DNSRecordType::RP) => { return flags & LOG_RP != 0; } - DNS_RECORD_TYPE_AFSDB => { + Some(DNSRecordType::AFSDB) => { return flags & LOG_AFSDB != 0; } - DNS_RECORD_TYPE_X25 => { + Some(DNSRecordType::X25) => { return flags & LOG_X25 != 0; } - DNS_RECORD_TYPE_ISDN => { + Some(DNSRecordType::ISDN) => { return flags & LOG_ISDN != 0; } - DNS_RECORD_TYPE_RT => { + Some(DNSRecordType::RT) => { return flags & LOG_RT != 0; } - DNS_RECORD_TYPE_NSAP => { + Some(DNSRecordType::NSAP) => { return flags & LOG_NSAP != 0; } - DNS_RECORD_TYPE_NSAPPTR => { + Some(DNSRecordType::NSAPPTR) => { return flags & LOG_NSAPPTR != 0; } - DNS_RECORD_TYPE_SIG => { + Some(DNSRecordType::SIG) => { return flags & LOG_SIG != 0; } - DNS_RECORD_TYPE_KEY => { + Some(DNSRecordType::KEY) => { return flags & LOG_KEY != 0; } - DNS_RECORD_TYPE_PX => { + Some(DNSRecordType::PX) => { return flags & LOG_PX != 0; } - DNS_RECORD_TYPE_GPOS => { + Some(DNSRecordType::GPOS) => { return flags & LOG_GPOS != 0; } - DNS_RECORD_TYPE_AAAA => { + Some(DNSRecordType::AAAA) => { return flags & LOG_AAAA != 0; } - DNS_RECORD_TYPE_LOC => { + Some(DNSRecordType::LOC) => { return flags & LOG_LOC != 0; } - DNS_RECORD_TYPE_NXT => { + Some(DNSRecordType::NXT) => { return flags & LOG_NXT != 0; } - DNS_RECORD_TYPE_SRV => { + Some(DNSRecordType::SRV) => { return flags & LOG_SRV != 0; } - DNS_RECORD_TYPE_ATMA => { + Some(DNSRecordType::ATMA) => { return flags & LOG_ATMA != 0; } - DNS_RECORD_TYPE_NAPTR => { + Some(DNSRecordType::NAPTR) => { return flags & LOG_NAPTR != 0; } - DNS_RECORD_TYPE_KX => { + Some(DNSRecordType::KX) => { return flags & LOG_KX != 0; } - DNS_RECORD_TYPE_CERT => { + Some(DNSRecordType::CERT) => { return flags & LOG_CERT != 0; } - DNS_RECORD_TYPE_A6 => { + Some(DNSRecordType::A6) => { return flags & LOG_A6 != 0; } - DNS_RECORD_TYPE_DNAME => { + Some(DNSRecordType::DNAME) => { return flags & LOG_DNAME != 0; } - DNS_RECORD_TYPE_OPT => { + Some(DNSRecordType::OPT) => { return flags & LOG_OPT != 0; } - DNS_RECORD_TYPE_APL => { + Some(DNSRecordType::APL) => { return flags & LOG_APL != 0; } - DNS_RECORD_TYPE_DS => { + Some(DNSRecordType::DS) => { return flags & LOG_DS != 0; } - DNS_RECORD_TYPE_SSHFP => { + Some(DNSRecordType::SSHFP) => { return flags & LOG_SSHFP != 0; } - DNS_RECORD_TYPE_IPSECKEY => { + Some(DNSRecordType::IPSECKEY) => { return flags & LOG_IPSECKEY != 0; } - DNS_RECORD_TYPE_RRSIG => { + Some(DNSRecordType::RRSIG) => { return flags & LOG_RRSIG != 0; } - DNS_RECORD_TYPE_NSEC => { + Some(DNSRecordType::NSEC) => { return flags & LOG_NSEC != 0; } - DNS_RECORD_TYPE_DNSKEY => { + Some(DNSRecordType::DNSKEY) => { return flags & LOG_DNSKEY != 0; } - DNS_RECORD_TYPE_DHCID => { + Some(DNSRecordType::DHCID) => { return flags & LOG_DHCID != 0; } - DNS_RECORD_TYPE_NSEC3 => return flags & LOG_NSEC3 != 0, - DNS_RECORD_TYPE_NSEC3PARAM => { + Some(DNSRecordType::NSEC3) => return flags & LOG_NSEC3 != 0, + Some(DNSRecordType::NSEC3PARAM) => { return flags & LOG_NSEC3PARAM != 0; } - DNS_RECORD_TYPE_TLSA => { + Some(DNSRecordType::TLSA) => { return flags & LOG_TLSA != 0; } - DNS_RECORD_TYPE_HIP => { + Some(DNSRecordType::HIP) => { return flags & LOG_HIP != 0; } - DNS_RECORD_TYPE_CDS => { + Some(DNSRecordType::CDS) => { return flags & LOG_CDS != 0; } - DNS_RECORD_TYPE_CDNSKEY => { + Some(DNSRecordType::CDNSKEY) => { return flags & LOG_CDNSKEY != 0; } - DNS_RECORD_TYPE_HTTPS => { + Some(DNSRecordType::HTTPS) => { return flags & LOG_HTTPS != 0; } - DNS_RECORD_TYPE_SPF => { + Some(DNSRecordType::SPF) => { return flags & LOG_SPF != 0; } - DNS_RECORD_TYPE_TKEY => { + Some(DNSRecordType::TKEY) => { return flags & LOG_TKEY != 0; } - DNS_RECORD_TYPE_TSIG => { + Some(DNSRecordType::TSIG) => { return flags & LOG_TSIG != 0; } - DNS_RECORD_TYPE_MAILA => { + Some(DNSRecordType::MAILA) => { return flags & LOG_MAILA != 0; } - DNS_RECORD_TYPE_ANY => { + Some(DNSRecordType::ANY) => { return flags & LOG_ANY != 0; } - DNS_RECORD_TYPE_URI => { + Some(DNSRecordType::URI) => { return flags & LOG_URI != 0; } _ => { @@ -279,71 +279,10 @@ fn dns_log_rrtype_enabled(rtype: u16, flags: u64) -> bool { } pub fn dns_rrtype_string(rrtype: u16) -> String { - match rrtype { - DNS_RECORD_TYPE_A => "A", - DNS_RECORD_TYPE_NS => "NS", - DNS_RECORD_TYPE_AAAA => "AAAA", - DNS_RECORD_TYPE_CNAME => "CNAME", - DNS_RECORD_TYPE_TXT => "TXT", - DNS_RECORD_TYPE_MX => "MX", - DNS_RECORD_TYPE_SOA => "SOA", - DNS_RECORD_TYPE_PTR => "PTR", - DNS_RECORD_TYPE_SIG => "SIG", - DNS_RECORD_TYPE_KEY => "KEY", - DNS_RECORD_TYPE_WKS => "WKS", - DNS_RECORD_TYPE_TKEY => "TKEY", - DNS_RECORD_TYPE_TSIG => "TSIG", - DNS_RECORD_TYPE_ANY => "ANY", - DNS_RECORD_TYPE_RRSIG => "RRSIG", - DNS_RECORD_TYPE_NSEC => "NSEC", - DNS_RECORD_TYPE_DNSKEY => "DNSKEY", - DNS_RECORD_TYPE_HINFO => "HINFO", - DNS_RECORD_TYPE_MINFO => "MINFO", - DNS_RECORD_TYPE_RP => "RP", - DNS_RECORD_TYPE_AFSDB => "AFSDB", - DNS_RECORD_TYPE_X25 => "X25", - DNS_RECORD_TYPE_ISDN => "ISDN", - DNS_RECORD_TYPE_RT => "RT", - DNS_RECORD_TYPE_NSAP => "NSAP", - DNS_RECORD_TYPE_NSAPPTR => "NSAPPT", - DNS_RECORD_TYPE_PX => "PX", - DNS_RECORD_TYPE_GPOS => "GPOS", - DNS_RECORD_TYPE_LOC => "LOC", - DNS_RECORD_TYPE_SRV => "SRV", - DNS_RECORD_TYPE_ATMA => "ATMA", - DNS_RECORD_TYPE_NAPTR => "NAPTR", - DNS_RECORD_TYPE_KX => "KX", - DNS_RECORD_TYPE_CERT => "CERT", - DNS_RECORD_TYPE_A6 => "A6", - DNS_RECORD_TYPE_DNAME => "DNAME", - DNS_RECORD_TYPE_OPT => "OPT", - DNS_RECORD_TYPE_APL => "APL", - DNS_RECORD_TYPE_DS => "DS", - DNS_RECORD_TYPE_SSHFP => "SSHFP", - DNS_RECORD_TYPE_IPSECKEY => "IPSECKEY", - DNS_RECORD_TYPE_DHCID => "DHCID", - DNS_RECORD_TYPE_NSEC3 => "NSEC3", - DNS_RECORD_TYPE_NSEC3PARAM => "NSEC3PARAM", - DNS_RECORD_TYPE_TLSA => "TLSA", - DNS_RECORD_TYPE_HIP => "HIP", - DNS_RECORD_TYPE_CDS => "CDS", - DNS_RECORD_TYPE_CDNSKEY => "CDSNKEY", - DNS_RECORD_TYPE_HTTPS => "HTTPS", - DNS_RECORD_TYPE_MAILA => "MAILA", - DNS_RECORD_TYPE_URI => "URI", - DNS_RECORD_TYPE_MB => "MB", - DNS_RECORD_TYPE_MG => "MG", - DNS_RECORD_TYPE_MR => "MR", - DNS_RECORD_TYPE_NULL => "NULL", - DNS_RECORD_TYPE_SPF => "SPF", - DNS_RECORD_TYPE_NXT => "NXT", - DNS_RECORD_TYPE_MD => "ND", - DNS_RECORD_TYPE_MF => "MF", - _ => { - return rrtype.to_string(); - } + if let Some(rt) = DNSRecordType::from_u(rrtype) { + return rt.to_str().to_uppercase(); } - .to_string() + return rrtype.to_string(); } pub fn dns_rcode_string(flags: u16) -> String { diff --git a/rust/src/dns/mod.rs b/rust/src/dns/mod.rs index 3a572a8211..42063899f2 100644 --- a/rust/src/dns/mod.rs +++ b/rust/src/dns/mod.rs @@ -20,5 +20,5 @@ pub mod detect; pub mod dns; pub mod log; -pub mod parser; pub mod lua; +pub mod parser; diff --git a/rust/src/dns/parser.rs b/rust/src/dns/parser.rs index d94daf9804..ee2366137f 100644 --- a/rust/src/dns/parser.rs +++ b/rust/src/dns/parser.rs @@ -18,6 +18,7 @@ //! Nom parsers for DNS. use crate::dns::dns::*; +use crate::detect::EnumString; use nom7::combinator::{complete, rest}; use nom7::error::ErrorKind; use nom7::multi::{count, length_data, many_m_n}; @@ -205,24 +206,21 @@ fn dns_parse_answer<'a>( for _ in 0..count { match subparser(input, message, flags) { Ok((rem, val)) => { - let n = match val.rrtype { - DNS_RECORD_TYPE_TXT => { - // For TXT records we need to run the parser - // multiple times. Set n high, to the maximum - // value based on a max txt side of 65535, but - // taking into considering that strings need - // to be quoted, so half that. - 32767 - } - _ => { - // For all other types we only want to run the - // parser once, so set n to 1. - 1 - } + let n = if val.rrtype == DNSRecordType::TXT as u16 { + // For TXT records we need to run the parser + // multiple times. Set n high, to the maximum + // value based on a max txt side of 65535, but + // taking into considering that strings need + // to be quoted, so half that. + 32767 + } else { + // For all other types we only want to run the + // parser once, so set n to 1. + 1 }; // edge case for additional section of type=OPT // with empty data (data length = 0x0000) - if val.data.is_empty() && val.rrtype == DNS_RECORD_TYPE_OPT { + if val.data.is_empty() && val.rrtype == DNSRecordType::OPT as u16 { answers.push(DNSAnswerEntry { name: val.name.clone(), rrtype: val.rrtype, @@ -414,19 +412,19 @@ fn dns_parse_rdata_unknown(input: &[u8]) -> IResult<&[u8], DNSRData> { fn dns_parse_rdata<'a>( input: &'a [u8], message: &'a [u8], rrtype: u16, flags: &mut DNSNameFlags, ) -> IResult<&'a [u8], DNSRData> { - match rrtype { - DNS_RECORD_TYPE_A => dns_parse_rdata_a(input), - DNS_RECORD_TYPE_AAAA => dns_parse_rdata_aaaa(input), - DNS_RECORD_TYPE_CNAME => dns_parse_rdata_cname(input, message, flags), - DNS_RECORD_TYPE_PTR => dns_parse_rdata_ptr(input, message, flags), - DNS_RECORD_TYPE_SOA => dns_parse_rdata_soa(input, message, flags), - DNS_RECORD_TYPE_MX => dns_parse_rdata_mx(input, message, flags), - DNS_RECORD_TYPE_NS => dns_parse_rdata_ns(input, message, flags), - DNS_RECORD_TYPE_TXT => dns_parse_rdata_txt(input), - DNS_RECORD_TYPE_NULL => dns_parse_rdata_null(input), - DNS_RECORD_TYPE_SSHFP => dns_parse_rdata_sshfp(input), - DNS_RECORD_TYPE_SRV => dns_parse_rdata_srv(input, message, flags), - DNS_RECORD_TYPE_OPT => dns_parse_rdata_opt(input), + match DNSRecordType::from_u(rrtype) { + Some(DNSRecordType::A) => dns_parse_rdata_a(input), + Some(DNSRecordType::AAAA) => dns_parse_rdata_aaaa(input), + Some(DNSRecordType::CNAME) => dns_parse_rdata_cname(input, message, flags), + Some(DNSRecordType::PTR) => dns_parse_rdata_ptr(input, message, flags), + Some(DNSRecordType::SOA) => dns_parse_rdata_soa(input, message, flags), + Some(DNSRecordType::MX) => dns_parse_rdata_mx(input, message, flags), + Some(DNSRecordType::NS) => dns_parse_rdata_ns(input, message, flags), + Some(DNSRecordType::TXT) => dns_parse_rdata_txt(input), + Some(DNSRecordType::NULL) => dns_parse_rdata_null(input), + Some(DNSRecordType::SSHFP) => dns_parse_rdata_sshfp(input), + Some(DNSRecordType::SRV) => dns_parse_rdata_srv(input, message, flags), + Some(DNSRecordType::OPT) => dns_parse_rdata_opt(input), _ => dns_parse_rdata_unknown(input), } } @@ -705,7 +703,7 @@ mod tests { value: vec![], flags: DNSNameFlags::default() }, - rrtype: DNS_RECORD_TYPE_OPT, + rrtype: DNSRecordType::OPT as u16, rrclass: 0x1000, // for OPT this is UDP payload size ttl: 0, // for OPT this is extended RCODE and flags data: DNSRData::OPT(vec![]), // empty rdata @@ -766,7 +764,7 @@ mod tests { value: vec![], flags: DNSNameFlags::default() }, - rrtype: DNS_RECORD_TYPE_OPT, + rrtype: DNSRecordType::OPT as u16, rrclass: 0x1000, // for OPT this is requestor's UDP payload size ttl: 0, // for OPT this is extended RCODE and flags // verify two options @@ -951,7 +949,7 @@ mod tests { value: vec![], flags: DNSNameFlags::default() }, - rrtype: DNS_RECORD_TYPE_OPT, + rrtype: DNSRecordType::OPT as u16, rrclass: 0x0200, // for OPT this is UDP payload size ttl: 0, // for OPT this is extended RCODE and flags data: DNSRData::OPT(vec![]), // no rdata @@ -997,7 +995,7 @@ mod tests { query.name.value, "vaaaakardli.pirate.sea".as_bytes().to_vec() ); - assert_eq!(query.rrtype, DNS_RECORD_TYPE_NULL); + assert_eq!(query.rrtype, DNSRecordType::NULL as u16); assert_eq!(query.rrclass, 1); assert_eq!(response.answers.len(), 1); @@ -1007,7 +1005,7 @@ mod tests { answer.name.value, "vaaaakardli.pirate.sea".as_bytes().to_vec() ); - assert_eq!(answer.rrtype, DNS_RECORD_TYPE_NULL); + assert_eq!(answer.rrtype, DNSRecordType::NULL as u16); assert_eq!(answer.rrclass, 1); assert_eq!(answer.ttl, 0); assert_eq!(