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-parser.h"
58 #include "detect-dns-query.h"
59 #include "detect-engine-dns.h"
60 
61 #include "util-unittest-helper.h"
62 #include "rust.h"
63 
64 static int DetectDnsQuerySetup (DetectEngineCtx *, Signature *, const char *);
65 static void DetectDnsQueryRegisterTests(void);
66 static int g_dns_query_buffer_id = 0;
67 
69  int local_id; /**< used as index into thread inspect array */
70  void *txv;
71 };
72 
73 static InspectionBuffer *DnsQueryGetData(DetectEngineThreadCtx *det_ctx,
74  const DetectEngineTransforms *transforms,
75  Flow *f, struct DnsQueryGetDataArgs *cbdata, int list_id, bool first)
76 {
77  SCEnter();
78 
81  if (buffer == NULL)
82  return NULL;
83  if (!first && buffer->inspect != NULL)
84  return buffer;
85 
86  const uint8_t *data;
87  uint32_t data_len;
88  if (rs_dns_tx_get_query_name(cbdata->txv, (uint16_t)cbdata->local_id,
89  &data, &data_len) == 0) {
90  return NULL;
91  }
92  InspectionBufferSetup(buffer, data, data_len);
93  InspectionBufferApplyTransforms(buffer, transforms);
94 
95  SCReturnPtr(buffer, "InspectionBuffer");
96 }
97 
98 static int DetectEngineInspectDnsQuery(
100  const DetectEngineAppInspectionEngine *engine,
101  const Signature *s,
102  Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
103 {
104  int local_id = 0;
105 
106  const DetectEngineTransforms *transforms = NULL;
107  if (!engine->mpm) {
108  transforms = engine->v2.transforms;
109  }
110 
111  while(1) {
112  struct DnsQueryGetDataArgs cbdata = { local_id, txv, };
113  InspectionBuffer *buffer = DnsQueryGetData(det_ctx,
114  transforms, f, &cbdata, engine->sm_list, false);
115  if (buffer == NULL || buffer->inspect == NULL)
116  break;
117 
118  det_ctx->buffer_offset = 0;
119  det_ctx->discontinue_matching = 0;
120  det_ctx->inspection_recursion_counter = 0;
121 
122  const int match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd,
123  NULL, f,
124  (uint8_t *)buffer->inspect,
125  buffer->inspect_len,
128  if (match == 1) {
130  }
131  local_id++;
132  }
134 }
135 
136 typedef struct PrefilterMpmDnsQuery {
137  int list_id;
138  const MpmCtx *mpm_ctx;
141 
142 /** \brief DnsQuery DnsQuery Mpm prefilter callback
143  *
144  * \param det_ctx detection engine thread ctx
145  * \param p packet to inspect
146  * \param f flow to inspect
147  * \param txv tx to inspect
148  * \param pectx inspection context
149  */
150 static void PrefilterTxDnsQuery(DetectEngineThreadCtx *det_ctx,
151  const void *pectx,
152  Packet *p, Flow *f, void *txv,
153  const uint64_t idx, const uint8_t flags)
154 {
155  SCEnter();
156 
157  const PrefilterMpmDnsQuery *ctx = (const PrefilterMpmDnsQuery *)pectx;
158  const MpmCtx *mpm_ctx = ctx->mpm_ctx;
159  const int list_id = ctx->list_id;
160 
161  int local_id = 0;
162  while(1) {
163  // loop until we get a NULL
164 
165  struct DnsQueryGetDataArgs cbdata = { local_id, txv };
166  InspectionBuffer *buffer = DnsQueryGetData(det_ctx, ctx->transforms,
167  f, &cbdata, list_id, true);
168  if (buffer == NULL)
169  break;
170 
171  if (buffer->inspect_len >= mpm_ctx->minlen) {
172  (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
173  &det_ctx->mtcu, &det_ctx->pmq,
174  buffer->inspect, buffer->inspect_len);
175  }
176 
177  local_id++;
178  }
179 }
180 
181 static void PrefilterMpmDnsQueryFree(void *ptr)
182 {
183  SCFree(ptr);
184 }
185 
186 static int PrefilterMpmDnsQueryRegister(DetectEngineCtx *de_ctx,
187  SigGroupHead *sgh, MpmCtx *mpm_ctx,
188  const DetectBufferMpmRegistery *mpm_reg, int list_id)
189 {
190  PrefilterMpmDnsQuery *pectx = SCCalloc(1, sizeof(*pectx));
191  if (pectx == NULL)
192  return -1;
193  pectx->list_id = list_id;
194  pectx->mpm_ctx = mpm_ctx;
195  pectx->transforms = &mpm_reg->transforms;
196 
197  return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxDnsQuery,
198  mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress,
199  pectx, PrefilterMpmDnsQueryFree, mpm_reg->pname);
200 }
201 
202 
203 /**
204  * \brief Registration function for keyword: dns_query
205  */
207 {
208  sigmatch_table[DETECT_AL_DNS_QUERY].name = "dns.query";
210  sigmatch_table[DETECT_AL_DNS_QUERY].desc = "sticky buffer to match DNS query-buffer";
211  sigmatch_table[DETECT_AL_DNS_QUERY].url = DOC_URL DOC_VERSION "/rules/dns-keywords.html#dns-query";
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  void *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 
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 
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)
338  if (det_ctx != NULL)
339  DetectEngineThreadCtxDeinit(&tv, det_ctx);
340  if (de_ctx != NULL)
342  if (de_ctx != NULL)
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  void *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 
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 
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);
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);
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)
512  if (det_ctx != NULL)
513  DetectEngineThreadCtxDeinit(&tv, det_ctx);
514  if (de_ctx != NULL)
516  if (de_ctx != NULL)
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  void *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 
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 
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)
602  if (det_ctx != NULL)
603  DetectEngineThreadCtxDeinit(&tv, det_ctx);
604  if (de_ctx != NULL)
606  if (de_ctx != NULL)
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  void *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 
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 
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);
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)
716  if (det_ctx != NULL)
717  DetectEngineThreadCtxDeinit(&tv, det_ctx);
718  if (de_ctx != NULL)
720  if (de_ctx != NULL)
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  void *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 
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 
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);
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);
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);
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)
927  if (det_ctx != NULL)
928  DetectEngineThreadCtxDeinit(&tv, det_ctx);
929  if (de_ctx != NULL)
931  if (de_ctx != NULL)
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  void *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 
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 
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)
1023  if (det_ctx != NULL)
1024  DetectEngineThreadCtxDeinit(&tv, det_ctx);
1025  if (de_ctx != NULL)
1027  if (de_ctx != NULL)
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  void *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 
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 
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);
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);
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)
1212  if (det_ctx != NULL)
1213  DetectEngineThreadCtxDeinit(&tv, det_ctx);
1214  if (de_ctx != NULL)
1216  if (de_ctx != NULL)
1218 
1219  FLOW_DESTROY(&f);
1220  UTHFreePacket(p1);
1221  UTHFreePacket(p2);
1222  UTHFreePacket(p3);
1223  PASS;
1224 }
1225 
1226 static int DetectDnsQueryIsdataatParseTest(void)
1227 {
1230  de_ctx->flags |= DE_QUIET;
1231 
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 
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 }
DetectEngineInspectDnsRequest
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)
Definition: detect-engine-dns.c:50
DetectEngineAppInspectionEngine_
Definition: detect.h:395
SigTableElmt_::url
const char * url
Definition: detect.h:1204
DetectSignatureSetAppProto
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:1459
detect-content.h
MpmCtx_::mpm_type
uint8_t mpm_type
Definition: util-mpm.h:90
DetectEngineThreadCtx_::buffer_offset
uint32_t buffer_offset
Definition: detect.h:1033
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SIGMATCH_INFO_STICKY_BUFFER
#define SIGMATCH_INFO_STICKY_BUFFER
Definition: detect.h:1394
SigTableElmt_::desc
const char * desc
Definition: detect.h:1203
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1077
flow-util.h
ALPROTO_DNS
@ ALPROTO_DNS
Definition: app-layer-protos.h:41
SigTableElmt_::name
const char * name
Definition: detect.h:1201
stream-tcp.h
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1337
SCFree
#define SCFree(a)
Definition: util-mem.h:322
DetectEngineTransforms
Definition: detect.h:369
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DetectIsdataatData_::flags
uint8_t flags
Definition: detect-isdataat.h:37
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE
@ DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE
Definition: detect-engine-content-inspection.h:35
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:562
detect-isdataat.h
Flow_::proto
uint8_t proto
Definition: flow.h:361
DetectBufferMpmRegistery_::transforms
DetectEngineTransforms transforms
Definition: detect.h:618
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:138
InspectionBuffer
Definition: detect.h:342
Packet_::flags
uint32_t flags
Definition: decode.h:444
DnsQueryGetDataArgs::txv
void * txv
Definition: detect-dns-query.c:70
threads.h
detect-engine-dns.h
Flow_
Flow data structure.
Definition: flow.h:342
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1103
Flow_::protomap
uint8_t protomap
Definition: flow.h:420
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1195
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:761
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2030
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:279
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:218
rust.h
DE_QUIET
#define DE_QUIET
Definition: detect.h:292
DetectBufferMpmRegistery_
one time registration of keywords at start up
Definition: detect.h:605
DetectIsdataatData_
Definition: detect-isdataat.h:35
DetectEngineContentInspection
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.
Definition: detect-engine-content-inspection.c:103
DnsQueryGetDataArgs::local_id
int local_id
Definition: detect-dns-query.c:69
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:440
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:237
UTHBuildPacketReal
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...
Definition: util-unittest-helper.c:167
Flow_::protoctx
void * protoctx
Definition: flow.h:416
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1187
DetectEngineCtx_::mpm_matcher
uint16_t mpm_matcher
Definition: detect.h:810
detect-pcre.h
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:94
detect-engine-prefilter.h
DetectEngineThreadCtx_::mtcu
MpmThreadCtx mtcu
Definition: detect.h:1101
util-unittest.h
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
FLOWLOCK_UNLOCK
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:260
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:860
detect-dns-query.h
DetectEngineAppInspectionEngine_::sm_list
uint16_t sm_list
Definition: detect.h:401
SignatureInitData_::smlists_tail
struct SigMatch_ ** smlists_tail
Definition: detect.h:518
InspectionBufferMultipleForList
Definition: detect.h:362
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:236
decode.h
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:16
DetectEngineThreadCtx_
Definition: detect.h:1004
STREAM_TOSERVER
#define STREAM_TOSERVER
Definition: stream.h:31
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:19
FLOWLOCK_WRLOCK
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:257
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:337
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
DetectEngineAppInspectionEngine_::mpm
uint16_t mpm
Definition: detect.h:399
DETECT_ENGINE_INSPECT_SIG_MATCH
#define DETECT_ENGINE_INSPECT_SIG_MATCH
Definition: detect-engine-state.h:39
InspectionBuffer::inspect_offset
uint64_t inspect_offset
Definition: detect.h:344
app-layer-parser.h
MpmCtx_::minlen
uint16_t minlen
Definition: util-mpm.h:99
TRUE
#define TRUE
Definition: suricata-common.h:33
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:321
SigMatchSignatures
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1665
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:1947
FlowGetProtoMapping
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:95
Packet_
Definition: decode.h:408
SCCalloc
#define SCCalloc(nm, a)
Definition: util-mem.h:253
ISDATAAT_RELATIVE
#define ISDATAAT_RELATIVE
Definition: detect-isdataat.h:27
StreamTcpFreeConfig
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
DetectAppLayerInspectEngineRegister2
void DetectAppLayerInspectEngineRegister2(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr2 Callback2, InspectionBufferGetDataPtr GetData)
register inspect engine at start up time
Definition: detect-engine.c:231
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:591
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:353
ISDATAAT_RAWBYTES
#define ISDATAAT_RAWBYTES
Definition: detect-isdataat.h:28
MpmTableElmt_::Search
uint32_t(* Search)(const struct MpmCtx_ *, struct MpmThreadCtx_ *, PrefilterRuleStore *, const uint8_t *, uint32_t)
Definition: util-mpm.h:162
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:219
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1876
SigMatch_::type
uint8_t type
Definition: detect.h:319
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:253
detect-engine-content-inspection.h
DetectEngineThreadCtx_::discontinue_matching
uint16_t discontinue_matching
Definition: detect.h:1068
DetectEngineAppInspectionEngine_::smd
SigMatchData * smd
Definition: detect.h:419
DetectAppLayerMpmRegister2
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
Definition: detect-engine-mpm.c:89
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2316
Packet_::flow
struct Flow_ * flow
Definition: decode.h:446
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:2726
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
DETECT_CI_FLAGS_SINGLE
#define DETECT_CI_FLAGS_SINGLE
Definition: detect-engine-content-inspection.h:46
DetectBufferMpmRegistery_::pname
char pname[32]
Definition: detect.h:607
flags
uint8_t flags
Definition: decode-gre.h:2
SigTableElmt_::alias
const char * alias
Definition: detect.h:1202
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1181
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:2934
DetectEngineInspectDnsResponse
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)
Definition: detect-engine-dns.c:59
InspectionBufferSetup
void InspectionBufferSetup(InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len)
setup the buffer with our initial data
Definition: detect-engine.c:1100
InspectionBufferApplyTransforms
void InspectionBufferApplyTransforms(InspectionBuffer *buffer, const DetectEngineTransforms *transforms)
Definition: detect-engine.c:1148
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
DetectEngineThreadCtx_::inspection_recursion_counter
int inspection_recursion_counter
Definition: detect.h:1080
util-spm.h
STREAM_TOCLIENT
#define STREAM_TOCLIENT
Definition: stream.h:32
DOC_URL
#define DOC_URL
Definition: suricata.h:86
PrefilterMpmDnsQuery::transforms
const DetectEngineTransforms * transforms
Definition: detect-dns-query.c:139
DetectDnsQueryRegister
void DetectDnsQueryRegister(void)
Registration function for keyword: dns_query.
Definition: detect-dns-query.c:206
DETECT_ENGINE_INSPECT_SIG_NO_MATCH
#define DETECT_ENGINE_INSPECT_SIG_NO_MATCH
Definition: detect-engine-state.h:38
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
ISDATAAT_NEGATED
#define ISDATAAT_NEGATED
Definition: detect-isdataat.h:29
InspectionBuffer::inspect_len
uint32_t inspect_len
Definition: detect.h:345
InspectionBuffer::inspect
const uint8_t * inspect
Definition: detect.h:343
str
#define str(s)
Definition: suricata-common.h:256
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:410
Flow_::alstate
void * alstate
Definition: flow.h:454
mpm_default_matcher
int mpm_default_matcher
Definition: util-mpm.c:49
Flow_::flags
uint32_t flags
Definition: flow.h:396
detect-parse.h
Signature_
Signature container.
Definition: detect.h:522
SigMatch_
a single match condition for a signature
Definition: detect.h:318
FAIL
#define FAIL
Definition: util-unittest.h:60
PrefilterAppendTxEngine
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)
Definition: detect-engine-prefilter.c:257
DETECT_ISDATAAT
@ DETECT_ISDATAAT
Definition: detect-engine-register.h:78
DetectEngineAppInspectionEngine_::transforms
const DetectEngineTransforms * transforms
Definition: detect.h:416
StreamTcpInitConfig
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:220
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:1985
PrefilterMpmDnsQuery::mpm_ctx
const MpmCtx * mpm_ctx
Definition: detect-dns-query.c:138
mpm_table
MpmTableElmt mpm_table[MPM_TABLE_SIZE]
Definition: util-mpm.c:48
DETECT_AL_DNS_QUERY
@ DETECT_AL_DNS_QUERY
Definition: detect-engine-register.h:197
DnsQueryGetDataArgs
Definition: detect-dns-query.c:68
InspectionBufferGetMulti
InspectionBufferMultipleForList * InspectionBufferGetMulti(DetectEngineThreadCtx *det_ctx, const int list_id)
Definition: detect-engine.c:1080
SIGMATCH_NOOPT
#define SIGMATCH_NOOPT
Definition: detect.h:1370
PrefilterMpmDnsQuery
Definition: detect-dns-query.c:136
DetectBufferSetActiveList
int DetectBufferSetActiveList(Signature *s, const int list)
Definition: detect-engine.c:972
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:762
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:85
DetectBufferTypeSetDescriptionByName
void DetectBufferTypeSetDescriptionByName(const char *name, const char *desc)
Definition: detect-engine.c:888
MpmCtx_
Definition: util-mpm.h:88
TcpSession_
Definition: stream-tcp-private.h:260
flow.h
DetectAppLayerInspectEngineRegister
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback)
register inspect engine at start up time
Definition: detect-engine.c:170
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:425
PrefilterMpmDnsQuery::list_id
int list_id
Definition: detect-dns-query.c:137
flow-var.h
PrefilterMpmDnsQuery
struct PrefilterMpmDnsQuery PrefilterMpmDnsQuery
DetectBufferMpmRegistery_::app_v2
struct DetectBufferMpmRegistery_::@96::@98 app_v2
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
DOC_VERSION
#define DOC_VERSION
Definition: suricata.h:91
InspectionBufferMultipleForListGet
InspectionBuffer * InspectionBufferMultipleForListGet(InspectionBufferMultipleForList *fb, uint32_t local_id)
for a InspectionBufferMultipleForList get a InspectionBuffer
Definition: detect-engine.c:1054
debug.h
DetectEngineAppInspectionEngine_::v2
struct DetectEngineAppInspectionEngine_::@94 v2
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1075
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1193
app-layer.h