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].url = DOC_URL DOC_VERSION "/rules/dns-keywords.html#dns-query";
213  sigmatch_table[DETECT_AL_DNS_QUERY].Setup = DetectDnsQuerySetup;
214  sigmatch_table[DETECT_AL_DNS_QUERY].RegisterTests = DetectDnsQueryRegisterTests;
217 
219  PrefilterMpmDnsQueryRegister, NULL,
220  ALPROTO_DNS, 1);
221 
224  DetectEngineInspectDnsQuery, NULL);
225 
227  "dns request query");
228 
229  g_dns_query_buffer_id = DetectBufferTypeGetByName("dns_query");
230 
231  /* register these generic engines from here for now */
238 
240  "dns requests");
242  "dns responses");
243 }
244 
245 
246 /**
247  * \brief setup the dns_query sticky buffer keyword used in the rule
248  *
249  * \param de_ctx Pointer to the Detection Engine Context
250  * \param s Pointer to the Signature to which the current keyword belongs
251  * \param str Should hold an empty string always
252  *
253  * \retval 0 On success
254  * \retval -1 On failure
255  */
256 
257 static int DetectDnsQuerySetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
258 {
259  if (DetectBufferSetActiveList(s, g_dns_query_buffer_id) < 0)
260  return -1;
262  return -1;
263  return 0;
264 }
265 
266 #ifdef UNITTESTS
267 #include "detect-isdataat.h"
268 
269 /** \test simple google.com query matching */
270 static int DetectDnsQueryTest01(void)
271 {
272  /* google.com */
273  uint8_t buf[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
274  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
276  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
277  0x00, 0x10, 0x00, 0x01, };
278  Flow f;
279  RSDNSState *dns_state = NULL;
280  Packet *p = NULL;
281  Signature *s = NULL;
282  ThreadVars tv;
283  DetectEngineThreadCtx *det_ctx = NULL;
285 
286  memset(&tv, 0, sizeof(ThreadVars));
287  memset(&f, 0, sizeof(Flow));
288 
289  p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP,
290  "192.168.1.5", "192.168.1.1",
291  41424, 53);
292 
293  FLOW_INITIALIZE(&f);
294  f.flags |= FLOW_IPV4;
295  f.proto = IPPROTO_UDP;
297 
298  p->flow = &f;
299  p->flags |= PKT_HAS_FLOW;
301  f.alproto = ALPROTO_DNS;
302 
304  FAIL_IF_NULL(de_ctx);
306  de_ctx->flags |= DE_QUIET;
307 
308  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
309  "(msg:\"Test dns_query option\"; "
310  "dns_query; content:\"google\"; nocase; sid:1;)");
311  FAIL_IF_NULL(s);
312 
313  SigGroupBuild(de_ctx);
314  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
315 
316  FLOWLOCK_WRLOCK(&f);
317  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
318  STREAM_TOSERVER, buf, sizeof(buf));
319  if (r != 0) {
320  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
321  FLOWLOCK_UNLOCK(&f);
322  FAIL;
323  }
324  FLOWLOCK_UNLOCK(&f);
325 
326  dns_state = f.alstate;
327  FAIL_IF_NULL(dns_state);
328 
329  /* do detect */
330  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
331 
332  if (!(PacketAlertCheck(p, 1))) {
333  printf("sig 1 didn't alert, but it should have: ");
334  FAIL;
335  }
336 
337  if (alp_tctx != NULL)
338  AppLayerParserThreadCtxFree(alp_tctx);
339  if (det_ctx != NULL)
340  DetectEngineThreadCtxDeinit(&tv, det_ctx);
341  if (de_ctx != NULL)
342  SigGroupCleanup(de_ctx);
343  if (de_ctx != NULL)
344  DetectEngineCtxFree(de_ctx);
345 
346  FLOW_DESTROY(&f);
347  UTHFreePacket(p);
348  PASS;
349 }
350 
351 /** \test multi tx google.(com|net) query matching */
352 static int DetectDnsQueryTest02(void)
353 {
354  /* google.com */
355  uint8_t buf1[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
356  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
358  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
359  0x00, 0x01, 0x00, 0x01, };
360 
361  uint8_t buf2[] = { 0x10, 0x32, /* tx id */
362  0x81, 0x80, /* flags: resp, recursion desired, recusion available */
363  0x00, 0x01, /* 1 query */
364  0x00, 0x01, /* 1 answer */
365  0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
366  /* query record */
367  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
368  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
369  0x00, 0x01, 0x00, 0x01, /* type a, class in */
370  /* answer */
371  0xc0, 0x0c, /* ref to name in query above */
372  0x00, 0x01, 0x00, 0x01, /* type a, class in */
373  0x00, 0x01, 0x40, 0xef, /* ttl */
374  0x00, 0x04, /* data len */
375  0x01, 0x02, 0x03, 0x04 }; /* addr */
376 
377  /* google.net */
378  uint8_t buf3[] = { 0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
379  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
381  0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
382  0x00, 0x10, 0x00, 0x01, };
383  Flow f;
384  RSDNSState *dns_state = NULL;
385  Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
386  Signature *s = NULL;
387  ThreadVars tv;
388  DetectEngineThreadCtx *det_ctx = NULL;
390 
391  memset(&tv, 0, sizeof(ThreadVars));
392  memset(&f, 0, sizeof(Flow));
393 
394  p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
395  "192.168.1.5", "192.168.1.1",
396  41424, 53);
397  p2 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
398  "192.168.1.5", "192.168.1.1",
399  41424, 53);
400  p3 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
401  "192.168.1.5", "192.168.1.1",
402  41424, 53);
403 
404  FLOW_INITIALIZE(&f);
405  f.flags |= FLOW_IPV4;
406  f.proto = IPPROTO_UDP;
408  f.alproto = ALPROTO_DNS;
409 
410  p1->flow = &f;
411  p1->flags |= PKT_HAS_FLOW;
413  p1->pcap_cnt = 1;
414 
415  p2->flow = &f;
416  p2->flags |= PKT_HAS_FLOW;
417  p2->flowflags |= FLOW_PKT_TOCLIENT;
418  p2->pcap_cnt = 2;
419 
420  p3->flow = &f;
421  p3->flags |= PKT_HAS_FLOW;
422  p3->flowflags |= FLOW_PKT_TOSERVER;
423  p3->pcap_cnt = 3;
424 
426  FAIL_IF_NULL(de_ctx);
428  de_ctx->flags |= DE_QUIET;
429 
430  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
431  "(msg:\"Test dns_query option\"; "
432  "dns_query; content:\"google.com\"; nocase; sid:1;)");
433  FAIL_IF_NULL(s);
434  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
435  "(msg:\"Test dns_query option\"; "
436  "dns_query; content:\"google.net\"; nocase; sid:2;)");
437  FAIL_IF_NULL(s);
438 
439  SigGroupBuild(de_ctx);
440  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
441 
442  FLOWLOCK_WRLOCK(&f);
443  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
444  STREAM_TOSERVER, buf1, sizeof(buf1));
445  if (r != 0) {
446  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
447  FLOWLOCK_UNLOCK(&f);
448  FAIL;
449  }
450  FLOWLOCK_UNLOCK(&f);
451 
452  dns_state = f.alstate;
453  FAIL_IF_NULL(dns_state);
454 
455  /* do detect */
456  SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
457 
458  if (!(PacketAlertCheck(p1, 1))) {
459  printf("(p1) sig 1 didn't alert, but it should have: ");
460  FAIL;
461  }
462  if (PacketAlertCheck(p1, 2)) {
463  printf("(p1) sig 2 did alert, but it should not have: ");
464  FAIL;
465  }
466 
467  FLOWLOCK_WRLOCK(&f);
468  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
469  buf2, sizeof(buf2));
470  if (r != 0) {
471  printf("toserver client 1 returned %" PRId32 ", expected 0: ", r);
472  FLOWLOCK_UNLOCK(&f);
473  FAIL;
474  }
475  FLOWLOCK_UNLOCK(&f);
476 
477  /* do detect */
478  SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
479 
480  if (PacketAlertCheck(p2, 1)) {
481  printf("(p2) sig 1 alerted, but it should not have: ");
482  FAIL;
483  }
484  if (PacketAlertCheck(p2, 2)) {
485  printf("(p2) sig 2 alerted, but it should not have: ");
486  FAIL;
487  }
488 
489  FLOWLOCK_WRLOCK(&f);
490  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
491  buf3, sizeof(buf3));
492  if (r != 0) {
493  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
494  FLOWLOCK_UNLOCK(&f);
495  FAIL;
496  }
497  FLOWLOCK_UNLOCK(&f);
498 
499  /* do detect */
500  SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
501 
502  if (PacketAlertCheck(p3, 1)) {
503  printf("(p3) sig 1 alerted, but it should not have: ");
504  FAIL;
505  }
506  if (!(PacketAlertCheck(p3, 2))) {
507  printf("(p3) sig 2 didn't alert, but it should have: ");
508  FAIL;
509  }
510 
511  if (alp_tctx != NULL)
512  AppLayerParserThreadCtxFree(alp_tctx);
513  if (det_ctx != NULL)
514  DetectEngineThreadCtxDeinit(&tv, det_ctx);
515  if (de_ctx != NULL)
516  SigGroupCleanup(de_ctx);
517  if (de_ctx != NULL)
518  DetectEngineCtxFree(de_ctx);
519 
520  FLOW_DESTROY(&f);
521  UTHFreePacket(p1);
522  UTHFreePacket(p2);
523  UTHFreePacket(p3);
524  PASS;
525 }
526 
527 /** \test simple google.com query matching (TCP) */
528 static int DetectDnsQueryTest03(void)
529 {
530  /* google.com */
531  uint8_t buf[] = { 0x00, 28,
532  0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
533  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
535  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
536  0x00, 0x10, 0x00, 0x01, };
537  Flow f;
538  RSDNSState *dns_state = NULL;
539  Packet *p = NULL;
540  Signature *s = NULL;
541  ThreadVars tv;
542  DetectEngineThreadCtx *det_ctx = NULL;
543  TcpSession ssn;
545 
546  memset(&tv, 0, sizeof(ThreadVars));
547  memset(&f, 0, sizeof(Flow));
548  memset(&ssn, 0, sizeof(TcpSession));
549 
550  p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_TCP,
551  "192.168.1.5", "192.168.1.1",
552  41424, 53);
553 
554  FLOW_INITIALIZE(&f);
555  f.protoctx = (void *)&ssn;
556  f.flags |= FLOW_IPV4;
557  f.proto = IPPROTO_TCP;
559 
560  p->flow = &f;
563  f.alproto = ALPROTO_DNS;
564 
566 
568  FAIL_IF_NULL(de_ctx);
570  de_ctx->flags |= DE_QUIET;
571 
572  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
573  "(msg:\"Test dns_query option\"; "
574  "dns_query; content:\"google\"; nocase; sid:1;)");
575  FAIL_IF_NULL(s);
576 
577  SigGroupBuild(de_ctx);
578  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
579 
580  FLOWLOCK_WRLOCK(&f);
581  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
582  STREAM_TOSERVER, buf, sizeof(buf));
583  if (r != 0) {
584  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
585  FLOWLOCK_UNLOCK(&f);
586  FAIL;
587  }
588  FLOWLOCK_UNLOCK(&f);
589 
590  dns_state = f.alstate;
591  FAIL_IF_NULL(dns_state);
592 
593  /* do detect */
594  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
595 
596  if (!(PacketAlertCheck(p, 1))) {
597  printf("sig 1 didn't alert, but it should have: ");
598  FAIL;
599  }
600 
601  if (alp_tctx != NULL)
602  AppLayerParserThreadCtxFree(alp_tctx);
603  if (det_ctx != NULL)
604  DetectEngineThreadCtxDeinit(&tv, det_ctx);
605  if (de_ctx != NULL)
606  SigGroupCleanup(de_ctx);
607  if (de_ctx != NULL)
608  DetectEngineCtxFree(de_ctx);
609 
611  FLOW_DESTROY(&f);
612  UTHFreePacket(p);
613  PASS;
614 }
615 
616 /** \test simple google.com query matching (TCP splicing) */
617 static int DetectDnsQueryTest04(void)
618 {
619  /* google.com */
620  uint8_t buf1[] = { 0x00, 28,
621  0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
622  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
623  uint8_t buf2[] = { 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
624  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
625  0x00, 0x10, 0x00, 0x01, };
626  Flow f;
627  RSDNSState *dns_state = NULL;
628  Packet *p1 = NULL, *p2 = NULL;
629  Signature *s = NULL;
630  ThreadVars tv;
631  DetectEngineThreadCtx *det_ctx = NULL;
632  TcpSession ssn;
634 
635  memset(&tv, 0, sizeof(ThreadVars));
636  memset(&f, 0, sizeof(Flow));
637  memset(&ssn, 0, sizeof(TcpSession));
638 
639  p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_TCP,
640  "192.168.1.5", "192.168.1.1",
641  41424, 53);
642  p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_TCP,
643  "192.168.1.5", "192.168.1.1",
644  41424, 53);
645 
646  FLOW_INITIALIZE(&f);
647  f.protoctx = (void *)&ssn;
648  f.flags |= FLOW_IPV4;
649  f.proto = IPPROTO_TCP;
651  f.alproto = ALPROTO_DNS;
652 
653  p1->flow = &f;
656 
657  p2->flow = &f;
659  p2->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
660 
662 
664  FAIL_IF_NULL(de_ctx);
666  de_ctx->flags |= DE_QUIET;
667 
668  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
669  "(msg:\"Test dns_query option\"; "
670  "dns_query; content:\"google\"; nocase; sid:1;)");
671  FAIL_IF_NULL(s);
672 
673  SigGroupBuild(de_ctx);
674  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
675 
676  FLOWLOCK_WRLOCK(&f);
677  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
678  STREAM_TOSERVER, buf1, sizeof(buf1));
679  if (r != 0) {
680  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
681  FLOWLOCK_UNLOCK(&f);
682  FAIL;
683  }
684  FLOWLOCK_UNLOCK(&f);
685 
686  dns_state = f.alstate;
687  FAIL_IF_NULL(dns_state);
688 
689  /* do detect */
690  SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
691 
692  if (PacketAlertCheck(p1, 1)) {
693  printf("sig 1 alerted, but it should not have: ");
694  FAIL;
695  }
696 
697  FLOWLOCK_WRLOCK(&f);
698  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
699  buf2, sizeof(buf2));
700  if (r != 0) {
701  printf("toserver chunk 1 returned %" PRId32 ", expected 0\n", r);
702  FLOWLOCK_UNLOCK(&f);
703  FAIL;
704  }
705  FLOWLOCK_UNLOCK(&f);
706 
707  /* do detect */
708  SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
709 
710  if (!(PacketAlertCheck(p2, 1))) {
711  printf("sig 1 didn't alert, but it should have: ");
712  FAIL;
713  }
714 
715  if (alp_tctx != NULL)
716  AppLayerParserThreadCtxFree(alp_tctx);
717  if (det_ctx != NULL)
718  DetectEngineThreadCtxDeinit(&tv, det_ctx);
719  if (de_ctx != NULL)
720  SigGroupCleanup(de_ctx);
721  if (de_ctx != NULL)
722  DetectEngineCtxFree(de_ctx);
723 
725  FLOW_DESTROY(&f);
726  UTHFreePacket(p1);
727  UTHFreePacket(p2);
728  PASS;
729 }
730 
731 /** \test simple google.com query matching (TCP splicing) */
732 static int DetectDnsQueryTest05(void)
733 {
734  /* google.com in 2 chunks (buf1 and buf2) */
735  uint8_t buf1[] = { 0x00, 28, /* len 28 */
736  0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
737  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
738 
739  uint8_t buf2[] = { 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
740  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
741  0x00, 0x10, 0x00, 0x01, };
742 
743  uint8_t buf3[] = { 0x00, 44, /* len 44 */
744  0x10, 0x32, /* tx id */
745  0x81, 0x80, /* flags: resp, recursion desired, recusion available */
746  0x00, 0x01, /* 1 query */
747  0x00, 0x01, /* 1 answer */
748  0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
749  /* query record */
750  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
751  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
752  0x00, 0x01, 0x00, 0x01, /* type a, class in */
753  /* answer */
754  0xc0, 0x0c, /* ref to name in query above */
755  0x00, 0x01, 0x00, 0x01, /* type a, class in */
756  0x00, 0x01, 0x40, 0xef, /* ttl */
757  0x00, 0x04, /* data len */
758  0x01, 0x02, 0x03, 0x04 }; /* addr */
759 
760  /* google.net */
761  uint8_t buf4[] = { 0x00, 28, /* len 28 */
762  0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
763  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
764  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
765  0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
766  0x00, 0x10, 0x00, 0x01, };
767  Flow f;
768  RSDNSState *dns_state = NULL;
769  Packet *p1 = NULL, *p2 = NULL, *p3 = NULL, *p4 = NULL;
770  Signature *s = NULL;
771  ThreadVars tv;
772  DetectEngineThreadCtx *det_ctx = NULL;
773  TcpSession ssn;
775 
776  memset(&tv, 0, sizeof(ThreadVars));
777  memset(&f, 0, sizeof(Flow));
778  memset(&ssn, 0, sizeof(TcpSession));
779 
780  p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_TCP,
781  "192.168.1.5", "192.168.1.1",
782  41424, 53);
783  p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_TCP,
784  "192.168.1.5", "192.168.1.1",
785  41424, 53);
786  p3 = UTHBuildPacketReal(buf3, sizeof(buf3), IPPROTO_TCP,
787  "192.168.1.5", "192.168.1.1",
788  41424, 53);
789  p4 = UTHBuildPacketReal(buf4, sizeof(buf4), IPPROTO_TCP,
790  "192.168.1.5", "192.168.1.1",
791  41424, 53);
792 
793  FLOW_INITIALIZE(&f);
794  f.protoctx = (void *)&ssn;
795  f.flags |= FLOW_IPV4;
796  f.proto = IPPROTO_TCP;
798  f.alproto = ALPROTO_DNS;
799 
800  p1->flow = &f;
803 
804  p2->flow = &f;
806  p2->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
807 
808  p3->flow = &f;
810  p3->flowflags |= FLOW_PKT_TOCLIENT|FLOW_PKT_ESTABLISHED;
811 
812  p4->flow = &f;
814  p4->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
815 
817 
819  FAIL_IF_NULL(de_ctx);
821  de_ctx->flags |= DE_QUIET;
822 
823  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
824  "(msg:\"Test dns_query option\"; "
825  "dns_query; content:\"google.com\"; nocase; sid:1;)");
826  FAIL_IF_NULL(s);
827  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
828  "(msg:\"Test dns_query option\"; "
829  "dns_query; content:\"google.net\"; nocase; sid:2;)");
830  FAIL_IF_NULL(s);
831 
832  SigGroupBuild(de_ctx);
833  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
834 
835  FLOWLOCK_WRLOCK(&f);
836  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
837  STREAM_TOSERVER, buf1, sizeof(buf1));
838  if (r != 0) {
839  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
840  FLOWLOCK_UNLOCK(&f);
841  FAIL;
842  }
843  FLOWLOCK_UNLOCK(&f);
844 
845  dns_state = f.alstate;
846  FAIL_IF_NULL(dns_state);
847 
848  /* do detect */
849  SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
850 
851  if (PacketAlertCheck(p1, 1)) {
852  printf("(p1) sig 1 alerted, but it should not have: ");
853  FAIL;
854  }
855  if (PacketAlertCheck(p1, 2)) {
856  printf("(p1) sig 2 did alert, but it should not have: ");
857  FAIL;
858  }
859 
860  FLOWLOCK_WRLOCK(&f);
861  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
862  buf2, sizeof(buf2));
863  if (r != 0) {
864  printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
865  FLOWLOCK_UNLOCK(&f);
866  FAIL;
867  }
868  FLOWLOCK_UNLOCK(&f);
869 
870  /* do detect */
871  SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
872 
873  if (!(PacketAlertCheck(p2, 1))) {
874  printf("sig 1 didn't alert, but it should have: ");
875  FAIL;
876  }
877  if (PacketAlertCheck(p2, 2)) {
878  printf("(p2) sig 2 did alert, but it should not have: ");
879  FAIL;
880  }
881 
882  FLOWLOCK_WRLOCK(&f);
883  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
884  buf3, sizeof(buf3));
885  if (r != 0) {
886  printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r);
887  FLOWLOCK_UNLOCK(&f);
888  FAIL;
889  }
890  FLOWLOCK_UNLOCK(&f);
891 
892  /* do detect */
893  SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
894 
895  if (PacketAlertCheck(p3, 1)) {
896  printf("sig 1 did alert, but it should not have: ");
897  FAIL;
898  }
899  if (PacketAlertCheck(p3, 2)) {
900  printf("(p3) sig 2 did alert, but it should not have: ");
901  FAIL;
902  }
903 
904  FLOWLOCK_WRLOCK(&f);
905  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
906  buf4, sizeof(buf4));
907  if (r != 0) {
908  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
909  FLOWLOCK_UNLOCK(&f);
910  FAIL;
911  }
912  FLOWLOCK_UNLOCK(&f);
913 
914  /* do detect */
915  SigMatchSignatures(&tv, de_ctx, det_ctx, p4);
916 
917  if (PacketAlertCheck(p4, 1)) {
918  printf("(p4) sig 1 did alert, but it should not have: ");
919  FAIL;
920  }
921  if (!(PacketAlertCheck(p4, 2))) {
922  printf("sig 1 didn't alert, but it should have: ");
923  FAIL;
924  }
925 
926  if (alp_tctx != NULL)
927  AppLayerParserThreadCtxFree(alp_tctx);
928  if (det_ctx != NULL)
929  DetectEngineThreadCtxDeinit(&tv, det_ctx);
930  if (de_ctx != NULL)
931  SigGroupCleanup(de_ctx);
932  if (de_ctx != NULL)
933  DetectEngineCtxFree(de_ctx);
934 
936  FLOW_DESTROY(&f);
937  UTHFreePacket(p1);
938  UTHFreePacket(p2);
939  UTHFreePacket(p3);
940  UTHFreePacket(p4);
941  PASS;
942 }
943 
944 /** \test simple google.com query matching, pcre */
945 static int DetectDnsQueryTest06(void)
946 {
947  /* google.com */
948  uint8_t buf[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
949  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
950  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
951  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
952  0x00, 0x10, 0x00, 0x01, };
953  Flow f;
954  RSDNSState *dns_state = NULL;
955  Packet *p = NULL;
956  Signature *s = NULL;
957  ThreadVars tv;
958  DetectEngineThreadCtx *det_ctx = NULL;
960 
961  memset(&tv, 0, sizeof(ThreadVars));
962  memset(&f, 0, sizeof(Flow));
963 
964  p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP,
965  "192.168.1.5", "192.168.1.1",
966  41424, 53);
967 
968  FLOW_INITIALIZE(&f);
969  f.flags |= FLOW_IPV4;
970  f.proto = IPPROTO_UDP;
972 
973  p->flow = &f;
974  p->flags |= PKT_HAS_FLOW;
976  f.alproto = ALPROTO_DNS;
977 
979  FAIL_IF_NULL(de_ctx);
981  de_ctx->flags |= DE_QUIET;
982 
983  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
984  "(msg:\"Test dns_query option\"; "
985  "dns_query; content:\"google\"; nocase; "
986  "pcre:\"/google\\.com$/i\"; sid:1;)");
987  FAIL_IF_NULL(s);
988  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
989  "(msg:\"Test dns_query option\"; "
990  "dns_query; content:\"google\"; nocase; "
991  "pcre:\"/^\\.[a-z]{2,3}$/iR\"; sid:2;)");
992  FAIL_IF_NULL(s);
993 
994  SigGroupBuild(de_ctx);
995  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
996 
997  FLOWLOCK_WRLOCK(&f);
998  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
999  STREAM_TOSERVER, buf, sizeof(buf));
1000  if (r != 0) {
1001  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1002  FLOWLOCK_UNLOCK(&f);
1003  FAIL;
1004  }
1005  FLOWLOCK_UNLOCK(&f);
1006 
1007  dns_state = f.alstate;
1008  FAIL_IF_NULL(dns_state);
1009 
1010  /* do detect */
1011  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1012 
1013  if (!(PacketAlertCheck(p, 1))) {
1014  printf("sig 1 didn't alert, but it should have: ");
1015  FAIL;
1016  }
1017  if (!(PacketAlertCheck(p, 2))) {
1018  printf("sig 2 didn't alert, but it should have: ");
1019  FAIL;
1020  }
1021 
1022  if (alp_tctx != NULL)
1023  AppLayerParserThreadCtxFree(alp_tctx);
1024  if (det_ctx != NULL)
1025  DetectEngineThreadCtxDeinit(&tv, det_ctx);
1026  if (de_ctx != NULL)
1027  SigGroupCleanup(de_ctx);
1028  if (de_ctx != NULL)
1029  DetectEngineCtxFree(de_ctx);
1030 
1031  FLOW_DESTROY(&f);
1032  UTHFreePacket(p);
1033  PASS;
1034 }
1035 
1036 /** \test multi tx google.(com|net) query matching +
1037  * app layer event */
1038 static int DetectDnsQueryTest07(void)
1039 {
1040  /* google.com */
1041  uint8_t buf1[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
1042  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1043  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
1044  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
1045  0x00, 0x01, 0x00, 0x01, };
1046 
1047  uint8_t buf2[] = { 0x10, 0x32, /* tx id */
1048  0x81, 0x80|0x40, /* flags: resp, recursion desired, recusion available */
1049  0x00, 0x01, /* 1 query */
1050  0x00, 0x01, /* 1 answer */
1051  0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
1052  /* query record */
1053  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
1054  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
1055  0x00, 0x01, 0x00, 0x01, /* type a, class in */
1056  /* answer */
1057  0xc0, 0x0c, /* ref to name in query above */
1058  0x00, 0x01, 0x00, 0x01, /* type a, class in */
1059  0x00, 0x01, 0x40, 0xef, /* ttl */
1060  0x00, 0x04, /* data len */
1061  0x01, 0x02, 0x03, 0x04 }; /* addr */
1062 
1063  /* google.net */
1064  uint8_t buf3[] = { 0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
1065  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1066  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
1067  0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
1068  0x00, 0x10, 0x00, 0x01, };
1069  Flow f;
1070  RSDNSState *dns_state = NULL;
1071  Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
1072  Signature *s = NULL;
1073  ThreadVars tv;
1074  DetectEngineThreadCtx *det_ctx = NULL;
1076 
1077  memset(&tv, 0, sizeof(ThreadVars));
1078  memset(&f, 0, sizeof(Flow));
1079 
1080  p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
1081  "192.168.1.5", "192.168.1.1",
1082  41424, 53);
1083  p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_UDP,
1084  "192.168.1.5", "192.168.1.1",
1085  41424, 53);
1086  p3 = UTHBuildPacketReal(buf3, sizeof(buf3), IPPROTO_UDP,
1087  "192.168.1.5", "192.168.1.1",
1088  41424, 53);
1089 
1090  FLOW_INITIALIZE(&f);
1091  f.flags |= FLOW_IPV4;
1092  f.proto = IPPROTO_UDP;
1094  f.alproto = ALPROTO_DNS;
1095 
1096  p1->flow = &f;
1097  p1->flags |= PKT_HAS_FLOW;
1099  p1->pcap_cnt = 1;
1100 
1101  p2->flow = &f;
1102  p2->flags |= PKT_HAS_FLOW;
1103  p2->flowflags |= FLOW_PKT_TOCLIENT;
1104  p2->pcap_cnt = 2;
1105 
1106  p3->flow = &f;
1107  p3->flags |= PKT_HAS_FLOW;
1108  p3->flowflags |= FLOW_PKT_TOSERVER;
1109  p3->pcap_cnt = 3;
1110 
1112  FAIL_IF_NULL(de_ctx);
1113  de_ctx->mpm_matcher = mpm_default_matcher;
1114  de_ctx->flags |= DE_QUIET;
1115 
1116  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
1117  "(msg:\"Test dns_query option\"; "
1118  "dns_query; content:\"google.com\"; nocase; sid:1;)");
1119  FAIL_IF_NULL(s);
1120  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
1121  "(msg:\"Test dns_query option\"; "
1122  "dns_query; content:\"google.net\"; nocase; sid:2;)");
1123  FAIL_IF_NULL(s);
1124  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
1125  "(msg:\"Test Z flag event\"; "
1126  "app-layer-event:dns.z_flag_set; sid:3;)");
1127  FAIL_IF_NULL(s);
1128 
1129  SigGroupBuild(de_ctx);
1130  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
1131 
1132  FLOWLOCK_WRLOCK(&f);
1133  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
1134  STREAM_TOSERVER, buf1, sizeof(buf1));
1135  if (r != 0) {
1136  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1137  FLOWLOCK_UNLOCK(&f);
1138  FAIL;
1139  }
1140  FLOWLOCK_UNLOCK(&f);
1141 
1142  dns_state = f.alstate;
1143  FAIL_IF_NULL(dns_state);
1144 
1145  /* do detect */
1146  SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
1147 
1148  if (!(PacketAlertCheck(p1, 1))) {
1149  printf("(p1) sig 1 didn't alert, but it should have: ");
1150  FAIL;
1151  }
1152  if (PacketAlertCheck(p1, 2)) {
1153  printf("(p1) sig 2 did alert, but it should not have: ");
1154  FAIL;
1155  }
1156 
1157  FLOWLOCK_WRLOCK(&f);
1158  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
1159  buf2, sizeof(buf2));
1160  if (r != -1) {
1161  printf("toserver client 1 returned %" PRId32 ", expected -1\n", r);
1162  FLOWLOCK_UNLOCK(&f);
1163  FAIL;
1164  }
1165  FLOWLOCK_UNLOCK(&f);
1166 
1167  /* do detect */
1168  SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
1169 
1170  if (PacketAlertCheck(p2, 1)) {
1171  printf("(p2) sig 1 alerted, but it should not have: ");
1172  FAIL;
1173  }
1174  if (PacketAlertCheck(p2, 2)) {
1175  printf("(p2) sig 2 alerted, but it should not have: ");
1176  FAIL;
1177  }
1178  if (!(PacketAlertCheck(p2, 3))) {
1179  printf("(p2) sig 3 didn't alert, but it should have: ");
1180  FAIL;
1181  }
1182 
1183  FLOWLOCK_WRLOCK(&f);
1184  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
1185  buf3, sizeof(buf3));
1186  if (r != 0) {
1187  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
1188  FLOWLOCK_UNLOCK(&f);
1189  FAIL;
1190  }
1191  FLOWLOCK_UNLOCK(&f);
1192 
1193  /* do detect */
1194  SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
1195 
1196  if (PacketAlertCheck(p3, 1)) {
1197  printf("(p3) sig 1 alerted, but it should not have: ");
1198  FAIL;
1199  }
1200  if (!(PacketAlertCheck(p3, 2))) {
1201  printf("(p3) sig 2 didn't alert, but it should have: ");
1202  FAIL;
1203  }
1204  /** \todo should not alert, bug #839
1205  if (PacketAlertCheck(p3, 3)) {
1206  printf("(p3) sig 3 did alert, but it should not have: ");
1207  goto end;
1208  }
1209  */
1210 
1211  if (alp_tctx != NULL)
1212  AppLayerParserThreadCtxFree(alp_tctx);
1213  if (det_ctx != NULL)
1214  DetectEngineThreadCtxDeinit(&tv, det_ctx);
1215  if (de_ctx != NULL)
1216  SigGroupCleanup(de_ctx);
1217  if (de_ctx != NULL)
1218  DetectEngineCtxFree(de_ctx);
1219 
1220  FLOW_DESTROY(&f);
1221  UTHFreePacket(p1);
1222  UTHFreePacket(p2);
1223  UTHFreePacket(p3);
1224  PASS;
1225 }
1226 
1227 static int DetectDnsQueryIsdataatParseTest(void)
1228 {
1230  FAIL_IF_NULL(de_ctx);
1231  de_ctx->flags |= DE_QUIET;
1232 
1233  Signature *s = DetectEngineAppendSig(de_ctx,
1234  "alert dns any any -> any any ("
1235  "dns_query; content:\"one\"; "
1236  "isdataat:!4,relative; sid:1;)");
1237  FAIL_IF_NULL(s);
1238 
1239  SigMatch *sm = s->init_data->smlists_tail[g_dns_query_buffer_id];
1240  FAIL_IF_NULL(sm);
1242 
1243  DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
1246  FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
1247 
1248  DetectEngineCtxFree(de_ctx);
1249  PASS;
1250 }
1251 
1252 #endif
1253 
1254 static void DetectDnsQueryRegisterTests(void)
1255 {
1256 #ifdef UNITTESTS
1257  UtRegisterTest("DetectDnsQueryTest01", DetectDnsQueryTest01);
1258  UtRegisterTest("DetectDnsQueryTest02", DetectDnsQueryTest02);
1259  UtRegisterTest("DetectDnsQueryTest03 -- tcp", DetectDnsQueryTest03);
1260  UtRegisterTest("DetectDnsQueryTest04 -- tcp splicing",
1261  DetectDnsQueryTest04);
1262  UtRegisterTest("DetectDnsQueryTest05 -- tcp splicing/multi tx",
1263  DetectDnsQueryTest05);
1264  UtRegisterTest("DetectDnsQueryTest06 -- pcre", DetectDnsQueryTest06);
1265  UtRegisterTest("DetectDnsQueryTest07 -- app layer event",
1266  DetectDnsQueryTest07);
1267 
1268  UtRegisterTest("DetectDnsQueryIsdataatParseTest",
1269  DetectDnsQueryIsdataatParseTest);
1270 #endif
1271 }
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:1448
SignatureInitData * init_data
Definition: detect.h:591
uint16_t flags
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
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:446
uint16_t minlen
Definition: util-mpm.h:99
struct DetectEngineAppInspectionEngine_::@93 v2
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:1067
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:618
struct DetectBufferMpmRegistery_::@95::@97 app_v2
#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:1336
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:668
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:240
uint64_t pcap_cnt
Definition: decode.h:562
uint32_t buffer_offset
Definition: detect.h:1032
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
#define ISDATAAT_RAWBYTES
const char * name
Definition: detect.h:1200
Signature container.
Definition: detect.h:522
#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
main detection engine ctx
Definition: detect.h:761
struct PrefilterMpmDnsQuery PrefilterMpmDnsQuery
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
void * alstate
Definition: flow.h:438
#define DE_QUIET
Definition: detect.h:292
int DetectBufferTypeGetByName(const char *name)
#define str(s)
#define SCCalloc(nm, a)
Definition: util-mem.h:253
#define SIG_FLAG_TOCLIENT
Definition: detect.h:237
#define SIGMATCH_INFO_STICKY_BUFFER
Definition: detect.h:1393
uint8_t flags
Definition: detect.h:762
#define DETECT_ENGINE_INSPECT_SIG_MATCH
const MpmCtx * mpm_ctx
uint64_t inspect_offset
Definition: detect.h:344
#define ISDATAAT_NEGATED
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
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:810
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
one time registration of keywords at start up
Definition: detect.h:605
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:236
#define SCEnter(...)
Definition: util-debug.h:337
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:364
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:1102
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:440
#define STREAM_TOCLIENT
Definition: stream.h:32
#define FLOW_PKT_TOSERVER
Definition: flow.h:201
struct SigMatch_ ** smlists_tail
Definition: detect.h:518
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:319
const char * desc
Definition: detect.h:1202
#define FAIL
Definition: util-unittest.h:60
SigMatchCtx * ctx
Definition: detect.h:321
const char * alias
Definition: detect.h:1201
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
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:1100
void InspectionBufferApplyTransforms(InspectionBuffer *buffer, const DetectEngineTransforms *transforms)
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
#define SIGMATCH_NOOPT
Definition: detect.h:1369
const char * url
Definition: detect.h:1203
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const 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 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:1079
#define PKT_HAS_FLOW
Definition: decode.h:1094
struct RSDNSState_ RSDNSState
#define DETECT_CI_FLAGS_SINGLE
uint32_t inspect_len
Definition: detect.h:345
#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:343
#define DOC_URL
Definition: suricata.h:86
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:444
#define DOC_VERSION
Definition: suricata.h:91
InspectionBuffer * InspectionBufferMultipleForListGet(InspectionBufferMultipleForList *fb, uint32_t local_id)
for a InspectionBufferMultipleForList get a InspectionBuffer
uint16_t flags
Definition: detect.h:1194
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:1092
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:1192
a single match condition for a signature
Definition: detect.h:318
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
const DetectEngineTransforms * transforms
Definition: detect.h:416
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)