suricata
app-layer-dns-common.h
Go to the documentation of this file.
1 /* Copyright (C) 2013 Open Information Security Foundation
2  *
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
5  * Software Foundation.
6  *
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.
11  *
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
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  */
23 
24 #ifndef __APP_LAYER_DNS_COMMON_H__
25 #define __APP_LAYER_DNS_COMMON_H__
26 
27 #include "app-layer-protos.h"
28 #include "app-layer-parser.h"
29 #include "flow.h"
30 #include "queue.h"
31 #include "util-byte.h"
32 
33 #define DNS_MAX_SIZE 256
34 
35 
36 #define DNS_RECORD_TYPE_A 1
37 #define DNS_RECORD_TYPE_NS 2
38 #define DNS_RECORD_TYPE_MD 3 // Obsolete
39 #define DNS_RECORD_TYPE_MF 4 // Obsolete
40 #define DNS_RECORD_TYPE_CNAME 5
41 #define DNS_RECORD_TYPE_SOA 6
42 #define DNS_RECORD_TYPE_MB 7 // Experimental
43 #define DNS_RECORD_TYPE_MG 8 // Experimental
44 #define DNS_RECORD_TYPE_MR 9 // Experimental
45 #define DNS_RECORD_TYPE_NULL 10 // Experimental
46 #define DNS_RECORD_TYPE_WKS 11
47 #define DNS_RECORD_TYPE_PTR 12
48 #define DNS_RECORD_TYPE_HINFO 13
49 #define DNS_RECORD_TYPE_MINFO 14
50 #define DNS_RECORD_TYPE_MX 15
51 #define DNS_RECORD_TYPE_TXT 16
52 #define DNS_RECORD_TYPE_RP 17
53 #define DNS_RECORD_TYPE_AFSDB 18
54 #define DNS_RECORD_TYPE_X25 19
55 #define DNS_RECORD_TYPE_ISDN 20
56 #define DNS_RECORD_TYPE_RT 21
57 #define DNS_RECORD_TYPE_NSAP 22
58 #define DNS_RECORD_TYPE_NSAPPTR 23
59 #define DNS_RECORD_TYPE_SIG 24
60 #define DNS_RECORD_TYPE_KEY 25
61 #define DNS_RECORD_TYPE_PX 26
62 #define DNS_RECORD_TYPE_GPOS 27
63 #define DNS_RECORD_TYPE_AAAA 28
64 #define DNS_RECORD_TYPE_LOC 29
65 #define DNS_RECORD_TYPE_NXT 30 // Obosolete
66 #define DNS_RECORD_TYPE_SRV 33
67 #define DNS_RECORD_TYPE_ATMA 34
68 #define DNS_RECORD_TYPE_NAPTR 35
69 #define DNS_RECORD_TYPE_KX 36
70 #define DNS_RECORD_TYPE_CERT 37
71 #define DNS_RECORD_TYPE_A6 38 // Obsolete
72 #define DNS_RECORD_TYPE_DNAME 39
73 #define DNS_RECORD_TYPE_OPT 41
74 #define DNS_RECORD_TYPE_APL 42
75 #define DNS_RECORD_TYPE_DS 43
76 #define DNS_RECORD_TYPE_SSHFP 44
77 #define DNS_RECORD_TYPE_IPSECKEY 45
78 #define DNS_RECORD_TYPE_RRSIG 46
79 #define DNS_RECORD_TYPE_NSEC 47
80 #define DNS_RECORD_TYPE_DNSKEY 48
81 #define DNS_RECORD_TYPE_DHCID 49
82 #define DNS_RECORD_TYPE_NSEC3 50
83 #define DNS_RECORD_TYPE_NSEC3PARAM 51
84 #define DNS_RECORD_TYPE_TLSA 52
85 #define DNS_RECORD_TYPE_HIP 55
86 #define DNS_RECORD_TYPE_CDS 59
87 #define DNS_RECORD_TYPE_CDNSKEY 60
88 #define DNS_RECORD_TYPE_SPF 99 // Obsolete
89 #define DNS_RECORD_TYPE_TKEY 249
90 #define DNS_RECORD_TYPE_TSIG 250
91 #define DNS_RECORD_TYPE_MAILA 254 // Obsolete
92 #define DNS_RECORD_TYPE_ANY 255
93 #define DNS_RECORD_TYPE_URI 256
94 
95 #define DNS_RCODE_NOERROR 0
96 #define DNS_RCODE_FORMERR 1
97 #define DNS_RCODE_SERVFAIL 2
98 #define DNS_RCODE_NXDOMAIN 3
99 #define DNS_RCODE_NOTIMP 4
100 #define DNS_RCODE_REFUSED 5
101 #define DNS_RCODE_YXDOMAIN 6
102 #define DNS_RCODE_YXRRSET 7
103 #define DNS_RCODE_NXRRSET 8
104 #define DNS_RCODE_NOTAUTH 9
105 #define DNS_RCODE_NOTZONE 10
106 // Support for OPT RR from RFC6891 will be needed to
107 // parse RCODE values over 15
108 #define DNS_RCODE_BADVERS 16
109 #define DNS_RCODE_BADSIG 16
110 #define DNS_RCODE_BADKEY 17
111 #define DNS_RCODE_BADTIME 18
112 #define DNS_RCODE_BADMODE 19
113 #define DNS_RCODE_BADNAME 20
114 #define DNS_RCODE_BADALG 21
115 #define DNS_RCODE_BADTRUNC 22
116 
117 enum {
125 };
126 
127 /** Opaque Rust types. */
128 typedef struct RSDNSState_ RSDNSState;
129 typedef struct RSDNSTransaction_ RSDNSTransaction;
130 
131 /** \brief DNS packet header */
132 typedef struct DNSHeader_ {
133  uint16_t tx_id;
134  uint16_t flags;
135  uint16_t questions;
136  uint16_t answer_rr;
137  uint16_t authority_rr;
138  uint16_t additional_rr;
139 } __attribute__((__packed__)) DNSHeader;
140 
141 typedef struct DNSQueryTrailer_ {
142  uint16_t type;
143  uint16_t class;
144 } __attribute__((__packed__)) DNSQueryTrailer;
145 
146 /** \brief DNS answer header
147  * packed as we don't want alignment to mess up sizeof() */
149  uint16_t type;
150  uint16_t class;
151  uint32_t ttl;
152  uint16_t len;
153 } __attribute__((__packed__));
155 
156 /** \brief List types in the TX.
157  * Used when storing answers from "Answer" or "Authority" */
158 typedef enum {
161 } DnsListEnum;
162 
163 /** \brief DNS Query storage. Stored in TX list.
164  *
165  * Layout is:
166  * [list ptr][2 byte type][2 byte class][2 byte len][...data...]
167  */
168 typedef struct DNSQueryEntry_ {
170  uint16_t type;
171  uint16_t class;
172  uint16_t len;
173 } DNSQueryEntry;
174 
175 /** \brief DNS Answer storage. Stored in TX list.
176  *
177  * Layout is:
178  * [list ptr][2 byte type][2 byte class][2 byte ttl] \
179  * [2 byte fqdn len][2 byte data len][...fqdn...][...data...]
180  */
181 typedef struct DNSAnswerEntry_ {
183 
184  uint16_t type;
185  uint16_t class;
186 
187  uint32_t ttl;
188 
189  uint16_t fqdn_len;
190  uint16_t data_len;
192 
193 /** \brief DNS Transaction, request/reply with same TX id. */
194 typedef struct DNSTransaction_ {
195  uint16_t tx_num; /**< internal: id */
196  uint16_t tx_id; /**< transaction id */
197  uint16_t flags; /**< dns flags */
198  uint32_t logged; /**< flags for loggers done logging */
199  uint8_t replied; /**< bool indicating request is
200  replied to. */
201  uint8_t reply_lost;
202  uint8_t rcode; /**< response code (e.g. "no error" / "no such name") */
203  uint8_t recursion_desired; /**< server said "recursion desired" */
204 
205  /** detection engine flags */
206  uint64_t detect_flags_ts;
207  uint64_t detect_flags_tc;
208 
209  TAILQ_HEAD(, DNSQueryEntry_) query_list; /**< list for query/queries */
210  TAILQ_HEAD(, DNSAnswerEntry_) answer_list; /**< list for answers */
211  TAILQ_HEAD(, DNSAnswerEntry_) authority_list; /**< list for authority records */
212 
213  AppLayerDecoderEvents *decoder_events; /**< per tx events */
214 
216  DetectEngineState *de_state;
218 
219 /** \brief Per flow DNS state container */
220 typedef struct DNSState_ {
221  TAILQ_HEAD(, DNSTransaction_) tx_list; /**< transaction list */
222  DNSTransaction *curr; /**< ptr to current tx */
224  uint64_t transaction_max;
225  uint32_t unreplied_cnt; /**< number of unreplied requests in a row */
226  uint32_t memuse; /**< state memuse, for comparing with
227  state-memcap settings */
228  struct timeval last_req; /**< Timestamp of last request. */
229  struct timeval last_resp; /**< Timestamp of last response. */
230 
231  uint16_t window; /**< Window of allowed unreplied
232  * requests. Set by the maximum
233  * number of subsequent requests
234  * without a response. */
235  uint16_t events;
236  uint16_t givenup;
237 
238  /* used by TCP only */
239  uint16_t offset;
240  uint16_t record_len;
241  uint8_t gap_ts; /**< Flag set when a gap has occurred. */
242  uint8_t gap_tc; /**< Flag set when a gap has occurred. */
243  uint8_t *buffer;
244 } DNSState;
245 
246 #define DNS_CONFIG_DEFAULT_REQUEST_FLOOD 500
247 #define DNS_CONFIG_DEFAULT_STATE_MEMCAP 512*1024
248 #define DNS_CONFIG_DEFAULT_GLOBAL_MEMCAP 16*1024*1024
249 
250 void DNSConfigInit(void);
251 void DNSConfigSetRequestFlood(uint32_t value);
252 void DNSConfigSetStateMemcap(uint32_t value);
253 void DNSConfigSetGlobalMemcap(uint64_t value);
254 
255 void DNSIncrMemcap(uint32_t size, DNSState *state);
256 void DNSDecrMemcap(uint32_t size, DNSState *state);
257 int DNSCheckMemcap(uint32_t want, DNSState *state);
258 uint64_t DNSMemcapGetMemuseCounter(void);
259 uint64_t DNSMemcapGetMemcapStateCounter(void);
260 uint64_t DNSMemcapGetMemcapGlobalCounter(void);
261 
262 void RegisterDNSParsers(void);
263 void DNSParserTests(void);
264 void DNSParserRegisterTests(void);
265 void DNSAppLayerDecoderEventsRegister(int alproto);
266 int DNSStateGetEventInfo(const char *event_name,
267  int *event_id, AppLayerEventType *event_type);
268 void DNSAppLayerRegisterGetEventInfo(uint8_t ipproto, AppProto alproto);
269 
270 void *DNSGetTx(void *alstate, uint64_t tx_id);
271 uint64_t DNSGetTxCnt(void *alstate);
272 void DNSSetTxLogged(void *alstate, void *tx, LoggerId logged);
273 LoggerId DNSGetTxLogged(void *alstate, void *tx);
274 int DNSGetAlstateProgress(void *tx, uint8_t direction);
275 int DNSGetAlstateProgressCompletionStatus(uint8_t direction);
276 
277 void DNSStateTransactionFree(void *state, uint64_t tx_id);
278 DNSTransaction *DNSTransactionFindByTxId(const DNSState *dns_state, const uint16_t tx_id);
279 
281 int DNSSetTxDetectState(void *vtx, DetectEngineState *s);
282 uint64_t DNSGetTxDetectFlags(void *vtx, uint8_t dir);
283 void DNSSetTxDetectFlags(void *vtx, uint8_t dir, uint64_t detect_flags);
284 
285 void DNSSetEvent(DNSState *s, uint8_t e);
286 void *DNSStateAlloc(void);
287 void DNSStateFree(void *s);
288 AppLayerDecoderEvents *DNSGetEvents(void *state, uint64_t id);
289 
290 int DNSValidateRequestHeader(DNSState *, const DNSHeader *dns_header);
291 int DNSValidateResponseHeader(DNSState *, const DNSHeader *dns_header);
292 
293 void DNSStoreQueryInState(DNSState *dns_state, const uint8_t *fqdn, const uint16_t fqdn_len,
294  const uint16_t type, const uint16_t class, const uint16_t tx_id);
295 
296 void DNSStoreAnswerInState(DNSState *dns_state, const int rtype, const uint8_t *fqdn,
297  const uint16_t fqdn_len, const uint16_t type, const uint16_t class, const uint16_t ttl,
298  const uint8_t *data, const uint16_t data_len, const uint16_t tx_id);
299 
300 const uint8_t *DNSReponseParse(DNSState *dns_state, const DNSHeader * const dns_header,
301  const uint16_t num, const DnsListEnum list, const uint8_t * const input,
302  const uint32_t input_len, const uint8_t *data);
303 
304 uint16_t DNSUdpResponseGetNameByOffset(const uint8_t * const input, const uint32_t input_len,
305  const uint16_t offset, uint8_t *fqdn, const size_t fqdn_size);
306 
307 void DNSCreateTypeString(uint16_t type, char *str, size_t str_size);
308 void DNSCreateRcodeString(uint8_t rcode, char *str, size_t str_size);
309 
310 #endif /* __APP_LAYER_DNS_COMMON_H__ */
struct DNSAnswerEntry_ DNSAnswerEntry
DNS Answer storage. Stored in TX list.
enum AppLayerEventType_ AppLayerEventType
void * DNSGetTx(void *alstate, uint64_t tx_id)
struct DNSState_ DNSState
Per flow DNS state container.
void DNSAppLayerDecoderEventsRegister(int alproto)
DnsListEnum
List types in the TX. Used when storing answers from "Answer" or "Authority".
int DNSGetAlstateProgress(void *tx, uint8_t direction)
void DNSDecrMemcap(uint32_t size, DNSState *state)
struct HtpBodyChunk_ * next
uint32_t event_type
DetectEngineState * DNSGetTxDetectState(void *vtx)
void DNSConfigInit(void)
Per flow DNS state container.
LoggerId
int DNSValidateResponseHeader(DNSState *, const DNSHeader *dns_header)
Validation checks for DNS response header.
const uint8_t * DNSReponseParse(DNSState *dns_state, const DNSHeader *const dns_header, const uint16_t num, const DnsListEnum list, const uint8_t *const input, const uint32_t input_len, const uint8_t *data)
uint64_t DNSMemcapGetMemuseCounter(void)
void DNSParserTests(void)
DNS Transaction, request/reply with same TX id.
uint64_t offset
#define TAILQ_HEAD(name, type)
Definition: queue.h:321
uint16_t AppProto
DNS Answer storage. Stored in TX list.
typedef __attribute__
DNP3 application header.
void DNSStateTransactionFree(void *state, uint64_t tx_id)
dns transaction cleanup callback
void DNSConfigSetRequestFlood(uint32_t value)
uint64_t DNSGetTxCnt(void *alstate)
uint64_t DNSGetTxDetectFlags(void *vtx, uint8_t dir)
DNS Query storage. Stored in TX list.
#define str(s)
Data structure to store app layer decoder events.
int DNSValidateRequestHeader(DNSState *, const DNSHeader *dns_header)
Validation checks for DNS request header.
void DNSStateFree(void *s)
uint16_t type
int DNSGetAlstateProgressCompletionStatus(uint8_t direction)
get value for &#39;complete&#39; status in DNS
uint64_t DNSMemcapGetMemcapStateCounter(void)
DNSTransaction * curr
uint32_t unreplied_cnt
DNSTransaction * iter
uint16_t additional_rr
void DNSSetTxDetectFlags(void *vtx, uint8_t dir, uint64_t detect_flags)
void DNSAppLayerRegisterGetEventInfo(uint8_t ipproto, AppProto alproto)
uint32_t ttl
LoggerId DNSGetTxLogged(void *alstate, void *tx)
DNS answer header packed as we don&#39;t want alignment to mess up sizeof()
void DNSSetTxLogged(void *alstate, void *tx, LoggerId logged)
uint64_t DNSMemcapGetMemcapGlobalCounter(void)
#define TAILQ_ENTRY(type)
Definition: queue.h:330
void DNSConfigSetStateMemcap(uint32_t value)
int DNSSetTxDetectState(void *vtx, DetectEngineState *s)
void DNSStoreQueryInState(DNSState *dns_state, const uint8_t *fqdn, const uint16_t fqdn_len, const uint16_t type, const uint16_t class, const uint16_t tx_id)
void DNSCreateTypeString(uint16_t type, char *str, size_t str_size)
void DNSSetEvent(DNSState *s, uint8_t e)
DNSTransaction * DNSTransactionFindByTxId(const DNSState *dns_state, const uint16_t tx_id)
void DNSConfigSetGlobalMemcap(uint64_t value)
struct DNSQueryEntry_ DNSQueryEntry
DNS Query storage. Stored in TX list.
DNS packet header.
void DNSIncrMemcap(uint32_t size, DNSState *state)
struct RSDNSState_ RSDNSState
void DNSStoreAnswerInState(DNSState *dns_state, const int rtype, const uint8_t *fqdn, const uint16_t fqdn_len, const uint16_t type, const uint16_t class, const uint16_t ttl, const uint8_t *data, const uint16_t data_len, const uint16_t tx_id)
int DNSStateGetEventInfo(const char *event_name, int *event_id, AppLayerEventType *event_type)
struct RSDNSTransaction_ RSDNSTransaction
void DNSCreateRcodeString(uint8_t rcode, char *str, size_t str_size)
AppLayerDecoderEvents * DNSGetEvents(void *state, uint64_t id)
void RegisterDNSParsers(void)
void DNSParserRegisterTests(void)
int DNSCheckMemcap(uint32_t want, DNSState *state)
void * DNSStateAlloc(void)
uint64_t transaction_max
uint16_t DNSUdpResponseGetNameByOffset(const uint8_t *const input, const uint32_t input_len, const uint16_t offset, uint8_t *fqdn, const size_t fqdn_size)