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"
32 #include "detect-engine-sigorder.h"
33 #include "detect-pcre.h"
34 #include "detect-engine-build.h"
35 
36 #include "util-unittest.h"
37 #include "util-unittest-helper.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  */
73 typedef enum {
82 
83 /**
84  * \brief Signature wrapper used by signature ordering module while ordering
85  * signatures
86  */
87 typedef 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  */
101 typedef 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  */
118 static void SCSigRegisterSignatureOrderingFunc(DetectEngineCtx *de_ctx,
120 {
121  SCSigOrderFunc *curr = NULL;
122  SCSigOrderFunc *prev = NULL;
123  SCSigOrderFunc *temp = NULL;
124 
125  curr = de_ctx->sc_sig_order_funcs;
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)
147  de_ctx->sc_sig_order_funcs = temp;
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  */
166 static 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;
177  if (fb->cmd == DETECT_FLOWBITS_CMD_ISNOTSET ||
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 
221 static 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  */
293 static 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  */
351 static 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  */
409 static 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 ||
422  fb->cmd == DETECT_XBITS_CMD_ISSET) {
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 ||
441  fb->cmd == DETECT_XBITS_CMD_UNSET ||
442  fb->cmd == DETECT_XBITS_CMD_TOGGLE) {
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  */
475 static 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  */
487 static inline void SCSigProcessUserDataForFlowvar(SCSigSignatureWrapper *sw)
488 {
489  sw->user[DETECT_SIGORDER_FLOWVAR] = SCSigGetFlowvarType(sw->sig);
490 }
491 
492 static 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  */
504 static 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  */
516 static 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  */
528 static 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. */
534 static 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 */
555 static 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;
562  SCSigSignatureWrapper *first;
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  */
631 static 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  */
644 static 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  */
657 static 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  */
670 static int SCSigOrderByPktvarCompare(SCSigSignatureWrapper *sw1,
672 {
674 }
675 
676 static 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  */
689 static 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  */
702 static 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  */
715 static 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 
726 /**
727  * \brief Creates a Wrapper around the Signature
728  *
729  * \param Pointer to the Signature to be wrapped
730  *
731  * \retval sw Pointer to the wrapper that holds the signature
732  */
733 static inline SCSigSignatureWrapper *SCSigAllocSignatureWrapper(Signature *sig)
734 {
735  SCSigSignatureWrapper *sw = NULL;
736 
737  if ((sw = SCCalloc(1, sizeof(SCSigSignatureWrapper))) == NULL)
738  return NULL;
739 
740  sw->sig = sig;
741 
742  /* Process data from the signature into a cache for further use by the
743  * sig_ordering module */
744  SCSigProcessUserDataForFlowbits(sw);
745  SCSigProcessUserDataForFlowvar(sw);
746  SCSigProcessUserDataForFlowint(sw);
747  SCSigProcessUserDataForPktvar(sw);
748  SCSigProcessUserDataForHostbits(sw);
749  SCSigProcessUserDataForIPPairbits(sw);
750 
751  return sw;
752 }
753 
754 /**
755  * \brief Orders the signatures
756  *
757  * \param de_ctx Pointer to the Detection Engine Context that holds the
758  * signatures to be ordered
759  */
761 {
762  if (de_ctx->sig_list == NULL) {
763  SCLogDebug("no signatures to order");
764  return;
765  }
766 
767  Signature *sig = NULL;
768  SCSigSignatureWrapper *sigw = NULL;
769  SCSigSignatureWrapper *sigw_list = NULL;
770 #ifdef DEBUG
771  int i = 0;
772 #endif
773  SCLogDebug("ordering signatures in memory");
774 
775  sig = de_ctx->sig_list;
776  while (sig != NULL) {
777  sigw = SCSigAllocSignatureWrapper(sig);
778  /* Push signature wrapper onto a list, order doesn't matter here. */
779  sigw->next = sigw_list;
780  sigw_list = sigw;
781 
782  sig = sig->next;
783 #ifdef DEBUG
784  i++;
785 #endif
786  }
787 
788  /* Sort the list */
789  sigw_list = SCSigOrder(sigw_list, de_ctx->sc_sig_order_funcs);
790 
791  SCLogDebug("Total Signatures to be processed by the"
792  "sigordering module: %d", i);
793 
794  /* Recreate the sig list in order */
795  de_ctx->sig_list = NULL;
796  sigw = sigw_list;
797 #ifdef DEBUG
798  i = 0;
799 #endif
800  while (sigw != NULL) {
801 #ifdef DEBUG
802  i++;
803 #endif
804  sigw->sig->next = NULL;
805  if (de_ctx->sig_list == NULL) {
806  /* First entry on the list */
807  de_ctx->sig_list = sigw->sig;
808  sig = de_ctx->sig_list;
809  } else {
810  sig->next = sigw->sig;
811  sig = sig->next;
812  }
813  SCSigSignatureWrapper *sigw_to_free = sigw;
814  sigw = sigw->next;
815  SCFree(sigw_to_free);
816  }
817 
818  SCLogDebug("total signatures reordered by the sigordering module: %d", i);
819 }
820 
821 /**
822  * \brief Lets you register the Signature ordering functions. The order in
823  * which the functions are registered shows the priority. The first
824  * function registered provides more priority than the function
825  * registered after it. To add a new registration function, register
826  * it by listing it in the correct position in the below sequence,
827  * based on the priority you would want to offer to that keyword.
828  *
829  * \param de_ctx Pointer to the detection engine context from which the
830  * signatures have to be ordered.
831  */
833 {
834  SCLogDebug("registering signature ordering functions");
835 
836  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
837  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
838  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowintCompare);
839  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
840  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
841  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByHostbitsCompare);
842  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByIPPairbitsCompare);
843  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
844 }
845 
846 /**
847  * \brief De-registers all the signature ordering functions registered
848  *
849  * \param de_ctx Pointer to the detection engine context from which the
850  * signatures were ordered.
851  */
853 {
854  SCSigOrderFunc *funcs;
855  void *temp;
856 
857  /* clean the memory alloted to the signature ordering funcs */
858  funcs = de_ctx->sc_sig_order_funcs;
859  while (funcs != NULL) {
860  temp = funcs;
861  funcs = funcs->next;
862  SCFree(temp);
863  }
864  de_ctx->sc_sig_order_funcs = NULL;
865 }
866 
867 /**********Unittests**********/
868 
873 
874 #ifdef UNITTESTS
875 
876 static int SCSigOrderingTest01(void)
877 {
878  SCSigOrderFunc *temp = NULL;
879  int i = 0;
880 
883 
884  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
885  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
886  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
887  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
888  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
889  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
890  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
891  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
892  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
893  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
894  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
895 
896  temp = de_ctx->sc_sig_order_funcs;
897  while (temp != NULL) {
898  i++;
899  temp = temp->next;
900  }
901 
903 
904  FAIL_IF_NOT(i == 5);
905 
906  PASS;
907 }
908 
909 static int SCSigOrderingTest02(void)
910 {
911  Signature *sig = NULL;
912 
914  FAIL_IF(de_ctx == NULL);
915 
917  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
918  FAIL_IF_NULL(sig);
919 
921  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:2;)");
922  FAIL_IF_NULL(sig);
923 
925  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:3;)");
926  FAIL_IF_NULL(sig);
927 
929  "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;)");
930  FAIL_IF_NULL(sig);
931 
933  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:5;)");
934  FAIL_IF_NULL(sig);
935 
937  "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;)");
938  FAIL_IF_NULL(sig);
939 
941  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:7;)");
942  FAIL_IF_NULL(sig);
943 
945  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
946  FAIL_IF_NULL(sig);
947 
949  "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;)");
950  FAIL_IF_NULL(sig);
951 
953  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:10;)");
954  FAIL_IF_NULL(sig);
955 
957  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:11;)");
958  FAIL_IF_NULL(sig);
959 
961  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:12;)");
962  FAIL_IF_NULL(sig);
963 
965  "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;)");
966  FAIL_IF_NULL(sig);
967 
969  "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;)");
970  FAIL_IF_NULL(sig);
971 
972  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
973  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
974  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
975  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
976  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
978 
979  sig = de_ctx->sig_list;
980 
981 #ifdef DEBUG
982  while (sig != NULL) {
983  printf("sid: %d\n", sig->id);
984  sig = sig->next;
985  }
986 #endif
987 
988  sig = de_ctx->sig_list;
989 
990  /* pass */
991  FAIL_IF_NOT(sig->id == 6);
992  sig = sig->next;
993  FAIL_IF_NOT(sig->id == 4);
994  sig = sig->next;
995  FAIL_IF_NOT(sig->id == 8);
996  sig = sig->next;
997  FAIL_IF_NOT(sig->id == 7);
998  sig = sig->next;
999  FAIL_IF_NOT(sig->id == 10);
1000  sig = sig->next;
1001 
1002  /* drops */
1003  FAIL_IF_NOT(sig->id == 9);
1004  sig = sig->next;
1005  FAIL_IF_NOT(sig->id == 13);
1006  sig = sig->next;
1007  FAIL_IF_NOT(sig->id == 2);
1008  sig = sig->next;
1009  FAIL_IF_NOT(sig->id == 3);
1010  sig = sig->next;
1011 
1012  /* alerts */
1013  FAIL_IF_NOT(sig->id == 14);
1014  sig = sig->next;
1015  FAIL_IF_NOT(sig->id == 5);
1016  sig = sig->next;
1017  FAIL_IF_NOT(sig->id == 1);
1018  sig = sig->next;
1019  FAIL_IF_NOT(sig->id == 11);
1020  sig = sig->next;
1021  FAIL_IF_NOT(sig->id == 12);
1022  sig = sig->next;
1023 
1025  PASS;
1026 }
1027 
1028 static int SCSigOrderingTest03(void)
1029 {
1030  Signature *sig = NULL;
1031 
1034 
1036  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1037  "offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:1;)");
1038  FAIL_IF_NULL(sig);
1039 
1041  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1042  "offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:2;)");
1043  FAIL_IF_NULL(sig);
1044 
1046  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1047  "offset:10; depth:4; pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; "
1048  "flowbits:unset,TEST.one; rev:4; priority:2; sid:3;)");
1049  FAIL_IF_NULL(sig);
1050 
1052  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1053  "offset:0; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1054  "flowbits:isset,TEST.one; rev:4; priority:1; sid:4;)");
1055  FAIL_IF_NULL(sig);
1056 
1058  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1059  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; priority:2; sid:5;)");
1060  FAIL_IF_NULL(sig);
1061 
1063  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1064  "content:\"220\"; offset:10; flowbits:isnotset,TEST.one; pcre:\"/^User-Agent: "
1065  "(?P<flow_http_host>.*)\\r\\n/m\"; rev:4; sid:6;)");
1066  FAIL_IF_NULL(sig);
1067 
1069  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1070  "content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; "
1071  "flowbits:unset,TEST.one; rev:4; priority:3; sid:7;)");
1072  FAIL_IF_NULL(sig);
1073 
1075  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1076  "offset:10; depth:4; pcre:\"/220[- ]/\"; flowbits:toggle,TEST.one; rev:4; priority:1; "
1077  "pktvar:http_host,\"www.oisf.net\"; sid:8;)");
1078  FAIL_IF_NULL(sig);
1079 
1081  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1082  "content:\"220\"; offset:10; depth:4; rev:4; flowbits:set,TEST.one; "
1083  "flowbits:noalert; pktvar:http_host,\"www.oisf.net\"; sid:9;)");
1084  FAIL_IF_NULL(sig);
1085 
1087  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1088  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:10;)");
1089  FAIL_IF_NULL(sig);
1090 
1092  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1093  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:11;)");
1094  FAIL_IF_NULL(sig);
1095 
1097  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1098  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:12;)");
1099  FAIL_IF_NULL(sig);
1100 
1102  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1103  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; flowbits:isnotset,TEST.one; sid:13;)");
1104  FAIL_IF_NULL(sig);
1105 
1107  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1108  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; flowbits:set,TEST.one; sid:14;)");
1109  FAIL_IF_NULL(sig);
1110 
1111  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1112  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1113  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1114  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1115  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1117 
1118  sig = de_ctx->sig_list;
1119 
1120 #ifdef DEBUG
1121  while (sig != NULL) {
1122  printf("sid: %d\n", sig->id);
1123  sig = sig->next;
1124  }
1125 #endif
1126 
1127  sig = de_ctx->sig_list;
1128 
1129  FAIL_IF_NOT(sig->id == 3);
1130  sig = sig->next;
1131 
1132  FAIL_IF_NOT(sig->id == 8);
1133  sig = sig->next;
1134  FAIL_IF_NOT(sig->id == 9);
1135  sig = sig->next;
1136  FAIL_IF_NOT(sig->id == 7);
1137  sig = sig->next;
1138  FAIL_IF_NOT(sig->id == 14);
1139  sig = sig->next;
1140  FAIL_IF_NOT(sig->id == 6);
1141  sig = sig->next;
1142  FAIL_IF_NOT(sig->id == 4);
1143  sig = sig->next;
1144  FAIL_IF_NOT(sig->id == 13);
1145  sig = sig->next;
1146  FAIL_IF_NOT(sig->id == 2);
1147  sig = sig->next;
1148  FAIL_IF_NOT(sig->id == 5);
1149  sig = sig->next;
1150  FAIL_IF_NOT(sig->id == 1);
1151  sig = sig->next;
1152  FAIL_IF_NOT(sig->id == 10);
1153  sig = sig->next;
1154  FAIL_IF_NOT(sig->id == 11);
1155  sig = sig->next;
1156  FAIL_IF_NOT(sig->id == 12);
1157 
1158  sig = sig->next;
1159 
1161 
1162  PASS;
1163 }
1164 
1165 static int SCSigOrderingTest04(void)
1166 {
1167 
1168  Signature *sig = NULL;
1169 
1171  FAIL_IF(de_ctx == NULL);
1172 
1174  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1175  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1176  FAIL_IF_NULL(sig);
1177 
1179  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1180  "pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; content:\"220\"; "
1181  "offset:10; rev:4; priority:3; sid:2;)");
1182  FAIL_IF_NULL(sig);
1183 
1185  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1186  "content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: "
1187  "(?P<flow_http_host>.*)\\r\\n/m\"; rev:4; priority:3; sid:3;)");
1188  FAIL_IF_NULL(sig);
1189 
1191  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1192  "offset:10; depth:4; pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; rev:4; "
1193  "priority:3; flowvar:http_host,\"www.oisf.net\"; sid:4;)");
1194  FAIL_IF_NULL(sig);
1195 
1197  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1198  "offset:11; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1199  "pcre:\"/220[- ]/\"; rev:4; priority:3; sid:5;)");
1200  FAIL_IF_NULL(sig);
1201 
1203  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1204  "offset:11; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1205  "pktvar:http_host,\"www.oisf.net\"; rev:4; priority:1; sid:6;)");
1206  FAIL_IF_NULL(sig);
1207 
1209  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1210  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; flowvar:http_host,\"www.oisf.net\"; "
1211  "pktvar:http_host,\"www.oisf.net\"; priority:1; sid:7;)");
1212  FAIL_IF_NULL(sig);
1213 
1215  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1216  "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1217  "flowvar:http_host,\"www.oisf.net\"; sid:8;)");
1218  FAIL_IF_NULL(sig);
1219 
1221  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1222  "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1223  "flowvar:http_host,\"www.oisf.net\"; sid:9;)");
1224  FAIL_IF_NULL(sig);
1225 
1226  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1227  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1228  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1229  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1230  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1232 
1233  sig = de_ctx->sig_list;
1234 
1235 #ifdef DEBUG
1236  while (sig != NULL) {
1237  printf("sid: %d\n", sig->id);
1238  sig = sig->next;
1239  }
1240 #endif
1241 
1242  sig = de_ctx->sig_list;
1243 
1244  /* flowvar set */
1245  sig = sig->next;
1246  FAIL_IF_NOT(sig->id == 3);
1247  sig = sig->next;
1248  FAIL_IF_NOT(sig->id == 4);
1249  sig = sig->next;
1250  FAIL_IF_NOT(sig->id == 7);
1251  sig = sig->next;
1252  FAIL_IF_NOT(sig->id == 8);
1253  sig = sig->next;
1254  FAIL_IF_NOT(sig->id == 9);
1255  sig = sig->next;
1256 
1257  /* pktvar */
1258 
1259  FAIL_IF_NOT(sig->id == 5);
1260  sig = sig->next;
1261  FAIL_IF_NOT(sig->id == 6);
1262  sig = sig->next;
1263 
1264  FAIL_IF_NOT(sig->id == 1);
1265  sig = sig->next;
1266 
1268 
1269  PASS;
1270 }
1271 
1272 static int SCSigOrderingTest05(void)
1273 {
1274  Signature *sig = NULL;
1275 
1277  FAIL_IF(de_ctx == NULL);
1278 
1280  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1281  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1282  FAIL_IF_NULL(sig);
1283 
1285  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1286  "pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; content:\"220\"; "
1287  "offset:10; rev:4; priority:3; sid:2;)");
1288  FAIL_IF_NULL(sig);
1289 
1291  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1292  "content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: "
1293  "(?P<pkt_http_host>.*)\\r\\n/m\"; rev:4; priority:3; sid:3;)");
1294  FAIL_IF_NULL(sig);
1295 
1297  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1298  "offset:10; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; rev:4; "
1299  "priority:3; pktvar:http_host,\"www.oisf.net\"; sid:4;)");
1300  FAIL_IF_NULL(sig);
1301 
1303  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1304  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:5;)");
1305  FAIL_IF_NULL(sig);
1306 
1308  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1309  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:6;)");
1310  FAIL_IF_NULL(sig);
1311 
1313  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1314  "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1315  "pktvar:http_host,\"www.oisf.net\"; sid:7;)");
1316  FAIL_IF_NULL(sig);
1317 
1319  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1320  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; "
1321  "pktvar:http_host,\"www.oisf.net\"; sid:8;)");
1322  FAIL_IF_NULL(sig);
1323 
1324  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1325  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1326  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1327  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1328  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1330 
1331  sig = de_ctx->sig_list;
1332 
1333  //#ifdef DEBUG
1334  while (sig != NULL) {
1335  printf("sid: %d\n", sig->id);
1336  sig = sig->next;
1337  }
1338  //#endif
1339 
1340  sig = de_ctx->sig_list;
1341 
1342  /* pktvar set */
1343  FAIL_IF_NOT(sig->id == 2);
1344  sig = sig->next;
1345  FAIL_IF_NOT(sig->id == 3);
1346  sig = sig->next;
1347  FAIL_IF_NOT(sig->id == 4);
1348  sig = sig->next;
1349  /* pktvar read */
1350  FAIL_IF_NOT(sig->id == 7);
1351  sig = sig->next;
1352  FAIL_IF_NOT(sig->id == 8);
1353  sig = sig->next;
1354  FAIL_IF_NOT(sig->id == 1);
1355  sig = sig->next;
1356  FAIL_IF_NOT(sig->id == 5);
1357  sig = sig->next;
1358  FAIL_IF_NOT(sig->id == 6);
1359  sig = sig->next;
1360 
1362 
1363  PASS;
1364 }
1365 
1366 static int SCSigOrderingTest06(void)
1367 {
1368 
1369  Signature *sig = NULL;
1370 
1373 
1375  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1376  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1377  FAIL_IF_NULL(sig);
1378 
1380  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1381  "content:\"220\"; offset:10; rev:4; priority:2; sid:2;)");
1382  FAIL_IF_NULL(sig);
1383 
1385  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1386  "content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:3;)");
1387  FAIL_IF_NULL(sig);
1388 
1390  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1391  "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1392  FAIL_IF_NULL(sig);
1393 
1395  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1396  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1397  FAIL_IF_NULL(sig);
1398 
1400  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1401  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1402  FAIL_IF_NULL(sig);
1404  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1405  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1406  FAIL_IF_NULL(sig);
1407 
1409  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1410  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1411  FAIL_IF_NULL(sig);
1412 
1413  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1414  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1415  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1416  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1417  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1419 
1420  sig = de_ctx->sig_list;
1421 
1422 #ifdef DEBUG
1423  while (sig != NULL) {
1424  printf("sid: %d\n", sig->id);
1425  sig = sig->next;
1426  }
1427 #endif
1428 
1429  sig = de_ctx->sig_list;
1430 
1431  FAIL_IF_NOT(sig->id == 6);
1432  sig = sig->next;
1433  FAIL_IF_NOT(sig->id == 2);
1434  sig = sig->next;
1435  FAIL_IF_NOT(sig->id == 4);
1436  sig = sig->next;
1437  FAIL_IF_NOT(sig->id == 5);
1438  sig = sig->next;
1439  FAIL_IF_NOT(sig->id == 7);
1440  sig = sig->next;
1441  FAIL_IF_NOT(sig->id == 8);
1442  sig = sig->next;
1443  FAIL_IF_NOT(sig->id == 1);
1444  sig = sig->next;
1445  FAIL_IF_NOT(sig->id == 3);
1446  sig = sig->next;
1447 
1449 
1450  PASS;
1451 }
1452 static int SCSigOrderingTest07(void)
1453 {
1454 
1455  Signature *sig = NULL;
1456 
1458  FAIL_IF(de_ctx == NULL);
1459 
1461  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1462  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1; rev:4;)");
1463  FAIL_IF_NULL(sig);
1464 
1466  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1467  "content:\"220\"; offset:10; sid:2; rev:4; priority:2;)");
1468  FAIL_IF_NULL(sig);
1469 
1471  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1472  "content:\"220\"; offset:10; depth:4; sid:3; rev:4; priority:3;)");
1473  FAIL_IF_NULL(sig);
1474 
1476  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1477  "content:\"220\"; offset:10; depth:4; sid:4; rev:4; priority:2;)");
1478  FAIL_IF_NULL(sig);
1479 
1481  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1482  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:5; rev:4; priority:2;)");
1483  FAIL_IF_NULL(sig);
1484 
1486  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1487  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:6; rev:4; priority:1;)");
1488  FAIL_IF_NULL(sig);
1489 
1491  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1492  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:7; rev:4; priority:2;)");
1493  FAIL_IF_NULL(sig);
1494 
1496  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1497  "offset:12; depth:4; pcre:\"/220[- ]/\"; sid:8; rev:4; priority:2;)");
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 == 2);
1519  sig = sig->next;
1520  FAIL_IF_NOT(sig->id == 4);
1521  sig = sig->next;
1522  FAIL_IF_NOT(sig->id == 5);
1523  sig = sig->next;
1524  FAIL_IF_NOT(sig->id == 7);
1525  sig = sig->next;
1526  FAIL_IF_NOT(sig->id == 6);
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 }
1539 
1540 /**
1541  * \test Order with a different Action priority
1542  * (as specified from config)
1543  */
1544 static int SCSigOrderingTest08(void)
1545 {
1546 #ifdef HAVE_LIBNET11
1547 
1548  Signature *sig = NULL;
1549  extern uint8_t action_order_sigs[4];
1550 
1551  /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1556 
1558  FAIL_IF(de_ctx == NULL);
1559 
1561  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1562  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1; rev:4;)");
1563  FAIL_IF_NULL(sig);
1564 
1566  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1567  "content:\"220\"; offset:10; sid:2; rev:4; priority:2;)");
1568  FAIL_IF_NULL(sig);
1569 
1571  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1572  "content:\"220\"; offset:10; depth:4; sid:3; rev:4; priority:3;)");
1573  FAIL_IF_NULL(sig);
1574 
1576  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1577  "content:\"220\"; offset:10; depth:4; sid:4; rev:4; priority:2;)");
1578  FAIL_IF_NULL(sig);
1579 
1581  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1582  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:5; rev:4; priority:2;)");
1583  FAIL_IF_NULL(sig);
1584 
1586  "reject tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1587  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:6; rev:4; priority:1;)");
1588  FAIL_IF_NULL(sig);
1589 
1591  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; "
1592  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; sid:7; rev:4;)");
1593  FAIL_IF_NULL(sig);
1594 
1596  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1597  "offset:12; depth:4; pcre:\"/220[- ]/\"; sid:8; rev:4; priority:2;)");
1598  FAIL_IF_NULL(sig);
1599 
1600  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1601  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1602  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1603  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1604  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1606 
1607  sig = de_ctx->sig_list;
1608 
1609 #ifdef DEBUG
1610  while (sig != NULL) {
1611  printf("sid: %d\n", sig->id);
1612  sig = sig->next;
1613  }
1614 #endif
1615 
1616  sig = de_ctx->sig_list;
1617 
1618  FAIL_IF_NOT(sig->id == 6);
1619  sig = sig->next;
1620  FAIL_IF_NOT(sig->id == 8);
1621  sig = sig->next;
1622  FAIL_IF_NOT(sig->id == 1);
1623  sig = sig->next;
1624  FAIL_IF_NOT(sig->id == 3);
1625  sig = sig->next;
1626  FAIL_IF_NOT(sig->id == 2);
1627  sig = sig->next;
1628  FAIL_IF_NOT(sig->id == 4);
1629  sig = sig->next;
1630  FAIL_IF_NOT(sig->id == 5);
1631  sig = sig->next;
1632  FAIL_IF_NOT(sig->id == 7);
1633  sig = sig->next;
1634 
1635  /* Restore the default pre-order definition */
1640 
1642 
1643 #endif
1644  PASS;
1645 }
1646 
1647 /**
1648  * \test Order with a different Action priority
1649  * (as specified from config)
1650  */
1651 static int SCSigOrderingTest09(void)
1652 {
1653 
1654  Signature *sig = NULL;
1655  extern uint8_t action_order_sigs[4];
1656 
1657  /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1662 
1664  FAIL_IF(de_ctx == NULL);
1665 
1667  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1668  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1;)");
1669  FAIL_IF_NULL(sig);
1670 
1672  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1673  "content:\"220\"; offset:10; priority:2; sid:2;)");
1674  FAIL_IF_NULL(sig);
1675 
1677  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1678  "content:\"220\"; offset:10; depth:4; priority:3; sid:3;)");
1679  FAIL_IF_NULL(sig);
1680 
1682  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1683  "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1684  FAIL_IF_NULL(sig);
1685 
1687  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1688  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1689  FAIL_IF_NULL(sig);
1690 
1692  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1693  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1694  FAIL_IF_NULL(sig);
1695 
1697  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1698  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1699  FAIL_IF_NULL(sig);
1700 
1702  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1703  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1704  FAIL_IF_NULL(sig);
1705 
1706  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1707  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1708  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1709  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1710  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1712 
1713  sig = de_ctx->sig_list;
1714 
1715 #ifdef DEBUG
1716  while (sig != NULL) {
1717  printf("sid: %d\n", sig->id);
1718  sig = sig->next;
1719  }
1720 #endif
1721 
1722  sig = de_ctx->sig_list;
1723 
1724  FAIL_IF_NOT(sig->id == 6);
1725  sig = sig->next;
1726  FAIL_IF_NOT(sig->id == 7);
1727  sig = sig->next;
1728  FAIL_IF_NOT(sig->id == 8);
1729  sig = sig->next;
1730  FAIL_IF_NOT(sig->id == 1);
1731  sig = sig->next;
1732  FAIL_IF_NOT(sig->id == 3);
1733  sig = sig->next;
1734  FAIL_IF_NOT(sig->id == 2);
1735  sig = sig->next;
1736  FAIL_IF_NOT(sig->id == 4);
1737  sig = sig->next;
1738  FAIL_IF_NOT(sig->id == 5);
1739  sig = sig->next;
1740 
1741  /* Restore the default pre-order definition */
1746 
1748  PASS;
1749 }
1750 
1751 /**
1752  * \test Order with a different Action priority
1753  * (as specified from config)
1754  */
1755 static int SCSigOrderingTest10(void)
1756 {
1757 
1758  Signature *sig = NULL;
1759  extern uint8_t action_order_sigs[4];
1760 
1761  /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1766 
1768  FAIL_IF(de_ctx == NULL);
1769 
1771  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1772  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1773  FAIL_IF_NULL(sig);
1774 
1776  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1777  "content:\"220\"; offset:10; rev:4; priority:2; sid:2;)");
1778  FAIL_IF_NULL(sig);
1779 
1781  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1782  "content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:3;)");
1783  FAIL_IF_NULL(sig);
1784 
1786  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1787  "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1788  FAIL_IF_NULL(sig);
1789 
1791  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1792  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1793  FAIL_IF_NULL(sig);
1794 
1796  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1797  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1798  FAIL_IF_NULL(sig);
1799 
1801  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1802  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1803  FAIL_IF_NULL(sig);
1804 
1806  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1807  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1808  FAIL_IF_NULL(sig);
1809 
1810  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1811  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1812  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1813  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1814  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1816 
1817  sig = de_ctx->sig_list;
1818 
1819 #ifdef DEBUG
1820  while (sig != NULL) {
1821  printf("sid: %d\n", sig->id);
1822  sig = sig->next;
1823  }
1824 #endif
1825 
1826  sig = de_ctx->sig_list;
1827 
1828  FAIL_IF_NOT(sig->id == 2);
1829  sig = sig->next;
1830  FAIL_IF_NOT(sig->id == 4);
1831  sig = sig->next;
1832  FAIL_IF_NOT(sig->id == 5);
1833  sig = sig->next;
1834  FAIL_IF_NOT(sig->id == 8);
1835  sig = sig->next;
1836  FAIL_IF_NOT(sig->id == 1);
1837  sig = sig->next;
1838  FAIL_IF_NOT(sig->id == 3);
1839  sig = sig->next;
1840  FAIL_IF_NOT(sig->id == 6);
1841  sig = sig->next;
1842  FAIL_IF_NOT(sig->id == 7);
1843  sig = sig->next;
1844 
1845  /* Restore the default pre-order definition */
1850 
1852  PASS;
1853 }
1854 
1855 static int SCSigOrderingTest11(void)
1856 {
1857 
1858  Signature *sig = NULL;
1859 
1861  FAIL_IF(de_ctx == NULL);
1862 
1864  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering set\"; "
1865  "flowbits:isnotset,myflow1; rev:4; sid:1;)");
1866  FAIL_IF_NULL(sig);
1867 
1869  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering toggle\"; "
1870  "flowbits:toggle,myflow2; rev:4; sid:2;)");
1871  FAIL_IF_NULL(sig);
1872 
1874  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering unset\"; "
1875  "flowbits:isset, myflow1; flowbits:unset,myflow2; rev:4; priority:3; sid:3;)");
1876  FAIL_IF_NULL(sig);
1877 
1878  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1879  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1880  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1881  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1882  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1884 
1885  sig = de_ctx->sig_list;
1886 
1887 #ifdef DEBUG
1888  while (sig != NULL) {
1889  printf("sid: %d\n", sig->id);
1890  sig = sig->next;
1891  }
1892 #endif
1893 
1894  sig = de_ctx->sig_list;
1895 
1896  FAIL_IF_NOT(sig->id == 2);
1897  sig = sig->next;
1898  FAIL_IF_NOT(sig->id == 3);
1899  sig = sig->next;
1900  FAIL_IF_NOT(sig->id == 1);
1901  sig = sig->next;
1902 
1904  PASS;
1905 }
1906 
1907 static int SCSigOrderingTest12(void)
1908 {
1909  Signature *sig = NULL;
1910  Packet *p = NULL;
1911  uint8_t buf[] = "test message";
1912  Flow f;
1913 
1914  FLOW_INITIALIZE(&f);
1915  f.flags |= FLOW_IPV4;
1917  f.proto = IPPROTO_TCP;
1918 
1920  FAIL_IF(de_ctx == NULL);
1921  de_ctx->flags |= DE_QUIET;
1922 
1923  const char *sigs[2];
1924  sigs[0] = "alert tcp any any -> any any (content:\"test\"; dsize:>0; flowbits:isset,one; flowbits:set,two; sid:1;)";
1925  sigs[1] = "alert tcp any any -> any any (content:\"test\"; dsize:>0; flowbits:set,one; sid:2;)";
1926  UTHAppendSigs(de_ctx, sigs, 2);
1927 
1928  sig = de_ctx->sig_list;
1929  FAIL_IF_NULL(sig);
1930  FAIL_IF_NULL(sig->next);
1931  FAIL_IF_NOT_NULL(sig->next->next);
1932  FAIL_IF(de_ctx->signum != 2);
1933 
1935  p = UTHBuildPacket(buf, sizeof(buf), IPPROTO_TCP);
1936  FAIL_IF_NULL(p);
1937 
1938  p->flow = &f;
1942 
1943  UTHMatchPackets(de_ctx, &p, 1);
1944 
1945  uint32_t sids[2] = {1, 2};
1946  uint32_t results[2] = {1, 1};
1947  FAIL_IF_NOT(UTHCheckPacketMatchResults(p, sids, results, 2));
1948 
1949  UTHFreePackets(&p, 1);
1950 
1952 
1953  FlowShutdown();
1954 
1955  PASS;
1956 }
1957 
1958 /** \test Bug 1061 */
1959 static int SCSigOrderingTest13(void)
1960 {
1961 
1962  Signature *sig = NULL;
1963 
1965  FAIL_IF(de_ctx == NULL);
1966 
1967  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:isset,bit1; flowbits:set,bit2; flowbits:set,bit3; sid:6;)");
1968  FAIL_IF_NULL(sig);
1969  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:set,bit1; flowbits:set,bit2; sid:7;)");
1970  FAIL_IF_NULL(sig);
1971  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:isset,bit1; flowbits:isset,bit2; flowbits:isset,bit3; sid:5;)");
1972  FAIL_IF_NULL(sig);
1973 
1974  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1976 
1977 #ifdef DEBUG
1978  sig = de_ctx->sig_list;
1979  while (sig != NULL) {
1980  printf("sid: %d\n", sig->id);
1981  sig = sig->next;
1982  }
1983 #endif
1984 
1985  sig = de_ctx->sig_list;
1986 
1987  FAIL_IF_NOT(sig->id == 7);
1988  sig = sig->next;
1989  FAIL_IF_NOT(sig->id == 6);
1990  sig = sig->next;
1991  FAIL_IF_NOT(sig->id == 5);
1992  sig = sig->next;
1993 
1995  PASS;
1996 }
1997 
1998 #endif
1999 
2001 {
2002 
2003 #ifdef UNITTESTS
2004  UtRegisterTest("SCSigOrderingTest01", SCSigOrderingTest01);
2005  UtRegisterTest("SCSigOrderingTest02", SCSigOrderingTest02);
2006  UtRegisterTest("SCSigOrderingTest03", SCSigOrderingTest03);
2007  UtRegisterTest("SCSigOrderingTest04", SCSigOrderingTest04);
2008  UtRegisterTest("SCSigOrderingTest05", SCSigOrderingTest05);
2009  UtRegisterTest("SCSigOrderingTest06", SCSigOrderingTest06);
2010  UtRegisterTest("SCSigOrderingTest07", SCSigOrderingTest07);
2011  UtRegisterTest("SCSigOrderingTest08", SCSigOrderingTest08);
2012  UtRegisterTest("SCSigOrderingTest09", SCSigOrderingTest09);
2013  UtRegisterTest("SCSigOrderingTest10", SCSigOrderingTest10);
2014  UtRegisterTest("SCSigOrderingTest11", SCSigOrderingTest11);
2015  UtRegisterTest("SCSigOrderingTest12", SCSigOrderingTest12);
2016  UtRegisterTest("SCSigOrderingTest13", SCSigOrderingTest13);
2017 #endif
2018 }
DetectPcreData_::idx
uint8_t idx
Definition: detect-pcre.h:47
DETECT_SIGORDER_IPPAIRBITS
@ DETECT_SIGORDER_IPPAIRBITS
Definition: detect-engine-sigorder.c:79
SCSigSignatureWrapper
struct SCSigSignatureWrapper_ SCSigSignatureWrapper
Signature wrapper used by signature ordering module while ordering signatures.
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:116
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SignatureInitData_::smlists
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition: detect.h:588
DETECT_FLOWINT_TYPE_SET
#define DETECT_FLOWINT_TYPE_SET
Definition: detect-engine-sigorder.c:62
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1268
flow-util.h
SigFree
void SigFree(DetectEngineCtx *, Signature *)
Definition: detect-parse.c:1629
SCSigOrderFunc_::next
struct SCSigOrderFunc_ * next
Definition: detect-engine-sigorder.c:105
ACTION_PASS
#define ACTION_PASS
Definition: action-globals.h:34
ACTION_REJECT
#define ACTION_REJECT
Definition: action-globals.h:31
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DETECT_FLOWINT_TYPE_READ
#define DETECT_FLOWINT_TYPE_READ
Definition: detect-engine-sigorder.c:60
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
FLOWINT_MODIFIER_GT
@ FLOWINT_MODIFIER_GT
Definition: detect-flowint.h:40
Flow_::proto
uint8_t proto
Definition: flow.h:378
DETECT_FLOWBITS_CMD_ISNOTSET
#define DETECT_FLOWBITS_CMD_ISNOTSET
Definition: detect-flowbits.h:31
action-globals.h
Packet_::flags
uint32_t flags
Definition: decode.h:513
Flow_
Flow data structure.
Definition: flow.h:356
ActionOrderVal
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
DetectSigorderUserDataType
DetectSigorderUserDataType
Different kinds of helper data that can be used by the signature ordering module. Used by the "user" ...
Definition: detect-engine-sigorder.c:73
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:843
DetectFlowintData_
Definition: detect-flowint.h:61
DetectXbitsData_::cmd
uint8_t cmd
Definition: detect-xbits.h:42
DETECT_SIGORDER_FLOWBITS
@ DETECT_SIGORDER_FLOWBITS
Definition: detect-engine-sigorder.c:74
DetectFlowbitsData_::cmd
uint8_t cmd
Definition: detect-flowbits.h:37
DETECT_XBITS_TYPE_SET_READ
#define DETECT_XBITS_TYPE_SET_READ
Definition: detect-engine-sigorder.c:66
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2623
SCSigSignatureWrapper_::next
struct SCSigSignatureWrapper_ * next
Definition: detect-engine-sigorder.c:94
detect-flowint.h
SCSigSignatureOrderingModuleCleanup
void SCSigSignatureOrderingModuleCleanup(DetectEngineCtx *de_ctx)
De-registers all the signature ordering functions registered.
Definition: detect-engine-sigorder.c:852
UTHCheckPacketMatchResults
int UTHCheckPacketMatchResults(Packet *p, uint32_t sids[], uint32_t results[], int numsigs)
UTHCheckPacketMatches: function to check if a packet match some sids.
Definition: util-unittest-helper.c:605
FLOWINT_MODIFIER_NE
@ FLOWINT_MODIFIER_NE
Definition: detect-flowint.h:38
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:232
DE_QUIET
#define DE_QUIET
Definition: detect.h:323
FLOWINT_MODIFIER_EQ
@ FLOWINT_MODIFIER_EQ
Definition: detect-flowint.h:37
DETECT_PKTVAR_TYPE_READ
#define DETECT_PKTVAR_TYPE_READ
Definition: detect-engine-sigorder.c:50
UTHBuildPacket
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.
Definition: util-unittest-helper.c:359
SCSigRegisterSignatureOrderingTests
void SCSigRegisterSignatureOrderingTests(void)
Definition: detect-engine-sigorder.c:2000
DETECT_FLOWBITS_CMD_TOGGLE
#define DETECT_FLOWBITS_CMD_TOGGLE
Definition: detect-flowbits.h:29
DETECT_FLOWBITS_CMD_ISSET
#define DETECT_FLOWBITS_CMD_ISSET
Definition: detect-flowbits.h:32
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2591
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:507
action_order_sigs
uint8_t action_order_sigs[4]
Definition: util-action.c:40
SCSigSignatureWrapper_::sig
Signature * sig
Definition: detect-engine-sigorder.c:89
FLOWINT_MODIFIER_ISNOTSET
@ FLOWINT_MODIFIER_ISNOTSET
Definition: detect-flowint.h:43
detect-pcre.h
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:99
DetectXbitsData_
Definition: detect-xbits.h:40
FLOWINT_MODIFIER_ISSET
@ FLOWINT_MODIFIER_ISSET
Definition: detect-flowint.h:42
util-unittest.h
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
DETECT_HOSTBITS
@ DETECT_HOSTBITS
Definition: detect-engine-register.h:66
Signature_::next
struct Signature_ * next
Definition: detect.h:675
DetectFlowbitsData_
Definition: detect-flowbits.h:35
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:533
UTHMatchPackets
int UTHMatchPackets(DetectEngineCtx *de_ctx, Packet **p, int num_packets)
Definition: util-unittest-helper.c:712
DETECT_SM_LIST_POSTMATCH
@ DETECT_SM_LIST_POSTMATCH
Definition: detect.h:124
DETECT_FLOWVAR_TYPE_SET
#define DETECT_FLOWVAR_TYPE_SET
Definition: detect-engine-sigorder.c:47
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
detect-xbits.h
DETECT_XBITS_CMD_ISNOTSET
#define DETECT_XBITS_CMD_ISNOTSET
Definition: detect-xbits.h:30
DETECT_XBITS_TYPE_READ
#define DETECT_XBITS_TYPE_READ
Definition: detect-engine-sigorder.c:65
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DETECT_FLOWINT
@ DETECT_FLOWINT
Definition: detect-engine-register.h:65
DETECT_FLOWVAR
@ DETECT_FLOWVAR
Definition: detect-engine-register.h:63
SCSigOrderSignatures
void SCSigOrderSignatures(DetectEngineCtx *de_ctx)
Orders the signatures.
Definition: detect-engine-sigorder.c:760
SCSigOrderFunc
struct SCSigOrderFunc_ SCSigOrderFunc
Structure holding the signature ordering function used by the signature ordering module.
detect.h
DETECT_FLOWBITS_TYPE_SET_READ
#define DETECT_FLOWBITS_TYPE_SET_READ
Definition: detect-engine-sigorder.c:56
DETECT_SIGORDER_FLOWINT
@ DETECT_SIGORDER_FLOWINT
Definition: detect-engine-sigorder.c:77
SCSigSignatureWrapper_
Signature wrapper used by signature ordering module while ordering signatures.
Definition: detect-engine-sigorder.c:87
SCSigRegisterSignatureOrderingFuncs
void SCSigRegisterSignatureOrderingFuncs(DetectEngineCtx *de_ctx)
Lets you register the Signature ordering functions. The order in which the functions are registered s...
Definition: detect-engine-sigorder.c:832
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:353
FLOWINT_MODIFIER_LT
@ FLOWINT_MODIFIER_LT
Definition: detect-flowint.h:35
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:114
DETECT_XBITS_NOT_USED
#define DETECT_XBITS_NOT_USED
Definition: detect-engine-sigorder.c:64
DETECT_XBITS
@ DETECT_XBITS
Definition: detect-engine-register.h:67
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:352
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:300
Signature_::action
uint8_t action
Definition: detect.h:618
DETECT_FLOWVAR_TYPE_READ
#define DETECT_FLOWVAR_TYPE_READ
Definition: detect-engine-sigorder.c:45
DetectXbitsData_::type
enum VarTypes type
Definition: detect-xbits.h:46
DETECT_SIGORDER_PKTVAR
@ DETECT_SIGORDER_PKTVAR
Definition: detect-engine-sigorder.c:76
DETECT_PKTVAR_NOT_USED
#define DETECT_PKTVAR_NOT_USED
Definition: detect-engine-sigorder.c:49
ACTION_ALERT
#define ACTION_ALERT
Definition: action-globals.h:29
Packet_
Definition: decode.h:476
detect-engine-build.h
type
uint16_t type
Definition: decode-vlan.c:107
DETECT_SIGORDER_HOSTBITS
@ DETECT_SIGORDER_HOSTBITS
Definition: detect-engine-sigorder.c:78
SCSigOrderFunc_
Structure holding the signature ordering function used by the signature ordering module.
Definition: detect-engine-sigorder.c:101
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:672
DetectFlowintData_::modifier
uint8_t modifier
Definition: detect-flowint.h:70
DETECT_FLOWBITS_NOT_USED
#define DETECT_FLOWBITS_NOT_USED
Definition: detect-engine-sigorder.c:54
util-action.h
FLOWINT_MODIFIER_SUB
@ FLOWINT_MODIFIER_SUB
Definition: detect-flowint.h:32
DETECT_PKTVAR_TYPE_SET
#define DETECT_PKTVAR_TYPE_SET
Definition: detect-engine-sigorder.c:52
detect-flowbits.h
DETECT_PCRE
@ DETECT_PCRE
Definition: detect-engine-register.h:74
DETECT_SIGORDER_FLOWVAR
@ DETECT_SIGORDER_FLOWVAR
Definition: detect-engine-sigorder.c:75
DetectPcreData_::captypes
uint8_t captypes[DETECT_PCRE_CAPTURE_MAX]
Definition: detect-pcre.h:48
Packet_::flow
struct Flow_ * flow
Definition: decode.h:515
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
suricata-common.h
FLOWINT_MODIFIER_LE
@ FLOWINT_MODIFIER_LE
Definition: detect-flowint.h:36
SigMatch_::type
uint16_t type
Definition: detect.h:350
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:680
DETECT_FLOWINT_NOT_USED
#define DETECT_FLOWINT_NOT_USED
Definition: detect-engine-sigorder.c:59
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
DETECT_FLOWINT_TYPE_SET_READ
#define DETECT_FLOWINT_TYPE_SET_READ
Definition: detect-engine-sigorder.c:61
FatalError
#define FatalError(...)
Definition: util-debug.h:502
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:851
DETECT_FLOWBITS
@ DETECT_FLOWBITS
Definition: detect-engine-register.h:62
Signature_::prio
int prio
Definition: detect.h:641
DETECT_XBITS_TYPE_SET
#define DETECT_XBITS_TYPE_SET
Definition: detect-engine-sigorder.c:67
VAR_TYPE_HOST_BIT
@ VAR_TYPE_HOST_BIT
Definition: util-var.h:40
util-validate.h
detect-engine-sigorder.h
FLOWINT_MODIFIER_ADD
@ FLOWINT_MODIFIER_ADD
Definition: detect-flowint.h:31
SCSigOrderFunc_::SWCompare
int(* SWCompare)(SCSigSignatureWrapper *sw1, SCSigSignatureWrapper *sw2)
Definition: detect-engine-sigorder.c:103
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DETECT_FLOWVAR_TYPE_SET_READ
#define DETECT_FLOWVAR_TYPE_SET_READ
Definition: detect-engine-sigorder.c:46
Signature_::id
uint32_t id
Definition: detect.h:638
DETECT_FLOWBITS_CMD_UNSET
#define DETECT_FLOWBITS_CMD_UNSET
Definition: detect-flowbits.h:30
Flow_::flags
uint32_t flags
Definition: flow.h:426
detect-parse.h
Signature_
Signature container.
Definition: detect.h:603
SigMatch_
a single match condition for a signature
Definition: detect.h:349
VAR_TYPE_FLOW_VAR
@ VAR_TYPE_FLOW_VAR
Definition: util-var.h:38
DETECT_PKTVAR_TYPE_SET_READ
#define DETECT_PKTVAR_TYPE_SET_READ
Definition: detect-engine-sigorder.c:51
DETECT_XBITS_CMD_ISSET
#define DETECT_XBITS_CMD_ISSET
Definition: detect-xbits.h:31
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:234
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2584
VarTypes
VarTypes
Definition: util-var.h:28
DetectPcreData_
Definition: detect-pcre.h:42
FLOWINT_MODIFIER_GE
@ FLOWINT_MODIFIER_GE
Definition: detect-flowint.h:39
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:43
DETECT_XBITS_CMD_SET
#define DETECT_XBITS_CMD_SET
Definition: detect-xbits.h:27
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:845
UTHAppendSigs
int UTHAppendSigs(DetectEngineCtx *de_ctx, const char *sigs[], int numsigs)
UTHAppendSigs: Add sigs to the detection_engine checking for errors.
Definition: util-unittest-helper.c:638
DETECT_XBITS_CMD_TOGGLE
#define DETECT_XBITS_CMD_TOGGLE
Definition: detect-xbits.h:28
Signature_::msg
char * msg
Definition: detect.h:661
DETECT_XBITS_CMD_UNSET
#define DETECT_XBITS_CMD_UNSET
Definition: detect-xbits.h:29
VAR_TYPE_IPPAIR_BIT
@ VAR_TYPE_IPPAIR_BIT
Definition: util-var.h:44
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:455
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
DETECT_FLOWBITS_TYPE_SET
#define DETECT_FLOWBITS_TYPE_SET
Definition: detect-engine-sigorder.c:57
DETECT_SIGORDER_MAX
@ DETECT_SIGORDER_MAX
Definition: detect-engine-sigorder.c:80
FLOWINT_MODIFIER_SET
@ FLOWINT_MODIFIER_SET
Definition: detect-flowint.h:30
DetectEngineCtx_::signum
uint32_t signum
Definition: detect.h:863
DETECT_FLOWVAR_NOT_USED
#define DETECT_FLOWVAR_NOT_USED
Definition: detect-engine-sigorder.c:44
SCSigSignatureWrapper_::user
int user[DETECT_SIGORDER_MAX]
Definition: detect-engine-sigorder.c:92
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
VAR_TYPE_PKT_VAR
@ VAR_TYPE_PKT_VAR
Definition: util-var.h:33
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1265
DetectEngineCtx_::sc_sig_order_funcs
struct SCSigOrderFunc_ * sc_sig_order_funcs
Definition: detect.h:870
DETECT_FLOWBITS_CMD_SET
#define DETECT_FLOWBITS_CMD_SET
Definition: detect-flowbits.h:28
DETECT_PKTVAR
@ DETECT_PKTVAR
Definition: detect-engine-register.h:68
DETECT_FLOWBITS_TYPE_READ
#define DETECT_FLOWBITS_TYPE_READ
Definition: detect-engine-sigorder.c:55
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:450