suricata
detect-engine-sigorder.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2024 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 * \file
20 *
21 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
22 *
23 * Signature ordering part of the detection engine.
24 */
25
26#include "suricata-common.h"
27#include "detect.h"
28#include "detect-xbits.h"
29#include "detect-flowbits.h"
30#include "detect-flowint.h"
31#include "detect-parse.h"
33#include "detect-pcre.h"
34#include "detect-engine-build.h"
35
36#include "util-unittest.h"
38#include "util-debug.h"
39#include "util-action.h"
40#include "action-globals.h"
41#include "flow-util.h"
42#include "util-validate.h"
43
44#define DETECT_FLOWVAR_NOT_USED 1
45#define DETECT_FLOWVAR_TYPE_READ 2
46#define DETECT_FLOWVAR_TYPE_SET_READ 3
47#define DETECT_FLOWVAR_TYPE_SET 4
48
49#define DETECT_PKTVAR_NOT_USED 1
50#define DETECT_PKTVAR_TYPE_READ 2
51#define DETECT_PKTVAR_TYPE_SET_READ 3
52#define DETECT_PKTVAR_TYPE_SET 4
53
54#define DETECT_FLOWBITS_NOT_USED 1
55#define DETECT_FLOWBITS_TYPE_READ 2
56#define DETECT_FLOWBITS_TYPE_SET_READ 3
57#define DETECT_FLOWBITS_TYPE_SET 4
58
59#define DETECT_FLOWINT_NOT_USED 1
60#define DETECT_FLOWINT_TYPE_READ 2
61#define DETECT_FLOWINT_TYPE_SET_READ 3
62#define DETECT_FLOWINT_TYPE_SET 4
63
64#define DETECT_XBITS_NOT_USED 1
65#define DETECT_XBITS_TYPE_READ 2
66#define DETECT_XBITS_TYPE_SET_READ 3
67#define DETECT_XBITS_TYPE_SET 4
68
69/**
70 * \brief Different kinds of helper data that can be used by the signature
71 * ordering module. Used by the "user" field in SCSigSignatureWrapper
72 */
82
83/**
84 * \brief Signature wrapper used by signature ordering module while ordering
85 * signatures
86 */
87typedef struct SCSigSignatureWrapper_ {
88 /* the wrapped signature */
90
91 /* user data that is to be associated with this sigwrapper */
93
96
97/**
98 * \brief Structure holding the signature ordering function used by the
99 * signature ordering module
100 */
101typedef struct SCSigOrderFunc_ {
102 /* Pointer to the Signature Ordering function */
104
107
108/**
109 * \brief Registers a keyword-based, signature ordering function
110 *
111 * \param de_ctx Pointer to the detection engine context from which the
112 * signatures have to be ordered.
113 * \param FuncPtr Pointer to the signature ordering function. The prototype of
114 * the signature ordering function should accept a pointer to a
115 * SCSigSignatureWrapper as its argument and shouldn't return
116 * anything
117 */
118static void SCSigRegisterSignatureOrderingFunc(DetectEngineCtx *de_ctx,
120{
121 SCSigOrderFunc *curr = NULL;
122 SCSigOrderFunc *prev = NULL;
123 SCSigOrderFunc *temp = NULL;
124
126
127 /* Walk to the end of the list, and leave prev pointing at the
128 last element. */
129 prev = curr;
130 while (curr != NULL) {
131 if (curr->SWCompare == SWCompare) {
132 /* Already specified this compare */
133 return;
134 }
135 prev = curr;
136 curr = curr->next;
137 }
138
139 if ((temp = SCCalloc(1, sizeof(SCSigOrderFunc))) == NULL) {
140 FatalError("Fatal error encountered in SCSigRegisterSignatureOrderingFunc. Exiting...");
141 }
142
143 temp->SWCompare = SWCompare;
144
145 /* Append the new compare function at the end of the list. */
146 if (prev == NULL)
148 else
149 prev->next = temp;
150}
151
152/**
153 * \brief Returns the flowbit type set for this signature. If more than one
154 * flowbit has been set for the same rule, we return the flowbit type of
155 * the maximum priority/value, where priority/value is maximum for the
156 * ones that set the value and the lowest for ones that read the value.
157 * If no flowbit has been set for the rule, we return 0, which indicates
158 * the least value amongst flowbit types.
159 *
160 * \param sig Pointer to the Signature from which the flowbit value has to be
161 * returned.
162 *
163 * \retval flowbits The flowbits type for this signature if it is set; if it is
164 * not set, return 0
165 */
166static inline int SCSigGetFlowbitsType(Signature *sig)
167{
168 DetectFlowbitsData *fb = NULL;
169 int flowbits_user_type = DETECT_FLOWBITS_NOT_USED;
170 int read = 0;
171 int write = 0;
173
174 while (sm != NULL) {
175 if (sm->type == DETECT_FLOWBITS) {
176 fb = (DetectFlowbitsData *)sm->ctx;
179 read++;
180 } else {
181#ifdef DEBUG
182 BUG_ON(1);
183#endif
184 }
185 }
186
187 sm = sm->next;
188 }
189
191 while (sm != NULL) {
192 if (sm->type == DETECT_FLOWBITS) {
193 fb = (DetectFlowbitsData *)sm->ctx;
194 if (fb->cmd == DETECT_FLOWBITS_CMD_SET ||
197 write++;
198 } else {
199#ifdef DEBUG
200 BUG_ON(1);
201#endif
202 }
203 }
204
205 sm = sm->next;
206 }
207
208 if (read > 0 && write == 0) {
209 flowbits_user_type = DETECT_FLOWBITS_TYPE_READ;
210 } else if (read == 0 && write > 0) {
211 flowbits_user_type = DETECT_FLOWBITS_TYPE_SET;
212 } else if (read > 0 && write > 0) {
213 flowbits_user_type = DETECT_FLOWBITS_TYPE_SET_READ;
214 }
215
216 SCLogDebug("Sig %s typeval %d", sig->msg, flowbits_user_type);
217
218 return flowbits_user_type;
219}
220
221static inline int SCSigGetFlowintType(Signature *sig)
222{
223 DetectFlowintData *fi = NULL;
224 int flowint_user_type = DETECT_FLOWINT_NOT_USED;
225 int read = 0;
226 int write = 0;
228
229 while (sm != NULL) {
230 if (sm->type == DETECT_FLOWINT) {
231 fi = (DetectFlowintData *)sm->ctx;
237 read++;
238 } else {
239#ifdef DEBUG
240 BUG_ON(1);
241#endif
242 }
243 }
244
245 sm = sm->next;
246 }
247
249 while (sm != NULL) {
250 if (sm->type == DETECT_FLOWINT) {
251 fi = (DetectFlowintData *)sm->ctx;
252 if (fi->modifier == FLOWINT_MODIFIER_SET ||
255 write++;
256 } else {
257#ifdef DEBUG
258 BUG_ON(1);
259#endif
260 }
261 }
262
263 sm = sm->next;
264 }
265
266 if (read > 0 && write == 0) {
267 flowint_user_type = DETECT_FLOWINT_TYPE_READ;
268 } else if (read == 0 && write > 0) {
269 flowint_user_type = DETECT_FLOWINT_TYPE_SET;
270 } else if (read > 0 && write > 0) {
271 flowint_user_type = DETECT_FLOWINT_TYPE_SET_READ;
272 }
273
274 SCLogDebug("Sig %s typeval %d", sig->msg, flowint_user_type);
275
276 return flowint_user_type;
277}
278
279/**
280 * \brief Returns whether the flowvar set for this rule, sets the flowvar or
281 * reads the flowvar. If the rule sets the flowvar the function returns
282 * DETECT_FLOWVAR_TYPE_SET(3), if it reads the flowvar the function
283 * returns DETECT_FLOWVAR_TYPE_READ(2), and if flowvar is not used in this
284 * rule the function returns DETECT_FLOWVAR_NOT_USED(1)
285 *
286 * \param sig Pointer to the Signature from which the flowvar type has to be
287 * returned.
288 *
289 * \retval type DETECT_FLOWVAR_TYPE_SET(3) if the rule sets the flowvar,
290 * DETECT_FLOWVAR_TYPE_READ(2) if it reads, and
291 * DETECT_FLOWVAR_NOT_USED(1) if flowvar is not used.
292 */
293static inline int SCSigGetFlowvarType(Signature *sig)
294{
295 DetectPcreData *pd = NULL;
297 int read = 0;
298 int write = 0;
300
301 while (sm != NULL) {
302 pd = (DetectPcreData *)sm->ctx;
303 if (sm->type == DETECT_PCRE) {
304 uint8_t x;
305 for (x = 0; x < pd->idx; x++) {
306 if (pd->captypes[x] == VAR_TYPE_FLOW_VAR) {
307 write++;
308 break;
309 }
310 }
311 }
312
313 sm = sm->next;
314 }
315
317 pd = NULL;
318 while (sm != NULL) {
319 if (sm->type == DETECT_FLOWVAR) {
320 read++;
321 }
322
323 sm = sm->next;
324 }
325
326 if (read > 0 && write == 0) {
328 } else if (read == 0 && write > 0) {
330 } else if (read > 0 && write > 0) {
332 }
333
334 return type;
335}
336
337/**
338 * \brief Returns whether the pktvar set for this rule, sets the flowvar or
339 * reads the pktvar. If the rule sets the pktvar the function returns
340 * DETECT_PKTVAR_TYPE_SET(3), if it reads the pktvar the function
341 * returns DETECT_PKTVAR_TYPE_READ(2), and if pktvar is not used in this
342 * rule the function returns DETECT_PKTVAR_NOT_USED(1)
343 *
344 * \param sig Pointer to the Signature from which the pktvar type has to be
345 * returned.
346 *
347 * \retval type DETECT_PKTVAR_TYPE_SET(3) if the rule sets the flowvar,
348 * DETECT_PKTVAR_TYPE_READ(2) if it reads, and
349 * DETECT_PKTVAR_NOT_USED(1) if pktvar is not used.
350 */
351static inline int SCSigGetPktvarType(Signature *sig)
352{
353 DetectPcreData *pd = NULL;
355 int read = 0;
356 int write = 0;
358
359 while (sm != NULL) {
360 pd = (DetectPcreData *)sm->ctx;
361 if (sm->type == DETECT_PCRE) {
362 uint8_t x;
363 for (x = 0; x < pd->idx; x++) {
364 if (pd->captypes[x] == VAR_TYPE_PKT_VAR) {
365 write++;
366 break;
367 }
368 }
369 }
370
371 sm = sm->next;
372 }
373
375 pd = NULL;
376 while (sm != NULL) {
377 if (sm->type == DETECT_PKTVAR) {
378 read++;
379 }
380
381 sm = sm->next;
382 }
383
384 if (read > 0 && write == 0) {
386 } else if (read == 0 && write > 0) {
388 } else if (read > 0 && write > 0) {
390 }
391
392 return type;
393}
394
395/**
396 * \brief Returns the xbit type set for this signature. If more than one
397 * xbit has been set for the same rule, we return the xbit type of
398 * the maximum priority/value, where priority/value is maximum for the
399 * ones that set the value and the lowest for ones that read the value.
400 * If no xbit has been set for the rule, we return 0, which indicates
401 * the least value amongst xbit types.
402 *
403 * \param sig Pointer to the Signature from which the xbit value has to be
404 * returned.
405 *
406 * \retval xbits The xbits type for this signature if it is set; if it is
407 * not set, return 0
408 */
409static inline int SCSigGetXbitsType(Signature *sig, enum VarTypes type)
410{
411 DetectXbitsData *fb = NULL;
412 int xbits_user_type = DETECT_XBITS_NOT_USED;
413 int read = 0;
414 int write = 0;
416
417 while (sm != NULL) {
418 if (sm->type == DETECT_XBITS) {
419 fb = (DetectXbitsData *)sm->ctx;
420 if (fb->type == type) {
421 if (fb->cmd == DETECT_XBITS_CMD_ISNOTSET ||
423 read++;
424 } else {
425#ifdef DEBUG
426 BUG_ON(1);
427#endif
428 }
429 }
430 }
431
432 sm = sm->next;
433 }
434
436 while (sm != NULL) {
437 if (sm->type == DETECT_HOSTBITS) {
438 fb = (DetectXbitsData *)sm->ctx;
439 if (fb->type == type) {
440 if (fb->cmd == DETECT_XBITS_CMD_SET ||
443 write++;
444 } else {
445#ifdef DEBUG
446 BUG_ON(1);
447#endif
448 }
449 }
450 }
451
452 sm = sm->next;
453 }
454
455 if (read > 0 && write == 0) {
456 xbits_user_type = DETECT_XBITS_TYPE_READ;
457 } else if (read == 0 && write > 0) {
458 xbits_user_type = DETECT_XBITS_TYPE_SET;
459 } else if (read > 0 && write > 0) {
460 xbits_user_type = DETECT_XBITS_TYPE_SET_READ;
461 }
462
463 SCLogDebug("Sig %s typeval %d", sig->msg, xbits_user_type);
464
465 return xbits_user_type;
466}
467
468/**
469 * \brief Processes the flowbits data for this signature and caches it for
470 * future use. This is needed to optimize the sig_ordering module.
471 *
472 * \param sw The sigwrapper/signature for which the flowbits data has to be
473 * cached
474 */
475static inline void SCSigProcessUserDataForFlowbits(SCSigSignatureWrapper *sw)
476{
477 sw->user[DETECT_SIGORDER_FLOWBITS] = SCSigGetFlowbitsType(sw->sig);
478}
479
480/**
481 * \brief Processes the flowvar data for this signature and caches it for
482 * future use. This is needed to optimize the sig_ordering module.
483 *
484 * \param sw The sigwrapper/signature for which the flowvar data has to be
485 * cached
486 */
487static inline void SCSigProcessUserDataForFlowvar(SCSigSignatureWrapper *sw)
488{
489 sw->user[DETECT_SIGORDER_FLOWVAR] = SCSigGetFlowvarType(sw->sig);
490}
491
492static inline void SCSigProcessUserDataForFlowint(SCSigSignatureWrapper *sw)
493{
494 sw->user[DETECT_SIGORDER_FLOWINT] = SCSigGetFlowintType(sw->sig);
495}
496
497/**
498 * \brief Processes the pktvar data for this signature and caches it for
499 * future use. This is needed to optimize the sig_ordering module.
500 *
501 * \param sw The sigwrapper/signature for which the pktvar data has to be
502 * cached
503 */
504static inline void SCSigProcessUserDataForPktvar(SCSigSignatureWrapper *sw)
505{
506 sw->user[DETECT_SIGORDER_PKTVAR] = SCSigGetPktvarType(sw->sig);
507}
508
509/**
510 * \brief Processes the hostbits data for this signature and caches it for
511 * future use. This is needed to optimize the sig_ordering module.
512 *
513 * \param sw The sigwrapper/signature for which the hostbits data has to be
514 * cached
515 */
516static inline void SCSigProcessUserDataForHostbits(SCSigSignatureWrapper *sw)
517{
518 sw->user[DETECT_SIGORDER_HOSTBITS] = SCSigGetXbitsType(sw->sig, VAR_TYPE_HOST_BIT);
519}
520
521/**
522 * \brief Processes the hostbits data for this signature and caches it for
523 * future use. This is needed to optimize the sig_ordering module.
524 *
525 * \param sw The sigwrapper/signature for which the hostbits data has to be
526 * cached
527 */
528static inline void SCSigProcessUserDataForIPPairbits(SCSigSignatureWrapper *sw)
529{
530 sw->user[DETECT_SIGORDER_IPPAIRBITS] = SCSigGetXbitsType(sw->sig, VAR_TYPE_IPPAIR_BIT);
531}
532
533/* Return 1 if sw1 comes before sw2 in the final list. */
534static int SCSigLessThan(SCSigSignatureWrapper *sw1,
536 SCSigOrderFunc *cmp_func_list)
537{
538 SCSigOrderFunc *funcs = cmp_func_list;
539
540 while (funcs != NULL) {
541 int delta = funcs->SWCompare(sw1, sw2);
542 if (delta > 0)
543 return 1;
544 else if (delta < 0)
545 return 0;
546
547 funcs = funcs->next;
548 }
549 // They are equal, so use sid as the final decider.
550 return sw1->sig->id < sw2->sig->id;
551}
552
553/* Merge sort based on a list of compare functions
554 * debug asserts are here to guide scan-build */
555static SCSigSignatureWrapper *SCSigOrder(SCSigSignatureWrapper *sw,
556 SCSigOrderFunc *cmp_func_list)
557{
558 DEBUG_VALIDATE_BUG_ON(sw == NULL);
559
560 SCSigSignatureWrapper *subA = NULL;
561 SCSigSignatureWrapper *subB = NULL;
563 SCSigSignatureWrapper *second;
564 SCSigSignatureWrapper *result = NULL;
565 SCSigSignatureWrapper *last = NULL;
566 SCSigSignatureWrapper *new = NULL;
567
568 /* Divide input list into two sub-lists. */
569 while (sw != NULL) {
570 first = sw;
571 sw = sw->next;
572 /* Push the first element onto sub-list A */
573 first->next = subA;
574 subA = first;
575
576 if (sw == NULL)
577 break;
578 second = sw;
579 sw = sw->next;
580 /* Push the second element onto sub-list B */
581 second->next = subB;
582 subB = second;
583 }
584 if (subB == NULL) {
585 /* Only zero or one element on the list. */
586 return subA;
587 }
588 DEBUG_VALIDATE_BUG_ON(subA == NULL);
589
590 /* Now sort each list */
591 subA = SCSigOrder(subA, cmp_func_list);
592 subB = SCSigOrder(subB, cmp_func_list);
593 DEBUG_VALIDATE_BUG_ON(subA == NULL);
594 DEBUG_VALIDATE_BUG_ON(subB == NULL);
595
596 /* Merge the two sorted lists. */
597 while (subA != NULL && subB != NULL) {
598 if (SCSigLessThan(subA, subB, cmp_func_list)) {
599 new = subA;
600 subA = subA->next;
601 } else {
602 new = subB;
603 subB = subB->next;
604 }
605 /* Push onto the end of the output list. */
606 new->next = NULL;
607 if (result == NULL) {
608 result = new;
609 last = new;
610 } else {
611 last->next = new;
612 last = new;
613 }
614 }
615 /* Attach the rest of any remaining list. Only one can be non-NULL here. */
616 if (subA == NULL)
617 last->next = subB;
618 else if (subB == NULL)
619 last->next = subA;
620
621 return result;
622}
623
624/**
625 * \brief Orders an incoming Signature based on its action
626 *
627 * \param de_ctx Pointer to the detection engine context from which the
628 * signatures have to be ordered.
629 * \param sw The new signature that has to be ordered based on its action
630 */
631static int SCSigOrderByActionCompare(SCSigSignatureWrapper *sw1,
633{
634 return ActionOrderVal(sw2->sig->action) - ActionOrderVal(sw1->sig->action);
635}
636
637/**
638 * \brief Orders an incoming Signature based on its flowbits type
639 *
640 * \param de_ctx Pointer to the detection engine context from which the
641 * signatures have to be ordered.
642 * \param sw The new signature that has to be ordered based on its flowbits
643 */
644static int SCSigOrderByFlowbitsCompare(SCSigSignatureWrapper *sw1,
646{
648}
649
650/**
651 * \brief Orders an incoming Signature based on its flowvar type
652 *
653 * \param de_ctx Pointer to the detection engine context from which the
654 * signatures have to be ordered.
655 * \param sw The new signature that has to be ordered based on its flowvar
656 */
657static int SCSigOrderByFlowvarCompare(SCSigSignatureWrapper *sw1,
659{
661}
662
663/**
664 * \brief Orders an incoming Signature based on its pktvar type
665 *
666 * \param de_ctx Pointer to the detection engine context from which the
667 * signatures have to be ordered.
668 * \param sw The new signature that has to be ordered based on its pktvar
669 */
670static int SCSigOrderByPktvarCompare(SCSigSignatureWrapper *sw1,
672{
674}
675
676static int SCSigOrderByFlowintCompare(SCSigSignatureWrapper *sw1,
678{
680}
681
682/**
683 * \brief Orders an incoming Signature based on its hostbits type
684 *
685 * \param de_ctx Pointer to the detection engine context from which the
686 * signatures have to be ordered.
687 * \param sw The new signature that has to be ordered based on its hostbits
688 */
689static int SCSigOrderByHostbitsCompare(SCSigSignatureWrapper *sw1,
691{
693}
694
695/**
696 * \brief Orders an incoming Signature based on its ippairbits (xbits) type
697 *
698 * \param de_ctx Pointer to the detection engine context from which the
699 * signatures have to be ordered.
700 * \param sw The new signature that has to be ordered based on its bits
701 */
702static int SCSigOrderByIPPairbitsCompare(SCSigSignatureWrapper *sw1,
704{
706}
707
708/**
709 * \brief Orders an incoming Signature based on its priority type
710 *
711 * \param de_ctx Pointer to the detection engine context from which the
712 * signatures have to be ordered.
713 * \param sw The new signature that has to be ordered based on its priority
714 */
715static int SCSigOrderByPriorityCompare(SCSigSignatureWrapper *sw1,
717{
718 if (sw1->sig->prio > sw2->sig->prio) {
719 return -1;
720 } else if (sw1->sig->prio < sw2->sig->prio) {
721 return 1;
722 }
723 return 0;
724}
725
726static int SCSigOrderByIId(SCSigSignatureWrapper *sw1, SCSigSignatureWrapper *sw2)
727{
728 if (sw1->sig->iid > sw2->sig->iid) {
729 return -1;
730 } else if (sw1->sig->iid < sw2->sig->iid) {
731 return 1;
732 }
733 return 0;
734}
735
736/* sort by:
737 * alproto, progress, iid
738 */
739static int SCSigOrderByAppFirewall(SCSigSignatureWrapper *sw1, SCSigSignatureWrapper *sw2)
740{
741 int sw1dir = (sw1->sig->flags & SIG_FLAG_TOSERVER) != 0 ? 0 : 1;
742 int sw2dir = (sw2->sig->flags & SIG_FLAG_TOSERVER) != 0 ? 0 : 1;
743
744 if (sw1dir > sw2dir) {
745 return -1;
746 } else if (sw1dir < sw2dir) {
747 return 1;
748 }
749
750 if (sw1->sig->alproto > sw2->sig->alproto) {
751 return -1;
752 } else if (sw1->sig->alproto < sw2->sig->alproto) {
753 return 1;
754 }
755
756 if (sw1->sig->app_progress_hook > sw2->sig->app_progress_hook) {
757 return -1;
758 } else if (sw1->sig->app_progress_hook < sw2->sig->app_progress_hook) {
759 return 1;
760 }
761
762 if (sw1->sig->iid > sw2->sig->iid) {
763 return -1;
764 } else if (sw1->sig->iid < sw2->sig->iid) {
765 return 1;
766 }
767 return 0;
768}
769
770/**
771 * \brief Creates a Wrapper around the Signature
772 *
773 * \param Pointer to the Signature to be wrapped
774 *
775 * \retval sw Pointer to the wrapper that holds the signature
776 */
777static inline SCSigSignatureWrapper *SCSigAllocSignatureWrapper(Signature *sig)
778{
779 SCSigSignatureWrapper *sw = NULL;
780
781 if ((sw = SCCalloc(1, sizeof(SCSigSignatureWrapper))) == NULL)
782 return NULL;
783
784 sw->sig = sig;
785
786 /* Process data from the signature into a cache for further use by the
787 * sig_ordering module */
788 SCSigProcessUserDataForFlowbits(sw);
789 SCSigProcessUserDataForFlowvar(sw);
790 SCSigProcessUserDataForFlowint(sw);
791 SCSigProcessUserDataForPktvar(sw);
792 SCSigProcessUserDataForHostbits(sw);
793 SCSigProcessUserDataForIPPairbits(sw);
794
795 return sw;
796}
797
798/**
799 * \brief Orders the signatures
800 *
801 * \param de_ctx Pointer to the Detection Engine Context that holds the
802 * signatures to be ordered
803 */
805{
806 if (de_ctx->sig_list == NULL) {
807 SCLogDebug("no signatures to order");
808 return;
809 }
810
811 SCLogDebug("ordering signatures in memory");
812 SCSigSignatureWrapper *sigw = NULL;
813 SCSigSignatureWrapper *td_sigw_list = NULL; /* unified td list */
814
815 SCSigSignatureWrapper *fw_pf_sigw_list = NULL; /* hook: packet_filter */
816 SCSigSignatureWrapper *fw_af_sigw_list = NULL; /* hook: app_filter */
817
818 Signature *sig = de_ctx->sig_list;
819 while (sig != NULL) {
820 sigw = SCSigAllocSignatureWrapper(sig);
821 /* Push signature wrapper onto a list, order doesn't matter here. */
822 if (sig->init_data->firewall_rule) {
823 if (sig->type == SIG_TYPE_PKT) {
824 sigw->next = fw_pf_sigw_list;
825 fw_pf_sigw_list = sigw;
826 } else {
827 // TODO review types.
828 sigw->next = fw_af_sigw_list;
829 fw_af_sigw_list = sigw;
830 }
831 } else {
832 sigw->next = td_sigw_list;
833 td_sigw_list = sigw;
834 }
835 sig = sig->next;
836 }
837
838 /* despite having Append in the name, the new Sig/Rule funcs actually prepend with some special
839 * logic around bidir sigs. So to respect the firewall rule order, we sort this part of the list
840 * by the add order. */
841 if (fw_pf_sigw_list) {
842 SCSigOrderFunc OrderFn = { .SWCompare = SCSigOrderByIId, .next = NULL };
843 fw_pf_sigw_list = SCSigOrder(fw_pf_sigw_list, &OrderFn);
844 }
845 if (fw_af_sigw_list) {
846 SCSigOrderFunc OrderFn = { .SWCompare = SCSigOrderByAppFirewall, .next = NULL };
847 fw_af_sigw_list = SCSigOrder(fw_af_sigw_list, &OrderFn);
848 }
849 if (td_sigw_list) {
850 /* Sort the list */
851 td_sigw_list = SCSigOrder(td_sigw_list, de_ctx->sc_sig_order_funcs);
852 }
853 /* Recreate the sig list in order */
854 de_ctx->sig_list = NULL;
855
856 /* firewall list for hook packet_filter */
857 for (sigw = fw_pf_sigw_list; sigw != NULL;) {
858 SCLogDebug("post-sort packet_filter: sid %u", sigw->sig->id);
859 sigw->sig->next = NULL;
860 if (de_ctx->sig_list == NULL) {
861 /* First entry on the list */
862 de_ctx->sig_list = sigw->sig;
863 sig = de_ctx->sig_list;
864 } else {
865 sig->next = sigw->sig;
866 sig = sig->next;
867 }
868
869 SCSigSignatureWrapper *sigw_to_free = sigw;
870 sigw = sigw->next;
871 SCFree(sigw_to_free);
872 }
873 /* firewall list for hook app_filter */
874 for (sigw = fw_af_sigw_list; sigw != NULL;) {
875 SCLogDebug("post-sort app_filter: sid %u", sigw->sig->id);
876 sigw->sig->next = NULL;
877 if (de_ctx->sig_list == NULL) {
878 /* First entry on the list */
879 de_ctx->sig_list = sigw->sig;
880 sig = de_ctx->sig_list;
881 } else {
882 sig->next = sigw->sig;
883 sig = sig->next;
884 }
885
886 SCSigSignatureWrapper *sigw_to_free = sigw;
887 sigw = sigw->next;
888 SCFree(sigw_to_free);
889 }
890 /* threat detect list for hook app_td */
891 for (sigw = td_sigw_list; sigw != NULL;) {
892 sigw->sig->next = NULL;
893 if (de_ctx->sig_list == NULL) {
894 /* First entry on the list */
895 de_ctx->sig_list = sigw->sig;
896 sig = de_ctx->sig_list;
897 } else {
898 sig->next = sigw->sig;
899 sig = sig->next;
900 }
901
902 SCSigSignatureWrapper *sigw_to_free = sigw;
903 sigw = sigw->next;
904 SCFree(sigw_to_free);
905 }
906}
907
908/**
909 * \brief Lets you register the Signature ordering functions. The order in
910 * which the functions are registered shows the priority. The first
911 * function registered provides more priority than the function
912 * registered after it. To add a new registration function, register
913 * it by listing it in the correct position in the below sequence,
914 * based on the priority you would want to offer to that keyword.
915 *
916 * \param de_ctx Pointer to the detection engine context from which the
917 * signatures have to be ordered.
918 */
920{
921 SCLogDebug("registering signature ordering functions");
922
923 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
924 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
925 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowintCompare);
926 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
927 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
928 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByHostbitsCompare);
929 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByIPPairbitsCompare);
930 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
931}
932
933/**
934 * \brief De-registers all the signature ordering functions registered
935 *
936 * \param de_ctx Pointer to the detection engine context from which the
937 * signatures were ordered.
938 */
940{
941 SCSigOrderFunc *funcs;
942 void *temp;
943
944 /* clean the memory alloted to the signature ordering funcs */
945 funcs = de_ctx->sc_sig_order_funcs;
946 while (funcs != NULL) {
947 temp = funcs;
948 funcs = funcs->next;
949 SCFree(temp);
950 }
952}
953
954/**********Unittests**********/
955
960
961#ifdef UNITTESTS
962
963static int SCSigOrderingTest01(void)
964{
965 SCSigOrderFunc *temp = NULL;
966 int i = 0;
967
970
971 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
972 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
973 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
974 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
975 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
976 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
977 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
978 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
979 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
980 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
981 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
982
984 while (temp != NULL) {
985 i++;
986 temp = temp->next;
987 }
988
990
991 FAIL_IF_NOT(i == 5);
992
993 PASS;
994}
995
996static int SCSigOrderingTest02(void)
997{
998 Signature *sig = NULL;
999
1001 FAIL_IF(de_ctx == NULL);
1002
1004 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1005 FAIL_IF_NULL(sig);
1006
1008 "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:2;)");
1009 FAIL_IF_NULL(sig);
1010
1012 "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:3;)");
1013 FAIL_IF_NULL(sig);
1014
1016 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; flowvar:http_host,\"www.oisf.net\"; rev:4; priority:1; sid:4;)");
1017 FAIL_IF_NULL(sig);
1018
1020 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:5;)");
1021 FAIL_IF_NULL(sig);
1022
1024 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:6;)");
1025 FAIL_IF_NULL(sig);
1026
1028 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:7;)");
1029 FAIL_IF_NULL(sig);
1030
1032 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1033 FAIL_IF_NULL(sig);
1034
1036 "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; rev:4; priority:3; flowbits:set,TEST.one; flowbits:noalert; sid:9;)");
1037 FAIL_IF_NULL(sig);
1038
1040 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:10;)");
1041 FAIL_IF_NULL(sig);
1042
1044 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:11;)");
1045 FAIL_IF_NULL(sig);
1046
1048 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:12;)");
1049 FAIL_IF_NULL(sig);
1050
1052 "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; pktvar:http_host,\"www.oisf.net\"; priority:2; flowbits:isnotset,TEST.two; sid:13;)");
1053 FAIL_IF_NULL(sig);
1054
1056 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; flowbits:set,TEST.two; sid:14;)");
1057 FAIL_IF_NULL(sig);
1058
1059 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1060 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1061 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1062 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1063 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1065
1066 sig = de_ctx->sig_list;
1067
1068#ifdef DEBUG
1069 while (sig != NULL) {
1070 printf("sid: %d\n", sig->id);
1071 sig = sig->next;
1072 }
1073#endif
1074
1075 sig = de_ctx->sig_list;
1076
1077 /* pass */
1078 FAIL_IF_NOT(sig->id == 6);
1079 sig = sig->next;
1080 FAIL_IF_NOT(sig->id == 4);
1081 sig = sig->next;
1082 FAIL_IF_NOT(sig->id == 8);
1083 sig = sig->next;
1084 FAIL_IF_NOT(sig->id == 7);
1085 sig = sig->next;
1086 FAIL_IF_NOT(sig->id == 10);
1087 sig = sig->next;
1088
1089 /* drops */
1090 FAIL_IF_NOT(sig->id == 9);
1091 sig = sig->next;
1092 FAIL_IF_NOT(sig->id == 13);
1093 sig = sig->next;
1094 FAIL_IF_NOT(sig->id == 2);
1095 sig = sig->next;
1096 FAIL_IF_NOT(sig->id == 3);
1097 sig = sig->next;
1098
1099 /* alerts */
1100 FAIL_IF_NOT(sig->id == 14);
1101 sig = sig->next;
1102 FAIL_IF_NOT(sig->id == 5);
1103 sig = sig->next;
1104 FAIL_IF_NOT(sig->id == 1);
1105 sig = sig->next;
1106 FAIL_IF_NOT(sig->id == 11);
1107 sig = sig->next;
1108 FAIL_IF_NOT(sig->id == 12);
1109 sig = sig->next;
1110
1112 PASS;
1113}
1114
1115static int SCSigOrderingTest03(void)
1116{
1117 Signature *sig = NULL;
1118
1121
1123 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1124 "offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:1;)");
1125 FAIL_IF_NULL(sig);
1126
1128 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1129 "offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:2;)");
1130 FAIL_IF_NULL(sig);
1131
1133 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1134 "offset:10; depth:4; pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; "
1135 "flowbits:unset,TEST.one; rev:4; priority:2; sid:3;)");
1136 FAIL_IF_NULL(sig);
1137
1139 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1140 "offset:0; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1141 "flowbits:isset,TEST.one; rev:4; priority:1; sid:4;)");
1142 FAIL_IF_NULL(sig);
1143
1145 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1146 "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; priority:2; sid:5;)");
1147 FAIL_IF_NULL(sig);
1148
1150 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1151 "content:\"220\"; offset:10; flowbits:isnotset,TEST.one; pcre:\"/^User-Agent: "
1152 "(?P<flow_http_host>.*)\\r\\n/m\"; rev:4; sid:6;)");
1153 FAIL_IF_NULL(sig);
1154
1156 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1157 "content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; "
1158 "flowbits:unset,TEST.one; rev:4; priority:3; sid:7;)");
1159 FAIL_IF_NULL(sig);
1160
1162 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1163 "offset:10; depth:4; pcre:\"/220[- ]/\"; flowbits:toggle,TEST.one; rev:4; priority:1; "
1164 "pktvar:http_host,\"www.oisf.net\"; sid:8;)");
1165 FAIL_IF_NULL(sig);
1166
1168 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1169 "content:\"220\"; offset:10; depth:4; rev:4; flowbits:set,TEST.one; "
1170 "flowbits:noalert; pktvar:http_host,\"www.oisf.net\"; sid:9;)");
1171 FAIL_IF_NULL(sig);
1172
1174 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1175 "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:10;)");
1176 FAIL_IF_NULL(sig);
1177
1179 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1180 "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:11;)");
1181 FAIL_IF_NULL(sig);
1182
1184 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1185 "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:12;)");
1186 FAIL_IF_NULL(sig);
1187
1189 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1190 "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; flowbits:isnotset,TEST.one; sid:13;)");
1191 FAIL_IF_NULL(sig);
1192
1194 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1195 "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; flowbits:set,TEST.one; sid:14;)");
1196 FAIL_IF_NULL(sig);
1197
1198 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1199 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1200 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1201 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1202 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1204
1205 sig = de_ctx->sig_list;
1206
1207#ifdef DEBUG
1208 while (sig != NULL) {
1209 printf("sid: %d\n", sig->id);
1210 sig = sig->next;
1211 }
1212#endif
1213
1214 sig = de_ctx->sig_list;
1215
1216 FAIL_IF_NOT(sig->id == 3);
1217 sig = sig->next;
1218
1219 FAIL_IF_NOT(sig->id == 8);
1220 sig = sig->next;
1221 FAIL_IF_NOT(sig->id == 9);
1222 sig = sig->next;
1223 FAIL_IF_NOT(sig->id == 7);
1224 sig = sig->next;
1225 FAIL_IF_NOT(sig->id == 14);
1226 sig = sig->next;
1227 FAIL_IF_NOT(sig->id == 6);
1228 sig = sig->next;
1229 FAIL_IF_NOT(sig->id == 4);
1230 sig = sig->next;
1231 FAIL_IF_NOT(sig->id == 13);
1232 sig = sig->next;
1233 FAIL_IF_NOT(sig->id == 2);
1234 sig = sig->next;
1235 FAIL_IF_NOT(sig->id == 5);
1236 sig = sig->next;
1237 FAIL_IF_NOT(sig->id == 1);
1238 sig = sig->next;
1239 FAIL_IF_NOT(sig->id == 10);
1240 sig = sig->next;
1241 FAIL_IF_NOT(sig->id == 11);
1242 sig = sig->next;
1243 FAIL_IF_NOT(sig->id == 12);
1244
1245 sig = sig->next;
1246
1248
1249 PASS;
1250}
1251
1252static int SCSigOrderingTest04(void)
1253{
1254
1255 Signature *sig = NULL;
1256
1258 FAIL_IF(de_ctx == NULL);
1259
1261 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1262 "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1263 FAIL_IF_NULL(sig);
1264
1266 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1267 "pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; content:\"220\"; "
1268 "offset:10; rev:4; priority:3; sid:2;)");
1269 FAIL_IF_NULL(sig);
1270
1272 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1273 "content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: "
1274 "(?P<flow_http_host>.*)\\r\\n/m\"; rev:4; priority:3; sid:3;)");
1275 FAIL_IF_NULL(sig);
1276
1278 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1279 "offset:10; depth:4; pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; rev:4; "
1280 "priority:3; flowvar:http_host,\"www.oisf.net\"; sid:4;)");
1281 FAIL_IF_NULL(sig);
1282
1284 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1285 "offset:11; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1286 "pcre:\"/220[- ]/\"; rev:4; priority:3; sid:5;)");
1287 FAIL_IF_NULL(sig);
1288
1290 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1291 "offset:11; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1292 "pktvar:http_host,\"www.oisf.net\"; rev:4; priority:1; sid:6;)");
1293 FAIL_IF_NULL(sig);
1294
1296 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1297 "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; flowvar:http_host,\"www.oisf.net\"; "
1298 "pktvar:http_host,\"www.oisf.net\"; priority:1; sid:7;)");
1299 FAIL_IF_NULL(sig);
1300
1302 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1303 "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1304 "flowvar:http_host,\"www.oisf.net\"; sid:8;)");
1305 FAIL_IF_NULL(sig);
1306
1308 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1309 "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1310 "flowvar:http_host,\"www.oisf.net\"; sid:9;)");
1311 FAIL_IF_NULL(sig);
1312
1313 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1314 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1315 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1316 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1317 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1319
1320 sig = de_ctx->sig_list;
1321
1322#ifdef DEBUG
1323 while (sig != NULL) {
1324 printf("sid: %d\n", sig->id);
1325 sig = sig->next;
1326 }
1327#endif
1328
1329 sig = de_ctx->sig_list;
1330
1331 /* flowvar set */
1332 sig = sig->next;
1333 FAIL_IF_NOT(sig->id == 3);
1334 sig = sig->next;
1335 FAIL_IF_NOT(sig->id == 4);
1336 sig = sig->next;
1337 FAIL_IF_NOT(sig->id == 7);
1338 sig = sig->next;
1339 FAIL_IF_NOT(sig->id == 8);
1340 sig = sig->next;
1341 FAIL_IF_NOT(sig->id == 9);
1342 sig = sig->next;
1343
1344 /* pktvar */
1345
1346 FAIL_IF_NOT(sig->id == 5);
1347 sig = sig->next;
1348 FAIL_IF_NOT(sig->id == 6);
1349 sig = sig->next;
1350
1351 FAIL_IF_NOT(sig->id == 1);
1352 sig = sig->next;
1353
1355
1356 PASS;
1357}
1358
1359static int SCSigOrderingTest05(void)
1360{
1361 Signature *sig = NULL;
1362
1364 FAIL_IF(de_ctx == NULL);
1365
1367 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1368 "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1369 FAIL_IF_NULL(sig);
1370
1372 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1373 "pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; content:\"220\"; "
1374 "offset:10; rev:4; priority:3; sid:2;)");
1375 FAIL_IF_NULL(sig);
1376
1378 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1379 "content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: "
1380 "(?P<pkt_http_host>.*)\\r\\n/m\"; rev:4; priority:3; sid:3;)");
1381 FAIL_IF_NULL(sig);
1382
1384 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1385 "offset:10; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; rev:4; "
1386 "priority:3; pktvar:http_host,\"www.oisf.net\"; sid:4;)");
1387 FAIL_IF_NULL(sig);
1388
1390 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1391 "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:5;)");
1392 FAIL_IF_NULL(sig);
1393
1395 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1396 "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:6;)");
1397 FAIL_IF_NULL(sig);
1398
1400 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1401 "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1402 "pktvar:http_host,\"www.oisf.net\"; sid:7;)");
1403 FAIL_IF_NULL(sig);
1404
1406 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1407 "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; "
1408 "pktvar:http_host,\"www.oisf.net\"; sid:8;)");
1409 FAIL_IF_NULL(sig);
1410
1411 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1412 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1413 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1414 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1415 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1417
1418 sig = de_ctx->sig_list;
1419
1420 //#ifdef DEBUG
1421 while (sig != NULL) {
1422 printf("sid: %d\n", sig->id);
1423 sig = sig->next;
1424 }
1425 //#endif
1426
1427 sig = de_ctx->sig_list;
1428
1429 /* pktvar set */
1430 FAIL_IF_NOT(sig->id == 2);
1431 sig = sig->next;
1432 FAIL_IF_NOT(sig->id == 3);
1433 sig = sig->next;
1434 FAIL_IF_NOT(sig->id == 4);
1435 sig = sig->next;
1436 /* pktvar read */
1437 FAIL_IF_NOT(sig->id == 7);
1438 sig = sig->next;
1439 FAIL_IF_NOT(sig->id == 8);
1440 sig = sig->next;
1441 FAIL_IF_NOT(sig->id == 1);
1442 sig = sig->next;
1443 FAIL_IF_NOT(sig->id == 5);
1444 sig = sig->next;
1445 FAIL_IF_NOT(sig->id == 6);
1446 sig = sig->next;
1447
1449
1450 PASS;
1451}
1452
1453static int SCSigOrderingTest06(void)
1454{
1455
1456 Signature *sig = NULL;
1457
1460
1462 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1463 "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1464 FAIL_IF_NULL(sig);
1465
1467 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1468 "content:\"220\"; offset:10; rev:4; priority:2; sid:2;)");
1469 FAIL_IF_NULL(sig);
1470
1472 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1473 "content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:3;)");
1474 FAIL_IF_NULL(sig);
1475
1477 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1478 "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1479 FAIL_IF_NULL(sig);
1480
1482 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1483 "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1484 FAIL_IF_NULL(sig);
1485
1487 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1488 "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1489 FAIL_IF_NULL(sig);
1491 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1492 "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1493 FAIL_IF_NULL(sig);
1494
1496 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1497 "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1498 FAIL_IF_NULL(sig);
1499
1500 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1501 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1502 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1503 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1504 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1506
1507 sig = de_ctx->sig_list;
1508
1509#ifdef DEBUG
1510 while (sig != NULL) {
1511 printf("sid: %d\n", sig->id);
1512 sig = sig->next;
1513 }
1514#endif
1515
1516 sig = de_ctx->sig_list;
1517
1518 FAIL_IF_NOT(sig->id == 6);
1519 sig = sig->next;
1520 FAIL_IF_NOT(sig->id == 2);
1521 sig = sig->next;
1522 FAIL_IF_NOT(sig->id == 4);
1523 sig = sig->next;
1524 FAIL_IF_NOT(sig->id == 5);
1525 sig = sig->next;
1526 FAIL_IF_NOT(sig->id == 7);
1527 sig = sig->next;
1528 FAIL_IF_NOT(sig->id == 8);
1529 sig = sig->next;
1530 FAIL_IF_NOT(sig->id == 1);
1531 sig = sig->next;
1532 FAIL_IF_NOT(sig->id == 3);
1533 sig = sig->next;
1534
1536
1537 PASS;
1538}
1539static int SCSigOrderingTest07(void)
1540{
1541
1542 Signature *sig = NULL;
1543
1545 FAIL_IF(de_ctx == NULL);
1546
1548 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1549 "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1; rev:4;)");
1550 FAIL_IF_NULL(sig);
1551
1553 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1554 "content:\"220\"; offset:10; sid:2; rev:4; priority:2;)");
1555 FAIL_IF_NULL(sig);
1556
1558 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1559 "content:\"220\"; offset:10; depth:4; sid:3; rev:4; priority:3;)");
1560 FAIL_IF_NULL(sig);
1561
1563 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1564 "content:\"220\"; offset:10; depth:4; sid:4; rev:4; priority:2;)");
1565 FAIL_IF_NULL(sig);
1566
1568 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1569 "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:5; rev:4; priority:2;)");
1570 FAIL_IF_NULL(sig);
1571
1573 "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1574 "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:6; rev:4; priority:1;)");
1575 FAIL_IF_NULL(sig);
1576
1578 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1579 "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:7; rev:4; priority:2;)");
1580 FAIL_IF_NULL(sig);
1581
1583 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1584 "offset:12; depth:4; pcre:\"/220[- ]/\"; sid:8; rev:4; priority:2;)");
1585 FAIL_IF_NULL(sig);
1586
1587 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1588 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1589 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1590 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1591 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1593
1594 sig = de_ctx->sig_list;
1595
1596#ifdef DEBUG
1597 while (sig != NULL) {
1598 printf("sid: %d\n", sig->id);
1599 sig = sig->next;
1600 }
1601#endif
1602
1603 sig = de_ctx->sig_list;
1604
1605 FAIL_IF_NOT(sig->id == 2);
1606 sig = sig->next;
1607 FAIL_IF_NOT(sig->id == 4);
1608 sig = sig->next;
1609 FAIL_IF_NOT(sig->id == 5);
1610 sig = sig->next;
1611 FAIL_IF_NOT(sig->id == 7);
1612 sig = sig->next;
1613 FAIL_IF_NOT(sig->id == 6);
1614 sig = sig->next;
1615 FAIL_IF_NOT(sig->id == 8);
1616 sig = sig->next;
1617 FAIL_IF_NOT(sig->id == 1);
1618 sig = sig->next;
1619 FAIL_IF_NOT(sig->id == 3);
1620 sig = sig->next;
1621
1623
1624 PASS;
1625}
1626
1627/**
1628 * \test Order with a different Action priority
1629 * (as specified from config)
1630 */
1631static int SCSigOrderingTest08(void)
1632{
1633#ifdef HAVE_LIBNET11
1634
1635 Signature *sig = NULL;
1636 extern uint8_t action_order_sigs[4];
1637
1638 /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1643
1645 FAIL_IF(de_ctx == NULL);
1646
1648 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1649 "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1; rev:4;)");
1650 FAIL_IF_NULL(sig);
1651
1653 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1654 "content:\"220\"; offset:10; sid:2; rev:4; priority:2;)");
1655 FAIL_IF_NULL(sig);
1656
1658 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1659 "content:\"220\"; offset:10; depth:4; sid:3; rev:4; priority:3;)");
1660 FAIL_IF_NULL(sig);
1661
1663 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1664 "content:\"220\"; offset:10; depth:4; sid:4; rev:4; priority:2;)");
1665 FAIL_IF_NULL(sig);
1666
1668 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1669 "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:5; rev:4; priority:2;)");
1670 FAIL_IF_NULL(sig);
1671
1673 "reject tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1674 "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:6; rev:4; priority:1;)");
1675 FAIL_IF_NULL(sig);
1676
1678 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; "
1679 "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; sid:7; rev:4;)");
1680 FAIL_IF_NULL(sig);
1681
1683 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1684 "offset:12; depth:4; pcre:\"/220[- ]/\"; sid:8; rev:4; priority:2;)");
1685 FAIL_IF_NULL(sig);
1686
1687 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1688 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1689 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1690 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1691 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1693
1694 sig = de_ctx->sig_list;
1695
1696#ifdef DEBUG
1697 while (sig != NULL) {
1698 printf("sid: %d\n", sig->id);
1699 sig = sig->next;
1700 }
1701#endif
1702
1703 sig = de_ctx->sig_list;
1704
1705 FAIL_IF_NOT(sig->id == 6);
1706 sig = sig->next;
1707 FAIL_IF_NOT(sig->id == 8);
1708 sig = sig->next;
1709 FAIL_IF_NOT(sig->id == 1);
1710 sig = sig->next;
1711 FAIL_IF_NOT(sig->id == 3);
1712 sig = sig->next;
1713 FAIL_IF_NOT(sig->id == 2);
1714 sig = sig->next;
1715 FAIL_IF_NOT(sig->id == 4);
1716 sig = sig->next;
1717 FAIL_IF_NOT(sig->id == 5);
1718 sig = sig->next;
1719 FAIL_IF_NOT(sig->id == 7);
1720 sig = sig->next;
1721
1722 /* Restore the default pre-order definition */
1727
1729
1730#endif
1731 PASS;
1732}
1733
1734/**
1735 * \test Order with a different Action priority
1736 * (as specified from config)
1737 */
1738static int SCSigOrderingTest09(void)
1739{
1740
1741 Signature *sig = NULL;
1742 extern uint8_t action_order_sigs[4];
1743
1744 /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1749
1751 FAIL_IF(de_ctx == NULL);
1752
1754 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1755 "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1;)");
1756 FAIL_IF_NULL(sig);
1757
1759 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1760 "content:\"220\"; offset:10; priority:2; sid:2;)");
1761 FAIL_IF_NULL(sig);
1762
1764 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1765 "content:\"220\"; offset:10; depth:4; priority:3; sid:3;)");
1766 FAIL_IF_NULL(sig);
1767
1769 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1770 "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1771 FAIL_IF_NULL(sig);
1772
1774 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1775 "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1776 FAIL_IF_NULL(sig);
1777
1779 "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1780 "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1781 FAIL_IF_NULL(sig);
1782
1784 "drop tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1785 "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1786 FAIL_IF_NULL(sig);
1787
1789 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1790 "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1791 FAIL_IF_NULL(sig);
1792
1793 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1794 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1795 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1796 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1797 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1799
1800 sig = de_ctx->sig_list;
1801
1802#ifdef DEBUG
1803 while (sig != NULL) {
1804 printf("sid: %d\n", sig->id);
1805 sig = sig->next;
1806 }
1807#endif
1808
1809 sig = de_ctx->sig_list;
1810
1811 FAIL_IF_NOT(sig->id == 6);
1812 sig = sig->next;
1813 FAIL_IF_NOT(sig->id == 7);
1814 sig = sig->next;
1815 FAIL_IF_NOT(sig->id == 8);
1816 sig = sig->next;
1817 FAIL_IF_NOT(sig->id == 1);
1818 sig = sig->next;
1819 FAIL_IF_NOT(sig->id == 3);
1820 sig = sig->next;
1821 FAIL_IF_NOT(sig->id == 2);
1822 sig = sig->next;
1823 FAIL_IF_NOT(sig->id == 4);
1824 sig = sig->next;
1825 FAIL_IF_NOT(sig->id == 5);
1826 sig = sig->next;
1827
1828 /* Restore the default pre-order definition */
1833
1835 PASS;
1836}
1837
1838/**
1839 * \test Order with a different Action priority
1840 * (as specified from config)
1841 */
1842static int SCSigOrderingTest10(void)
1843{
1844
1845 Signature *sig = NULL;
1846 extern uint8_t action_order_sigs[4];
1847
1848 /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1853
1855 FAIL_IF(de_ctx == NULL);
1856
1858 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1859 "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1860 FAIL_IF_NULL(sig);
1861
1863 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1864 "content:\"220\"; offset:10; rev:4; priority:2; sid:2;)");
1865 FAIL_IF_NULL(sig);
1866
1868 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1869 "content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:3;)");
1870 FAIL_IF_NULL(sig);
1871
1873 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1874 "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1875 FAIL_IF_NULL(sig);
1876
1878 "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1879 "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1880 FAIL_IF_NULL(sig);
1881
1883 "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1884 "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1885 FAIL_IF_NULL(sig);
1886
1888 "drop tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1889 "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1890 FAIL_IF_NULL(sig);
1891
1893 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1894 "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1895 FAIL_IF_NULL(sig);
1896
1897 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1898 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1899 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1900 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1901 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1903
1904 sig = de_ctx->sig_list;
1905
1906#ifdef DEBUG
1907 while (sig != NULL) {
1908 printf("sid: %d\n", sig->id);
1909 sig = sig->next;
1910 }
1911#endif
1912
1913 sig = de_ctx->sig_list;
1914
1915 FAIL_IF_NOT(sig->id == 2);
1916 sig = sig->next;
1917 FAIL_IF_NOT(sig->id == 4);
1918 sig = sig->next;
1919 FAIL_IF_NOT(sig->id == 5);
1920 sig = sig->next;
1921 FAIL_IF_NOT(sig->id == 8);
1922 sig = sig->next;
1923 FAIL_IF_NOT(sig->id == 1);
1924 sig = sig->next;
1925 FAIL_IF_NOT(sig->id == 3);
1926 sig = sig->next;
1927 FAIL_IF_NOT(sig->id == 6);
1928 sig = sig->next;
1929 FAIL_IF_NOT(sig->id == 7);
1930 sig = sig->next;
1931
1932 /* Restore the default pre-order definition */
1937
1939 PASS;
1940}
1941
1942static int SCSigOrderingTest11(void)
1943{
1944
1945 Signature *sig = NULL;
1946
1948 FAIL_IF(de_ctx == NULL);
1949
1951 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering set\"; "
1952 "flowbits:isnotset,myflow1; rev:4; sid:1;)");
1953 FAIL_IF_NULL(sig);
1954
1956 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering toggle\"; "
1957 "flowbits:toggle,myflow2; rev:4; sid:2;)");
1958 FAIL_IF_NULL(sig);
1959
1961 "alert tcp any !21:902 -> any any (msg:\"Testing sigordering unset\"; "
1962 "flowbits:isset, myflow1; flowbits:unset,myflow2; rev:4; priority:3; sid:3;)");
1963 FAIL_IF_NULL(sig);
1964
1965 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1966 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1967 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1968 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1969 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1971
1972 sig = de_ctx->sig_list;
1973
1974#ifdef DEBUG
1975 while (sig != NULL) {
1976 printf("sid: %d\n", sig->id);
1977 sig = sig->next;
1978 }
1979#endif
1980
1981 sig = de_ctx->sig_list;
1982
1983 FAIL_IF_NOT(sig->id == 2);
1984 sig = sig->next;
1985 FAIL_IF_NOT(sig->id == 3);
1986 sig = sig->next;
1987 FAIL_IF_NOT(sig->id == 1);
1988 sig = sig->next;
1989
1991 PASS;
1992}
1993
1994static int SCSigOrderingTest12(void)
1995{
1996 Signature *sig = NULL;
1997 Packet *p = NULL;
1998 uint8_t buf[] = "test message";
1999 Flow f;
2000
2001 FLOW_INITIALIZE(&f);
2002 f.flags |= FLOW_IPV4;
2004 f.proto = IPPROTO_TCP;
2005
2007 FAIL_IF(de_ctx == NULL);
2008 de_ctx->flags |= DE_QUIET;
2009
2010 const char *sigs[2];
2011 sigs[0] = "alert tcp any any -> any any (content:\"test\"; dsize:>0; flowbits:isset,one; flowbits:set,two; sid:1;)";
2012 sigs[1] = "alert tcp any any -> any any (content:\"test\"; dsize:>0; flowbits:set,one; sid:2;)";
2013 UTHAppendSigs(de_ctx, sigs, 2);
2014
2015 sig = de_ctx->sig_list;
2016 FAIL_IF_NULL(sig);
2017 FAIL_IF_NULL(sig->next);
2018 FAIL_IF_NOT_NULL(sig->next->next);
2019 FAIL_IF(de_ctx->signum != 2);
2020
2022 p = UTHBuildPacket(buf, sizeof(buf), IPPROTO_TCP);
2023 FAIL_IF_NULL(p);
2024
2025 p->flow = &f;
2029
2030 UTHMatchPackets(de_ctx, &p, 1);
2031
2032 uint32_t sids[2] = {1, 2};
2033 uint32_t results[2] = {1, 1};
2034 FAIL_IF_NOT(UTHCheckPacketMatchResults(p, sids, results, 2));
2035
2036 UTHFreePackets(&p, 1);
2037
2039
2040 FlowShutdown();
2041
2042 PASS;
2043}
2044
2045/** \test Bug 1061 */
2046static int SCSigOrderingTest13(void)
2047{
2048
2049 Signature *sig = NULL;
2050
2052 FAIL_IF(de_ctx == NULL);
2053
2054 sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:isset,bit1; flowbits:set,bit2; flowbits:set,bit3; sid:6;)");
2055 FAIL_IF_NULL(sig);
2056 sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:set,bit1; flowbits:set,bit2; sid:7;)");
2057 FAIL_IF_NULL(sig);
2058 sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:isset,bit1; flowbits:isset,bit2; flowbits:isset,bit3; sid:5;)");
2059 FAIL_IF_NULL(sig);
2060
2061 SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
2063
2064#ifdef DEBUG
2065 sig = de_ctx->sig_list;
2066 while (sig != NULL) {
2067 printf("sid: %d\n", sig->id);
2068 sig = sig->next;
2069 }
2070#endif
2071
2072 sig = de_ctx->sig_list;
2073
2074 FAIL_IF_NOT(sig->id == 7);
2075 sig = sig->next;
2076 FAIL_IF_NOT(sig->id == 6);
2077 sig = sig->next;
2078 FAIL_IF_NOT(sig->id == 5);
2079 sig = sig->next;
2080
2082 PASS;
2083}
2084
2085#endif
2086
2088{
2089
2090#ifdef UNITTESTS
2091 UtRegisterTest("SCSigOrderingTest01", SCSigOrderingTest01);
2092 UtRegisterTest("SCSigOrderingTest02", SCSigOrderingTest02);
2093 UtRegisterTest("SCSigOrderingTest03", SCSigOrderingTest03);
2094 UtRegisterTest("SCSigOrderingTest04", SCSigOrderingTest04);
2095 UtRegisterTest("SCSigOrderingTest05", SCSigOrderingTest05);
2096 UtRegisterTest("SCSigOrderingTest06", SCSigOrderingTest06);
2097 UtRegisterTest("SCSigOrderingTest07", SCSigOrderingTest07);
2098 UtRegisterTest("SCSigOrderingTest08", SCSigOrderingTest08);
2099 UtRegisterTest("SCSigOrderingTest09", SCSigOrderingTest09);
2100 UtRegisterTest("SCSigOrderingTest10", SCSigOrderingTest10);
2101 UtRegisterTest("SCSigOrderingTest11", SCSigOrderingTest11);
2102 UtRegisterTest("SCSigOrderingTest12", SCSigOrderingTest12);
2103 UtRegisterTest("SCSigOrderingTest13", SCSigOrderingTest13);
2104#endif
2105}
#define ACTION_REJECT
#define ACTION_PASS
#define ACTION_ALERT
#define ACTION_DROP
@ ALPROTO_UNKNOWN
uint16_t type
#define PKT_HAS_FLOW
Definition decode.h:1266
#define PKT_STREAM_EST
Definition decode.h:1262
@ DETECT_HOSTBITS
@ DETECT_FLOWBITS
void SCSigOrderSignatures(DetectEngineCtx *de_ctx)
Orders the signatures.
#define DETECT_XBITS_TYPE_SET_READ
void SCSigRegisterSignatureOrderingTests(void)
#define DETECT_FLOWVAR_NOT_USED
#define DETECT_FLOWINT_TYPE_SET_READ
DetectEngineCtx * DetectEngineCtxInit(void)
#define DETECT_PKTVAR_TYPE_READ
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
#define DETECT_FLOWINT_TYPE_SET
#define DETECT_FLOWBITS_TYPE_SET_READ
#define DETECT_XBITS_TYPE_READ
DetectSigorderUserDataType
Different kinds of helper data that can be used by the signature ordering module. Used by the "user" ...
@ DETECT_SIGORDER_FLOWBITS
@ DETECT_SIGORDER_PKTVAR
@ DETECT_SIGORDER_HOSTBITS
@ DETECT_SIGORDER_IPPAIRBITS
@ DETECT_SIGORDER_MAX
@ DETECT_SIGORDER_FLOWVAR
@ DETECT_SIGORDER_FLOWINT
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
void SCSigSignatureOrderingModuleCleanup(DetectEngineCtx *de_ctx)
De-registers all the signature ordering functions registered.
#define DETECT_PKTVAR_TYPE_SET_READ
struct SCSigSignatureWrapper_ SCSigSignatureWrapper
Signature wrapper used by signature ordering module while ordering signatures.
#define DETECT_FLOWINT_NOT_USED
#define DETECT_FLOWINT_TYPE_READ
#define DETECT_FLOWBITS_NOT_USED
#define DETECT_FLOWVAR_TYPE_SET_READ
#define DETECT_XBITS_TYPE_SET
#define DETECT_XBITS_NOT_USED
struct SCSigOrderFunc_ SCSigOrderFunc
Structure holding the signature ordering function used by the signature ordering module.
#define DETECT_PKTVAR_NOT_USED
#define DETECT_FLOWVAR_TYPE_READ
#define DETECT_FLOWVAR_TYPE_SET
void SCSigRegisterSignatureOrderingFuncs(DetectEngineCtx *de_ctx)
Lets you register the Signature ordering functions. The order in which the functions are registered s...
#define DETECT_PKTVAR_TYPE_SET
#define DETECT_FLOWBITS_TYPE_READ
void SigFree(DetectEngineCtx *, Signature *)
#define DETECT_FLOWBITS_TYPE_SET
#define DETECT_FLOWBITS_CMD_ISNOTSET
#define DETECT_FLOWBITS_CMD_ISSET
#define DETECT_FLOWBITS_CMD_TOGGLE
#define DETECT_FLOWBITS_CMD_UNSET
#define DETECT_FLOWBITS_CMD_SET
@ FLOWINT_MODIFIER_GE
@ FLOWINT_MODIFIER_LT
@ FLOWINT_MODIFIER_SUB
@ FLOWINT_MODIFIER_GT
@ FLOWINT_MODIFIER_ADD
@ FLOWINT_MODIFIER_ISSET
@ FLOWINT_MODIFIER_ISNOTSET
@ FLOWINT_MODIFIER_NE
@ FLOWINT_MODIFIER_EQ
@ FLOWINT_MODIFIER_LE
@ FLOWINT_MODIFIER_SET
#define DETECT_XBITS_CMD_TOGGLE
#define DETECT_XBITS_CMD_SET
#define DETECT_XBITS_CMD_ISNOTSET
#define DETECT_XBITS_CMD_UNSET
#define DETECT_XBITS_CMD_ISSET
#define DE_QUIET
Definition detect.h:330
@ SIG_TYPE_PKT
Definition detect.h:72
#define SIG_FLAG_TOSERVER
Definition detect.h:271
@ DETECT_SM_LIST_MATCH
Definition detect.h:117
@ DETECT_SM_LIST_PMATCH
Definition detect.h:119
@ DETECT_SM_LIST_POSTMATCH
Definition detect.h:127
#define FLOW_INITIALIZE(f)
Definition flow-util.h:38
void FlowInitConfig(bool quiet)
initialize the configuration
Definition flow.c:547
void FlowShutdown(void)
shutdown the flow engine
Definition flow.c:691
#define FLOW_PKT_TOSERVER
Definition flow.h:233
#define FLOW_QUIET
Definition flow.h:43
#define FLOW_PKT_ESTABLISHED
Definition flow.h:235
#define FLOW_IPV4
Definition flow.h:100
DetectEngineCtx * de_ctx
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
main detection engine ctx
Definition detect.h:932
uint8_t flags
Definition detect.h:934
struct SCSigOrderFunc_ * sc_sig_order_funcs
Definition detect.h:956
Signature * sig_list
Definition detect.h:941
uint32_t signum
Definition detect.h:953
uint8_t captypes[DETECT_PCRE_CAPTURE_MAX]
Definition detect-pcre.h:53
enum VarTypes type
Flow data structure.
Definition flow.h:356
uint8_t proto
Definition flow.h:378
uint32_t flags
Definition flow.h:421
AppProto alproto
application level protocol
Definition flow.h:450
uint8_t flowflags
Definition decode.h:532
struct Flow_ * flow
Definition decode.h:546
uint32_t flags
Definition decode.h:544
Structure holding the signature ordering function used by the signature ordering module.
int(* SWCompare)(SCSigSignatureWrapper *sw1, SCSigSignatureWrapper *sw2)
struct SCSigOrderFunc_ * next
Signature wrapper used by signature ordering module while ordering signatures.
int user[DETECT_SIGORDER_MAX]
struct SCSigSignatureWrapper_ * next
a single match condition for a signature
Definition detect.h:356
uint16_t type
Definition detect.h:357
struct SigMatch_ * next
Definition detect.h:360
SigMatchCtx * ctx
Definition detect.h:359
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition detect.h:642
Signature container.
Definition detect.h:668
uint8_t action
Definition detect.h:683
enum SignatureType type
Definition detect.h:671
uint32_t flags
Definition detect.h:669
SignatureInitData * init_data
Definition detect.h:747
SigIntId iid
Definition detect.h:680
AppProto alproto
Definition detect.h:673
int prio
Definition detect.h:716
uint32_t id
Definition detect.h:713
struct Signature_ * next
Definition detect.h:750
char * msg
Definition detect.h:736
uint8_t app_progress_hook
Definition detect.h:705
#define BUG_ON(x)
uint8_t ActionOrderVal(uint8_t action)
Return the priority associated to an action (to order sigs as specified at config) action_order_sigs ...
Definition util-action.c:53
uint8_t action_order_sigs[4]
Definition util-action.c:40
#define FatalError(...)
Definition util-debug.h:510
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
int UTHMatchPackets(DetectEngineCtx *de_ctx, Packet **p, int num_packets)
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
int UTHAppendSigs(DetectEngineCtx *de_ctx, const char *sigs[], int numsigs)
UTHAppendSigs: Add sigs to the detection_engine checking for errors.
int UTHCheckPacketMatchResults(Packet *p, uint32_t sids[], uint32_t results[], int numsigs)
UTHCheckPacketMatches: function to check if a packet match some sids.
#define DEBUG_VALIDATE_BUG_ON(exp)
VarTypes
Definition util-var.h:28
@ VAR_TYPE_IPPAIR_BIT
Definition util-var.h:45
@ VAR_TYPE_FLOW_VAR
Definition util-var.h:39
@ VAR_TYPE_PKT_VAR
Definition util-var.h:33
@ VAR_TYPE_HOST_BIT
Definition util-var.h:41