tx.tx_data.set_event(event as u8);
}
- fn parse_request(&mut self, input: &[u8]) -> bool {
+ fn validate_header(&self, input: &[u8]) -> bool {
+ parser::dns_parse_header(input)
+ .map(|(_, header)| probe_header_validity(header, input.len()).0)
+ .unwrap_or(false)
+ }
+
+ fn parse_request(&mut self, input: &[u8], is_tcp: bool) -> bool {
+ if !self.validate_header(input) {
+ return !is_tcp;
+ }
+
match parser::dns_parse_request(input) {
Ok((_, request)) => {
if request.header.flags & 0x8000 != 0 {
input.len() as i64,
DnsFrameType::Pdu as u8,
);
- self.parse_request(input)
+ self.parse_request(input, false)
}
fn parse_response_udp(&mut self, flow: *const core::Flow, stream_slice: StreamSlice) -> bool {
input.len() as i64,
DnsFrameType::Pdu as u8,
);
- self.parse_response(input)
+ self.parse_response(input, false)
}
- pub fn parse_response(&mut self, input: &[u8]) -> bool {
+ pub fn parse_response(&mut self, input: &[u8], is_tcp: bool) -> bool {
+ if !self.validate_header(input) {
+ return !is_tcp;
+ }
+
match parser::dns_parse_response(input) {
Ok((_, response)) => {
SCLogDebug!("Response header flags: {}", response.header.flags);
msg.len() as i64,
DnsFrameType::Pdu as u8,
);
- if self.parse_request(msg) {
+ if self.parse_request(msg, true) {
cur_i = &cur_i[(size + 2)..];
consumed += size + 2;
} else {
msg.len() as i64,
DnsFrameType::Pdu as u8,
);
- if self.parse_response(msg) {
+ if self.parse_response(msg, true) {
cur_i = &cur_i[(size + 2)..];
consumed += size + 2;
} else {
const DNS_HEADER_SIZE: usize = 12;
fn probe_header_validity(header: DNSHeader, rlen: usize) -> (bool, bool, bool) {
- if 2 * (header.additional_rr as usize
- + header.answer_rr as usize
- + header.authority_rr as usize
- + header.questions as usize)
- + DNS_HEADER_SIZE
- > rlen
- {
- //not enough data for such a DNS record
+ let min_msg_size = 2
+ * (header.additional_rr as usize
+ + header.answer_rr as usize
+ + header.authority_rr as usize
+ + header.questions as usize)
+ + DNS_HEADER_SIZE;
+
+ if min_msg_size > rlen {
+ // Not enough data for records defined in the header, or
+ // impossibly large.
return (false, false, false);
}
+
let is_request = header.flags & 0x8000 == 0;
return (true, is_request, false);
}
0x80,
];
let mut state = DNSState::new();
- assert!(state.parse_response(buf));
+ assert!(state.parse_response(buf, false));
}
// Port of the C RustDNSUDPParserTest02 unit test.
0x10,0x00,0x02,0xC0,0x85,0x00,0x00,0x29,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
];
let mut state = DNSState::new();
- assert!(state.parse_response(buf));
+ assert!(state.parse_response(buf, false));
}
// Port of the C RustDNSUDPParserTest03 unit test.
0x29,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00
];
let mut state = DNSState::new();
- assert!(state.parse_response(buf));
+ assert!(state.parse_response(buf, false));
}
// Port of the C RustDNSUDPParserTest04 unit test.
0x6b,0x00,0x01,0x00,0x01,0x00,0x09,0x3a,0x80,0x00,0x04,0x0a,0x1e,0x1c,0x5f
];
let mut state = DNSState::new();
- assert!(state.parse_response(buf));
+ assert!(state.parse_response(buf, false));
}
// Port of the C RustDNSUDPParserTest05 unit test.
0x6b,0x00,0x01,0x00,0x01,0x00,0x09,0x3a,0x80,0x00,0x04,0x0a,0x1e,0x1c,0x5f
];
let mut state = DNSState::new();
- assert!(!state.parse_response(buf));
+ assert!(!state.parse_response(buf, false));
}
// Port of the C RustDNSTCPParserTestMultiRecord unit test.