]> git.ipfire.org Git - people/ms/suricata.git/blame - src/detect-dns-query.c
mpm/spm: check for SSSE3 and enable/disable HS
[people/ms/suricata.git] / src / detect-dns-query.c
CommitLineData
f10dd603
VJ
1/* Copyright (C) 2013 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \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"
40#include "detect-content.h"
41#include "detect-pcre.h"
42
43#include "flow.h"
e567e122 44#include "flow-util.h"
f10dd603
VJ
45#include "flow-var.h"
46
47#include "util-debug.h"
48#include "util-unittest.h"
49#include "util-spm.h"
50#include "util-print.h"
51
429c6388
AS
52#include "stream-tcp.h"
53
f10dd603 54#include "app-layer.h"
e567e122 55#include "app-layer-dns-common.h"
f10dd603 56#include "detect-dns-query.h"
57ae3c43 57#include "detect-engine-dns.h"
f10dd603 58
e567e122
VJ
59#include "util-unittest-helper.h"
60
f10dd603 61static int DetectDnsQuerySetup (DetectEngineCtx *, Signature *, char *);
e567e122 62static void DetectDnsQueryRegisterTests(void);
f10dd603
VJ
63
64/**
57ae3c43 65 * \brief Registration function for keyword: dns_query
f10dd603 66 */
8f1d7503
KS
67void DetectDnsQueryRegister (void)
68{
f10dd603
VJ
69 sigmatch_table[DETECT_AL_DNS_QUERY].name = "dns_query";
70 sigmatch_table[DETECT_AL_DNS_QUERY].desc = "content modifier to match specifically and only on the DNS query-buffer";
71 sigmatch_table[DETECT_AL_DNS_QUERY].Match = NULL;
72 sigmatch_table[DETECT_AL_DNS_QUERY].AppLayerMatch = NULL;
f10dd603
VJ
73 sigmatch_table[DETECT_AL_DNS_QUERY].Setup = DetectDnsQuerySetup;
74 sigmatch_table[DETECT_AL_DNS_QUERY].Free = NULL;
e567e122 75 sigmatch_table[DETECT_AL_DNS_QUERY].RegisterTests = DetectDnsQueryRegisterTests;
f10dd603 76
02529b13 77 sigmatch_table[DETECT_AL_DNS_QUERY].flags |= SIGMATCH_NOOPT;
f10dd603 78 sigmatch_table[DETECT_AL_DNS_QUERY].flags |= SIGMATCH_PAYLOAD;
57ae3c43
VJ
79
80 DetectMpmAppLayerRegister("dns_query", SIG_FLAG_TOSERVER,
960461f4 81 DETECT_SM_LIST_DNSQUERYNAME_MATCH, 2,
57ae3c43
VJ
82 PrefilterTxDnsQueryRegister);
83
2db094ab
VJ
84 DetectAppLayerInspectEngineRegister(ALPROTO_DNS, SIG_FLAG_TOSERVER,
85 DETECT_SM_LIST_DNSQUERYNAME_MATCH,
86 DetectEngineInspectDnsQueryName);
87
88 /* register these generic engines from here for now */
89 DetectAppLayerInspectEngineRegister(ALPROTO_DNS, SIG_FLAG_TOSERVER,
90 DETECT_SM_LIST_DNSREQUEST_MATCH,
91 DetectEngineInspectDnsRequest);
92 DetectAppLayerInspectEngineRegister(ALPROTO_DNS, SIG_FLAG_TOCLIENT,
93 DETECT_SM_LIST_DNSRESPONSE_MATCH,
94 DetectEngineInspectDnsResponse);
f10dd603
VJ
95}
96
97
98/**
99 * \brief this function setups the dns_query modifier keyword used in the rule
100 *
101 * \param de_ctx Pointer to the Detection Engine Context
102 * \param s Pointer to the Signature to which the current keyword belongs
103 * \param str Should hold an empty string always
104 *
105 * \retval 0 On success
106 * \retval -1 On failure
107 */
108
109static int DetectDnsQuerySetup(DetectEngineCtx *de_ctx, Signature *s, char *str)
110{
2c8e8c25 111 s->list = DETECT_SM_LIST_DNSQUERYNAME_MATCH;
d0c5f512 112 s->alproto = ALPROTO_DNS;
f353fb63 113 return 0;
f10dd603 114}
e567e122
VJ
115
116#ifdef UNITTESTS
117/** \test simple google.com query matching */
8f1d7503
KS
118static int DetectDnsQueryTest01(void)
119{
e567e122
VJ
120 /* google.com */
121 uint8_t buf[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
124 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
125 0x00, 0x10, 0x00, 0x01, };
126 int result = 0;
127 Flow f;
128 DNSState *dns_state = NULL;
129 Packet *p = NULL;
130 Signature *s = NULL;
131 ThreadVars tv;
132 DetectEngineThreadCtx *det_ctx = NULL;
8dbf7a0d 133 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
e567e122
VJ
134
135 memset(&tv, 0, sizeof(ThreadVars));
136 memset(&f, 0, sizeof(Flow));
137
6f8cfd99
AS
138 p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP,
139 "192.168.1.5", "192.168.1.1",
140 41424, 53);
e567e122
VJ
141
142 FLOW_INITIALIZE(&f);
143 f.flags |= FLOW_IPV4;
144 f.proto = IPPROTO_UDP;
a77b9b36 145 f.protomap = FlowGetProtoMapping(f.proto);
e567e122
VJ
146
147 p->flow = &f;
148 p->flags |= PKT_HAS_FLOW;
149 p->flowflags |= FLOW_PKT_TOSERVER;
429c6388 150 f.alproto = ALPROTO_DNS;
e567e122
VJ
151
152 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
153 if (de_ctx == NULL) {
154 goto end;
155 }
e6044aaf 156 de_ctx->mpm_matcher = mpm_default_matcher;
e567e122
VJ
157 de_ctx->flags |= DE_QUIET;
158
f592c481 159 s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
ddde572f
AS
160 "(msg:\"Test dns_query option\"; "
161 "dns_query; content:\"google\"; nocase; sid:1;)");
e567e122
VJ
162 if (s == NULL) {
163 goto end;
164 }
165
166 SigGroupBuild(de_ctx);
167 DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
168
6530c3d0 169 FLOWLOCK_WRLOCK(&f);
675fa564
GL
170 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
171 STREAM_TOSERVER, buf, sizeof(buf));
e567e122
VJ
172 if (r != 0) {
173 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
6530c3d0 174 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
175 goto end;
176 }
6530c3d0 177 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
178
179 dns_state = f.alstate;
180 if (dns_state == NULL) {
181 printf("no dns state: ");
182 goto end;
183 }
184
185 /* do detect */
186 SigMatchSignatures(&tv, de_ctx, det_ctx, p);
187
188 if (!(PacketAlertCheck(p, 1))) {
189 printf("sig 1 didn't alert, but it should have: ");
190 goto end;
191 }
192
193 result = 1;
194
195end:
429c6388 196 if (alp_tctx != NULL)
fdefb65b 197 AppLayerParserThreadCtxFree(alp_tctx);
e567e122
VJ
198 if (det_ctx != NULL)
199 DetectEngineThreadCtxDeinit(&tv, det_ctx);
200 if (de_ctx != NULL)
201 SigGroupCleanup(de_ctx);
202 if (de_ctx != NULL)
203 DetectEngineCtxFree(de_ctx);
204
205 FLOW_DESTROY(&f);
206 UTHFreePacket(p);
207 return result;
208}
209
210/** \test multi tx google.(com|net) query matching */
8f1d7503
KS
211static int DetectDnsQueryTest02(void)
212{
e567e122
VJ
213 /* google.com */
214 uint8_t buf1[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
217 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
218 0x00, 0x01, 0x00, 0x01, };
219
220 uint8_t buf2[] = { 0x10, 0x32, /* tx id */
221 0x81, 0x80, /* flags: resp, recursion desired, recusion available */
222 0x00, 0x01, /* 1 query */
223 0x00, 0x01, /* 1 answer */
224 0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
225 /* query record */
226 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
227 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
228 0x00, 0x01, 0x00, 0x01, /* type a, class in */
229 /* answer */
230 0xc0, 0x0c, /* ref to name in query above */
231 0x00, 0x01, 0x00, 0x01, /* type a, class in */
232 0x00, 0x01, 0x40, 0xef, /* ttl */
233 0x00, 0x04, /* data len */
234 0x01, 0x02, 0x03, 0x04 }; /* addr */
235
236 /* google.net */
237 uint8_t buf3[] = { 0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
240 0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
241 0x00, 0x10, 0x00, 0x01, };
242 int result = 0;
243 Flow f;
244 DNSState *dns_state = NULL;
245 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
246 Signature *s = NULL;
247 ThreadVars tv;
248 DetectEngineThreadCtx *det_ctx = NULL;
8dbf7a0d 249 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
e567e122
VJ
250
251 memset(&tv, 0, sizeof(ThreadVars));
252 memset(&f, 0, sizeof(Flow));
253
6f8cfd99
AS
254 p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
255 "192.168.1.5", "192.168.1.1",
256 41424, 53);
257 p2 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
258 "192.168.1.5", "192.168.1.1",
259 41424, 53);
260 p3 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
261 "192.168.1.5", "192.168.1.1",
262 41424, 53);
e567e122
VJ
263
264 FLOW_INITIALIZE(&f);
265 f.flags |= FLOW_IPV4;
266 f.proto = IPPROTO_UDP;
a77b9b36 267 f.protomap = FlowGetProtoMapping(f.proto);
429c6388 268 f.alproto = ALPROTO_DNS;
e567e122
VJ
269
270 p1->flow = &f;
271 p1->flags |= PKT_HAS_FLOW;
272 p1->flowflags |= FLOW_PKT_TOSERVER;
273 p1->pcap_cnt = 1;
274
275 p2->flow = &f;
276 p2->flags |= PKT_HAS_FLOW;
277 p2->flowflags |= FLOW_PKT_TOCLIENT;
278 p2->pcap_cnt = 2;
279
280 p3->flow = &f;
281 p3->flags |= PKT_HAS_FLOW;
282 p3->flowflags |= FLOW_PKT_TOSERVER;
283 p3->pcap_cnt = 3;
284
285 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
286 if (de_ctx == NULL) {
287 goto end;
288 }
e6044aaf 289 de_ctx->mpm_matcher = mpm_default_matcher;
e567e122
VJ
290 de_ctx->flags |= DE_QUIET;
291
f592c481 292 s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
429c6388
AS
293 "(msg:\"Test dns_query option\"; "
294 "dns_query; content:\"google.com\"; nocase; sid:1;)");
e567e122
VJ
295 if (s == NULL) {
296 goto end;
297 }
f592c481 298 s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
429c6388
AS
299 "(msg:\"Test dns_query option\"; "
300 "dns_query; content:\"google.net\"; nocase; sid:2;)");
e567e122
VJ
301 if (s == NULL) {
302 goto end;
303 }
304
305 SigGroupBuild(de_ctx);
306 DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
307
6530c3d0 308 FLOWLOCK_WRLOCK(&f);
675fa564
GL
309 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
310 STREAM_TOSERVER, buf1, sizeof(buf1));
e567e122
VJ
311 if (r != 0) {
312 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
6530c3d0 313 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
314 goto end;
315 }
6530c3d0 316 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
317
318 dns_state = f.alstate;
319 if (dns_state == NULL) {
320 printf("no dns state: ");
321 goto end;
322 }
323
324 /* do detect */
325 SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
326
327 if (!(PacketAlertCheck(p1, 1))) {
328 printf("(p1) sig 1 didn't alert, but it should have: ");
329 goto end;
330 }
331 if (PacketAlertCheck(p1, 2)) {
332 printf("(p1) sig 2 did alert, but it should not have: ");
333 goto end;
334 }
335
6530c3d0 336 FLOWLOCK_WRLOCK(&f);
675fa564
GL
337 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
338 buf2, sizeof(buf2));
e567e122
VJ
339 if (r != 0) {
340 printf("toserver client 1 returned %" PRId32 ", expected 0: ", r);
6530c3d0 341 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
342 goto end;
343 }
6530c3d0 344 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
345
346 /* do detect */
347 SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
348
349 if (PacketAlertCheck(p2, 1)) {
350 printf("(p2) sig 1 alerted, but it should not have: ");
351 goto end;
352 }
353 if (PacketAlertCheck(p2, 2)) {
354 printf("(p2) sig 2 alerted, but it should not have: ");
355 goto end;
356 }
357
6530c3d0 358 FLOWLOCK_WRLOCK(&f);
675fa564
GL
359 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
360 buf3, sizeof(buf3));
e567e122
VJ
361 if (r != 0) {
362 printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
6530c3d0 363 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
364 goto end;
365 }
6530c3d0 366 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
367
368 /* do detect */
369 SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
370
371 if (PacketAlertCheck(p3, 1)) {
372 printf("(p3) sig 1 alerted, but it should not have: ");
373 goto end;
374 }
375 if (!(PacketAlertCheck(p3, 2))) {
376 printf("(p3) sig 2 didn't alert, but it should have: ");
377 goto end;
378 }
379
380 result = 1;
381
382end:
429c6388 383 if (alp_tctx != NULL)
fdefb65b 384 AppLayerParserThreadCtxFree(alp_tctx);
e567e122
VJ
385 if (det_ctx != NULL)
386 DetectEngineThreadCtxDeinit(&tv, det_ctx);
387 if (de_ctx != NULL)
388 SigGroupCleanup(de_ctx);
389 if (de_ctx != NULL)
390 DetectEngineCtxFree(de_ctx);
391
392 FLOW_DESTROY(&f);
393 UTHFreePacket(p1);
394 UTHFreePacket(p2);
395 UTHFreePacket(p3);
396 return result;
397}
398
399/** \test simple google.com query matching (TCP) */
8f1d7503
KS
400static int DetectDnsQueryTest03(void)
401{
e567e122
VJ
402 /* google.com */
403 uint8_t buf[] = { 0x00, 28,
404 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
407 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
408 0x00, 0x10, 0x00, 0x01, };
409 int result = 0;
410 Flow f;
411 DNSState *dns_state = NULL;
412 Packet *p = NULL;
413 Signature *s = NULL;
414 ThreadVars tv;
415 DetectEngineThreadCtx *det_ctx = NULL;
416 TcpSession ssn;
8dbf7a0d 417 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
e567e122
VJ
418
419 memset(&tv, 0, sizeof(ThreadVars));
420 memset(&f, 0, sizeof(Flow));
421 memset(&ssn, 0, sizeof(TcpSession));
422
6f8cfd99
AS
423 p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_TCP,
424 "192.168.1.5", "192.168.1.1",
425 41424, 53);
e567e122
VJ
426
427 FLOW_INITIALIZE(&f);
428 f.protoctx = (void *)&ssn;
429 f.flags |= FLOW_IPV4;
430 f.proto = IPPROTO_TCP;
a77b9b36 431 f.protomap = FlowGetProtoMapping(f.proto);
e567e122
VJ
432
433 p->flow = &f;
434 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
435 p->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
429c6388 436 f.alproto = ALPROTO_DNS;
e567e122
VJ
437
438 StreamTcpInitConfig(TRUE);
439
440 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
441 if (de_ctx == NULL) {
442 goto end;
443 }
e6044aaf 444 de_ctx->mpm_matcher = mpm_default_matcher;
e567e122
VJ
445 de_ctx->flags |= DE_QUIET;
446
429c6388
AS
447 s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
448 "(msg:\"Test dns_query option\"; "
449 "content:\"google\"; nocase; dns_query; sid:1;)");
e567e122
VJ
450 if (s == NULL) {
451 goto end;
452 }
453
454 SigGroupBuild(de_ctx);
455 DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
456
6530c3d0 457 FLOWLOCK_WRLOCK(&f);
675fa564
GL
458 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
459 STREAM_TOSERVER, buf, sizeof(buf));
e567e122
VJ
460 if (r != 0) {
461 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
6530c3d0 462 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
463 goto end;
464 }
6530c3d0 465 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
466
467 dns_state = f.alstate;
468 if (dns_state == NULL) {
469 printf("no dns state: ");
470 goto end;
471 }
472
473 /* do detect */
474 SigMatchSignatures(&tv, de_ctx, det_ctx, p);
475
476 if (!(PacketAlertCheck(p, 1))) {
477 printf("sig 1 didn't alert, but it should have: ");
478 goto end;
479 }
480
481 result = 1;
482
483end:
429c6388 484 if (alp_tctx != NULL)
fdefb65b 485 AppLayerParserThreadCtxFree(alp_tctx);
e567e122
VJ
486 if (det_ctx != NULL)
487 DetectEngineThreadCtxDeinit(&tv, det_ctx);
488 if (de_ctx != NULL)
489 SigGroupCleanup(de_ctx);
490 if (de_ctx != NULL)
491 DetectEngineCtxFree(de_ctx);
492
493 StreamTcpFreeConfig(TRUE);
494 FLOW_DESTROY(&f);
495 UTHFreePacket(p);
496 return result;
497}
498
499/** \test simple google.com query matching (TCP splicing) */
8f1d7503
KS
500static int DetectDnsQueryTest04(void)
501{
e567e122
VJ
502 /* google.com */
503 uint8_t buf1[] = { 0x00, 28,
504 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
506 uint8_t buf2[] = { 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
507 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
508 0x00, 0x10, 0x00, 0x01, };
509 int result = 0;
510 Flow f;
511 DNSState *dns_state = NULL;
512 Packet *p1 = NULL, *p2 = NULL;
513 Signature *s = NULL;
514 ThreadVars tv;
515 DetectEngineThreadCtx *det_ctx = NULL;
516 TcpSession ssn;
8dbf7a0d 517 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
e567e122
VJ
518
519 memset(&tv, 0, sizeof(ThreadVars));
520 memset(&f, 0, sizeof(Flow));
521 memset(&ssn, 0, sizeof(TcpSession));
522
6f8cfd99
AS
523 p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_TCP,
524 "192.168.1.5", "192.168.1.1",
525 41424, 53);
526 p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_TCP,
527 "192.168.1.5", "192.168.1.1",
528 41424, 53);
e567e122
VJ
529
530 FLOW_INITIALIZE(&f);
531 f.protoctx = (void *)&ssn;
532 f.flags |= FLOW_IPV4;
533 f.proto = IPPROTO_TCP;
a77b9b36 534 f.protomap = FlowGetProtoMapping(f.proto);
429c6388 535 f.alproto = ALPROTO_DNS;
e567e122
VJ
536
537 p1->flow = &f;
538 p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
539 p1->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
540
541 p2->flow = &f;
542 p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
543 p2->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
544
545 StreamTcpInitConfig(TRUE);
546
547 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
548 if (de_ctx == NULL) {
549 goto end;
550 }
e6044aaf 551 de_ctx->mpm_matcher = mpm_default_matcher;
e567e122
VJ
552 de_ctx->flags |= DE_QUIET;
553
429c6388
AS
554 s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
555 "(msg:\"Test dns_query option\"; "
556 "dns_query; content:\"google\"; nocase; sid:1;)");
e567e122
VJ
557 if (s == NULL) {
558 goto end;
559 }
560
561 SigGroupBuild(de_ctx);
562 DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
563
6530c3d0 564 FLOWLOCK_WRLOCK(&f);
675fa564
GL
565 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
566 STREAM_TOSERVER, buf1, sizeof(buf1));
e567e122
VJ
567 if (r != 0) {
568 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
6530c3d0 569 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
570 goto end;
571 }
6530c3d0 572 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
573
574 dns_state = f.alstate;
575 if (dns_state == NULL) {
576 printf("no dns state: ");
577 goto end;
578 }
579
580 /* do detect */
581 SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
582
583 if (PacketAlertCheck(p1, 1)) {
584 printf("sig 1 alerted, but it should not have: ");
585 goto end;
586 }
587
6530c3d0 588 FLOWLOCK_WRLOCK(&f);
675fa564
GL
589 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
590 buf2, sizeof(buf2));
e567e122
VJ
591 if (r != 0) {
592 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
6530c3d0 593 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
594 goto end;
595 }
6530c3d0 596 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
597
598 /* do detect */
599 SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
600
601 if (!(PacketAlertCheck(p2, 1))) {
602 printf("sig 1 didn't alert, but it should have: ");
603 goto end;
604 }
605
606 result = 1;
607
608end:
429c6388 609 if (alp_tctx != NULL)
fdefb65b 610 AppLayerParserThreadCtxFree(alp_tctx);
e567e122
VJ
611 if (det_ctx != NULL)
612 DetectEngineThreadCtxDeinit(&tv, det_ctx);
613 if (de_ctx != NULL)
614 SigGroupCleanup(de_ctx);
615 if (de_ctx != NULL)
616 DetectEngineCtxFree(de_ctx);
617
618 StreamTcpFreeConfig(TRUE);
619 FLOW_DESTROY(&f);
620 UTHFreePacket(p1);
621 UTHFreePacket(p2);
622 return result;
623}
624
625/** \test simple google.com query matching (TCP splicing) */
8f1d7503
KS
626static int DetectDnsQueryTest05(void)
627{
e567e122
VJ
628 /* google.com in 2 chunks (buf1 and buf2) */
629 uint8_t buf1[] = { 0x00, 28, /* len 28 */
630 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
632
633 uint8_t buf2[] = { 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
634 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
635 0x00, 0x10, 0x00, 0x01, };
636
637 uint8_t buf3[] = { 0x00, 44, /* len 44 */
638 0x10, 0x32, /* tx id */
639 0x81, 0x80, /* flags: resp, recursion desired, recusion available */
640 0x00, 0x01, /* 1 query */
641 0x00, 0x01, /* 1 answer */
642 0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
643 /* query record */
644 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
645 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
646 0x00, 0x01, 0x00, 0x01, /* type a, class in */
647 /* answer */
648 0xc0, 0x0c, /* ref to name in query above */
649 0x00, 0x01, 0x00, 0x01, /* type a, class in */
650 0x00, 0x01, 0x40, 0xef, /* ttl */
651 0x00, 0x04, /* data len */
652 0x01, 0x02, 0x03, 0x04 }; /* addr */
653
654 /* google.net */
655 uint8_t buf4[] = { 0x00, 28, /* len 28 */
656 0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
659 0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
660 0x00, 0x10, 0x00, 0x01, };
661 int result = 0;
662 Flow f;
663 DNSState *dns_state = NULL;
664 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL, *p4 = NULL;
665 Signature *s = NULL;
666 ThreadVars tv;
667 DetectEngineThreadCtx *det_ctx = NULL;
668 TcpSession ssn;
8dbf7a0d 669 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
e567e122
VJ
670
671 memset(&tv, 0, sizeof(ThreadVars));
672 memset(&f, 0, sizeof(Flow));
673 memset(&ssn, 0, sizeof(TcpSession));
674
6f8cfd99
AS
675 p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_TCP,
676 "192.168.1.5", "192.168.1.1",
677 41424, 53);
678 p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_TCP,
679 "192.168.1.5", "192.168.1.1",
680 41424, 53);
681 p3 = UTHBuildPacketReal(buf3, sizeof(buf3), IPPROTO_TCP,
682 "192.168.1.5", "192.168.1.1",
683 41424, 53);
684 p4 = UTHBuildPacketReal(buf4, sizeof(buf4), IPPROTO_TCP,
685 "192.168.1.5", "192.168.1.1",
686 41424, 53);
e567e122
VJ
687
688 FLOW_INITIALIZE(&f);
689 f.protoctx = (void *)&ssn;
690 f.flags |= FLOW_IPV4;
691 f.proto = IPPROTO_TCP;
a77b9b36 692 f.protomap = FlowGetProtoMapping(f.proto);
429c6388 693 f.alproto = ALPROTO_DNS;
e567e122
VJ
694
695 p1->flow = &f;
696 p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
697 p1->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
698
699 p2->flow = &f;
700 p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
701 p2->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
702
703 p3->flow = &f;
704 p3->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
705 p3->flowflags |= FLOW_PKT_TOCLIENT|FLOW_PKT_ESTABLISHED;
706
707 p4->flow = &f;
708 p4->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
709 p4->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
710
711 StreamTcpInitConfig(TRUE);
712
713 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
714 if (de_ctx == NULL) {
715 goto end;
716 }
e6044aaf 717 de_ctx->mpm_matcher = mpm_default_matcher;
e567e122
VJ
718 de_ctx->flags |= DE_QUIET;
719
429c6388
AS
720 s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
721 "(msg:\"Test dns_query option\"; "
722 "dns_query; content:\"google.com\"; nocase; sid:1;)");
e567e122
VJ
723 if (s == NULL) {
724 goto end;
725 }
429c6388
AS
726 s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
727 "(msg:\"Test dns_query option\"; "
728 "dns_query; content:\"google.net\"; nocase; sid:2;)");
e567e122
VJ
729 if (s == NULL) {
730 goto end;
731 }
732
733 SigGroupBuild(de_ctx);
734 DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
735
6530c3d0 736 FLOWLOCK_WRLOCK(&f);
675fa564
GL
737 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
738 STREAM_TOSERVER, buf1, sizeof(buf1));
e567e122
VJ
739 if (r != 0) {
740 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
6530c3d0 741 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
742 goto end;
743 }
6530c3d0 744 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
745
746 dns_state = f.alstate;
747 if (dns_state == NULL) {
748 printf("no dns state: ");
749 goto end;
750 }
751
752 /* do detect */
753 SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
754
755 if (PacketAlertCheck(p1, 1)) {
756 printf("(p1) sig 1 alerted, but it should not have: ");
757 goto end;
758 }
759 if (PacketAlertCheck(p1, 2)) {
760 printf("(p1) sig 2 did alert, but it should not have: ");
761 goto end;
762 }
763
6530c3d0 764 FLOWLOCK_WRLOCK(&f);
675fa564
GL
765 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
766 buf2, sizeof(buf2));
e567e122
VJ
767 if (r != 0) {
768 printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
6530c3d0 769 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
770 goto end;
771 }
6530c3d0 772 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
773
774 /* do detect */
775 SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
776
777 if (!(PacketAlertCheck(p2, 1))) {
778 printf("sig 1 didn't alert, but it should have: ");
779 goto end;
780 }
781 if (PacketAlertCheck(p2, 2)) {
782 printf("(p2) sig 2 did alert, but it should not have: ");
783 goto end;
784 }
785
6530c3d0 786 FLOWLOCK_WRLOCK(&f);
675fa564
GL
787 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
788 buf3, sizeof(buf3));
e567e122
VJ
789 if (r != 0) {
790 printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r);
6530c3d0 791 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
792 goto end;
793 }
6530c3d0 794 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
795
796 /* do detect */
797 SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
798
799 if (PacketAlertCheck(p3, 1)) {
800 printf("sig 1 did alert, but it should not have: ");
801 goto end;
802 }
803 if (PacketAlertCheck(p3, 2)) {
804 printf("(p3) sig 2 did alert, but it should not have: ");
805 goto end;
806 }
807
6530c3d0 808 FLOWLOCK_WRLOCK(&f);
675fa564
GL
809 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
810 buf4, sizeof(buf4));
e567e122
VJ
811 if (r != 0) {
812 printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
6530c3d0 813 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
814 goto end;
815 }
6530c3d0 816 FLOWLOCK_UNLOCK(&f);
e567e122
VJ
817
818 /* do detect */
819 SigMatchSignatures(&tv, de_ctx, det_ctx, p4);
820
821 if (PacketAlertCheck(p4, 1)) {
822 printf("(p4) sig 1 did alert, but it should not have: ");
823 goto end;
824 }
825 if (!(PacketAlertCheck(p4, 2))) {
826 printf("sig 1 didn't alert, but it should have: ");
827 goto end;
828 }
829
830 result = 1;
831
832end:
429c6388 833 if (alp_tctx != NULL)
fdefb65b 834 AppLayerParserThreadCtxFree(alp_tctx);
e567e122
VJ
835 if (det_ctx != NULL)
836 DetectEngineThreadCtxDeinit(&tv, det_ctx);
837 if (de_ctx != NULL)
838 SigGroupCleanup(de_ctx);
839 if (de_ctx != NULL)
840 DetectEngineCtxFree(de_ctx);
841
842 StreamTcpFreeConfig(TRUE);
843 FLOW_DESTROY(&f);
844 UTHFreePacket(p1);
845 UTHFreePacket(p2);
846 UTHFreePacket(p3);
847 UTHFreePacket(p4);
848 return result;
849}
4817e130
VJ
850
851/** \test simple google.com query matching, pcre */
8f1d7503
KS
852static int DetectDnsQueryTest06(void)
853{
4817e130
VJ
854 /* google.com */
855 uint8_t buf[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
856 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
857 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
858 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
859 0x00, 0x10, 0x00, 0x01, };
860 int result = 0;
861 Flow f;
862 DNSState *dns_state = NULL;
863 Packet *p = NULL;
864 Signature *s = NULL;
865 ThreadVars tv;
866 DetectEngineThreadCtx *det_ctx = NULL;
8dbf7a0d 867 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
4817e130
VJ
868
869 memset(&tv, 0, sizeof(ThreadVars));
870 memset(&f, 0, sizeof(Flow));
871
6f8cfd99
AS
872 p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP,
873 "192.168.1.5", "192.168.1.1",
874 41424, 53);
4817e130
VJ
875
876 FLOW_INITIALIZE(&f);
877 f.flags |= FLOW_IPV4;
878 f.proto = IPPROTO_UDP;
a77b9b36 879 f.protomap = FlowGetProtoMapping(f.proto);
4817e130
VJ
880
881 p->flow = &f;
882 p->flags |= PKT_HAS_FLOW;
883 p->flowflags |= FLOW_PKT_TOSERVER;
429c6388 884 f.alproto = ALPROTO_DNS;
4817e130
VJ
885
886 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
887 if (de_ctx == NULL) {
888 goto end;
889 }
e6044aaf 890 de_ctx->mpm_matcher = mpm_default_matcher;
4817e130
VJ
891 de_ctx->flags |= DE_QUIET;
892
f592c481 893 s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
429c6388
AS
894 "(msg:\"Test dns_query option\"; "
895 "dns_query; content:\"google\"; nocase; "
896 "pcre:\"/google\\.com$/i\"; sid:1;)");
4817e130
VJ
897 if (s == NULL) {
898 goto end;
899 }
f592c481 900 s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
4817e130 901 "(msg:\"Test dns_query option\"; "
f353fb63
VJ
902 "dns_query; content:\"google\"; nocase; "
903 "pcre:\"/^\\.[a-z]{2,3}$/iR\"; sid:2;)");
4817e130
VJ
904 if (s == NULL) {
905 goto end;
906 }
907
908
909 SigGroupBuild(de_ctx);
910 DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
911
6530c3d0 912 FLOWLOCK_WRLOCK(&f);
675fa564
GL
913 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
914 STREAM_TOSERVER, buf, sizeof(buf));
4817e130
VJ
915 if (r != 0) {
916 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
6530c3d0 917 FLOWLOCK_UNLOCK(&f);
4817e130
VJ
918 goto end;
919 }
6530c3d0 920 FLOWLOCK_UNLOCK(&f);
4817e130
VJ
921
922 dns_state = f.alstate;
923 if (dns_state == NULL) {
924 printf("no dns state: ");
925 goto end;
926 }
927
928 /* do detect */
929 SigMatchSignatures(&tv, de_ctx, det_ctx, p);
930
931 if (!(PacketAlertCheck(p, 1))) {
932 printf("sig 1 didn't alert, but it should have: ");
933 goto end;
934 }
935 if (!(PacketAlertCheck(p, 2))) {
936 printf("sig 2 didn't alert, but it should have: ");
937 goto end;
938 }
939
940 result = 1;
941
942end:
429c6388 943 if (alp_tctx != NULL)
fdefb65b 944 AppLayerParserThreadCtxFree(alp_tctx);
4817e130
VJ
945 if (det_ctx != NULL)
946 DetectEngineThreadCtxDeinit(&tv, det_ctx);
947 if (de_ctx != NULL)
948 SigGroupCleanup(de_ctx);
949 if (de_ctx != NULL)
950 DetectEngineCtxFree(de_ctx);
951
952 FLOW_DESTROY(&f);
953 UTHFreePacket(p);
954 return result;
955}
956
28a6c1d9
VJ
957/** \test multi tx google.(com|net) query matching +
958 * app layer event */
8f1d7503
KS
959static int DetectDnsQueryTest07(void)
960{
28a6c1d9
VJ
961 /* google.com */
962 uint8_t buf1[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
963 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
964 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
965 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
966 0x00, 0x01, 0x00, 0x01, };
967
968 uint8_t buf2[] = { 0x10, 0x32, /* tx id */
969 0x81, 0x80|0x40, /* flags: resp, recursion desired, recusion available */
970 0x00, 0x01, /* 1 query */
971 0x00, 0x01, /* 1 answer */
972 0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
973 /* query record */
974 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
975 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
976 0x00, 0x01, 0x00, 0x01, /* type a, class in */
977 /* answer */
978 0xc0, 0x0c, /* ref to name in query above */
979 0x00, 0x01, 0x00, 0x01, /* type a, class in */
980 0x00, 0x01, 0x40, 0xef, /* ttl */
981 0x00, 0x04, /* data len */
982 0x01, 0x02, 0x03, 0x04 }; /* addr */
983
984 /* google.net */
985 uint8_t buf3[] = { 0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
986 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
987 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
988 0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
989 0x00, 0x10, 0x00, 0x01, };
990 int result = 0;
991 Flow f;
992 DNSState *dns_state = NULL;
993 Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
994 Signature *s = NULL;
995 ThreadVars tv;
996 DetectEngineThreadCtx *det_ctx = NULL;
8dbf7a0d 997 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
28a6c1d9
VJ
998
999 memset(&tv, 0, sizeof(ThreadVars));
1000 memset(&f, 0, sizeof(Flow));
1001
6f8cfd99
AS
1002 p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
1003 "192.168.1.5", "192.168.1.1",
1004 41424, 53);
1005 p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_UDP,
1006 "192.168.1.5", "192.168.1.1",
1007 41424, 53);
1008 p3 = UTHBuildPacketReal(buf3, sizeof(buf3), IPPROTO_UDP,
1009 "192.168.1.5", "192.168.1.1",
1010 41424, 53);
28a6c1d9
VJ
1011
1012 FLOW_INITIALIZE(&f);
1013 f.flags |= FLOW_IPV4;
1014 f.proto = IPPROTO_UDP;
a77b9b36 1015 f.protomap = FlowGetProtoMapping(f.proto);
429c6388 1016 f.alproto = ALPROTO_DNS;
28a6c1d9
VJ
1017
1018 p1->flow = &f;
1019 p1->flags |= PKT_HAS_FLOW;
1020 p1->flowflags |= FLOW_PKT_TOSERVER;
1021 p1->pcap_cnt = 1;
1022
1023 p2->flow = &f;
1024 p2->flags |= PKT_HAS_FLOW;
1025 p2->flowflags |= FLOW_PKT_TOCLIENT;
1026 p2->pcap_cnt = 2;
1027
1028 p3->flow = &f;
1029 p3->flags |= PKT_HAS_FLOW;
1030 p3->flowflags |= FLOW_PKT_TOSERVER;
1031 p3->pcap_cnt = 3;
1032
1033 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1034 if (de_ctx == NULL) {
1035 goto end;
1036 }
e6044aaf 1037 de_ctx->mpm_matcher = mpm_default_matcher;
28a6c1d9
VJ
1038 de_ctx->flags |= DE_QUIET;
1039
f592c481 1040 s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
28a6c1d9 1041 "(msg:\"Test dns_query option\"; "
f353fb63 1042 "dns_query; content:\"google.com\"; nocase; sid:1;)");
28a6c1d9
VJ
1043 if (s == NULL) {
1044 goto end;
1045 }
f592c481 1046 s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
28a6c1d9 1047 "(msg:\"Test dns_query option\"; "
f353fb63 1048 "dns_query; content:\"google.net\"; nocase; sid:2;)");
28a6c1d9
VJ
1049 if (s == NULL) {
1050 goto end;
1051 }
f592c481 1052 s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
28a6c1d9
VJ
1053 "(msg:\"Test Z flag event\"; "
1054 "app-layer-event:dns.z_flag_set; sid:3;)");
1055 if (s == NULL) {
1056 goto end;
1057 }
1058
1059 SigGroupBuild(de_ctx);
1060 DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
1061
6530c3d0 1062 FLOWLOCK_WRLOCK(&f);
675fa564
GL
1063 int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
1064 STREAM_TOSERVER, buf1, sizeof(buf1));
28a6c1d9
VJ
1065 if (r != 0) {
1066 printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
6530c3d0 1067 FLOWLOCK_UNLOCK(&f);
28a6c1d9
VJ
1068 goto end;
1069 }
6530c3d0 1070 FLOWLOCK_UNLOCK(&f);
28a6c1d9
VJ
1071
1072 dns_state = f.alstate;
1073 if (dns_state == NULL) {
1074 printf("no dns state: ");
1075 goto end;
1076 }
1077
1078 /* do detect */
1079 SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
1080
1081 if (!(PacketAlertCheck(p1, 1))) {
1082 printf("(p1) sig 1 didn't alert, but it should have: ");
1083 goto end;
1084 }
1085 if (PacketAlertCheck(p1, 2)) {
1086 printf("(p1) sig 2 did alert, but it should not have: ");
1087 goto end;
1088 }
1089
6530c3d0 1090 FLOWLOCK_WRLOCK(&f);
675fa564
GL
1091 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
1092 buf2, sizeof(buf2));
28a6c1d9
VJ
1093 if (r != -1) {
1094 printf("toserver client 1 returned %" PRId32 ", expected 0: ", r);
6530c3d0 1095 FLOWLOCK_UNLOCK(&f);
28a6c1d9
VJ
1096 goto end;
1097 }
6530c3d0 1098 FLOWLOCK_UNLOCK(&f);
28a6c1d9
VJ
1099
1100 /* do detect */
1101 SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
1102
1103 if (PacketAlertCheck(p2, 1)) {
1104 printf("(p2) sig 1 alerted, but it should not have: ");
1105 goto end;
1106 }
1107 if (PacketAlertCheck(p2, 2)) {
1108 printf("(p2) sig 2 alerted, but it should not have: ");
1109 goto end;
1110 }
1111 if (!(PacketAlertCheck(p2, 3))) {
1112 printf("(p2) sig 3 didn't alert, but it should have: ");
1113 goto end;
1114 }
1115
6530c3d0 1116 FLOWLOCK_WRLOCK(&f);
675fa564
GL
1117 r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
1118 buf3, sizeof(buf3));
28a6c1d9
VJ
1119 if (r != 0) {
1120 printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
6530c3d0 1121 FLOWLOCK_UNLOCK(&f);
28a6c1d9
VJ
1122 goto end;
1123 }
6530c3d0 1124 FLOWLOCK_UNLOCK(&f);
28a6c1d9
VJ
1125
1126 /* do detect */
1127 SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
1128
1129 if (PacketAlertCheck(p3, 1)) {
1130 printf("(p3) sig 1 alerted, but it should not have: ");
1131 goto end;
1132 }
1133 if (!(PacketAlertCheck(p3, 2))) {
1134 printf("(p3) sig 2 didn't alert, but it should have: ");
1135 goto end;
1136 }
72e35efb 1137 /** \todo should not alert, bug #839
28a6c1d9 1138 if (PacketAlertCheck(p3, 3)) {
72e35efb 1139 printf("(p3) sig 3 did alert, but it should not have: ");
28a6c1d9
VJ
1140 goto end;
1141 }
72e35efb 1142 */
28a6c1d9
VJ
1143 result = 1;
1144
1145end:
429c6388 1146 if (alp_tctx != NULL)
fdefb65b 1147 AppLayerParserThreadCtxFree(alp_tctx);
28a6c1d9
VJ
1148 if (det_ctx != NULL)
1149 DetectEngineThreadCtxDeinit(&tv, det_ctx);
1150 if (de_ctx != NULL)
1151 SigGroupCleanup(de_ctx);
1152 if (de_ctx != NULL)
1153 DetectEngineCtxFree(de_ctx);
1154
1155 FLOW_DESTROY(&f);
1156 UTHFreePacket(p1);
1157 UTHFreePacket(p2);
1158 UTHFreePacket(p3);
1159 return result;
1160}
1161
e567e122
VJ
1162#endif
1163
8f1d7503
KS
1164static void DetectDnsQueryRegisterTests(void)
1165{
e567e122 1166#ifdef UNITTESTS
796dd522
JI
1167 UtRegisterTest("DetectDnsQueryTest01", DetectDnsQueryTest01);
1168 UtRegisterTest("DetectDnsQueryTest02", DetectDnsQueryTest02);
1169 UtRegisterTest("DetectDnsQueryTest03 -- tcp", DetectDnsQueryTest03);
1170 UtRegisterTest("DetectDnsQueryTest04 -- tcp splicing",
1171 DetectDnsQueryTest04);
1172 UtRegisterTest("DetectDnsQueryTest05 -- tcp splicing/multi tx",
1173 DetectDnsQueryTest05);
1174 UtRegisterTest("DetectDnsQueryTest06 -- pcre", DetectDnsQueryTest06);
1175 UtRegisterTest("DetectDnsQueryTest07 -- app layer event",
1176 DetectDnsQueryTest07);
e567e122
VJ
1177#endif
1178}