event as u8);
}
- pub 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 {
}
}
- pub fn parse_response(&mut self, input: &[u8]) -> bool {
+ fn parse_request_udp(&mut self, input: &[u8]) -> bool {
+ self.parse_request(input, false)
+ }
+
+ fn parse_response_udp(&mut self, input: &[u8]) -> bool {
+ self.parse_response(input, false)
+ }
+
+ 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!("[request] Have {} bytes, need {} to parse",
cur_i.len(), size + 2);
if size > 0 && cur_i.len() >= size + 2 {
- let msg = &cur_i[0..(size + 2)];
- if self.parse_request(&msg[2..]) {
+ let msg = &cur_i[2..(size + 2)];
+ if self.parse_request(msg, true) {
cur_i = &cur_i[(size + 2)..];
consumed += size + 2;
} else {
SCLogDebug!("[response] Have {} bytes, need {} to parse",
cur_i.len(), size + 2);
if size > 0 && cur_i.len() >= size + 2 {
- let msg = &cur_i[0..(size + 2)];
- if self.parse_response(&msg[2..]) {
+ let msg = &cur_i[2..(size + 2)];
+ 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);
}
-> AppLayerResult {
let state = cast_pointer!(state, DNSState);
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
- if state.parse_request(buf) {
- AppLayerResult::ok()
- } else {
- AppLayerResult::err()
- }
+ state.parse_request_udp(buf);
+ AppLayerResult::ok()
}
#[no_mangle]
-> AppLayerResult {
let state = cast_pointer!(state, DNSState);
let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
- if state.parse_response(buf) {
- AppLayerResult::ok()
- } else {
- AppLayerResult::err()
- }
+ state.parse_response_udp(buf);
+ AppLayerResult::ok()
}
/// C binding parse a DNS request. Returns 1 on success, -1 on failure.
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.