From: Nathan Scrivens Date: Thu, 16 May 2024 19:31:38 +0000 (-0400) Subject: dns parsing: add additional section X-Git-Tag: suricata-8.0.0-beta1~1045 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1cd89640efcb2f0002db7be8d09cdf1079e586e1;p=thirdparty%2Fsuricata.git dns parsing: add additional section Feature: 7011 Add additionals to DNSMessage struct. Add parsing logic to populate additional section data. Patch dns tests to account for additional section parsing. --- diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index a293a028e1..0b6f803930 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -226,6 +226,7 @@ pub struct DNSMessage { pub queries: Vec, pub answers: Vec, pub authorities: Vec, + pub additionals: Vec, } #[derive(Debug, Default)] diff --git a/rust/src/dns/parser.rs b/rust/src/dns/parser.rs index 5194e21d33..238b83a102 100644 --- a/rust/src/dns/parser.rs +++ b/rust/src/dns/parser.rs @@ -141,6 +141,19 @@ fn dns_parse_answer<'a>( 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 { + answers.push(DNSAnswerEntry { + name: val.name.clone(), + rrtype: val.rrtype, + rrclass: val.rrclass, + ttl: val.ttl, + data: DNSRData::Unknown(Vec::new()), + }); + input = rem; + continue; + } let result: IResult<&'a [u8], Vec> = many_m_n(1, n, complete(|b| dns_parse_rdata(b, message, val.rrtype)))(val.data); match result { @@ -332,6 +345,7 @@ pub fn dns_parse_body<'a>( let (i, queries) = count(|b| dns_parse_query(b, message), header.questions as usize)(i)?; let (i, answers) = dns_parse_answer(i, message, header.answer_rr as usize)?; let (i, authorities) = dns_parse_answer(i, message, header.authority_rr as usize)?; + let (i, additionals) = dns_parse_answer(i, message, header.additional_rr as usize)?; Ok(( i, DNSMessage { @@ -339,6 +353,7 @@ pub fn dns_parse_body<'a>( queries, answers, authorities, + additionals, }, )) } @@ -478,9 +493,8 @@ mod tests { let (body, header) = dns_parse_header(pkt).unwrap(); let res = dns_parse_body(body, pkt, header); let (rem, request) = res.unwrap(); - // For now we have some remainder data as there is an - // additional record type we don't parse yet. - assert!(!rem.is_empty()); + // The response should be fully parsed. + assert!(rem.is_empty()); assert_eq!( request.header, @@ -500,6 +514,20 @@ mod tests { assert_eq!(query.name, "www.suricata-ids.org".as_bytes().to_vec()); assert_eq!(query.rrtype, 1); assert_eq!(query.rrclass, 1); + + // verify additional section + assert_eq!(request.additionals.len(), 1); + let additional = &request.additionals[0]; + assert_eq!( + additional, + &DNSAnswerEntry { + name: vec![], + rrtype: DNS_RECORD_TYPE_OPT, + rrclass: 0x1000, // for OPT this is UDP payload size + ttl: 0, // for OPT this is extended RCODE and flags + data: DNSRData::Unknown(vec![]), // empty rdata + } + ); } /// Parse a DNS response. @@ -605,9 +633,8 @@ mod tests { ]; let (rem, response) = dns_parse_response(pkt).unwrap(); - // For now we have some remainder data as there is an - // additional record type we don't parse yet. - assert!(!rem.is_empty()); + // The response should be fully parsed. + assert!(rem.is_empty()); assert_eq!( response.header, @@ -640,6 +667,21 @@ mod tests { minimum: 86400, }) ); + + // verify additional section + assert_eq!(response.additionals.len(), 1); + + let additional = &response.additionals[0]; + assert_eq!( + additional, + &DNSAnswerEntry { + name: vec![], + rrtype: DNS_RECORD_TYPE_OPT, + rrclass: 0x0200, // for OPT this is UDP payload size + ttl: 0, // for OPT this is extended RCODE and flags + data: DNSRData::Unknown(vec![]), // no rdata + } + ); } #[test] @@ -740,7 +782,7 @@ mod tests { ;; MSG SIZE rcvd: 191 */ let pkt: &[u8] = &[ - 0xeb, 0x56, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x04, 0x5f, + 0xeb, 0x56, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, 0x73, 0x69, 0x70, 0x04, 0x5f, 0x75, 0x64, 0x70, 0x03, 0x73, 0x69, 0x70, 0x05, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x21, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00,