From: Jason Ish Date: Wed, 15 Nov 2023 21:58:36 +0000 (-0600) Subject: dns: consolidate DNSRequest and DNSResponse to DNSMessage X-Git-Tag: suricata-8.0.0-beta1~1926 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9464d0b14a8d1b39652210626d6a8852a7474372;p=thirdparty%2Fsuricata.git dns: consolidate DNSRequest and DNSResponse to DNSMessage DNS request and response messages follow the same format so there is no reason not to use the same data structure for each. While its unlikely to see fields like answers in a request, the message format does not disallow them, so it might be interesting data to have the ability to log. --- diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index c93547c151..aa0042f0b2 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -221,13 +221,7 @@ pub struct DNSAnswerEntry { } #[derive(Debug)] -pub struct DNSRequest { - pub header: DNSHeader, - pub queries: Vec, -} - -#[derive(Debug)] -pub struct DNSResponse { +pub struct DNSMessage { pub header: DNSHeader, pub queries: Vec, pub answers: Vec, @@ -237,8 +231,8 @@ pub struct DNSResponse { #[derive(Debug, Default)] pub struct DNSTransaction { pub id: u64, - pub request: Option, - pub response: Option, + pub request: Option, + pub response: Option, pub tx_data: AppLayerTxData, } @@ -402,7 +396,7 @@ impl DNSState { return !is_tcp; }; - match parser::dns_parse_request_body(body, input, header) { + match parser::dns_parse_body(body, input, header) { Ok((_, request)) => { if request.header.flags & 0x8000 != 0 { SCLogDebug!("DNS message is not a request"); @@ -474,7 +468,7 @@ impl DNSState { return !is_tcp; }; - match parser::dns_parse_response_body(body, input, header) { + match parser::dns_parse_body(body, input, header) { Ok((_, response)) => { SCLogDebug!("Response header flags: {}", response.header.flags); @@ -702,14 +696,9 @@ fn probe(input: &[u8], dlen: usize) -> (bool, bool, bool) { } } - match parser::dns_parse_request(input) { - Ok((_, request)) => { - return probe_header_validity(&request.header, dlen); - } - Err(Err::Incomplete(_)) => match parser::dns_parse_header(input) { - Ok((_, header)) => { - return probe_header_validity(&header, dlen); - } + match parser::dns_parse_header(input) { + Ok((body, header)) => match parser::dns_parse_body(body, input, header) { + Ok((_, request)) => probe_header_validity(&request.header, dlen), Err(Err::Incomplete(_)) => (false, false, true), Err(_) => (false, false, false), }, diff --git a/rust/src/dns/log.rs b/rust/src/dns/log.rs index 1bece89a5a..4c0d4fc065 100644 --- a/rust/src/dns/log.rs +++ b/rust/src/dns/log.rs @@ -476,7 +476,7 @@ fn dns_log_json_answer_detail(answer: &DNSAnswerEntry) -> Result Result<(), JsonError> { let header = &response.header; diff --git a/rust/src/dns/parser.rs b/rust/src/dns/parser.rs index a1d97a53fd..f7f9fd0d6e 100644 --- a/rust/src/dns/parser.rs +++ b/rust/src/dns/parser.rs @@ -24,27 +24,6 @@ use nom7::multi::{count, length_data, many_m_n}; use nom7::number::streaming::{be_u16, be_u32, be_u8}; use nom7::{error_position, Err, IResult}; -// Parse a DNS header. -pub fn dns_parse_header(i: &[u8]) -> IResult<&[u8], DNSHeader> { - let (i, tx_id) = be_u16(i)?; - let (i, flags) = be_u16(i)?; - let (i, questions) = be_u16(i)?; - let (i, answer_rr) = be_u16(i)?; - let (i, authority_rr) = be_u16(i)?; - let (i, additional_rr) = be_u16(i)?; - Ok(( - i, - DNSHeader { - tx_id, - flags, - questions, - answer_rr, - authority_rr, - additional_rr, - }, - )) -} - /// Parse a DNS name. /// /// Parameters: @@ -191,23 +170,6 @@ fn dns_parse_answer<'a>( return Ok((input, answers)); } -pub fn dns_parse_response_body<'a>( - i: &'a [u8], message: &'a [u8], header: DNSHeader, -) -> IResult<&'a [u8], DNSResponse> { - 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)?; - Ok(( - i, - DNSResponse { - header, - queries, - answers, - authorities, - }, - )) -} - /// Parse a single DNS query. /// /// Arguments are suitable for using with call!: @@ -343,19 +305,42 @@ pub fn dns_parse_rdata<'a>( } } -/// Parse a DNS request. -pub fn dns_parse_request(input: &[u8]) -> IResult<&[u8], DNSRequest> { - let i = input; - let (i, header) = dns_parse_header(i)?; - dns_parse_request_body(i, input, header) +// Parse a DNS header. +pub fn dns_parse_header(i: &[u8]) -> IResult<&[u8], DNSHeader> { + let (i, tx_id) = be_u16(i)?; + let (i, flags) = be_u16(i)?; + let (i, questions) = be_u16(i)?; + let (i, answer_rr) = be_u16(i)?; + let (i, authority_rr) = be_u16(i)?; + let (i, additional_rr) = be_u16(i)?; + Ok(( + i, + DNSHeader { + tx_id, + flags, + questions, + answer_rr, + authority_rr, + additional_rr, + }, + )) } -pub fn dns_parse_request_body<'a>( - input: &'a [u8], message: &'a [u8], header: DNSHeader, -) -> IResult<&'a [u8], DNSRequest> { - let i = input; +pub fn dns_parse_body<'a>( + i: &'a [u8], message: &'a [u8], header: DNSHeader, +) -> IResult<&'a [u8], DNSMessage> { let (i, queries) = count(|b| dns_parse_query(b, message), header.questions as usize)(i)?; - Ok((i, DNSRequest { header, queries })) + 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)?; + Ok(( + i, + DNSMessage { + header, + queries, + answers, + authorities, + }, + )) } #[cfg(test)] @@ -490,7 +475,8 @@ mod tests { 0x00, 0x00, 0x00, /* ... */ ]; - let res = dns_parse_request(pkt); + let (body, header) = dns_parse_header(pkt).unwrap(); + let res = dns_parse_body(body, pkt, header); match res { Ok((rem, request)) => { // For now we have some remainder data as there is an @@ -523,10 +509,10 @@ mod tests { } /// Parse a DNS response. - fn dns_parse_response(message: &[u8]) -> IResult<&[u8], DNSResponse> { + fn dns_parse_response(message: &[u8]) -> IResult<&[u8], DNSMessage> { let i = message; let (i, header) = dns_parse_header(i)?; - dns_parse_response_body(i, message, header) + dns_parse_body(i, message, header) } #[test]