1 /* Copyright (C) 2017 Open Information Security Foundation
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 use std::ffi::CString;
22 use std::mem::transmute;
23 use std::collections::HashMap;
24 use std::collections::VecDeque;
26 use crate::applayer::*;
27 use crate::core::{self, AppProto, ALPROTO_UNKNOWN, IPPROTO_UDP, IPPROTO_TCP};
28 use crate::dns::parser;
31 use nom::number::streaming::be_u16;
34 pub const DNS_RECORD_TYPE_A : u16 = 1;
35 pub const DNS_RECORD_TYPE_NS : u16 = 2;
36 pub const DNS_RECORD_TYPE_MD : u16 = 3; // Obsolete
37 pub const DNS_RECORD_TYPE_MF : u16 = 4; // Obsolete
38 pub const DNS_RECORD_TYPE_CNAME : u16 = 5;
39 pub const DNS_RECORD_TYPE_SOA : u16 = 6;
40 pub const DNS_RECORD_TYPE_MB : u16 = 7; // Experimental
41 pub const DNS_RECORD_TYPE_MG : u16 = 8; // Experimental
42 pub const DNS_RECORD_TYPE_MR : u16 = 9; // Experimental
43 pub const DNS_RECORD_TYPE_NULL : u16 = 10; // Experimental
44 pub const DNS_RECORD_TYPE_WKS : u16 = 11;
45 pub const DNS_RECORD_TYPE_PTR : u16 = 12;
46 pub const DNS_RECORD_TYPE_HINFO : u16 = 13;
47 pub const DNS_RECORD_TYPE_MINFO : u16 = 14;
48 pub const DNS_RECORD_TYPE_MX : u16 = 15;
49 pub const DNS_RECORD_TYPE_TXT : u16 = 16;
50 pub const DNS_RECORD_TYPE_RP : u16 = 17;
51 pub const DNS_RECORD_TYPE_AFSDB : u16 = 18;
52 pub const DNS_RECORD_TYPE_X25 : u16 = 19;
53 pub const DNS_RECORD_TYPE_ISDN : u16 = 20;
54 pub const DNS_RECORD_TYPE_RT : u16 = 21;
55 pub const DNS_RECORD_TYPE_NSAP : u16 = 22;
56 pub const DNS_RECORD_TYPE_NSAPPTR : u16 = 23;
57 pub const DNS_RECORD_TYPE_SIG : u16 = 24;
58 pub const DNS_RECORD_TYPE_KEY : u16 = 25;
59 pub const DNS_RECORD_TYPE_PX : u16 = 26;
60 pub const DNS_RECORD_TYPE_GPOS : u16 = 27;
61 pub const DNS_RECORD_TYPE_AAAA : u16 = 28;
62 pub const DNS_RECORD_TYPE_LOC : u16 = 29;
63 pub const DNS_RECORD_TYPE_NXT : u16 = 30; // Obsolete
64 pub const DNS_RECORD_TYPE_SRV : u16 = 33;
65 pub const DNS_RECORD_TYPE_ATMA : u16 = 34;
66 pub const DNS_RECORD_TYPE_NAPTR : u16 = 35;
67 pub const DNS_RECORD_TYPE_KX : u16 = 36;
68 pub const DNS_RECORD_TYPE_CERT : u16 = 37;
69 pub const DNS_RECORD_TYPE_A6 : u16 = 38; // Obsolete
70 pub const DNS_RECORD_TYPE_DNAME : u16 = 39;
71 pub const DNS_RECORD_TYPE_OPT : u16 = 41;
72 pub const DNS_RECORD_TYPE_APL : u16 = 42;
73 pub const DNS_RECORD_TYPE_DS : u16 = 43;
74 pub const DNS_RECORD_TYPE_SSHFP : u16 = 44;
75 pub const DNS_RECORD_TYPE_IPSECKEY : u16 = 45;
76 pub const DNS_RECORD_TYPE_RRSIG : u16 = 46;
77 pub const DNS_RECORD_TYPE_NSEC : u16 = 47;
78 pub const DNS_RECORD_TYPE_DNSKEY : u16 = 48;
79 pub const DNS_RECORD_TYPE_DHCID : u16 = 49;
80 pub const DNS_RECORD_TYPE_NSEC3 : u16 = 50;
81 pub const DNS_RECORD_TYPE_NSEC3PARAM : u16 = 51;
82 pub const DNS_RECORD_TYPE_TLSA : u16 = 52;
83 pub const DNS_RECORD_TYPE_HIP : u16 = 55;
84 pub const DNS_RECORD_TYPE_CDS : u16 = 59;
85 pub const DNS_RECORD_TYPE_CDNSKEY : u16 = 60;
86 pub const DNS_RECORD_TYPE_SPF : u16 = 99; // Obsolete
87 pub const DNS_RECORD_TYPE_TKEY : u16 = 249;
88 pub const DNS_RECORD_TYPE_TSIG : u16 = 250;
89 pub const DNS_RECORD_TYPE_MAILA : u16 = 254; // Obsolete
90 pub const DNS_RECORD_TYPE_ANY : u16 = 255;
91 pub const DNS_RECORD_TYPE_URI : u16 = 256;
94 pub const DNS_RCODE_NOERROR: u16 = 0;
95 pub const DNS_RCODE_FORMERR: u16 = 1;
96 pub const DNS_RCODE_SERVFAIL: u16 = 2;
97 pub const DNS_RCODE_NXDOMAIN: u16 = 3;
98 pub const DNS_RCODE_NOTIMP: u16 = 4;
99 pub const DNS_RCODE_REFUSED: u16 = 5;
100 pub const DNS_RCODE_YXDOMAIN: u16 = 6;
101 pub const DNS_RCODE_YXRRSET: u16 = 7;
102 pub const DNS_RCODE_NXRRSET: u16 = 8;
103 pub const DNS_RCODE_NOTAUTH: u16 = 9;
104 pub const DNS_RCODE_NOTZONE: u16 = 10;
105 // Support for OPT RR from RFC6891 will be needed to
106 // parse RCODE values over 15
107 pub const DNS_RCODE_BADVERS: u16 = 16;
108 pub const DNS_RCODE_BADSIG: u16 = 16;
109 pub const DNS_RCODE_BADKEY: u16 = 17;
110 pub const DNS_RCODE_BADTIME: u16 = 18;
111 pub const DNS_RCODE_BADMODE: u16 = 19;
112 pub const DNS_RCODE_BADNAME: u16 = 20;
113 pub const DNS_RCODE_BADALG: u16 = 21;
114 pub const DNS_RCODE_BADTRUNC: u16 = 22;
117 /// The maximum number of transactions to keep in the queue pending
118 /// processing before they are aggressively purged. Due to the
119 /// stateless nature of this parser this is rarely needed, especially
120 /// when one call to parse a request parses and a single request, and
121 /// likewise for responses.
123 /// Where this matters is when one TCP buffer contains multiple
124 /// requests are responses and one call into the parser creates
125 /// multiple transactions. In this case we have to hold onto
126 /// transactions longer than until handling the next transaction so it
128 const MAX_TRANSACTIONS: usize = 32;
130 static mut ALPROTO_DNS: AppProto = ALPROTO_UNKNOWN;
141 pub fn to_cstring(&self) -> &str {
143 DNSEvent::MalformedData => "MALFORMED_DATA\0",
144 DNSEvent::NotRequest => "NOT_A_REQUEST\0",
145 DNSEvent::NotResponse => "NOT_A_RESPONSE\0",
146 DNSEvent::ZFlagSet => "Z_FLAG_SET\0",
150 pub fn from_id(id: u32) -> Option<DNSEvent> {
152 0 => Some(DNSEvent::MalformedData),
153 1 => Some(DNSEvent::NotRequest),
154 2 => Some(DNSEvent::NotResponse),
155 4 => Some(DNSEvent::ZFlagSet),
160 pub fn from_string(s: &str) -> Option<DNSEvent> {
161 match s.to_lowercase().as_ref() {
162 "malformed_data" => Some(DNSEvent::MalformedData),
163 "not_a_request" => Some(DNSEvent::NotRequest),
164 "not_a_response" => Some(DNSEvent::NotRequest),
165 "z_flag_set" => Some(DNSEvent::ZFlagSet),
172 pub extern "C" fn rs_dns_state_get_event_info_by_id(
173 event_id: std::os::raw::c_int,
174 event_name: *mut *const std::os::raw::c_char,
175 event_type: *mut core::AppLayerEventType,
177 if let Some(e) = DNSEvent::from_id(event_id as u32) {
179 *event_name = e.to_cstring().as_ptr() as *const std::os::raw::c_char;
180 *event_type = core::APP_LAYER_EVENT_TYPE_TRANSACTION;
188 pub extern "C" fn rs_dns_state_get_event_info(
189 event_name: *const std::os::raw::c_char,
190 event_id: *mut std::os::raw::c_int,
191 event_type: *mut core::AppLayerEventType
192 ) -> std::os::raw::c_int {
193 if event_name == std::ptr::null() {
197 let event_name = unsafe { std::ffi::CStr::from_ptr(event_name) };
198 if let Ok(event_name) = event_name.to_str() {
199 if let Some(event) = DNSEvent::from_string(event_name) {
201 *event_id = event as std::os::raw::c_int;
202 *event_type = core::APP_LAYER_EVENT_TYPE_TRANSACTION;
209 // UTF-8 conversion failed. Should not happen.
216 #[derive(Debug,PartialEq)]
218 pub struct DNSHeader {
223 pub authority_rr: u16,
224 pub additional_rr: u16,
228 pub struct DNSQueryEntry {
234 #[derive(Debug,PartialEq)]
235 pub struct DNSRDataSOA {
236 /// Primary name server for this zone
238 /// Authority's mailbox
240 /// Serial version number
242 /// Refresh interval (seconds)
244 /// Retry interval (seconds)
246 /// Upper time limit until zone is no longer authoritative (seconds)
248 /// Minimum ttl for records in this zone (seconds)
252 #[derive(Debug,PartialEq)]
253 pub struct DNSRDataSSHFP {
259 pub fingerprint: Vec<u8>,
262 /// Represents RData of various formats
263 #[derive(Debug,PartialEq)]
265 // RData is an address
268 // RData is a domain name
276 // RData has several fields
278 SSHFP(DNSRDataSSHFP),
279 // RData for remaining types is sometimes ignored
283 #[derive(Debug,PartialEq)]
284 pub struct DNSAnswerEntry {
293 pub struct DNSRequest {
294 pub header: DNSHeader,
295 pub queries: Vec<DNSQueryEntry>,
299 pub struct DNSResponse {
300 pub header: DNSHeader,
301 pub queries: Vec<DNSQueryEntry>,
302 pub answers: Vec<DNSAnswerEntry>,
303 pub authorities: Vec<DNSAnswerEntry>,
307 pub struct DNSTransaction {
309 pub request: Option<DNSRequest>,
310 pub response: Option<DNSResponse>,
311 pub de_state: Option<*mut core::DetectEngineState>,
312 pub events: *mut core::AppLayerDecoderEvents,
313 pub tx_data: AppLayerTxData,
316 impl DNSTransaction {
318 pub fn new() -> DNSTransaction {
319 return DNSTransaction{
324 events: std::ptr::null_mut(),
325 tx_data: AppLayerTxData::new(),
329 pub fn free(&mut self) {
330 if self.events != std::ptr::null_mut() {
331 core::sc_app_layer_decoder_events_free_events(&mut self.events);
333 match self.de_state {
335 core::sc_detect_engine_state_free(state);
341 /// Get the DNS transactions ID (not the internal tracking ID).
342 pub fn tx_id(&self) -> u16 {
343 if let &Some(ref request) = &self.request {
344 return request.header.tx_id;
346 if let &Some(ref response) = &self.response {
347 return response.header.tx_id;
354 /// Get the reply code of the transaction. Note that this will
355 /// also return 0 if there is no reply.
356 pub fn rcode(&self) -> u16 {
357 if let &Some(ref response) = &self.response {
358 return response.header.flags & 0x000f;
365 impl Drop for DNSTransaction {
371 struct ConfigTracker {
372 map: HashMap<u16, AppLayerTxConfig>,
373 queue: VecDeque<u16>,
377 fn new() -> ConfigTracker {
380 queue: VecDeque::new(),
384 fn add(&mut self, id: u16, config: AppLayerTxConfig) {
385 // If at size limit, remove the oldest entry.
386 if self.queue.len() > 499 {
387 if let Some(id) = self.queue.pop_front() {
388 self.map.remove(&id);
392 self.map.insert(id, config);
393 self.queue.push_back(id);
396 fn remove(&mut self, id: &u16) -> Option<AppLayerTxConfig> {
401 pub struct DNSState {
402 // Internal transaction ID.
406 pub transactions: Vec<DNSTransaction>,
410 config: Option<ConfigTracker>,
417 pub fn new() -> DNSState {
420 transactions: Vec::new(),
427 pub fn new_tcp() -> DNSState {
430 transactions: Vec::new(),
437 pub fn new_tx(&mut self) -> DNSTransaction {
438 let mut tx = DNSTransaction::new();
444 pub fn free_tx(&mut self, tx_id: u64) {
445 let len = self.transactions.len();
446 let mut found = false;
449 let tx = &self.transactions[i];
450 if tx.id == tx_id + 1 {
457 self.transactions.remove(index);
461 // Purges all transactions except one. This is a stateless parser
462 // so we don't need to hang onto old transactions.
464 // This is to actually handle an edge case where a DNS flood
465 // occurs in a single direction with no response packets. In such
466 // a case the functions to free a transaction are never called by
467 // the app-layer as they require bidirectional traffic.
468 pub fn purge(&mut self, tx_id: u64) {
469 while self.transactions.len() > MAX_TRANSACTIONS {
470 if self.transactions[0].id == tx_id + 1 {
473 SCLogDebug!("Purging DNS TX with ID {}", self.transactions[0].id);
474 self.transactions.remove(0);
478 pub fn get_tx(&mut self, tx_id: u64) -> Option<&DNSTransaction> {
479 SCLogDebug!("get_tx: tx_id={}", tx_id);
481 for tx in &mut self.transactions {
482 if tx.id == tx_id + 1 {
483 SCLogDebug!("Found DNS TX with ID {}", tx_id);
487 SCLogDebug!("Failed to find DNS TX with ID {}", tx_id);
491 /// Set an event. The event is set on the most recent transaction.
492 pub fn set_event(&mut self, event: DNSEvent) {
493 let len = self.transactions.len();
498 let tx = &mut self.transactions[len - 1];
499 core::sc_app_layer_decoder_events_set_event_raw(&mut tx.events,
504 pub fn parse_request(&mut self, input: &[u8]) -> bool {
505 match parser::dns_parse_request(input) {
506 Ok((_, request)) => {
507 if request.header.flags & 0x8000 != 0 {
508 SCLogDebug!("DNS message is not a request");
509 self.set_event(DNSEvent::NotRequest);
513 if request.header.flags & 0x0040 != 0 {
514 SCLogDebug!("Z-flag set on DNS response");
515 self.set_event(DNSEvent::ZFlagSet);
519 let mut tx = self.new_tx();
520 tx.request = Some(request);
521 self.transactions.push(tx);
524 Err(nom::Err::Incomplete(_)) => {
525 // Insufficient data.
526 SCLogDebug!("Insufficient data while parsing DNS request");
527 self.set_event(DNSEvent::MalformedData);
531 // Error, probably malformed data.
532 SCLogDebug!("An error occurred while parsing DNS request");
533 self.set_event(DNSEvent::MalformedData);
539 pub fn parse_response(&mut self, input: &[u8]) -> bool {
540 match parser::dns_parse_response(input) {
541 Ok((_, response)) => {
543 SCLogDebug!("Response header flags: {}", response.header.flags);
545 if response.header.flags & 0x8000 == 0 {
546 SCLogDebug!("DNS message is not a response");
547 self.set_event(DNSEvent::NotResponse);
550 if response.header.flags & 0x0040 != 0 {
551 SCLogDebug!("Z-flag set on DNS response");
552 self.set_event(DNSEvent::ZFlagSet);
556 let mut tx = self.new_tx();
557 if let Some(ref mut config) = &mut self.config {
558 if let Some(config) = config.remove(&response.header.tx_id) {
559 tx.tx_data.config = config;
562 tx.response = Some(response);
563 self.transactions.push(tx);
566 Err(nom::Err::Incomplete(_)) => {
567 // Insufficient data.
568 SCLogDebug!("Insufficient data while parsing DNS response");
569 self.set_event(DNSEvent::MalformedData);
573 // Error, probably malformed data.
574 SCLogDebug!("An error occurred while parsing DNS response");
575 self.set_event(DNSEvent::MalformedData);
581 /// TCP variation of response request parser to handle the length
584 /// Returns the number of messages parsed.
585 pub fn parse_request_tcp(&mut self, input: &[u8]) -> AppLayerResult {
587 let (is_dns, _, is_incomplete) = probe_tcp(input);
588 if is_dns || is_incomplete {
591 AppLayerResult::ok();
595 let mut cur_i = input;
596 let mut consumed = 0;
597 while cur_i.len() > 0 {
598 if cur_i.len() == 1 {
599 return AppLayerResult::incomplete(consumed as u32, 2 as u32);
601 let size = match be_u16(&cur_i) as IResult<&[u8],u16> {
605 SCLogDebug!("[request] Have {} bytes, need {} to parse",
606 cur_i.len(), size + 2);
607 if size > 0 && cur_i.len() >= size + 2 {
608 let msg = &cur_i[0..(size + 2)];
609 if self.parse_request(&msg[2..]) {
610 cur_i = &cur_i[(size + 2)..];
611 consumed += size + 2;
613 return AppLayerResult::err();
615 } else if size == 0 {
619 SCLogDebug!("[request]Not enough DNS traffic to parse. Returning {}/{}",
620 consumed as u32, (size + 2) as u32);
621 return AppLayerResult::incomplete(consumed as u32,
628 /// TCP variation of the response parser to handle the length
631 /// Returns the number of messages parsed.
632 pub fn parse_response_tcp(&mut self, input: &[u8]) -> AppLayerResult {
634 let (is_dns, _, is_incomplete) = probe_tcp(input);
635 if is_dns || is_incomplete {
638 return AppLayerResult::ok();
642 let mut cur_i = input;
643 let mut consumed = 0;
644 while cur_i.len() > 0 {
645 if cur_i.len() == 1 {
646 return AppLayerResult::incomplete(consumed as u32, 2 as u32);
648 let size = match be_u16(&cur_i) as IResult<&[u8],u16> {
652 SCLogDebug!("[response] Have {} bytes, need {} to parse",
653 cur_i.len(), size + 2);
654 if size > 0 && cur_i.len() >= size + 2 {
655 let msg = &cur_i[0..(size + 2)];
656 if self.parse_response(&msg[2..]) {
657 cur_i = &cur_i[(size + 2)..];
658 consumed += size + 2;
660 return AppLayerResult::err();
662 } else if size == 0 {
666 SCLogDebug!("[response]Not enough DNS traffic to parse. Returning {}/{}",
667 consumed as u32, (cur_i.len() - consumed) as u32);
668 return AppLayerResult::incomplete(consumed as u32,
675 /// A gap has been seen in the request direction. Set the gap flag.
676 pub fn request_gap(&mut self, gap: u32) {
682 /// A gap has been seen in the response direction. Set the gap
684 pub fn response_gap(&mut self, gap: u32) {
691 /// Probe input to see if it looks like DNS.
692 fn probe(input: &[u8]) -> (bool, bool) {
693 match parser::dns_parse_request(input) {
694 Ok((_, request)) => {
695 let is_request = request.header.flags & 0x8000 == 0;
696 return (true, is_request);
698 Err(_) => (false, false),
702 /// Probe TCP input to see if it looks like DNS.
703 pub fn probe_tcp(input: &[u8]) -> (bool, bool, bool) {
704 match be_u16(input) as IResult<&[u8],_> {
707 return (r.0, r.1, false);
709 Err(nom::Err::Incomplete(_)) => {
710 return (false, false, true);
714 return (false, false, false);
717 /// Returns *mut DNSState
719 pub extern "C" fn rs_dns_state_new(_orig_state: *mut std::os::raw::c_void, _orig_proto: AppProto) -> *mut std::os::raw::c_void {
720 let state = DNSState::new();
721 let boxed = Box::new(state);
722 return unsafe{transmute(boxed)};
725 /// Returns *mut DNSState
727 pub extern "C" fn rs_dns_state_tcp_new() -> *mut std::os::raw::c_void {
728 let state = DNSState::new_tcp();
729 let boxed = Box::new(state);
730 return unsafe{transmute(boxed)};
734 /// - state: *mut DNSState as void pointer
736 pub extern "C" fn rs_dns_state_free(state: *mut std::os::raw::c_void) {
738 let _drop: Box<DNSState> = unsafe{transmute(state)};
742 pub extern "C" fn rs_dns_state_tx_free(state: *mut std::os::raw::c_void,
745 let state = cast_pointer!(state, DNSState);
746 state.free_tx(tx_id);
749 /// C binding parse a DNS request. Returns 1 on success, -1 on failure.
751 pub extern "C" fn rs_dns_parse_request(_flow: *const core::Flow,
752 state: *mut std::os::raw::c_void,
753 _pstate: *mut std::os::raw::c_void,
756 _data: *const std::os::raw::c_void,
759 let state = cast_pointer!(state, DNSState);
760 let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
761 if state.parse_request(buf) {
764 AppLayerResult::err()
769 pub extern "C" fn rs_dns_parse_response(_flow: *const core::Flow,
770 state: *mut std::os::raw::c_void,
771 _pstate: *mut std::os::raw::c_void,
774 _data: *const std::os::raw::c_void,
777 let state = cast_pointer!(state, DNSState);
778 let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)};
779 if state.parse_response(buf) {
782 AppLayerResult::err()
786 /// C binding parse a DNS request. Returns 1 on success, -1 on failure.
788 pub extern "C" fn rs_dns_parse_request_tcp(_flow: *const core::Flow,
789 state: *mut std::os::raw::c_void,
790 _pstate: *mut std::os::raw::c_void,
793 _data: *const std::os::raw::c_void,
796 let state = cast_pointer!(state, DNSState);
798 if input != std::ptr::null_mut() {
800 std::slice::from_raw_parts(input, input_len as usize)};
801 return state.parse_request_tcp(buf);
803 state.request_gap(input_len);
809 pub extern "C" fn rs_dns_parse_response_tcp(_flow: *const core::Flow,
810 state: *mut std::os::raw::c_void,
811 _pstate: *mut std::os::raw::c_void,
814 _data: *const std::os::raw::c_void,
817 let state = cast_pointer!(state, DNSState);
819 if input != std::ptr::null_mut() {
821 std::slice::from_raw_parts(input, input_len as usize)};
822 return state.parse_response_tcp(buf);
824 state.response_gap(input_len);
830 pub extern "C" fn rs_dns_tx_get_alstate_progress(_tx: *mut std::os::raw::c_void,
832 -> std::os::raw::c_int
834 // This is a stateless parser, just the existence of a transaction
835 // means its complete.
836 SCLogDebug!("rs_dns_tx_get_alstate_progress");
841 pub extern "C" fn rs_dns_state_get_tx_count(state: *mut std::os::raw::c_void)
844 let state = cast_pointer!(state, DNSState);
845 SCLogDebug!("rs_dns_state_get_tx_count: returning {}", state.tx_id);
850 pub extern "C" fn rs_dns_state_get_tx(state: *mut std::os::raw::c_void,
852 -> *mut std::os::raw::c_void
854 let state = cast_pointer!(state, DNSState);
855 match state.get_tx(tx_id) {
857 return unsafe{transmute(tx)};
860 return std::ptr::null_mut();
866 pub extern "C" fn rs_dns_state_set_tx_detect_state(
867 tx: *mut std::os::raw::c_void,
868 de_state: &mut core::DetectEngineState) -> std::os::raw::c_int
870 let tx = cast_pointer!(tx, DNSTransaction);
871 tx.de_state = Some(de_state);
876 pub extern "C" fn rs_dns_state_get_tx_detect_state(
877 tx: *mut std::os::raw::c_void)
878 -> *mut core::DetectEngineState
880 let tx = cast_pointer!(tx, DNSTransaction);
886 return std::ptr::null_mut();
892 pub extern "C" fn rs_dns_state_get_events(tx: *mut std::os::raw::c_void)
893 -> *mut core::AppLayerDecoderEvents
895 let tx = cast_pointer!(tx, DNSTransaction);
900 pub extern "C" fn rs_dns_state_get_tx_data(
901 tx: *mut std::os::raw::c_void)
902 -> *mut AppLayerTxData
904 let tx = cast_pointer!(tx, DNSTransaction);
905 return &mut tx.tx_data;
909 pub extern "C" fn rs_dns_tx_get_query_name(tx: &mut DNSTransaction,
915 if let &Some(ref request) = &tx.request {
916 if (i as usize) < request.queries.len() {
917 let query = &request.queries[i as usize];
918 if query.name.len() > 0 {
920 *len = query.name.len() as u32;
921 *buf = query.name.as_ptr();
930 /// Get the DNS transaction ID of a transaction.
932 /// extern uint16_t rs_dns_tx_get_tx_id(RSDNSTransaction *);
934 pub extern "C" fn rs_dns_tx_get_tx_id(tx: &mut DNSTransaction) -> u16
939 /// Get the DNS response flags for a transaction.
941 /// extern uint16_t rs_dns_tx_get_response_flags(RSDNSTransaction *);
943 pub extern "C" fn rs_dns_tx_get_response_flags(tx: &mut DNSTransaction)
950 pub extern "C" fn rs_dns_tx_get_query_rrtype(tx: &mut DNSTransaction,
955 if let &Some(ref request) = &tx.request {
956 if (i as usize) < request.queries.len() {
957 let query = &request.queries[i as usize];
958 if query.name.len() > 0 {
960 *rrtype = query.rrtype;
970 pub extern "C" fn rs_dns_probe(
971 _flow: *const core::Flow,
977 if len == 0 || len < std::mem::size_of::<DNSHeader>() as u32 {
978 return core::ALPROTO_UNKNOWN;
980 let slice: &[u8] = unsafe {
981 std::slice::from_raw_parts(input as *mut u8, len as usize)
983 let (is_dns, is_request) = probe(slice);
985 let dir = if is_request {
986 core::STREAM_TOSERVER
988 core::STREAM_TOCLIENT
999 pub extern "C" fn rs_dns_probe_tcp(
1000 _flow: *const core::Flow,
1006 if len == 0 || len < std::mem::size_of::<DNSHeader>() as u32 + 2 {
1007 return core::ALPROTO_UNKNOWN;
1009 let slice: &[u8] = unsafe {
1010 std::slice::from_raw_parts(input as *mut u8, len as usize)
1012 //is_incomplete is checked by caller
1013 let (is_dns, is_request, _) = probe_tcp(slice);
1015 let dir = if is_request {
1016 core::STREAM_TOSERVER
1018 core::STREAM_TOCLIENT
1020 if direction & (core::STREAM_TOSERVER|core::STREAM_TOCLIENT) != dir {
1021 unsafe { *rdir = dir };
1023 return unsafe { ALPROTO_DNS };
1029 pub extern "C" fn rs_dns_apply_tx_config(
1030 _state: *mut std::os::raw::c_void, _tx: *mut std::os::raw::c_void,
1031 _mode: std::os::raw::c_int, config: AppLayerTxConfig
1033 let tx = cast_pointer!(_tx, DNSTransaction);
1034 let state = cast_pointer!(_state, DNSState);
1035 if let Some(request) = &tx.request {
1036 if state.config.is_none() {
1037 state.config = Some(ConfigTracker::new());
1039 if let Some(ref mut tracker) = &mut state.config {
1040 tracker.add(request.header.tx_id, config);
1046 pub unsafe extern "C" fn rs_dns_init(proto: AppProto) {
1047 ALPROTO_DNS = proto;
1051 pub unsafe extern "C" fn rs_dns_udp_register_parser() {
1052 let default_port = std::ffi::CString::new("[53]").unwrap();
1053 let parser = RustParser{
1054 name: b"dns\0".as_ptr() as *const std::os::raw::c_char,
1055 default_port: default_port.as_ptr(),
1056 ipproto: IPPROTO_UDP,
1057 probe_ts: Some(rs_dns_probe),
1058 probe_tc: Some(rs_dns_probe),
1060 max_depth: std::mem::size_of::<DNSHeader>() as u16,
1061 state_new: rs_dns_state_new,
1062 state_free: rs_dns_state_free,
1063 tx_free: rs_dns_state_tx_free,
1064 parse_ts: rs_dns_parse_request,
1065 parse_tc: rs_dns_parse_response,
1066 get_tx_count: rs_dns_state_get_tx_count,
1067 get_tx: rs_dns_state_get_tx,
1070 tx_get_progress: rs_dns_tx_get_alstate_progress,
1071 get_events: Some(rs_dns_state_get_events),
1072 get_eventinfo: Some(rs_dns_state_get_event_info),
1073 get_eventinfo_byid: Some(rs_dns_state_get_event_info_by_id),
1074 localstorage_new: None,
1075 localstorage_free: None,
1077 get_tx_iterator: None,
1078 get_de_state: rs_dns_state_get_tx_detect_state,
1079 set_de_state: rs_dns_state_set_tx_detect_state,
1080 get_tx_data: rs_dns_state_get_tx_data,
1081 apply_tx_config: Some(rs_dns_apply_tx_config),
1082 flags: APP_LAYER_PARSER_OPT_UNIDIR_TXS,
1086 let ip_proto_str = CString::new("udp").unwrap();
1087 if AppLayerProtoDetectConfProtoDetectionEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
1088 let alproto = AppLayerRegisterProtocolDetection(&parser, 1);
1089 ALPROTO_DNS = alproto;
1090 if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
1091 let _ = AppLayerRegisterParser(&parser, alproto);
1097 pub unsafe extern "C" fn rs_dns_tcp_register_parser() {
1098 let default_port = std::ffi::CString::new("53").unwrap();
1099 let parser = RustParser{
1100 name: b"dns\0".as_ptr() as *const std::os::raw::c_char,
1101 default_port: default_port.as_ptr(),
1102 ipproto: IPPROTO_TCP,
1103 probe_ts: Some(rs_dns_probe_tcp),
1104 probe_tc: Some(rs_dns_probe_tcp),
1106 max_depth: std::mem::size_of::<DNSHeader>() as u16 + 2,
1107 state_new: rs_dns_state_new,
1108 state_free: rs_dns_state_free,
1109 tx_free: rs_dns_state_tx_free,
1110 parse_ts: rs_dns_parse_request_tcp,
1111 parse_tc: rs_dns_parse_response_tcp,
1112 get_tx_count: rs_dns_state_get_tx_count,
1113 get_tx: rs_dns_state_get_tx,
1116 tx_get_progress: rs_dns_tx_get_alstate_progress,
1117 get_events: Some(rs_dns_state_get_events),
1118 get_eventinfo: Some(rs_dns_state_get_event_info),
1119 get_eventinfo_byid: Some(rs_dns_state_get_event_info_by_id),
1120 localstorage_new: None,
1121 localstorage_free: None,
1123 get_tx_iterator: None,
1124 get_de_state: rs_dns_state_get_tx_detect_state,
1125 set_de_state: rs_dns_state_set_tx_detect_state,
1126 get_tx_data: rs_dns_state_get_tx_data,
1127 apply_tx_config: Some(rs_dns_apply_tx_config),
1128 flags: APP_LAYER_PARSER_OPT_ACCEPT_GAPS | APP_LAYER_PARSER_OPT_UNIDIR_TXS,
1132 let ip_proto_str = CString::new("tcp").unwrap();
1133 if AppLayerProtoDetectConfProtoDetectionEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
1134 let alproto = AppLayerRegisterProtocolDetection(&parser, 1);
1135 ALPROTO_DNS = alproto;
1136 if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
1137 let _ = AppLayerRegisterParser(&parser, alproto);
1148 fn test_dns_parse_request_tcp_valid() {
1149 // A UDP DNS request with the DNS payload starting at byte 42.
1150 // From pcap: https://github.com/jasonish/suricata-verify/blob/7cc0e1bd0a5249b52e6e87d82d57c0b6aaf75fce/dns-udp-dig-a-www-suricata-ids-org/dig-a-www.suricata-ids.org.pcap
1152 0x00, 0x15, 0x17, 0x0d, 0x06, 0xf7, 0xd8, 0xcb, /* ........ */
1153 0x8a, 0xed, 0xa1, 0x46, 0x08, 0x00, 0x45, 0x00, /* ...F..E. */
1154 0x00, 0x4d, 0x23, 0x11, 0x00, 0x00, 0x40, 0x11, /* .M#...@. */
1155 0x41, 0x64, 0x0a, 0x10, 0x01, 0x0b, 0x0a, 0x10, /* Ad...... */
1156 0x01, 0x01, 0xa3, 0x4d, 0x00, 0x35, 0x00, 0x39, /* ...M.5.9 */
1157 0xb2, 0xb3, 0x8d, 0x32, 0x01, 0x20, 0x00, 0x01, /* ...2. .. */
1158 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x77, /* .......w */
1159 0x77, 0x77, 0x0c, 0x73, 0x75, 0x72, 0x69, 0x63, /* ww.suric */
1160 0x61, 0x74, 0x61, 0x2d, 0x69, 0x64, 0x73, 0x03, /* ata-ids. */
1161 0x6f, 0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01, /* org..... */
1162 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x00, /* ..)..... */
1163 0x00, 0x00, 0x00 /* ... */
1166 // The DNS payload starts at offset 42.
1167 let dns_payload = &buf[42..];
1169 // Make a TCP DNS request payload.
1170 let mut request = Vec::new();
1171 request.push(((dns_payload.len() as u16) >> 8) as u8);
1172 request.push(((dns_payload.len() as u16) & 0xff) as u8);
1173 request.extend(dns_payload);
1175 let mut state = DNSState::new();
1177 AppLayerResult::ok(),
1178 state.parse_request_tcp(&request)
1183 fn test_dns_parse_request_tcp_short_payload() {
1184 // A UDP DNS request with the DNS payload starting at byte 42.
1185 // From pcap: https://github.com/jasonish/suricata-verify/blob/7cc0e1bd0a5249b52e6e87d82d57c0b6aaf75fce/dns-udp-dig-a-www-suricata-ids-org/dig-a-www.suricata-ids.org.pcap
1187 0x00, 0x15, 0x17, 0x0d, 0x06, 0xf7, 0xd8, 0xcb, /* ........ */
1188 0x8a, 0xed, 0xa1, 0x46, 0x08, 0x00, 0x45, 0x00, /* ...F..E. */
1189 0x00, 0x4d, 0x23, 0x11, 0x00, 0x00, 0x40, 0x11, /* .M#...@. */
1190 0x41, 0x64, 0x0a, 0x10, 0x01, 0x0b, 0x0a, 0x10, /* Ad...... */
1191 0x01, 0x01, 0xa3, 0x4d, 0x00, 0x35, 0x00, 0x39, /* ...M.5.9 */
1192 0xb2, 0xb3, 0x8d, 0x32, 0x01, 0x20, 0x00, 0x01, /* ...2. .. */
1193 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x77, /* .......w */
1194 0x77, 0x77, 0x0c, 0x73, 0x75, 0x72, 0x69, 0x63, /* ww.suric */
1195 0x61, 0x74, 0x61, 0x2d, 0x69, 0x64, 0x73, 0x03, /* ata-ids. */
1196 0x6f, 0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01, /* org..... */
1197 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x00, /* ..)..... */
1198 0x00, 0x00, 0x00 /* ... */
1201 // The DNS payload starts at offset 42.
1202 let dns_payload = &buf[42..];
1204 // Make a TCP DNS request payload but with the length 1 larger
1205 // than the available data.
1206 let mut request = Vec::new();
1207 request.push(((dns_payload.len() as u16) >> 8) as u8);
1208 request.push(((dns_payload.len() as u16) & 0xff) as u8 + 1);
1209 request.extend(dns_payload);
1211 let mut state = DNSState::new();
1213 AppLayerResult::incomplete(0, 52),
1214 state.parse_request_tcp(&request)
1219 fn test_dns_parse_response_tcp_valid() {
1220 // A UDP DNS response with the DNS payload starting at byte 42.
1221 // From pcap: https://github.com/jasonish/suricata-verify/blob/7cc0e1bd0a5249b52e6e87d82d57c0b6aaf75fce/dns-udp-dig-a-www-suricata-ids-org/dig-a-www.suricata-ids.org.pcap
1223 0xd8, 0xcb, 0x8a, 0xed, 0xa1, 0x46, 0x00, 0x15, /* .....F.. */
1224 0x17, 0x0d, 0x06, 0xf7, 0x08, 0x00, 0x45, 0x00, /* ......E. */
1225 0x00, 0x80, 0x65, 0x4e, 0x40, 0x00, 0x40, 0x11, /* ..eN@.@. */
1226 0xbe, 0xf3, 0x0a, 0x10, 0x01, 0x01, 0x0a, 0x10, /* ........ */
1227 0x01, 0x0b, 0x00, 0x35, 0xa3, 0x4d, 0x00, 0x6c, /* ...5.M.l */
1228 0x8d, 0x8c, 0x8d, 0x32, 0x81, 0xa0, 0x00, 0x01, /* ...2.... */
1229 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, /* .......w */
1230 0x77, 0x77, 0x0c, 0x73, 0x75, 0x72, 0x69, 0x63, /* ww.suric */
1231 0x61, 0x74, 0x61, 0x2d, 0x69, 0x64, 0x73, 0x03, /* ata-ids. */
1232 0x6f, 0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01, /* org..... */
1233 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, /* ........ */
1234 0x0d, 0xd8, 0x00, 0x12, 0x0c, 0x73, 0x75, 0x72, /* .....sur */
1235 0x69, 0x63, 0x61, 0x74, 0x61, 0x2d, 0x69, 0x64, /* icata-id */
1236 0x73, 0x03, 0x6f, 0x72, 0x67, 0x00, 0xc0, 0x32, /* s.org..2 */
1237 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf4, /* ........ */
1238 0x00, 0x04, 0xc0, 0x00, 0x4e, 0x18, 0xc0, 0x32, /* ....N..2 */
1239 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf4, /* ........ */
1240 0x00, 0x04, 0xc0, 0x00, 0x4e, 0x19 /* ....N. */
1243 // The DNS payload starts at offset 42.
1244 let dns_payload = &buf[42..];
1246 // Make a TCP DNS response payload.
1247 let mut request = Vec::new();
1248 request.push(((dns_payload.len() as u16) >> 8) as u8);
1249 request.push(((dns_payload.len() as u16) & 0xff) as u8);
1250 request.extend(dns_payload);
1252 let mut state = DNSState::new();
1254 AppLayerResult::ok(),
1255 state.parse_response_tcp(&request)
1259 // Test that a TCP DNS payload won't be parsed if there is not
1262 fn test_dns_parse_response_tcp_short_payload() {
1263 // A UDP DNS response with the DNS payload starting at byte 42.
1264 // From pcap: https://github.com/jasonish/suricata-verify/blob/7cc0e1bd0a5249b52e6e87d82d57c0b6aaf75fce/dns-udp-dig-a-www-suricata-ids-org/dig-a-www.suricata-ids.org.pcap
1266 0xd8, 0xcb, 0x8a, 0xed, 0xa1, 0x46, 0x00, 0x15, /* .....F.. */
1267 0x17, 0x0d, 0x06, 0xf7, 0x08, 0x00, 0x45, 0x00, /* ......E. */
1268 0x00, 0x80, 0x65, 0x4e, 0x40, 0x00, 0x40, 0x11, /* ..eN@.@. */
1269 0xbe, 0xf3, 0x0a, 0x10, 0x01, 0x01, 0x0a, 0x10, /* ........ */
1270 0x01, 0x0b, 0x00, 0x35, 0xa3, 0x4d, 0x00, 0x6c, /* ...5.M.l */
1271 0x8d, 0x8c, 0x8d, 0x32, 0x81, 0xa0, 0x00, 0x01, /* ...2.... */
1272 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, /* .......w */
1273 0x77, 0x77, 0x0c, 0x73, 0x75, 0x72, 0x69, 0x63, /* ww.suric */
1274 0x61, 0x74, 0x61, 0x2d, 0x69, 0x64, 0x73, 0x03, /* ata-ids. */
1275 0x6f, 0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01, /* org..... */
1276 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, /* ........ */
1277 0x0d, 0xd8, 0x00, 0x12, 0x0c, 0x73, 0x75, 0x72, /* .....sur */
1278 0x69, 0x63, 0x61, 0x74, 0x61, 0x2d, 0x69, 0x64, /* icata-id */
1279 0x73, 0x03, 0x6f, 0x72, 0x67, 0x00, 0xc0, 0x32, /* s.org..2 */
1280 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf4, /* ........ */
1281 0x00, 0x04, 0xc0, 0x00, 0x4e, 0x18, 0xc0, 0x32, /* ....N..2 */
1282 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf4, /* ........ */
1283 0x00, 0x04, 0xc0, 0x00, 0x4e, 0x19 /* ....N. */
1286 // The DNS payload starts at offset 42.
1287 let dns_payload = &buf[42..];
1289 // Make a TCP DNS response payload, but make the length 1 byte
1290 // larger than the actual size.
1291 let mut request = Vec::new();
1292 request.push(((dns_payload.len() as u16) >> 8) as u8);
1293 request.push((((dns_payload.len() as u16) & 0xff) + 1) as u8);
1294 request.extend(dns_payload);
1296 let mut state = DNSState::new();
1298 AppLayerResult::incomplete(0, 103),
1299 state.parse_response_tcp(&request)
1303 // Port of the C RustDNSUDPParserTest02 unit test.
1305 fn test_dns_udp_parser_test_01() {
1306 /* query: abcdefghijk.com
1308 * serial 20130422 refresh 28800 retry 7200 exp 604800 min ttl 86400
1311 0x00, 0x3c, 0x85, 0x00, 0x00, 0x01, 0x00, 0x00,
1312 0x00, 0x01, 0x00, 0x00, 0x0b, 0x61, 0x62, 0x63,
1313 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
1314 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x0f, 0x00,
1315 0x01, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01,
1316 0x51, 0x80, 0x00, 0x25, 0x02, 0x6e, 0x73, 0x00,
1317 0x0a, 0x68, 0x6f, 0x73, 0x74, 0x6d, 0x61, 0x73,
1318 0x74, 0x65, 0x72, 0xc0, 0x2f, 0x01, 0x33, 0x2a,
1319 0x76, 0x00, 0x00, 0x70, 0x80, 0x00, 0x00, 0x1c,
1320 0x20, 0x00, 0x09, 0x3a, 0x80, 0x00, 0x01, 0x51,
1323 let mut state = DNSState::new();
1324 assert!(state.parse_response(buf));
1327 // Port of the C RustDNSUDPParserTest02 unit test.
1329 fn test_dns_udp_parser_test_02() {
1331 0x6D,0x08,0x84,0x80,0x00,0x01,0x00,0x08,0x00,0x00,0x00,0x01,0x03,0x57,0x57,0x57,
1332 0x04,0x54,0x54,0x54,0x54,0x03,0x56,0x56,0x56,0x03,0x63,0x6F,0x6D,0x02,0x79,0x79,
1333 0x00,0x00,0x01,0x00,0x01,0xC0,0x0C,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,
1334 0x02,0xC0,0x0C,0xC0,0x31,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,
1335 0x31,0xC0,0x3F,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x3F,0xC0,
1336 0x4D,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x4D,0xC0,0x5B,0x00,
1337 0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x5B,0xC0,0x69,0x00,0x05,0x00,
1338 0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x69,0xC0,0x77,0x00,0x05,0x00,0x01,0x00,
1339 0x00,0x0E,0x10,0x00,0x02,0xC0,0x77,0xC0,0x85,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,
1340 0x10,0x00,0x02,0xC0,0x85,0x00,0x00,0x29,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1342 let mut state = DNSState::new();
1343 assert!(state.parse_response(buf));
1346 // Port of the C RustDNSUDPParserTest03 unit test.
1348 fn test_dns_udp_parser_test_03() {
1350 0x6F,0xB4,0x84,0x80,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x03,0x03,0x57,0x57,0x77,
1351 0x0B,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x03,0x55,0x55,0x55,
1352 0x02,0x79,0x79,0x00,0x00,0x01,0x00,0x01,0xC0,0x0C,0x00,0x05,0x00,0x01,0x00,0x00,
1353 0x0E,0x10,0x00,0x02,0xC0,0x10,0xC0,0x34,0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,
1354 0x00,0x04,0xC3,0xEA,0x04,0x19,0xC0,0x34,0x00,0x02,0x00,0x01,0x00,0x00,0x0E,0x10,
1355 0x00,0x0A,0x03,0x6E,0x73,0x31,0x03,0x61,0x67,0x62,0xC0,0x20,0xC0,0x46,0x00,0x02,
1356 0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x06,0x03,0x6E,0x73,0x32,0xC0,0x56,0xC0,0x52,
1357 0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x04,0xC3,0xEA,0x04,0x0A,0xC0,0x68,
1358 0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x04,0xC3,0xEA,0x05,0x14,0x00,0x00,
1359 0x29,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00
1361 let mut state = DNSState::new();
1362 assert!(state.parse_response(buf));
1365 // Port of the C RustDNSUDPParserTest04 unit test.
1367 // Test the TXT records in an answer.
1369 fn test_dns_udp_parser_test_04() {
1371 0xc2,0x2f,0x81,0x80,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x0a,0x41,0x41,0x41,
1372 0x41,0x41,0x4f,0x31,0x6b,0x51,0x41,0x05,0x3d,0x61,0x75,0x74,0x68,0x03,0x73,0x72,
1373 0x76,0x06,0x74,0x75,0x6e,0x6e,0x65,0x6c,0x03,0x63,0x6f,0x6d,0x00,0x00,0x10,0x00,
1375 /* answer record start */
1376 0xc0,0x0c,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x22,
1377 /* txt record starts: */
1378 0x20, /* <txt len 32 */ 0x41,0x68,0x76,0x4d,0x41,0x41,0x4f,0x31,0x6b,0x41,0x46,
1379 0x45,0x35,0x54,0x45,0x39,0x51,0x54,0x6a,0x46,0x46,0x4e,0x30,0x39,0x52,0x4e,0x31,
1380 0x6c,0x59,0x53,0x44,0x6b,0x00, /* <txt len 0 */ 0xc0,0x1d,0x00,0x02,0x00,0x01,
1381 0x00,0x09,0x3a,0x80,0x00,0x09,0x06,0x69,0x6f,0x64,0x69,0x6e,0x65,0xc0,0x21,0xc0,
1382 0x6b,0x00,0x01,0x00,0x01,0x00,0x09,0x3a,0x80,0x00,0x04,0x0a,0x1e,0x1c,0x5f
1384 let mut state = DNSState::new();
1385 assert!(state.parse_response(buf));
1388 // Port of the C RustDNSUDPParserTest05 unit test.
1390 // Test TXT records in answer with a bad length.
1392 fn test_dns_udp_parser_test_05() {
1394 0xc2,0x2f,0x81,0x80,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x0a,0x41,0x41,0x41,
1395 0x41,0x41,0x4f,0x31,0x6b,0x51,0x41,0x05,0x3d,0x61,0x75,0x74,0x68,0x03,0x73,0x72,
1396 0x76,0x06,0x74,0x75,0x6e,0x6e,0x65,0x6c,0x03,0x63,0x6f,0x6d,0x00,0x00,0x10,0x00,
1398 /* answer record start */
1399 0xc0,0x0c,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x22,
1400 /* txt record starts: */
1401 0x40, /* <txt len 64 */ 0x41,0x68,0x76,0x4d,0x41,0x41,0x4f,0x31,0x6b,0x41,0x46,
1402 0x45,0x35,0x54,0x45,0x39,0x51,0x54,0x6a,0x46,0x46,0x4e,0x30,0x39,0x52,0x4e,0x31,
1403 0x6c,0x59,0x53,0x44,0x6b,0x00, /* <txt len 0 */ 0xc0,0x1d,0x00,0x02,0x00,0x01,
1404 0x00,0x09,0x3a,0x80,0x00,0x09,0x06,0x69,0x6f,0x64,0x69,0x6e,0x65,0xc0,0x21,0xc0,
1405 0x6b,0x00,0x01,0x00,0x01,0x00,0x09,0x3a,0x80,0x00,0x04,0x0a,0x1e,0x1c,0x5f
1407 let mut state = DNSState::new();
1408 assert!(!state.parse_response(buf));
1411 // Port of the C RustDNSTCPParserTestMultiRecord unit test.
1413 fn test_dns_tcp_parser_multi_record() {
1415 0x00, 0x1e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
1416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30,
1417 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
1418 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
1419 0x00, 0x1e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01,
1420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31,
1421 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
1422 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
1423 0x00, 0x1e, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01,
1424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x32,
1425 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
1426 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
1427 0x00, 0x1e, 0x00, 0x03, 0x01, 0x00, 0x00, 0x01,
1428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x33,
1429 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
1430 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
1431 0x00, 0x1e, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01,
1432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x34,
1433 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
1434 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
1435 0x00, 0x1e, 0x00, 0x05, 0x01, 0x00, 0x00, 0x01,
1436 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x35,
1437 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
1438 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
1439 0x00, 0x1e, 0x00, 0x06, 0x01, 0x00, 0x00, 0x01,
1440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x36,
1441 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
1442 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
1443 0x00, 0x1e, 0x00, 0x07, 0x01, 0x00, 0x00, 0x01,
1444 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x37,
1445 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
1446 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
1447 0x00, 0x1e, 0x00, 0x08, 0x01, 0x00, 0x00, 0x01,
1448 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38,
1449 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
1450 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
1451 0x00, 0x1e, 0x00, 0x09, 0x01, 0x00, 0x00, 0x01,
1452 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x39,
1453 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
1454 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
1455 0x00, 0x1f, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x01,
1456 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31,
1457 0x30, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
1458 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
1459 0x01, 0x00, 0x1f, 0x00, 0x0b, 0x01, 0x00, 0x00,
1460 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1461 0x31, 0x31, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
1462 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01,
1463 0x00, 0x01, 0x00, 0x1f, 0x00, 0x0c, 0x01, 0x00,
1464 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1465 0x02, 0x31, 0x32, 0x06, 0x67, 0x6f, 0x6f, 0x67,
1466 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00,
1467 0x01, 0x00, 0x01, 0x00, 0x1f, 0x00, 0x0d, 0x01,
1468 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
1469 0x00, 0x02, 0x31, 0x33, 0x06, 0x67, 0x6f, 0x6f,
1470 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
1471 0x00, 0x01, 0x00, 0x01, 0x00, 0x1f, 0x00, 0x0e,
1472 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
1473 0x00, 0x00, 0x02, 0x31, 0x34, 0x06, 0x67, 0x6f,
1474 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d,
1475 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x1f, 0x00,
1476 0x0f, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1477 0x00, 0x00, 0x00, 0x02, 0x31, 0x35, 0x06, 0x67,
1478 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f,
1479 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x1f,
1480 0x00, 0x10, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
1481 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x36, 0x06,
1482 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63,
1483 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
1484 0x1f, 0x00, 0x11, 0x01, 0x00, 0x00, 0x01, 0x00,
1485 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x37,
1486 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
1487 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
1488 0x00, 0x1f, 0x00, 0x12, 0x01, 0x00, 0x00, 0x01,
1489 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31,
1490 0x38, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
1491 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
1492 0x01, 0x00, 0x1f, 0x00, 0x13, 0x01, 0x00, 0x00,
1493 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1494 0x31, 0x39, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
1495 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01,
1498 let mut state = DNSState::new();
1500 AppLayerResult::ok(),
1501 state.parse_request_tcp(buf)
1506 fn test_dns_tcp_parser_split_payload() {
1507 /* incomplete payload */
1508 let buf1: &[u8] = &[
1509 0x00, 0x1c, 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
1510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1512 /* complete payload plus the start of a new payload */
1513 let buf2: &[u8] = &[
1514 0x00, 0x1c, 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
1515 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1516 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03,
1517 0x63, 0x6F, 0x6D, 0x00, 0x00, 0x10, 0x00, 0x01,
1520 0x00, 0x1c, 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
1521 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1524 /* and the complete payload again with no trailing data. */
1525 let buf3: &[u8] = &[
1526 0x00, 0x1c, 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
1527 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1528 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03,
1529 0x63, 0x6F, 0x6D, 0x00, 0x00, 0x10, 0x00, 0x01,
1532 let mut state = DNSState::new();
1534 AppLayerResult::incomplete(0, 30),
1535 state.parse_request_tcp(buf1)
1538 AppLayerResult::incomplete(30, 30),
1539 state.parse_request_tcp(buf2)
1542 AppLayerResult::ok(),
1543 state.parse_request_tcp(buf3)