suricata
detect-dns-query.c
Go to the documentation of this file.
1 /* Copyright (C) 2013-2018 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  * \ingroup dnslayer
20  *
21  * @{
22  */
23 
24 
25 /**
26  * \file
27  *
28  * \author Victor Julien <victor@inliniac.net>
29  */
30 
31 #include "suricata-common.h"
32 #include "threads.h"
33 #include "debug.h"
34 #include "decode.h"
35 #include "detect.h"
36 
37 #include "detect-parse.h"
38 #include "detect-engine.h"
39 #include "detect-engine-mpm.h"
42 #include "detect-content.h"
43 #include "detect-pcre.h"
44 
45 #include "flow.h"
46 #include "flow-util.h"
47 #include "flow-var.h"
48 
49 #include "util-debug.h"
50 #include "util-unittest.h"
51 #include "util-spm.h"
52 #include "util-print.h"
53 
54 #include "stream-tcp.h"
55 
56 #include "app-layer.h"
57 #include "app-layer-dns-common.h"
58 #include "detect-dns-query.h"
59 #include "detect-engine-dns.h"
60 
61 #include "util-unittest-helper.h"
62 
63 #include "rust-dns-dns-gen.h"
64 
65 static int DetectDnsQuerySetup (DetectEngineCtx *, Signature *, const char *);
66 static void DetectDnsQueryRegisterTests(void);
67 static int g_dns_query_buffer_id = 0;
68 
70  int local_id; /**< used as index into thread inspect array */
71  void *txv;
72 };
73 
74 static InspectionBuffer *DnsQueryGetData(DetectEngineThreadCtx *det_ctx,
75  const DetectEngineTransforms *transforms,
76  Flow *f, struct DnsQueryGetDataArgs *cbdata, int list_id, bool first)
77 {
78  SCEnter();
79 
82  if (buffer == NULL)
83  return NULL;
84  if (!first && buffer->inspect != NULL)
85  return buffer;
86 
87  const uint8_t *data;
88  uint32_t data_len;
89  if (rs_dns_tx_get_query_name(cbdata->txv, (uint16_t)cbdata->local_id,
90  &data, &data_len) == 0) {
91  return NULL;
92  }
93  InspectionBufferSetup(buffer, data, data_len);
94  InspectionBufferApplyTransforms(buffer, transforms);
95 
96  SCReturnPtr(buffer, "InspectionBuffer");
97 }
98 
99 static int DetectEngineInspectDnsQuery(
100  DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
101  const DetectEngineAppInspectionEngine *engine,
102  const Signature *s,
103  Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
104 {
105  int local_id = 0;
106 
107  const DetectEngineTransforms *transforms = NULL;
108  if (!engine->mpm) {
109  transforms = engine->v2.transforms;
110  }
111 
112  while(1) {
113  struct DnsQueryGetDataArgs cbdata = { local_id, txv, };
114  InspectionBuffer *buffer = DnsQueryGetData(det_ctx,
115  transforms, f, &cbdata, engine->sm_list, false);
116  if (buffer == NULL || buffer->inspect == NULL)
117  break;
118 
119  det_ctx->buffer_offset = 0;
120  det_ctx->discontinue_matching = 0;
121  det_ctx->inspection_recursion_counter = 0;
122 
123  const int match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd,
124  NULL, f,
125  (uint8_t *)buffer->inspect,
126  buffer->inspect_len,
129  if (match == 1) {
131  }
132  local_id++;
133  }
135 }
136 
137 typedef struct PrefilterMpmDnsQuery {
138  int list_id;
139  const MpmCtx *mpm_ctx;
142 
143 /** \brief DnsQuery DnsQuery Mpm prefilter callback
144  *
145  * \param det_ctx detection engine thread ctx
146  * \param p packet to inspect
147  * \param f flow to inspect
148  * \param txv tx to inspect
149  * \param pectx inspection context
150  */
151 static void PrefilterTxDnsQuery(DetectEngineThreadCtx *det_ctx,
152  const void *pectx,
153  Packet *p, Flow *f, void *txv,
154  const uint64_t idx, const uint8_t flags)
155 {
156  SCEnter();
157 
158  const PrefilterMpmDnsQuery *ctx = (const PrefilterMpmDnsQuery *)pectx;
159  const MpmCtx *mpm_ctx = ctx->mpm_ctx;
160  const int list_id = ctx->list_id;
161 
162  int local_id = 0;
163  while(1) {
164  // loop until we get a NULL
165 
166  struct DnsQueryGetDataArgs cbdata = { local_id, txv };
167  InspectionBuffer *buffer = DnsQueryGetData(det_ctx, ctx->transforms,
168  f, &cbdata, list_id, true);
169  if (buffer == NULL)
170  break;
171 
172  if (buffer->inspect_len >= mpm_ctx->minlen) {
173  (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
174  &det_ctx->mtcu, &det_ctx->pmq,
175  buffer->inspect, buffer->inspect_len);
176  }
177 
178  local_id++;
179  }
180 }
181 
182 static void PrefilterMpmDnsQueryFree(void *ptr)
183 {
184  SCFree(ptr);
185 }
186 
187 static int PrefilterMpmDnsQueryRegister(DetectEngineCtx *de_ctx,
188  SigGroupHead *sgh, MpmCtx *mpm_ctx,
189  const DetectBufferMpmRegistery *mpm_reg, int list_id)
190 {
191  PrefilterMpmDnsQuery *pectx = SCCalloc(1, sizeof(*pectx));
192  if (pectx == NULL)
193  return -1;
194  pectx->list_id = list_id;
195  pectx->mpm_ctx = mpm_ctx;
196  pectx->transforms = &mpm_reg->transforms;
197 
198  return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxDnsQuery,
199  mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress,
200  pectx, PrefilterMpmDnsQueryFree, mpm_reg->pname);
201 }
202 
203 
204 /**
205  * \brief Registration function for keyword: dns_query
206  */
208 {
209  sigmatch_table[DETECT_AL_DNS_QUERY].name = "dns.query";
211  sigmatch_table[DETECT_AL_DNS_QUERY].desc = "sticky buffer to match DNS query-buffer";
212  sigmatch_table[DETECT_AL_DNS_QUERY].Setup = DetectDnsQuerySetup;
213  sigmatch_table[DETECT_AL_DNS_QUERY].RegisterTests = DetectDnsQueryRegisterTests;
216 
218  PrefilterMpmDnsQueryRegister, NULL,
219  ALPROTO_DNS, 1);
220 
223  DetectEngineInspectDnsQuery, NULL);
224 
226  "dns request query");
227 
228  g_dns_query_buffer_id = DetectBufferTypeGetByName("dns_query");
229 
230  /* register these generic engines from here for now */
237 
239  "dns requests");
241  "dns responses");
242 }
243 
244 
245 /**
246  * \brief setup the dns_query sticky buffer keyword used in the rule
247  *
248  * \param de_ctx Pointer to the Detection Engine Context
249  * \param s Pointer to the Signature to which the current keyword belongs
250  * \param str Should hold an empty string always
251  *
252  * \retval 0 On success
253  * \retval -1 On failure
254  */
255 
256 static int DetectDnsQuerySetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
257 {
258  if (DetectBufferSetActiveList(s, g_dns_query_buffer_id) < 0)
259  return -1;
261  return -1;
262  return 0;
263 }
264 
265 #ifdef UNITTESTS
266 #include "detect-isdataat.h"
267 
268 /** \test simple google.com query matching */
269 static int DetectDnsQueryTest01(void)
270 {
271  /* google.com */
272  uint8_t buf[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
273  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
275  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
276  0x00, 0x10, 0x00, 0x01, };
277  Flow f;
278  RSDNSState *dns_state = NULL;
279  Packet *p = NULL;
280  Signature *s = NULL;
281  ThreadVars tv;
282  DetectEngineThreadCtx *det_ctx = NULL;
284 
285  memset(&tv, 0, sizeof(ThreadVars));
286  memset(&f, 0, sizeof(Flow));
287 
288  p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP,
289  "192.168.1.5", "192.168.1.1",
290  41424, 53);
291 
292  FLOW_INITIALIZE(&f);
293  f.flags |= FLOW_IPV4;
294  f.proto = IPPROTO_UDP;
296 
297  p->flow = &f;
298  p->flags |= PKT_HAS_FLOW;
300  f.alproto = ALPROTO_DNS;
301 
303  FAIL_IF_NULL(de_ctx);
305  de_ctx->flags |= DE_QUIET;
306 
307  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
308  "(msg:\"Test dns_query option\"; "
309  "dns_query; content:\"google\"; nocase; sid:1;)");
310  FAIL_IF_NULL(s);
311 
312  SigGroupBuild(de_ctx);
313  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
314 
315  FLOWLOCK_WRLOCK(&f);
316  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
317  STREAM_TOSERVER, buf, sizeof(buf));
318  if (r != 0) {
319  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
320  FLOWLOCK_UNLOCK(&f);
321  FAIL;
322  }
323  FLOWLOCK_UNLOCK(&f);
324 
325  dns_state = f.alstate;
326  FAIL_IF_NULL(dns_state);
327 
328  /* do detect */
329  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
330 
331  if (!(PacketAlertCheck(p, 1))) {
332  printf("sig 1 didn't alert, but it should have: ");
333  FAIL;
334  }
335 
336  if (alp_tctx != NULL)
337  AppLayerParserThreadCtxFree(alp_tctx);
338  if (det_ctx != NULL)
339  DetectEngineThreadCtxDeinit(&tv, det_ctx);
340  if (de_ctx != NULL)
341  SigGroupCleanup(de_ctx);
342  if (de_ctx != NULL)
343  DetectEngineCtxFree(de_ctx);
344 
345  FLOW_DESTROY(&f);
346  UTHFreePacket(p);
347  PASS;
348 }
349 
350 /** \test multi tx google.(com|net) query matching */
351 static int DetectDnsQueryTest02(void)
352 {
353  /* google.com */
354  uint8_t buf1[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
355  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
357  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
358  0x00, 0x01, 0x00, 0x01, };
359 
360  uint8_t buf2[] = { 0x10, 0x32, /* tx id */
361  0x81, 0x80, /* flags: resp, recursion desired, recusion available */
362  0x00, 0x01, /* 1 query */
363  0x00, 0x01, /* 1 answer */
364  0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
365  /* query record */
366  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
367  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
368  0x00, 0x01, 0x00, 0x01, /* type a, class in */
369  /* answer */
370  0xc0, 0x0c, /* ref to name in query above */
371  0x00, 0x01, 0x00, 0x01, /* type a, class in */
372  0x00, 0x01, 0x40, 0xef, /* ttl */
373  0x00, 0x04, /* data len */
374  0x01, 0x02, 0x03, 0x04 }; /* addr */
375 
376  /* google.net */
377  uint8_t buf3[] = { 0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
378  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
380  0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
381  0x00, 0x10, 0x00, 0x01, };
382  Flow f;
383  RSDNSState *dns_state = NULL;
384  Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
385  Signature *s = NULL;
386  ThreadVars tv;
387  DetectEngineThreadCtx *det_ctx = NULL;
389 
390  memset(&tv, 0, sizeof(ThreadVars));
391  memset(&f, 0, sizeof(Flow));
392 
393  p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
394  "192.168.1.5", "192.168.1.1",
395  41424, 53);
396  p2 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
397  "192.168.1.5", "192.168.1.1",
398  41424, 53);
399  p3 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
400  "192.168.1.5", "192.168.1.1",
401  41424, 53);
402 
403  FLOW_INITIALIZE(&f);
404  f.flags |= FLOW_IPV4;
405  f.proto = IPPROTO_UDP;
407  f.alproto = ALPROTO_DNS;
408 
409  p1->flow = &f;
410  p1->flags |= PKT_HAS_FLOW;
412  p1->pcap_cnt = 1;
413 
414  p2->flow = &f;
415  p2->flags |= PKT_HAS_FLOW;
416  p2->flowflags |= FLOW_PKT_TOCLIENT;
417  p2->pcap_cnt = 2;
418 
419  p3->flow = &f;
420  p3->flags |= PKT_HAS_FLOW;
421  p3->flowflags |= FLOW_PKT_TOSERVER;
422  p3->pcap_cnt = 3;
423 
425  FAIL_IF_NULL(de_ctx);
427  de_ctx->flags |= DE_QUIET;
428 
429  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
430  "(msg:\"Test dns_query option\"; "
431  "dns_query; content:\"google.com\"; nocase; sid:1;)");
432  FAIL_IF_NULL(s);
433  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
434  "(msg:\"Test dns_query option\"; "
435  "dns_query; content:\"google.net\"; nocase; sid:2;)");
436  FAIL_IF_NULL(s);
437 
438  SigGroupBuild(de_ctx);
439  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
440 
441  FLOWLOCK_WRLOCK(&f);
442  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
443  STREAM_TOSERVER, buf1, sizeof(buf1));
444  if (r != 0) {
445  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
446  FLOWLOCK_UNLOCK(&f);
447  FAIL;
448  }
449  FLOWLOCK_UNLOCK(&f);
450 
451  dns_state = f.alstate;
452  FAIL_IF_NULL(dns_state);
453 
454  /* do detect */
455  SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
456 
457  if (!(PacketAlertCheck(p1, 1))) {
458  printf("(p1) sig 1 didn't alert, but it should have: ");
459  FAIL;
460  }
461  if (PacketAlertCheck(p1, 2)) {
462  printf("(p1) sig 2 did alert, but it should not have: ");
463  FAIL;
464  }
465 
466  FLOWLOCK_WRLOCK(&f);
467  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
468  buf2, sizeof(buf2));
469  if (r != 0) {
470  printf("toserver client 1 returned %" PRId32 ", expected 0: ", r);
471  FLOWLOCK_UNLOCK(&f);
472  FAIL;
473  }
474  FLOWLOCK_UNLOCK(&f);
475 
476  /* do detect */
477  SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
478 
479  if (PacketAlertCheck(p2, 1)) {
480  printf("(p2) sig 1 alerted, but it should not have: ");
481  FAIL;
482  }
483  if (PacketAlertCheck(p2, 2)) {
484  printf("(p2) sig 2 alerted, but it should not have: ");
485  FAIL;
486  }
487 
488  FLOWLOCK_WRLOCK(&f);
489  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
490  buf3, sizeof(buf3));
491  if (r != 0) {
492  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
493  FLOWLOCK_UNLOCK(&f);
494  FAIL;
495  }
496  FLOWLOCK_UNLOCK(&f);
497 
498  /* do detect */
499  SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
500 
501  if (PacketAlertCheck(p3, 1)) {
502  printf("(p3) sig 1 alerted, but it should not have: ");
503  FAIL;
504  }
505  if (!(PacketAlertCheck(p3, 2))) {
506  printf("(p3) sig 2 didn't alert, but it should have: ");
507  FAIL;
508  }
509 
510  if (alp_tctx != NULL)
511  AppLayerParserThreadCtxFree(alp_tctx);
512  if (det_ctx != NULL)
513  DetectEngineThreadCtxDeinit(&tv, det_ctx);
514  if (de_ctx != NULL)
515  SigGroupCleanup(de_ctx);
516  if (de_ctx != NULL)
517  DetectEngineCtxFree(de_ctx);
518 
519  FLOW_DESTROY(&f);
520  UTHFreePacket(p1);
521  UTHFreePacket(p2);
522  UTHFreePacket(p3);
523  PASS;
524 }
525 
526 /** \test simple google.com query matching (TCP) */
527 static int DetectDnsQueryTest03(void)
528 {
529  /* google.com */
530  uint8_t buf[] = { 0x00, 28,
531  0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
532  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
533  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
534  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
535  0x00, 0x10, 0x00, 0x01, };
536  Flow f;
537  RSDNSState *dns_state = NULL;
538  Packet *p = NULL;
539  Signature *s = NULL;
540  ThreadVars tv;
541  DetectEngineThreadCtx *det_ctx = NULL;
542  TcpSession ssn;
544 
545  memset(&tv, 0, sizeof(ThreadVars));
546  memset(&f, 0, sizeof(Flow));
547  memset(&ssn, 0, sizeof(TcpSession));
548 
549  p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_TCP,
550  "192.168.1.5", "192.168.1.1",
551  41424, 53);
552 
553  FLOW_INITIALIZE(&f);
554  f.protoctx = (void *)&ssn;
555  f.flags |= FLOW_IPV4;
556  f.proto = IPPROTO_TCP;
558 
559  p->flow = &f;
562  f.alproto = ALPROTO_DNS;
563 
565 
567  FAIL_IF_NULL(de_ctx);
569  de_ctx->flags |= DE_QUIET;
570 
571  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
572  "(msg:\"Test dns_query option\"; "
573  "dns_query; content:\"google\"; nocase; sid:1;)");
574  FAIL_IF_NULL(s);
575 
576  SigGroupBuild(de_ctx);
577  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
578 
579  FLOWLOCK_WRLOCK(&f);
580  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
581  STREAM_TOSERVER, buf, sizeof(buf));
582  if (r != 0) {
583  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
584  FLOWLOCK_UNLOCK(&f);
585  FAIL;
586  }
587  FLOWLOCK_UNLOCK(&f);
588 
589  dns_state = f.alstate;
590  FAIL_IF_NULL(dns_state);
591 
592  /* do detect */
593  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
594 
595  if (!(PacketAlertCheck(p, 1))) {
596  printf("sig 1 didn't alert, but it should have: ");
597  FAIL;
598  }
599 
600  if (alp_tctx != NULL)
601  AppLayerParserThreadCtxFree(alp_tctx);
602  if (det_ctx != NULL)
603  DetectEngineThreadCtxDeinit(&tv, det_ctx);
604  if (de_ctx != NULL)
605  SigGroupCleanup(de_ctx);
606  if (de_ctx != NULL)
607  DetectEngineCtxFree(de_ctx);
608 
610  FLOW_DESTROY(&f);
611  UTHFreePacket(p);
612  PASS;
613 }
614 
615 /** \test simple google.com query matching (TCP splicing) */
616 static int DetectDnsQueryTest04(void)
617 {
618  /* google.com */
619  uint8_t buf1[] = { 0x00, 28,
620  0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
621  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
622  uint8_t buf2[] = { 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
623  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
624  0x00, 0x10, 0x00, 0x01, };
625  Flow f;
626  RSDNSState *dns_state = NULL;
627  Packet *p1 = NULL, *p2 = NULL;
628  Signature *s = NULL;
629  ThreadVars tv;
630  DetectEngineThreadCtx *det_ctx = NULL;
631  TcpSession ssn;
633 
634  memset(&tv, 0, sizeof(ThreadVars));
635  memset(&f, 0, sizeof(Flow));
636  memset(&ssn, 0, sizeof(TcpSession));
637 
638  p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_TCP,
639  "192.168.1.5", "192.168.1.1",
640  41424, 53);
641  p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_TCP,
642  "192.168.1.5", "192.168.1.1",
643  41424, 53);
644 
645  FLOW_INITIALIZE(&f);
646  f.protoctx = (void *)&ssn;
647  f.flags |= FLOW_IPV4;
648  f.proto = IPPROTO_TCP;
650  f.alproto = ALPROTO_DNS;
651 
652  p1->flow = &f;
655 
656  p2->flow = &f;
658  p2->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
659 
661 
663  FAIL_IF_NULL(de_ctx);
665  de_ctx->flags |= DE_QUIET;
666 
667  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
668  "(msg:\"Test dns_query option\"; "
669  "dns_query; content:\"google\"; nocase; sid:1;)");
670  FAIL_IF_NULL(s);
671 
672  SigGroupBuild(de_ctx);
673  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
674 
675  FLOWLOCK_WRLOCK(&f);
676  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
677  STREAM_TOSERVER, buf1, sizeof(buf1));
678  if (r != 0) {
679  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
680  FLOWLOCK_UNLOCK(&f);
681  FAIL;
682  }
683  FLOWLOCK_UNLOCK(&f);
684 
685  dns_state = f.alstate;
686  FAIL_IF_NULL(dns_state);
687 
688  /* do detect */
689  SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
690 
691  if (PacketAlertCheck(p1, 1)) {
692  printf("sig 1 alerted, but it should not have: ");
693  FAIL;
694  }
695 
696  FLOWLOCK_WRLOCK(&f);
697  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
698  buf2, sizeof(buf2));
699  if (r != 0) {
700  printf("toserver chunk 1 returned %" PRId32 ", expected 0\n", r);
701  FLOWLOCK_UNLOCK(&f);
702  FAIL;
703  }
704  FLOWLOCK_UNLOCK(&f);
705 
706  /* do detect */
707  SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
708 
709  if (!(PacketAlertCheck(p2, 1))) {
710  printf("sig 1 didn't alert, but it should have: ");
711  FAIL;
712  }
713 
714  if (alp_tctx != NULL)
715  AppLayerParserThreadCtxFree(alp_tctx);
716  if (det_ctx != NULL)
717  DetectEngineThreadCtxDeinit(&tv, det_ctx);
718  if (de_ctx != NULL)
719  SigGroupCleanup(de_ctx);
720  if (de_ctx != NULL)
721  DetectEngineCtxFree(de_ctx);
722 
724  FLOW_DESTROY(&f);
725  UTHFreePacket(p1);
726  UTHFreePacket(p2);
727  PASS;
728 }
729 
730 /** \test simple google.com query matching (TCP splicing) */
731 static int DetectDnsQueryTest05(void)
732 {
733  /* google.com in 2 chunks (buf1 and buf2) */
734  uint8_t buf1[] = { 0x00, 28, /* len 28 */
735  0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
736  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
737 
738  uint8_t buf2[] = { 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
739  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
740  0x00, 0x10, 0x00, 0x01, };
741 
742  uint8_t buf3[] = { 0x00, 44, /* len 44 */
743  0x10, 0x32, /* tx id */
744  0x81, 0x80, /* flags: resp, recursion desired, recusion available */
745  0x00, 0x01, /* 1 query */
746  0x00, 0x01, /* 1 answer */
747  0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
748  /* query record */
749  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
750  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
751  0x00, 0x01, 0x00, 0x01, /* type a, class in */
752  /* answer */
753  0xc0, 0x0c, /* ref to name in query above */
754  0x00, 0x01, 0x00, 0x01, /* type a, class in */
755  0x00, 0x01, 0x40, 0xef, /* ttl */
756  0x00, 0x04, /* data len */
757  0x01, 0x02, 0x03, 0x04 }; /* addr */
758 
759  /* google.net */
760  uint8_t buf4[] = { 0x00, 28, /* len 28 */
761  0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
762  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
763  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
764  0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
765  0x00, 0x10, 0x00, 0x01, };
766  Flow f;
767  RSDNSState *dns_state = NULL;
768  Packet *p1 = NULL, *p2 = NULL, *p3 = NULL, *p4 = NULL;
769  Signature *s = NULL;
770  ThreadVars tv;
771  DetectEngineThreadCtx *det_ctx = NULL;
772  TcpSession ssn;
774 
775  memset(&tv, 0, sizeof(ThreadVars));
776  memset(&f, 0, sizeof(Flow));
777  memset(&ssn, 0, sizeof(TcpSession));
778 
779  p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_TCP,
780  "192.168.1.5", "192.168.1.1",
781  41424, 53);
782  p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_TCP,
783  "192.168.1.5", "192.168.1.1",
784  41424, 53);
785  p3 = UTHBuildPacketReal(buf3, sizeof(buf3), IPPROTO_TCP,
786  "192.168.1.5", "192.168.1.1",
787  41424, 53);
788  p4 = UTHBuildPacketReal(buf4, sizeof(buf4), IPPROTO_TCP,
789  "192.168.1.5", "192.168.1.1",
790  41424, 53);
791 
792  FLOW_INITIALIZE(&f);
793  f.protoctx = (void *)&ssn;
794  f.flags |= FLOW_IPV4;
795  f.proto = IPPROTO_TCP;
797  f.alproto = ALPROTO_DNS;
798 
799  p1->flow = &f;
802 
803  p2->flow = &f;
805  p2->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
806 
807  p3->flow = &f;
809  p3->flowflags |= FLOW_PKT_TOCLIENT|FLOW_PKT_ESTABLISHED;
810 
811  p4->flow = &f;
813  p4->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
814 
816 
818  FAIL_IF_NULL(de_ctx);
820  de_ctx->flags |= DE_QUIET;
821 
822  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
823  "(msg:\"Test dns_query option\"; "
824  "dns_query; content:\"google.com\"; nocase; sid:1;)");
825  FAIL_IF_NULL(s);
826  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
827  "(msg:\"Test dns_query option\"; "
828  "dns_query; content:\"google.net\"; nocase; sid:2;)");
829  FAIL_IF_NULL(s);
830 
831  SigGroupBuild(de_ctx);
832  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
833 
834  FLOWLOCK_WRLOCK(&f);
835  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
836  STREAM_TOSERVER, buf1, sizeof(buf1));
837  if (r != 0) {
838  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
839  FLOWLOCK_UNLOCK(&f);
840  FAIL;
841  }
842  FLOWLOCK_UNLOCK(&f);
843 
844  dns_state = f.alstate;
845  FAIL_IF_NULL(dns_state);
846 
847  /* do detect */
848  SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
849 
850  if (PacketAlertCheck(p1, 1)) {
851  printf("(p1) sig 1 alerted, but it should not have: ");
852  FAIL;
853  }
854  if (PacketAlertCheck(p1, 2)) {
855  printf("(p1) sig 2 did alert, but it should not have: ");
856  FAIL;
857  }
858 
859  FLOWLOCK_WRLOCK(&f);
860  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
861  buf2, sizeof(buf2));
862  if (r != 0) {
863  printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
864  FLOWLOCK_UNLOCK(&f);
865  FAIL;
866  }
867  FLOWLOCK_UNLOCK(&f);
868 
869  /* do detect */
870  SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
871 
872  if (!(PacketAlertCheck(p2, 1))) {
873  printf("sig 1 didn't alert, but it should have: ");
874  FAIL;
875  }
876  if (PacketAlertCheck(p2, 2)) {
877  printf("(p2) sig 2 did alert, but it should not have: ");
878  FAIL;
879  }
880 
881  FLOWLOCK_WRLOCK(&f);
882  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
883  buf3, sizeof(buf3));
884  if (r != 0) {
885  printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r);
886  FLOWLOCK_UNLOCK(&f);
887  FAIL;
888  }
889  FLOWLOCK_UNLOCK(&f);
890 
891  /* do detect */
892  SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
893 
894  if (PacketAlertCheck(p3, 1)) {
895  printf("sig 1 did alert, but it should not have: ");
896  FAIL;
897  }
898  if (PacketAlertCheck(p3, 2)) {
899  printf("(p3) sig 2 did alert, but it should not have: ");
900  FAIL;
901  }
902 
903  FLOWLOCK_WRLOCK(&f);
904  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
905  buf4, sizeof(buf4));
906  if (r != 0) {
907  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
908  FLOWLOCK_UNLOCK(&f);
909  FAIL;
910  }
911  FLOWLOCK_UNLOCK(&f);
912 
913  /* do detect */
914  SigMatchSignatures(&tv, de_ctx, det_ctx, p4);
915 
916  if (PacketAlertCheck(p4, 1)) {
917  printf("(p4) sig 1 did alert, but it should not have: ");
918  FAIL;
919  }
920  if (!(PacketAlertCheck(p4, 2))) {
921  printf("sig 1 didn't alert, but it should have: ");
922  FAIL;
923  }
924 
925  if (alp_tctx != NULL)
926  AppLayerParserThreadCtxFree(alp_tctx);
927  if (det_ctx != NULL)
928  DetectEngineThreadCtxDeinit(&tv, det_ctx);
929  if (de_ctx != NULL)
930  SigGroupCleanup(de_ctx);
931  if (de_ctx != NULL)
932  DetectEngineCtxFree(de_ctx);
933 
935  FLOW_DESTROY(&f);
936  UTHFreePacket(p1);
937  UTHFreePacket(p2);
938  UTHFreePacket(p3);
939  UTHFreePacket(p4);
940  PASS;
941 }
942 
943 /** \test simple google.com query matching, pcre */
944 static int DetectDnsQueryTest06(void)
945 {
946  /* google.com */
947  uint8_t buf[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
948  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
949  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
950  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
951  0x00, 0x10, 0x00, 0x01, };
952  Flow f;
953  RSDNSState *dns_state = NULL;
954  Packet *p = NULL;
955  Signature *s = NULL;
956  ThreadVars tv;
957  DetectEngineThreadCtx *det_ctx = NULL;
959 
960  memset(&tv, 0, sizeof(ThreadVars));
961  memset(&f, 0, sizeof(Flow));
962 
963  p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP,
964  "192.168.1.5", "192.168.1.1",
965  41424, 53);
966 
967  FLOW_INITIALIZE(&f);
968  f.flags |= FLOW_IPV4;
969  f.proto = IPPROTO_UDP;
971 
972  p->flow = &f;
973  p->flags |= PKT_HAS_FLOW;
975  f.alproto = ALPROTO_DNS;
976 
978  FAIL_IF_NULL(de_ctx);
980  de_ctx->flags |= DE_QUIET;
981 
982  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
983  "(msg:\"Test dns_query option\"; "
984  "dns_query; content:\"google\"; nocase; "
985  "pcre:\"/google\\.com$/i\"; sid:1;)");
986  FAIL_IF_NULL(s);
987  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
988  "(msg:\"Test dns_query option\"; "
989  "dns_query; content:\"google\"; nocase; "
990  "pcre:\"/^\\.[a-z]{2,3}$/iR\"; sid:2;)");
991  FAIL_IF_NULL(s);
992 
993  SigGroupBuild(de_ctx);
994  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
995 
996  FLOWLOCK_WRLOCK(&f);
997  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
998  STREAM_TOSERVER, buf, sizeof(buf));
999  if (r != 0) {
1000  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1001  FLOWLOCK_UNLOCK(&f);
1002  FAIL;
1003  }
1004  FLOWLOCK_UNLOCK(&f);
1005 
1006  dns_state = f.alstate;
1007  FAIL_IF_NULL(dns_state);
1008 
1009  /* do detect */
1010  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1011 
1012  if (!(PacketAlertCheck(p, 1))) {
1013  printf("sig 1 didn't alert, but it should have: ");
1014  FAIL;
1015  }
1016  if (!(PacketAlertCheck(p, 2))) {
1017  printf("sig 2 didn't alert, but it should have: ");
1018  FAIL;
1019  }
1020 
1021  if (alp_tctx != NULL)
1022  AppLayerParserThreadCtxFree(alp_tctx);
1023  if (det_ctx != NULL)
1024  DetectEngineThreadCtxDeinit(&tv, det_ctx);
1025  if (de_ctx != NULL)
1026  SigGroupCleanup(de_ctx);
1027  if (de_ctx != NULL)
1028  DetectEngineCtxFree(de_ctx);
1029 
1030  FLOW_DESTROY(&f);
1031  UTHFreePacket(p);
1032  PASS;
1033 }
1034 
1035 /** \test multi tx google.(com|net) query matching +
1036  * app layer event */
1037 static int DetectDnsQueryTest07(void)
1038 {
1039  /* google.com */
1040  uint8_t buf1[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
1041  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1042  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
1043  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
1044  0x00, 0x01, 0x00, 0x01, };
1045 
1046  uint8_t buf2[] = { 0x10, 0x32, /* tx id */
1047  0x81, 0x80|0x40, /* flags: resp, recursion desired, recusion available */
1048  0x00, 0x01, /* 1 query */
1049  0x00, 0x01, /* 1 answer */
1050  0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
1051  /* query record */
1052  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
1053  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
1054  0x00, 0x01, 0x00, 0x01, /* type a, class in */
1055  /* answer */
1056  0xc0, 0x0c, /* ref to name in query above */
1057  0x00, 0x01, 0x00, 0x01, /* type a, class in */
1058  0x00, 0x01, 0x40, 0xef, /* ttl */
1059  0x00, 0x04, /* data len */
1060  0x01, 0x02, 0x03, 0x04 }; /* addr */
1061 
1062  /* google.net */
1063  uint8_t buf3[] = { 0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
1064  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1065  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
1066  0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
1067  0x00, 0x10, 0x00, 0x01, };
1068  Flow f;
1069  RSDNSState *dns_state = NULL;
1070  Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1071  Signature *s = NULL;
1072  ThreadVars tv;
1073  DetectEngineThreadCtx *det_ctx = NULL;
1075 
1076  memset(&tv, 0, sizeof(ThreadVars));
1077  memset(&f, 0, sizeof(Flow));
1078 
1079  p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
1080  "192.168.1.5", "192.168.1.1",
1081  41424, 53);
1082  p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_UDP,
1083  "192.168.1.5", "192.168.1.1",
1084  41424, 53);
1085  p3 = UTHBuildPacketReal(buf3, sizeof(buf3), IPPROTO_UDP,
1086  "192.168.1.5", "192.168.1.1",
1087  41424, 53);
1088 
1089  FLOW_INITIALIZE(&f);
1090  f.flags |= FLOW_IPV4;
1091  f.proto = IPPROTO_UDP;
1093  f.alproto = ALPROTO_DNS;
1094 
1095  p1->flow = &f;
1096  p1->flags |= PKT_HAS_FLOW;
1098  p1->pcap_cnt = 1;
1099 
1100  p2->flow = &f;
1101  p2->flags |= PKT_HAS_FLOW;
1102  p2->flowflags |= FLOW_PKT_TOCLIENT;
1103  p2->pcap_cnt = 2;
1104 
1105  p3->flow = &f;
1106  p3->flags |= PKT_HAS_FLOW;
1107  p3->flowflags |= FLOW_PKT_TOSERVER;
1108  p3->pcap_cnt = 3;
1109 
1111  FAIL_IF_NULL(de_ctx);
1112  de_ctx->mpm_matcher = mpm_default_matcher;
1113  de_ctx->flags |= DE_QUIET;
1114 
1115  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
1116  "(msg:\"Test dns_query option\"; "
1117  "dns_query; content:\"google.com\"; nocase; sid:1;)");
1118  FAIL_IF_NULL(s);
1119  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
1120  "(msg:\"Test dns_query option\"; "
1121  "dns_query; content:\"google.net\"; nocase; sid:2;)");
1122  FAIL_IF_NULL(s);
1123  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
1124  "(msg:\"Test Z flag event\"; "
1125  "app-layer-event:dns.z_flag_set; sid:3;)");
1126  FAIL_IF_NULL(s);
1127 
1128  SigGroupBuild(de_ctx);
1129  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
1130 
1131  FLOWLOCK_WRLOCK(&f);
1132  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
1133  STREAM_TOSERVER, buf1, sizeof(buf1));
1134  if (r != 0) {
1135  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1136  FLOWLOCK_UNLOCK(&f);
1137  FAIL;
1138  }
1139  FLOWLOCK_UNLOCK(&f);
1140 
1141  dns_state = f.alstate;
1142  FAIL_IF_NULL(dns_state);
1143 
1144  /* do detect */
1145  SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
1146 
1147  if (!(PacketAlertCheck(p1, 1))) {
1148  printf("(p1) sig 1 didn't alert, but it should have: ");
1149  FAIL;
1150  }
1151  if (PacketAlertCheck(p1, 2)) {
1152  printf("(p1) sig 2 did alert, but it should not have: ");
1153  FAIL;
1154  }
1155 
1156  FLOWLOCK_WRLOCK(&f);
1157  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
1158  buf2, sizeof(buf2));
1159  if (r != -1) {
1160  printf("toserver client 1 returned %" PRId32 ", expected -1\n", r);
1161  FLOWLOCK_UNLOCK(&f);
1162  FAIL;
1163  }
1164  FLOWLOCK_UNLOCK(&f);
1165 
1166  /* do detect */
1167  SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
1168 
1169  if (PacketAlertCheck(p2, 1)) {
1170  printf("(p2) sig 1 alerted, but it should not have: ");
1171  FAIL;
1172  }
1173  if (PacketAlertCheck(p2, 2)) {
1174  printf("(p2) sig 2 alerted, but it should not have: ");
1175  FAIL;
1176  }
1177  if (!(PacketAlertCheck(p2, 3))) {
1178  printf("(p2) sig 3 didn't alert, but it should have: ");
1179  FAIL;
1180  }
1181 
1182  FLOWLOCK_WRLOCK(&f);
1183  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
1184  buf3, sizeof(buf3));
1185  if (r != 0) {
1186  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
1187  FLOWLOCK_UNLOCK(&f);
1188  FAIL;
1189  }
1190  FLOWLOCK_UNLOCK(&f);
1191 
1192  /* do detect */
1193  SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
1194 
1195  if (PacketAlertCheck(p3, 1)) {
1196  printf("(p3) sig 1 alerted, but it should not have: ");
1197  FAIL;
1198  }
1199  if (!(PacketAlertCheck(p3, 2))) {
1200  printf("(p3) sig 2 didn't alert, but it should have: ");
1201  FAIL;
1202  }
1203  /** \todo should not alert, bug #839
1204  if (PacketAlertCheck(p3, 3)) {
1205  printf("(p3) sig 3 did alert, but it should not have: ");
1206  goto end;
1207  }
1208  */
1209 
1210  if (alp_tctx != NULL)
1211  AppLayerParserThreadCtxFree(alp_tctx);
1212  if (det_ctx != NULL)
1213  DetectEngineThreadCtxDeinit(&tv, det_ctx);
1214  if (de_ctx != NULL)
1215  SigGroupCleanup(de_ctx);
1216  if (de_ctx != NULL)
1217  DetectEngineCtxFree(de_ctx);
1218 
1219  FLOW_DESTROY(&f);
1220  UTHFreePacket(p1);
1221  UTHFreePacket(p2);
1222  UTHFreePacket(p3);
1223  PASS;
1224 }
1225 
1226 static int DetectDnsQueryIsdataatParseTest(void)
1227 {
1229  FAIL_IF_NULL(de_ctx);
1230  de_ctx->flags |= DE_QUIET;
1231 
1232  Signature *s = DetectEngineAppendSig(de_ctx,
1233  "alert dns any any -> any any ("
1234  "dns_query; content:\"one\"; "
1235  "isdataat:!4,relative; sid:1;)");
1236  FAIL_IF_NULL(s);
1237 
1238  SigMatch *sm = s->init_data->smlists_tail[g_dns_query_buffer_id];
1239  FAIL_IF_NULL(sm);
1241 
1242  DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
1245  FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
1246 
1247  DetectEngineCtxFree(de_ctx);
1248  PASS;
1249 }
1250 
1251 #endif
1252 
1253 static void DetectDnsQueryRegisterTests(void)
1254 {
1255 #ifdef UNITTESTS
1256  UtRegisterTest("DetectDnsQueryTest01", DetectDnsQueryTest01);
1257  UtRegisterTest("DetectDnsQueryTest02", DetectDnsQueryTest02);
1258  UtRegisterTest("DetectDnsQueryTest03 -- tcp", DetectDnsQueryTest03);
1259  UtRegisterTest("DetectDnsQueryTest04 -- tcp splicing",
1260  DetectDnsQueryTest04);
1261  UtRegisterTest("DetectDnsQueryTest05 -- tcp splicing/multi tx",
1262  DetectDnsQueryTest05);
1263  UtRegisterTest("DetectDnsQueryTest06 -- pcre", DetectDnsQueryTest06);
1264  UtRegisterTest("DetectDnsQueryTest07 -- app layer event",
1265  DetectDnsQueryTest07);
1266 
1267  UtRegisterTest("DetectDnsQueryIsdataatParseTest",
1268  DetectDnsQueryIsdataatParseTest);
1269 #endif
1270 }
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1439
SignatureInitData * init_data
Definition: detect.h:586
uint16_t flags
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1179
int DetectEngineInspectDnsResponse(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
struct Flow_ * flow
Definition: decode.h:445
uint16_t minlen
Definition: util-mpm.h:99
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
uint16_t discontinue_matching
Definition: detect.h:1060
uint8_t proto
Definition: flow.h:344
void DetectDnsQueryRegister(void)
Registration function for keyword: dns_query.
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:243
#define PASS
Pass the test.
DetectEngineTransforms transforms
Definition: detect.h:613
int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, uint8_t *buffer, uint32_t buffer_len, uint32_t stream_start_offset, uint8_t flags, uint8_t inspection_mode)
Run the actual payload match functions.
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:95
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:203
#define ISDATAAT_RELATIVE
Container for matching data for a signature group.
Definition: detect.h:1329
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:240
uint64_t pcap_cnt
Definition: decode.h:561
uint32_t buffer_offset
Definition: detect.h:1025
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
#define ISDATAAT_RAWBYTES
const char * name
Definition: detect.h:1193
Signature container.
Definition: detect.h:517
#define TRUE
void DetectAppLayerMpmRegister2(const char *name, int direction, int priority, int(*PrefilterRegister)(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistery *mpm_reg, int list_id), InspectionBufferGetDataPtr GetData, AppProto alproto, int tx_min_progress)
register a MPM engine
void * protoctx
Definition: flow.h:400
struct DetectEngineAppInspectionEngine_::@92 v2
main detection engine ctx
Definition: detect.h:756
struct PrefilterMpmDnsQuery PrefilterMpmDnsQuery
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
void * alstate
Definition: flow.h:438
#define DE_QUIET
Definition: detect.h:287
int DetectBufferTypeGetByName(const char *name)
#define str(s)
#define SCCalloc(nm, a)
Definition: util-mem.h:253
#define SIG_FLAG_TOCLIENT
Definition: detect.h:233
#define SIGMATCH_INFO_STICKY_BUFFER
Definition: detect.h:1386
uint8_t flags
Definition: detect.h:757
#define DETECT_ENGINE_INSPECT_SIG_MATCH
const MpmCtx * mpm_ctx
uint64_t inspect_offset
Definition: detect.h:339
#define ISDATAAT_NEGATED
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
uint8_t mpm_type
Definition: util-mpm.h:90
uint16_t mpm_matcher
Definition: detect.h:805
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
one time registration of keywords at start up
Definition: detect.h:600
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1670
#define SIG_FLAG_TOSERVER
Definition: detect.h:232
#define SCEnter(...)
Definition: util-debug.h:337
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
void DetectAppLayerInspectEngineRegister2(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr2 Callback2, InspectionBufferGetDataPtr GetData)
register inspect engine at start up time
PrefilterRuleStore pmq
Definition: detect.h:1095
Packet * UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, uint8_t ipproto, const char *src, const char *dst, uint16_t sport, uint16_t dport)
UTHBuildPacketReal is a function that create tcp/udp packets for unittests specifying ip and port sou...
uint8_t flowflags
Definition: decode.h:439
#define STREAM_TOCLIENT
Definition: stream.h:32
#define FLOW_PKT_TOSERVER
Definition: flow.h:201
struct SigMatch_ ** smlists_tail
Definition: detect.h:513
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol&#39;s parser thread context.
int SigGroupCleanup(DetectEngineCtx *de_ctx)
uint8_t type
Definition: detect.h:314
const char * desc
Definition: detect.h:1195
#define FAIL
Definition: util-unittest.h:60
SigMatchCtx * ctx
Definition: detect.h:316
const char * alias
Definition: detect.h:1194
int mpm_default_matcher
Definition: util-mpm.h:170
#define DETECT_ENGINE_INSPECT_SIG_NO_MATCH
MpmTableElmt mpm_table[MPM_TABLE_SIZE]
Definition: util-mpm.h:169
#define SCFree(a)
Definition: util-mem.h:322
uint16_t tx_id
struct DetectBufferMpmRegistery_::@94::@96 app_v2
void InspectionBufferSetup(InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len)
setup the buffer with our initial data
MpmThreadCtx mtcu
Definition: detect.h:1093
void InspectionBufferApplyTransforms(InspectionBuffer *buffer, const DetectEngineTransforms *transforms)
#define SIGMATCH_NOOPT
Definition: detect.h:1362
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
#define STREAM_TOSERVER
Definition: stream.h:31
#define SCReturnPtr(x, type)
Definition: util-debug.h:353
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself...
InspectionBufferMultipleForList * InspectionBufferGetMulti(DetectEngineThreadCtx *det_ctx, const int list_id)
int inspection_recursion_counter
Definition: detect.h:1072
#define PKT_HAS_FLOW
Definition: decode.h:1090
struct RSDNSState_ RSDNSState
#define DETECT_CI_FLAGS_SINGLE
uint32_t inspect_len
Definition: detect.h:340
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
int DetectBufferSetActiveList(Signature *s, const int list)
const uint8_t * inspect
Definition: detect.h:338
void DetectBufferTypeSetDescriptionByName(const char *name, const char *desc)
uint32_t(* Search)(const struct MpmCtx_ *, struct MpmThreadCtx_ *, PrefilterRuleStore *, const uint8_t *, uint32_t)
Definition: util-mpm.h:162
int PrefilterAppendTxEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh, void(*PrefilterTxFunc)(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f, void *tx, const uint64_t idx, const uint8_t flags), AppProto alproto, int tx_min_progress, void *pectx, void(*FreeFunc)(void *pectx), const char *name)
Per thread variable structure.
Definition: threadvars.h:57
const DetectEngineTransforms * transforms
#define FLOW_PKT_TOCLIENT
Definition: flow.h:202
AppProto alproto
application level protocol
Definition: flow.h:409
uint32_t flags
Definition: decode.h:443
InspectionBuffer * InspectionBufferMultipleForListGet(InspectionBufferMultipleForList *fb, uint32_t local_id)
for a InspectionBufferMultipleForList get a InspectionBuffer
uint16_t flags
Definition: detect.h:1187
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
uint8_t protomap
Definition: flow.h:404
Flow data structure.
Definition: flow.h:325
#define FLOW_IPV4
Definition: flow.h:94
uint32_t flags
Definition: flow.h:379
#define PKT_STREAM_EST
Definition: decode.h:1088
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback)
register inspect engine at start up time
void(* RegisterTests)(void)
Definition: detect.h:1185
a single match condition for a signature
Definition: detect.h:313
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
const DetectEngineTransforms * transforms
Definition: detect.h:411
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, uint8_t *input, uint32_t input_len)
DetectEngineCtx * DetectEngineCtxInit(void)
int DetectEngineInspectDnsRequest(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)