1 /* Copyright (C) 2011-2014 Open Information Security Foundation
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
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.
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
21 * \author Eric Leblond <eric@regit.org>
23 * Replace part of the detection engine.
25 * If previous filter is of content type, replace can be used to change
26 * the matched part to a new value.
29 #include "suricata-common.h"
38 #include "detect-parse.h"
39 #include "detect-content.h"
40 #include "detect-uricontent.h"
41 #include "detect-byte-extract.h"
42 #include "detect-replace.h"
43 #include "app-layer.h"
45 #include "detect-engine-mpm.h"
46 #include "detect-engine.h"
47 #include "detect-engine-state.h"
49 #include "util-checksum.h"
51 #include "util-unittest.h"
52 #include "util-unittest-helper.h"
56 #include "util-debug.h"
60 #include "util-profiling.h"
62 static int DetectReplaceSetup(DetectEngineCtx
*, Signature
*, const char *);
64 static void DetectReplaceRegisterTests(void);
66 static int DetectReplacePostMatch(DetectEngineThreadCtx
*det_ctx
,
67 Packet
*p
, const Signature
*s
, const SigMatchCtx
*ctx
);
69 void DetectReplaceRegister (void)
71 sigmatch_table
[DETECT_REPLACE
].name
= "replace";
72 sigmatch_table
[DETECT_REPLACE
].desc
= "only to be used in IPS-mode. Change the following content into another";
73 sigmatch_table
[DETECT_REPLACE
].url
= "/rules/payload-keywords.html#replace";
74 sigmatch_table
[DETECT_REPLACE
].Match
= DetectReplacePostMatch
;
75 sigmatch_table
[DETECT_REPLACE
].Setup
= DetectReplaceSetup
;
77 sigmatch_table
[DETECT_REPLACE
].RegisterTests
= DetectReplaceRegisterTests
;
79 sigmatch_table
[DETECT_REPLACE
].flags
= (SIGMATCH_QUOTES_MANDATORY
|SIGMATCH_HANDLE_NEGATION
);
82 static int DetectReplacePostMatch(DetectEngineThreadCtx
*det_ctx
,
83 Packet
*p
, const Signature
*s
, const SigMatchCtx
*ctx
)
85 if (det_ctx
->replist
) {
86 DetectReplaceExecuteInternal(p
, det_ctx
->replist
);
87 det_ctx
->replist
= NULL
;
92 int DetectReplaceSetup(DetectEngineCtx
*de_ctx
, Signature
*s
, const char *replacestr
)
94 uint8_t *content
= NULL
;
97 if (s
->init_data
->negated
) {
98 SCLogError(SC_ERR_INVALID_VALUE
, "Can't negate replacement string: %s",
108 SCLogWarning(SC_ERR_RUNMODE
,
109 "Can't use 'replace' keyword in non IPS mode: %s",
111 /* this is a success, having the alert is interesting */
115 int ret
= DetectContentDataParse("replace", replacestr
, &content
, &len
);
119 /* add to the latest "content" keyword from pmatch */
120 const SigMatch
*pm
= DetectGetLastSMByListId(s
, DETECT_SM_LIST_PMATCH
,
123 SCLogError(SC_ERR_WITHIN_MISSING_CONTENT
, "replace needs"
124 "preceding content option for raw sig");
129 /* we can remove this switch now with the unified structure */
130 DetectContentData
*ud
= (DetectContentData
*)pm
->ctx
;
132 SCLogError(SC_ERR_INVALID_ARGUMENT
, "invalid argument");
136 if (ud
->flags
& DETECT_CONTENT_NEGATED
) {
137 SCLogError(SC_ERR_INVALID_SIGNATURE
, "can't have a relative "
138 "negated keyword set along with a replacement");
141 if (ud
->content_len
!= len
) {
142 SCLogError(SC_ERR_INVALID_SIGNATURE
, "can't have a content "
143 "length different from replace length");
147 ud
->replace
= SCMalloc(len
);
148 if (ud
->replace
== NULL
) {
151 memcpy(ud
->replace
, content
, len
);
152 ud
->replace_len
= len
;
153 ud
->flags
|= DETECT_CONTENT_REPLACE
;
154 /* want packet matching only won't be able to replace data with
157 s
->flags
|= SIG_FLAG_REQUIRE_PACKET
;
161 SigMatch
*sm
= SigMatchAlloc();
162 if (unlikely(sm
== NULL
)) {
167 sm
->type
= DETECT_REPLACE
;
169 SigMatchAppendSMToList(s
, sm
, DETECT_SM_LIST_POSTMATCH
);
179 /* Add to the head of the replace-list.
181 * The first to add to the replace-list has the highest priority. So,
182 * adding the the head of the list results in the newest modifications
183 * of content being applied first, so later changes can over ride
184 * earlier changes. Thus the highest priority modifications should be
187 DetectReplaceList
*DetectReplaceAddToList(DetectReplaceList
*replist
,
189 DetectContentData
*cd
)
191 DetectReplaceList
*newlist
;
193 if (cd
->content_len
!= cd
->replace_len
)
195 SCLogDebug("replace: Adding match");
197 newlist
= SCMalloc(sizeof(DetectReplaceList
));
198 if (unlikely(newlist
== NULL
))
200 newlist
->found
= found
;
202 /* Push new value onto the front of the list. */
203 newlist
->next
= replist
;
209 void DetectReplaceExecuteInternal(Packet
*p
, DetectReplaceList
*replist
)
211 DetectReplaceList
*tlist
= NULL
;
213 SCLogDebug("replace: Executing match");
215 memcpy(replist
->found
, replist
->cd
->replace
, replist
->cd
->replace_len
);
216 SCLogDebug("replace: replaced data");
217 p
->flags
|= PKT_STREAM_MODIFIED
;
218 ReCalculateChecksum(p
);
220 replist
= replist
->next
;
226 void DetectReplaceFreeInternal(DetectReplaceList
*replist
)
228 DetectReplaceList
*tlist
= NULL
;
230 SCLogDebug("replace: Freeing match");
232 replist
= replist
->next
;
237 #ifdef UNITTESTS /* UNITTESTS */
240 * \test Test packet Matches
241 * \param raw_eth_pkt pointer to the ethernet packet
242 * \param pktsize size of the packet
243 * \param sig pointer to the signature to test
244 * \param sid sid number of the signature
245 * \retval return 1 if match
246 * \retval return 0 if not
249 int DetectReplaceLongPatternMatchTest(uint8_t *raw_eth_pkt
, uint16_t pktsize
,
250 const char *sig
, uint32_t sid
, uint8_t *pp
,
256 p
= PacketGetFromAlloc();
257 if (unlikely(p
== NULL
))
260 DecodeThreadVars dtv
;
263 DetectEngineThreadCtx
*det_ctx
= NULL
;
266 SCLogDebug("replace: looks like a second run");
269 PacketCopyData(p
, raw_eth_pkt
, pktsize
);
270 memset(&dtv
, 0, sizeof(DecodeThreadVars
));
271 memset(&th_v
, 0, sizeof(th_v
));
272 dtv
.app_tctx
= AppLayerGetCtxThread(&th_v
);
274 FlowInitConfig(FLOW_QUIET
);
275 DecodeEthernet(&th_v
, &dtv
, p
, GET_PKT_DATA(p
), pktsize
);
277 DetectEngineCtx
*de_ctx
= DetectEngineCtxInit();
278 if (de_ctx
== NULL
) {
281 de_ctx
->flags
|= DE_QUIET
;
283 de_ctx
->sig_list
= SigInit(de_ctx
, sig
);
284 if (de_ctx
->sig_list
== NULL
) {
287 de_ctx
->sig_list
->next
= NULL
;
289 if (de_ctx
->sig_list
->sm_lists_tail
[DETECT_SM_LIST_PMATCH
]->type
== DETECT_CONTENT
) {
290 DetectContentData
*co
= (DetectContentData
*)de_ctx
->sig_list
->sm_lists_tail
[DETECT_SM_LIST_PMATCH
]->ctx
;
291 if (co
->flags
& DETECT_CONTENT_RELATIVE_NEXT
) {
292 printf("relative next flag set on final match which is content: ");
297 SigGroupBuild(de_ctx
);
298 DetectEngineAddToMaster(de_ctx
);
299 DetectEngineThreadCtxInit(&th_v
, NULL
, (void *)&det_ctx
);
301 SigMatchSignatures(&th_v
, de_ctx
, det_ctx
, p
);
302 DetectEngineMoveToFreeList(de_ctx
);
304 if (PacketAlertCheck(p
, sid
) != 1) {
305 SCLogDebug("replace: no alert on sig %d", sid
);
310 memcpy(pp
, GET_PKT_DATA(p
), GET_PKT_LEN(p
));
312 SCLogDebug("replace: copying %d on %p", *len
, pp
);
318 if (dtv
.app_tctx
!= NULL
)
319 AppLayerDestroyCtxThread(dtv
.app_tctx
);
321 DetectEngineThreadCtxDeinit(&th_v
, (void *)det_ctx
);
322 DetectEnginePruneFreeList();
333 * \brief Wrapper for DetectContentLongPatternMatchTest
335 static int DetectReplaceLongPatternMatchTestWrp(const char *sig
, uint32_t sid
, const char *sig_rep
, uint32_t sid_rep
)
338 /** Real packet with the following tcp data:
339 * "Hi, this is a big test to check content matches of splitted"
340 * "patterns between multiple chunks!"
341 * (without quotes! :) )
343 uint8_t raw_eth_pkt
[] = {
344 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
345 0x00,0x00,0x00,0x00,0x08,0x00,0x45,0x00,
346 0x00,0x85,0x00,0x01,0x00,0x00,0x40,0x06,
347 0x7c,0x70,0x7f,0x00,0x00,0x01,0x7f,0x00,
348 0x00,0x01,0x00,0x14,0x00,0x50,0x00,0x00,
349 0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x02,
350 0x20,0x00,0xc9,0xad,0x00,0x00,0x48,0x69,
351 0x2c,0x20,0x74,0x68,0x69,0x73,0x20,0x69,
352 0x73,0x20,0x61,0x20,0x62,0x69,0x67,0x20,
353 0x74,0x65,0x73,0x74,0x20,0x74,0x6f,0x20,
354 0x63,0x68,0x65,0x63,0x6b,0x20,0x63,0x6f,
355 0x6e,0x74,0x65,0x6e,0x74,0x20,0x6d,0x61,
356 0x74,0x63,0x68,0x65,0x73,0x20,0x6f,0x66,
357 0x20,0x73,0x70,0x6c,0x69,0x74,0x74,0x65,
358 0x64,0x20,0x70,0x61,0x74,0x74,0x65,0x72,
359 0x6e,0x73,0x20,0x62,0x65,0x74,0x77,0x65,
360 0x65,0x6e,0x20,0x6d,0x75,0x6c,0x74,0x69,
361 0x70,0x6c,0x65,0x20,0x63,0x68,0x75,0x6e,
362 0x6b,0x73,0x21 }; /* end raw_eth_pkt */
363 uint8_t p
[sizeof(raw_eth_pkt
)];
364 uint16_t psize
= sizeof(raw_eth_pkt
);
366 /* would be unittest */
367 int run_mode_backup
= run_mode
;
368 run_mode
= RUNMODE_NFQ
;
369 ret
= DetectReplaceLongPatternMatchTest(raw_eth_pkt
, (uint16_t)sizeof(raw_eth_pkt
),
370 sig
, sid
, p
, &psize
);
372 SCLogDebug("replace: test1 phase1");
373 ret
= DetectReplaceLongPatternMatchTest(p
, psize
, sig_rep
, sid_rep
, NULL
, NULL
);
375 run_mode
= run_mode_backup
;
381 * \brief Wrapper for DetectContentLongPatternMatchTest
383 static int DetectReplaceLongPatternMatchTestUDPWrp(const char *sig
, uint32_t sid
, const char *sig_rep
, uint32_t sid_rep
)
386 /** Real UDP DNS packet with a request A to a1.twimg.com
388 uint8_t raw_eth_pkt
[] = {
389 0x8c, 0xa9, 0x82, 0x75, 0x5d, 0x62, 0xb4, 0x07,
390 0xf9, 0xf3, 0xc7, 0x0a, 0x08, 0x00, 0x45, 0x00,
391 0x00, 0x3a, 0x92, 0x4f, 0x40, 0x00, 0x40, 0x11,
392 0x31, 0x1a, 0xc0, 0xa8, 0x00, 0x02, 0xc1, 0xbd,
393 0xf4, 0xe1, 0x3b, 0x7e, 0x00, 0x35, 0x00, 0x26,
394 0xcb, 0x81, 0x37, 0x62, 0x01, 0x00, 0x00, 0x01,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x61,
396 0x31, 0x05, 0x74, 0x77, 0x69, 0x6d, 0x67, 0x03,
397 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01 };
399 uint8_t p
[sizeof(raw_eth_pkt
)];
400 uint16_t psize
= sizeof(raw_eth_pkt
);
402 int run_mode_backup
= run_mode
;
403 run_mode
= RUNMODE_NFQ
;
404 ret
= DetectReplaceLongPatternMatchTest(raw_eth_pkt
, (uint16_t)sizeof(raw_eth_pkt
),
405 sig
, sid
, p
, &psize
);
407 SCLogDebug("replace: test1 phase1 ok: %" PRIuMAX
" vs %d",(uintmax_t)sizeof(raw_eth_pkt
),psize
);
408 ret
= DetectReplaceLongPatternMatchTest(p
, psize
, sig_rep
, sid_rep
, NULL
, NULL
);
410 run_mode
= run_mode_backup
;
415 * \test Check if replace is working
417 static int DetectReplaceMatchTest01(void)
419 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
420 " content:\"big\"; replace:\"pig\"; sid:1;)";
421 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
422 " content:\"this is a pig test\"; sid:2;)";
423 return DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
427 * \test Check if replace is working with offset
429 static int DetectReplaceMatchTest02(void)
431 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
432 " content:\"th\"; offset: 4; replace:\"TH\"; sid:1;)";
433 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
434 " content:\"THis\"; offset:4; sid:2;)";
435 return DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
439 * \test Check if replace is working with offset and keyword inversion
441 static int DetectReplaceMatchTest03(void)
443 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
444 " content:\"th\"; replace:\"TH\"; offset: 4; sid:1;)";
445 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
446 " content:\"THis\"; offset:4; sid:2;)";
447 return DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
451 * \test Check if replace is working with second content
453 static int DetectReplaceMatchTest04(void)
455 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
456 " content:\"th\"; replace:\"TH\"; content:\"patter\"; replace:\"matter\"; sid:1;)";
457 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
458 " content:\"THis\"; content:\"matterns\"; sid:2;)";
459 return DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
463 * \test Check if replace is not done when second content don't match
465 static int DetectReplaceMatchTest05(void)
467 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
468 " content:\"th\"; replace:\"TH\"; content:\"nutella\"; sid:1;)";
469 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
470 " content:\"TH\"; sid:2;)";
471 return !DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
475 * \test Check if replace is not done when second content match and not
478 static int DetectReplaceMatchTest06(void)
480 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
481 " content:\"nutella\"; replace:\"commode\"; content:\"this is\"; sid:1;)";
482 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
483 " content:\"commode\"; sid:2;)";
484 return !DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
488 * \test Check if replace is working when nocase used
490 static int DetectReplaceMatchTest07(void)
492 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
493 " content:\"BiG\"; nocase; replace:\"pig\"; sid:1;)";
494 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
495 " content:\"this is a pig test\"; sid:2;)";
496 return DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
500 * \test Check if replace is working when depth is used
502 static int DetectReplaceMatchTest08(void)
504 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
505 " content:\"big\"; depth:17; replace:\"pig\"; sid:1;)";
506 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
507 " content:\"this is a pig test\"; sid:2;)";
508 return DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
512 * \test Check if replace is working when depth block match used
514 static int DetectReplaceMatchTest09(void)
516 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
517 " content:\"big\"; depth:16; replace:\"pig\"; sid:1;)";
518 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
519 " content:\"this is a pig test\"; sid:2;)";
520 return !DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
524 * \test Check if replace is working when depth block match used
526 static int DetectReplaceMatchTest10(void)
528 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
529 " content:\"big\"; depth:17; replace:\"pig\"; offset: 14; sid:1;)";
530 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
531 " content:\"pig\"; depth:17; offset:14; sid:2;)";
532 return DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
536 * \test Check if replace is working with within
538 static int DetectReplaceMatchTest11(void)
540 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
541 " content:\"big\"; replace:\"pig\"; content:\"to\"; within: 11; sid:1;)";
542 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
543 " content:\"pig\"; depth:17; offset:14; sid:2;)";
544 return DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
548 * \test Check if replace is working with within
550 static int DetectReplaceMatchTest12(void)
552 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
553 " content:\"big\"; replace:\"pig\"; content:\"to\"; within: 4; sid:1;)";
554 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
555 " content:\"pig\"; depth:17; offset:14; sid:2;)";
556 return !DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
560 * \test Check if replace is working with within
562 static int DetectReplaceMatchTest13(void)
564 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
565 " content:\"big\"; replace:\"pig\"; content:\"test\"; distance: 1; sid:1;)";
566 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
567 " content:\"pig\"; depth:17; offset:14; sid:2;)";
568 return DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
572 * \test Check if replace is working with within
574 static int DetectReplaceMatchTest14(void)
576 const char *sig
= "alert tcp any any -> any any (msg:\"Nothing..\";"
577 " content:\"big\"; replace:\"pig\"; content:\"test\"; distance: 2; sid:1;)";
578 const char *sig_rep
= "alert tcp any any -> any any (msg:\"replace worked\";"
579 " content:\"pig\"; depth:17; offset:14; sid:2;)";
580 return !DetectReplaceLongPatternMatchTestWrp(sig
, 1, sig_rep
, 2);
584 * \test Check if replace is working with within
586 static int DetectReplaceMatchTest15(void)
588 const char *sig
= "alert udp any any -> any any (msg:\"Nothing..\";"
589 " content:\"com\"; replace:\"org\"; sid:1;)";
590 const char *sig_rep
= "alert udp any any -> any any (msg:\"replace worked\";"
591 " content:\"twimg|03|org\"; sid:2;)";
592 return DetectReplaceLongPatternMatchTestUDPWrp(sig
, 1, sig_rep
, 2);
599 static int DetectReplaceParseTest01(void)
601 int run_mode_backup
= run_mode
;
602 run_mode
= RUNMODE_NFQ
;
604 DetectEngineCtx
*de_ctx
= NULL
;
607 de_ctx
= DetectEngineCtxInit();
611 de_ctx
->flags
|= DE_QUIET
;
612 de_ctx
->sig_list
= SigInit(de_ctx
,
613 "alert udp any any -> any any "
614 "(msg:\"test\"; content:\"doh\"; replace:\"; sid:238012;)");
615 if (de_ctx
->sig_list
!= NULL
) {
621 run_mode
= run_mode_backup
;
623 SigGroupCleanup(de_ctx
);
624 SigCleanSignatures(de_ctx
);
625 DetectEngineCtxFree(de_ctx
);
631 * \test Parsing test: non valid because of http protocol
633 static int DetectReplaceParseTest02(void)
635 int run_mode_backup
= run_mode
;
636 run_mode
= RUNMODE_NFQ
;
638 DetectEngineCtx
*de_ctx
= NULL
;
641 de_ctx
= DetectEngineCtxInit();
645 de_ctx
->flags
|= DE_QUIET
;
646 de_ctx
->sig_list
= SigInit(de_ctx
,
647 "alert http any any -> any any "
648 "(msg:\"test\"; content:\"doh\"; replace:\"bon\"; sid:238012;)");
649 if (de_ctx
->sig_list
== NULL
) {
655 run_mode
= run_mode_backup
;
657 SigGroupCleanup(de_ctx
);
658 SigCleanSignatures(de_ctx
);
659 DetectEngineCtxFree(de_ctx
);
665 * \test Parsing test: non valid because of http_header on same content
668 static int DetectReplaceParseTest03(void)
670 int run_mode_backup
= run_mode
;
671 run_mode
= RUNMODE_NFQ
;
673 DetectEngineCtx
*de_ctx
= NULL
;
676 de_ctx
= DetectEngineCtxInit();
680 de_ctx
->flags
|= DE_QUIET
;
681 de_ctx
->sig_list
= SigInit(de_ctx
,
682 "alert tcp any any -> any any "
683 "(msg:\"test\"; content:\"doh\"; replace:\"don\"; http_header; sid:238012;)");
684 if (de_ctx
->sig_list
!= NULL
) {
690 run_mode
= run_mode_backup
;
692 SigGroupCleanup(de_ctx
);
693 SigCleanSignatures(de_ctx
);
694 DetectEngineCtxFree(de_ctx
);
700 * \test Parsing test no content
702 static int DetectReplaceParseTest04(void)
704 int run_mode_backup
= run_mode
;
705 run_mode
= RUNMODE_NFQ
;
707 DetectEngineCtx
*de_ctx
= NULL
;
710 de_ctx
= DetectEngineCtxInit();
714 de_ctx
->flags
|= DE_QUIET
;
715 de_ctx
->sig_list
= SigInit(de_ctx
,
716 "alert tcp any any -> any any "
717 "(msg:\"test\"; replace:\"don\"; sid:238012;)");
718 if (de_ctx
->sig_list
!= NULL
) {
724 run_mode
= run_mode_backup
;
726 SigGroupCleanup(de_ctx
);
727 SigCleanSignatures(de_ctx
);
728 DetectEngineCtxFree(de_ctx
);
734 * \test Parsing test content after replace
736 static int DetectReplaceParseTest05(void)
738 int run_mode_backup
= run_mode
;
739 run_mode
= RUNMODE_NFQ
;
741 DetectEngineCtx
*de_ctx
= NULL
;
744 de_ctx
= DetectEngineCtxInit();
748 de_ctx
->flags
|= DE_QUIET
;
749 de_ctx
->sig_list
= SigInit(de_ctx
,
750 "alert tcp any any -> any any "
751 "(msg:\"test\"; replace:\"don\"; content:\"doh\"; sid:238012;)");
752 if (de_ctx
->sig_list
!= NULL
) {
758 run_mode
= run_mode_backup
;
760 SigGroupCleanup(de_ctx
);
761 SigCleanSignatures(de_ctx
);
762 DetectEngineCtxFree(de_ctx
);
768 * \test Parsing test content and replace length differ
770 static int DetectReplaceParseTest06(void)
772 int run_mode_backup
= run_mode
;
773 run_mode
= RUNMODE_NFQ
;
775 DetectEngineCtx
*de_ctx
= NULL
;
778 de_ctx
= DetectEngineCtxInit();
782 de_ctx
->flags
|= DE_QUIET
;
783 de_ctx
->sig_list
= SigInit(de_ctx
,
784 "alert tcp any any -> any any "
785 "(msg:\"test\"; content:\"don\"; replace:\"donut\"; sid:238012;)");
786 if (de_ctx
->sig_list
!= NULL
) {
792 run_mode
= run_mode_backup
;
794 SigGroupCleanup(de_ctx
);
795 SigCleanSignatures(de_ctx
);
796 DetectEngineCtxFree(de_ctx
);
802 * \test Parsing test content and replace length differ
804 static int DetectReplaceParseTest07(void)
806 int run_mode_backup
= run_mode
;
807 run_mode
= RUNMODE_NFQ
;
809 DetectEngineCtx
*de_ctx
= NULL
;
812 de_ctx
= DetectEngineCtxInit();
816 de_ctx
->flags
|= DE_QUIET
;
817 de_ctx
->sig_list
= SigInit(de_ctx
,
818 "alert tcp any any -> any any "
819 "(msg:\"test\"; content:\"don\"; replace:\"dou\"; content:\"jpg\"; http_header; sid:238012;)");
820 if (de_ctx
->sig_list
!= NULL
) {
826 run_mode
= run_mode_backup
;
828 SigGroupCleanup(de_ctx
);
829 SigCleanSignatures(de_ctx
);
830 DetectEngineCtxFree(de_ctx
);
836 * \brief this function registers unit tests for DetectContent
838 void DetectReplaceRegisterTests(void)
841 UtRegisterTest("DetectReplaceMatchTest01", DetectReplaceMatchTest01
);
842 UtRegisterTest("DetectReplaceMatchTest02", DetectReplaceMatchTest02
);
843 UtRegisterTest("DetectReplaceMatchTest03", DetectReplaceMatchTest03
);
844 UtRegisterTest("DetectReplaceMatchTest04", DetectReplaceMatchTest04
);
845 UtRegisterTest("DetectReplaceMatchTest05", DetectReplaceMatchTest05
);
846 UtRegisterTest("DetectReplaceMatchTest06", DetectReplaceMatchTest06
);
847 UtRegisterTest("DetectReplaceMatchTest07", DetectReplaceMatchTest07
);
848 UtRegisterTest("DetectReplaceMatchTest08", DetectReplaceMatchTest08
);
849 UtRegisterTest("DetectReplaceMatchTest09", DetectReplaceMatchTest09
);
850 UtRegisterTest("DetectReplaceMatchTest10", DetectReplaceMatchTest10
);
851 UtRegisterTest("DetectReplaceMatchTest11", DetectReplaceMatchTest11
);
852 UtRegisterTest("DetectReplaceMatchTest12", DetectReplaceMatchTest12
);
853 UtRegisterTest("DetectReplaceMatchTest13", DetectReplaceMatchTest13
);
854 UtRegisterTest("DetectReplaceMatchTest14", DetectReplaceMatchTest14
);
855 UtRegisterTest("DetectReplaceMatchTest15", DetectReplaceMatchTest15
);
857 UtRegisterTest("DetectReplaceParseTest01", DetectReplaceParseTest01
);
858 UtRegisterTest("DetectReplaceParseTest02", DetectReplaceParseTest02
);
859 UtRegisterTest("DetectReplaceParseTest03", DetectReplaceParseTest03
);
860 UtRegisterTest("DetectReplaceParseTest04", DetectReplaceParseTest04
);
861 UtRegisterTest("DetectReplaceParseTest05", DetectReplaceParseTest05
);
862 UtRegisterTest("DetectReplaceParseTest06", DetectReplaceParseTest06
);
863 UtRegisterTest("DetectReplaceParseTest07", DetectReplaceParseTest07
);
865 #endif /* UNITTESTS */