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;
232  if (fi->modifier == FLOWINT_MODIFIER_LT ||
233  fi->modifier == FLOWINT_MODIFIER_LE ||
234  fi->modifier == FLOWINT_MODIFIER_EQ ||
235  fi->modifier == FLOWINT_MODIFIER_NE ||
236  fi->modifier == FLOWINT_MODIFIER_GE ||
237  fi->modifier == FLOWINT_MODIFIER_GT ||
240  read++;
241  } else {
242 #ifdef DEBUG
243  BUG_ON(1);
244 #endif
245  }
246  }
247 
248  sm = sm->next;
249  }
250 
252  while (sm != NULL) {
253  if (sm->type == DETECT_FLOWINT) {
254  fi = (DetectFlowintData *)sm->ctx;
255  if (fi->modifier == FLOWINT_MODIFIER_SET ||
258  write++;
259  } else {
260 #ifdef DEBUG
261  BUG_ON(1);
262 #endif
263  }
264  }
265 
266  sm = sm->next;
267  }
268 
269  if (read > 0 && write == 0) {
270  flowint_user_type = DETECT_FLOWINT_TYPE_READ;
271  } else if (read == 0 && write > 0) {
272  flowint_user_type = DETECT_FLOWINT_TYPE_SET;
273  } else if (read > 0 && write > 0) {
274  flowint_user_type = DETECT_FLOWINT_TYPE_SET_READ;
275  }
276 
277  SCLogDebug("Sig %s typeval %d", sig->msg, flowint_user_type);
278 
279  return flowint_user_type;
280 }
281 
282 /**
283  * \brief Returns whether the flowvar set for this rule, sets the flowvar or
284  * reads the flowvar. If the rule sets the flowvar the function returns
285  * DETECT_FLOWVAR_TYPE_SET(3), if it reads the flowvar the function
286  * returns DETECT_FLOWVAR_TYPE_READ(2), and if flowvar is not used in this
287  * rule the function returns DETECT_FLOWVAR_NOT_USED(1)
288  *
289  * \param sig Pointer to the Signature from which the flowvar type has to be
290  * returned.
291  *
292  * \retval type DETECT_FLOWVAR_TYPE_SET(3) if the rule sets the flowvar,
293  * DETECT_FLOWVAR_TYPE_READ(2) if it reads, and
294  * DETECT_FLOWVAR_NOT_USED(1) if flowvar is not used.
295  */
296 static inline int SCSigGetFlowvarType(Signature *sig)
297 {
298  DetectPcreData *pd = NULL;
300  int read = 0;
301  int write = 0;
303 
304  while (sm != NULL) {
305  pd = (DetectPcreData *)sm->ctx;
306  if (sm->type == DETECT_PCRE) {
307  uint8_t x;
308  for (x = 0; x < pd->idx; x++) {
309  if (pd->captypes[x] == VAR_TYPE_FLOW_VAR) {
310  write++;
311  break;
312  }
313  }
314  }
315 
316  sm = sm->next;
317  }
318 
320  pd = NULL;
321  while (sm != NULL) {
322  if (sm->type == DETECT_FLOWVAR) {
323  read++;
324  }
325 
326  sm = sm->next;
327  }
328 
329  if (read > 0 && write == 0) {
331  } else if (read == 0 && write > 0) {
333  } else if (read > 0 && write > 0) {
335  }
336 
337  return type;
338 }
339 
340 /**
341  * \brief Returns whether the pktvar set for this rule, sets the flowvar or
342  * reads the pktvar. If the rule sets the pktvar the function returns
343  * DETECT_PKTVAR_TYPE_SET(3), if it reads the pktvar the function
344  * returns DETECT_PKTVAR_TYPE_READ(2), and if pktvar is not used in this
345  * rule the function returns DETECT_PKTVAR_NOT_USED(1)
346  *
347  * \param sig Pointer to the Signature from which the pktvar type has to be
348  * returned.
349  *
350  * \retval type DETECT_PKTVAR_TYPE_SET(3) if the rule sets the flowvar,
351  * DETECT_PKTVAR_TYPE_READ(2) if it reads, and
352  * DETECT_PKTVAR_NOT_USED(1) if pktvar is not used.
353  */
354 static inline int SCSigGetPktvarType(Signature *sig)
355 {
356  DetectPcreData *pd = NULL;
358  int read = 0;
359  int write = 0;
361 
362  while (sm != NULL) {
363  pd = (DetectPcreData *)sm->ctx;
364  if (sm->type == DETECT_PCRE) {
365  uint8_t x;
366  for (x = 0; x < pd->idx; x++) {
367  if (pd->captypes[x] == VAR_TYPE_PKT_VAR) {
368  write++;
369  break;
370  }
371  }
372  }
373 
374  sm = sm->next;
375  }
376 
378  pd = NULL;
379  while (sm != NULL) {
380  if (sm->type == DETECT_PKTVAR) {
381  read++;
382  }
383 
384  sm = sm->next;
385  }
386 
387  if (read > 0 && write == 0) {
389  } else if (read == 0 && write > 0) {
391  } else if (read > 0 && write > 0) {
393  }
394 
395  return type;
396 }
397 
398 /**
399  * \brief Returns the xbit type set for this signature. If more than one
400  * xbit has been set for the same rule, we return the xbit type of
401  * the maximum priority/value, where priority/value is maximum for the
402  * ones that set the value and the lowest for ones that read the value.
403  * If no xbit has been set for the rule, we return 0, which indicates
404  * the least value amongst xbit types.
405  *
406  * \param sig Pointer to the Signature from which the xbit value has to be
407  * returned.
408  *
409  * \retval xbits The xbits type for this signature if it is set; if it is
410  * not set, return 0
411  */
412 static inline int SCSigGetXbitsType(Signature *sig, enum VarTypes type)
413 {
414  DetectXbitsData *fb = NULL;
415  int xbits_user_type = DETECT_XBITS_NOT_USED;
416  int read = 0;
417  int write = 0;
419 
420  while (sm != NULL) {
421  if (sm->type == DETECT_XBITS) {
422  fb = (DetectXbitsData *)sm->ctx;
423  if (fb->type == type) {
424  if (fb->cmd == DETECT_XBITS_CMD_ISNOTSET ||
425  fb->cmd == DETECT_XBITS_CMD_ISSET) {
426  read++;
427  } else {
428 #ifdef DEBUG
429  BUG_ON(1);
430 #endif
431  }
432  }
433  }
434 
435  sm = sm->next;
436  }
437 
439  while (sm != NULL) {
440  if (sm->type == DETECT_HOSTBITS) {
441  fb = (DetectXbitsData *)sm->ctx;
442  if (fb->type == type) {
443  if (fb->cmd == DETECT_XBITS_CMD_SET ||
444  fb->cmd == DETECT_XBITS_CMD_UNSET ||
445  fb->cmd == DETECT_XBITS_CMD_TOGGLE) {
446  write++;
447  } else {
448 #ifdef DEBUG
449  BUG_ON(1);
450 #endif
451  }
452  }
453  }
454 
455  sm = sm->next;
456  }
457 
458  if (read > 0 && write == 0) {
459  xbits_user_type = DETECT_XBITS_TYPE_READ;
460  } else if (read == 0 && write > 0) {
461  xbits_user_type = DETECT_XBITS_TYPE_SET;
462  } else if (read > 0 && write > 0) {
463  xbits_user_type = DETECT_XBITS_TYPE_SET_READ;
464  }
465 
466  SCLogDebug("Sig %s typeval %d", sig->msg, xbits_user_type);
467 
468  return xbits_user_type;
469 }
470 
471 /**
472  * \brief Processes the flowbits data for this signature and caches it for
473  * future use. This is needed to optimize the sig_ordering module.
474  *
475  * \param sw The sigwrapper/signature for which the flowbits data has to be
476  * cached
477  */
478 static inline void SCSigProcessUserDataForFlowbits(SCSigSignatureWrapper *sw)
479 {
480  sw->user[DETECT_SIGORDER_FLOWBITS] = SCSigGetFlowbitsType(sw->sig);
481 }
482 
483 /**
484  * \brief Processes the flowvar data for this signature and caches it for
485  * future use. This is needed to optimize the sig_ordering module.
486  *
487  * \param sw The sigwrapper/signature for which the flowvar data has to be
488  * cached
489  */
490 static inline void SCSigProcessUserDataForFlowvar(SCSigSignatureWrapper *sw)
491 {
492  sw->user[DETECT_SIGORDER_FLOWVAR] = SCSigGetFlowvarType(sw->sig);
493 }
494 
495 static inline void SCSigProcessUserDataForFlowint(SCSigSignatureWrapper *sw)
496 {
497  sw->user[DETECT_SIGORDER_FLOWINT] = SCSigGetFlowintType(sw->sig);
498 }
499 
500 /**
501  * \brief Processes the pktvar data for this signature and caches it for
502  * future use. This is needed to optimize the sig_ordering module.
503  *
504  * \param sw The sigwrapper/signature for which the pktvar data has to be
505  * cached
506  */
507 static inline void SCSigProcessUserDataForPktvar(SCSigSignatureWrapper *sw)
508 {
509  sw->user[DETECT_SIGORDER_PKTVAR] = SCSigGetPktvarType(sw->sig);
510 }
511 
512 /**
513  * \brief Processes the hostbits data for this signature and caches it for
514  * future use. This is needed to optimize the sig_ordering module.
515  *
516  * \param sw The sigwrapper/signature for which the hostbits data has to be
517  * cached
518  */
519 static inline void SCSigProcessUserDataForHostbits(SCSigSignatureWrapper *sw)
520 {
521  sw->user[DETECT_SIGORDER_HOSTBITS] = SCSigGetXbitsType(sw->sig, VAR_TYPE_HOST_BIT);
522 }
523 
524 /**
525  * \brief Processes the hostbits data for this signature and caches it for
526  * future use. This is needed to optimize the sig_ordering module.
527  *
528  * \param sw The sigwrapper/signature for which the hostbits data has to be
529  * cached
530  */
531 static inline void SCSigProcessUserDataForIPPairbits(SCSigSignatureWrapper *sw)
532 {
533  sw->user[DETECT_SIGORDER_IPPAIRBITS] = SCSigGetXbitsType(sw->sig, VAR_TYPE_IPPAIR_BIT);
534 }
535 
536 /* Return 1 if sw1 comes before sw2 in the final list. */
537 static int SCSigLessThan(SCSigSignatureWrapper *sw1,
539  SCSigOrderFunc *cmp_func_list)
540 {
541  SCSigOrderFunc *funcs = cmp_func_list;
542 
543  while (funcs != NULL) {
544  int delta = funcs->SWCompare(sw1, sw2);
545  if (delta > 0)
546  return 1;
547  else if (delta < 0)
548  return 0;
549 
550  funcs = funcs->next;
551  }
552  // They are equal, so use sid as the final decider.
553  return sw1->sig->id < sw2->sig->id;
554 }
555 
556 /* Merge sort based on a list of compare functions
557  * debug asserts are here to guide scan-build */
558 static SCSigSignatureWrapper *SCSigOrder(SCSigSignatureWrapper *sw,
559  SCSigOrderFunc *cmp_func_list)
560 {
561  DEBUG_VALIDATE_BUG_ON(sw == NULL);
562 
563  SCSigSignatureWrapper *subA = NULL;
564  SCSigSignatureWrapper *subB = NULL;
565  SCSigSignatureWrapper *first;
566  SCSigSignatureWrapper *second;
567  SCSigSignatureWrapper *result = NULL;
568  SCSigSignatureWrapper *last = NULL;
569  SCSigSignatureWrapper *new = NULL;
570 
571  /* Divide input list into two sub-lists. */
572  while (sw != NULL) {
573  first = sw;
574  sw = sw->next;
575  /* Push the first element onto sub-list A */
576  first->next = subA;
577  subA = first;
578 
579  if (sw == NULL)
580  break;
581  second = sw;
582  sw = sw->next;
583  /* Push the second element onto sub-list B */
584  second->next = subB;
585  subB = second;
586  }
587  if (subB == NULL) {
588  /* Only zero or one element on the list. */
589  return subA;
590  }
591  DEBUG_VALIDATE_BUG_ON(subA == NULL);
592 
593  /* Now sort each list */
594  subA = SCSigOrder(subA, cmp_func_list);
595  subB = SCSigOrder(subB, cmp_func_list);
596  DEBUG_VALIDATE_BUG_ON(subA == NULL);
597  DEBUG_VALIDATE_BUG_ON(subB == NULL);
598 
599  /* Merge the two sorted lists. */
600  while (subA != NULL && subB != NULL) {
601  if (SCSigLessThan(subA, subB, cmp_func_list)) {
602  new = subA;
603  subA = subA->next;
604  } else {
605  new = subB;
606  subB = subB->next;
607  }
608  /* Push onto the end of the output list. */
609  new->next = NULL;
610  if (result == NULL) {
611  result = new;
612  last = new;
613  } else {
614  last->next = new;
615  last = new;
616  }
617  }
618  /* Attach the rest of any remaining list. Only one can be non-NULL here. */
619  if (subA == NULL)
620  last->next = subB;
621  else if (subB == NULL)
622  last->next = subA;
623 
624  return result;
625 }
626 
627 /**
628  * \brief Orders an incoming Signature based on its action
629  *
630  * \param de_ctx Pointer to the detection engine context from which the
631  * signatures have to be ordered.
632  * \param sw The new signature that has to be ordered based on its action
633  */
634 static int SCSigOrderByActionCompare(SCSigSignatureWrapper *sw1,
636 {
637  return ActionOrderVal(sw2->sig->action) - ActionOrderVal(sw1->sig->action);
638 }
639 
640 /**
641  * \brief Orders an incoming Signature based on its flowbits type
642  *
643  * \param de_ctx Pointer to the detection engine context from which the
644  * signatures have to be ordered.
645  * \param sw The new signature that has to be ordered based on its flowbits
646  */
647 static int SCSigOrderByFlowbitsCompare(SCSigSignatureWrapper *sw1,
649 {
651 }
652 
653 /**
654  * \brief Orders an incoming Signature based on its flowvar type
655  *
656  * \param de_ctx Pointer to the detection engine context from which the
657  * signatures have to be ordered.
658  * \param sw The new signature that has to be ordered based on its flowvar
659  */
660 static int SCSigOrderByFlowvarCompare(SCSigSignatureWrapper *sw1,
662 {
664 }
665 
666 /**
667  * \brief Orders an incoming Signature based on its pktvar type
668  *
669  * \param de_ctx Pointer to the detection engine context from which the
670  * signatures have to be ordered.
671  * \param sw The new signature that has to be ordered based on its pktvar
672  */
673 static int SCSigOrderByPktvarCompare(SCSigSignatureWrapper *sw1,
675 {
677 }
678 
679 static int SCSigOrderByFlowintCompare(SCSigSignatureWrapper *sw1,
681 {
683 }
684 
685 /**
686  * \brief Orders an incoming Signature based on its hostbits type
687  *
688  * \param de_ctx Pointer to the detection engine context from which the
689  * signatures have to be ordered.
690  * \param sw The new signature that has to be ordered based on its hostbits
691  */
692 static int SCSigOrderByHostbitsCompare(SCSigSignatureWrapper *sw1,
694 {
696 }
697 
698 /**
699  * \brief Orders an incoming Signature based on its ippairbits (xbits) type
700  *
701  * \param de_ctx Pointer to the detection engine context from which the
702  * signatures have to be ordered.
703  * \param sw The new signature that has to be ordered based on its bits
704  */
705 static int SCSigOrderByIPPairbitsCompare(SCSigSignatureWrapper *sw1,
707 {
709 }
710 
711 /**
712  * \brief Orders an incoming Signature based on its priority type
713  *
714  * \param de_ctx Pointer to the detection engine context from which the
715  * signatures have to be ordered.
716  * \param sw The new signature that has to be ordered based on its priority
717  */
718 static int SCSigOrderByPriorityCompare(SCSigSignatureWrapper *sw1,
720 {
721  if (sw1->sig->prio > sw2->sig->prio) {
722  return -1;
723  } else if (sw1->sig->prio < sw2->sig->prio) {
724  return 1;
725  }
726  return 0;
727 }
728 
729 /**
730  * \brief Creates a Wrapper around the Signature
731  *
732  * \param Pointer to the Signature to be wrapped
733  *
734  * \retval sw Pointer to the wrapper that holds the signature
735  */
736 static inline SCSigSignatureWrapper *SCSigAllocSignatureWrapper(Signature *sig)
737 {
738  SCSigSignatureWrapper *sw = NULL;
739 
740  if ((sw = SCCalloc(1, sizeof(SCSigSignatureWrapper))) == NULL)
741  return NULL;
742 
743  sw->sig = sig;
744 
745  /* Process data from the signature into a cache for further use by the
746  * sig_ordering module */
747  SCSigProcessUserDataForFlowbits(sw);
748  SCSigProcessUserDataForFlowvar(sw);
749  SCSigProcessUserDataForFlowint(sw);
750  SCSigProcessUserDataForPktvar(sw);
751  SCSigProcessUserDataForHostbits(sw);
752  SCSigProcessUserDataForIPPairbits(sw);
753 
754  return sw;
755 }
756 
757 /**
758  * \brief Orders the signatures
759  *
760  * \param de_ctx Pointer to the Detection Engine Context that holds the
761  * signatures to be ordered
762  */
764 {
765  if (de_ctx->sig_list == NULL) {
766  SCLogDebug("no signatures to order");
767  return;
768  }
769 
770  Signature *sig = NULL;
771  SCSigSignatureWrapper *sigw = NULL;
772  SCSigSignatureWrapper *sigw_list = NULL;
773 #ifdef DEBUG
774  int i = 0;
775 #endif
776  SCLogDebug("ordering signatures in memory");
777 
778  sig = de_ctx->sig_list;
779  while (sig != NULL) {
780  sigw = SCSigAllocSignatureWrapper(sig);
781  /* Push signature wrapper onto a list, order doesn't matter here. */
782  sigw->next = sigw_list;
783  sigw_list = sigw;
784 
785  sig = sig->next;
786 #ifdef DEBUG
787  i++;
788 #endif
789  }
790 
791  /* Sort the list */
792  sigw_list = SCSigOrder(sigw_list, de_ctx->sc_sig_order_funcs);
793 
794  SCLogDebug("Total Signatures to be processed by the"
795  "sigordering module: %d", i);
796 
797  /* Recreate the sig list in order */
798  de_ctx->sig_list = NULL;
799  sigw = sigw_list;
800 #ifdef DEBUG
801  i = 0;
802 #endif
803  while (sigw != NULL) {
804 #ifdef DEBUG
805  i++;
806 #endif
807  sigw->sig->next = NULL;
808  if (de_ctx->sig_list == NULL) {
809  /* First entry on the list */
810  de_ctx->sig_list = sigw->sig;
811  sig = de_ctx->sig_list;
812  } else {
813  sig->next = sigw->sig;
814  sig = sig->next;
815  }
816  SCSigSignatureWrapper *sigw_to_free = sigw;
817  sigw = sigw->next;
818  SCFree(sigw_to_free);
819  }
820 
821  SCLogDebug("total signatures reordered by the sigordering module: %d", i);
822 }
823 
824 /**
825  * \brief Lets you register the Signature ordering functions. The order in
826  * which the functions are registered shows the priority. The first
827  * function registered provides more priority than the function
828  * registered after it. To add a new registration function, register
829  * it by listing it in the correct position in the below sequence,
830  * based on the priority you would want to offer to that keyword.
831  *
832  * \param de_ctx Pointer to the detection engine context from which the
833  * signatures have to be ordered.
834  */
836 {
837  SCLogDebug("registering signature ordering functions");
838 
839  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
840  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
841  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowintCompare);
842  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
843  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
844  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByHostbitsCompare);
845  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByIPPairbitsCompare);
846  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
847 }
848 
849 /**
850  * \brief De-registers all the signature ordering functions registered
851  *
852  * \param de_ctx Pointer to the detection engine context from which the
853  * signatures were ordered.
854  */
856 {
857  SCSigOrderFunc *funcs;
858  void *temp;
859 
860  /* clean the memory alloted to the signature ordering funcs */
861  funcs = de_ctx->sc_sig_order_funcs;
862  while (funcs != NULL) {
863  temp = funcs;
864  funcs = funcs->next;
865  SCFree(temp);
866  }
867  de_ctx->sc_sig_order_funcs = NULL;
868 }
869 
870 /**********Unittests**********/
871 
876 
877 #ifdef UNITTESTS
878 
879 static int SCSigOrderingTest01(void)
880 {
881  SCSigOrderFunc *temp = NULL;
882  int i = 0;
883 
886 
887  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
888  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
889  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
890  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
891  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
892  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
893  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
894  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
895  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
896  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
897  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
898 
899  temp = de_ctx->sc_sig_order_funcs;
900  while (temp != NULL) {
901  i++;
902  temp = temp->next;
903  }
904 
906 
907  FAIL_IF_NOT(i == 5);
908 
909  PASS;
910 }
911 
912 static int SCSigOrderingTest02(void)
913 {
914  Signature *sig = NULL;
915 
917  FAIL_IF(de_ctx == NULL);
918 
920  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
921  FAIL_IF_NULL(sig);
922 
924  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:2;)");
925  FAIL_IF_NULL(sig);
926 
928  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:3;)");
929  FAIL_IF_NULL(sig);
930 
932  "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;)");
933  FAIL_IF_NULL(sig);
934 
936  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:5;)");
937  FAIL_IF_NULL(sig);
938 
940  "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;)");
941  FAIL_IF_NULL(sig);
942 
944  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:7;)");
945  FAIL_IF_NULL(sig);
946 
948  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
949  FAIL_IF_NULL(sig);
950 
952  "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;)");
953  FAIL_IF_NULL(sig);
954 
956  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:10;)");
957  FAIL_IF_NULL(sig);
958 
960  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:11;)");
961  FAIL_IF_NULL(sig);
962 
964  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:12;)");
965  FAIL_IF_NULL(sig);
966 
968  "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;)");
969  FAIL_IF_NULL(sig);
970 
972  "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;)");
973  FAIL_IF_NULL(sig);
974 
975  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
976  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
977  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
978  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
979  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
981 
982  sig = de_ctx->sig_list;
983 
984 #ifdef DEBUG
985  while (sig != NULL) {
986  printf("sid: %d\n", sig->id);
987  sig = sig->next;
988  }
989 #endif
990 
991  sig = de_ctx->sig_list;
992 
993  /* pass */
994  FAIL_IF_NOT(sig->id == 6);
995  sig = sig->next;
996  FAIL_IF_NOT(sig->id == 4);
997  sig = sig->next;
998  FAIL_IF_NOT(sig->id == 8);
999  sig = sig->next;
1000  FAIL_IF_NOT(sig->id == 7);
1001  sig = sig->next;
1002  FAIL_IF_NOT(sig->id == 10);
1003  sig = sig->next;
1004 
1005  /* drops */
1006  FAIL_IF_NOT(sig->id == 9);
1007  sig = sig->next;
1008  FAIL_IF_NOT(sig->id == 13);
1009  sig = sig->next;
1010  FAIL_IF_NOT(sig->id == 2);
1011  sig = sig->next;
1012  FAIL_IF_NOT(sig->id == 3);
1013  sig = sig->next;
1014 
1015  /* alerts */
1016  FAIL_IF_NOT(sig->id == 14);
1017  sig = sig->next;
1018  FAIL_IF_NOT(sig->id == 5);
1019  sig = sig->next;
1020  FAIL_IF_NOT(sig->id == 1);
1021  sig = sig->next;
1022  FAIL_IF_NOT(sig->id == 11);
1023  sig = sig->next;
1024  FAIL_IF_NOT(sig->id == 12);
1025  sig = sig->next;
1026 
1028  PASS;
1029 }
1030 
1031 static int SCSigOrderingTest03(void)
1032 {
1033  Signature *sig = NULL;
1034 
1037 
1039  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1040  "offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:1;)");
1041  FAIL_IF_NULL(sig);
1042 
1044  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1045  "offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:2;)");
1046  FAIL_IF_NULL(sig);
1047 
1049  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1050  "offset:10; depth:4; pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; "
1051  "flowbits:unset,TEST.one; rev:4; priority:2; sid:3;)");
1052  FAIL_IF_NULL(sig);
1053 
1055  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1056  "offset:0; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1057  "flowbits:isset,TEST.one; rev:4; priority:1; sid:4;)");
1058  FAIL_IF_NULL(sig);
1059 
1061  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1062  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; priority:2; sid:5;)");
1063  FAIL_IF_NULL(sig);
1064 
1066  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1067  "content:\"220\"; offset:10; flowbits:isnotset,TEST.one; pcre:\"/^User-Agent: "
1068  "(?P<flow_http_host>.*)\\r\\n/m\"; rev:4; sid:6;)");
1069  FAIL_IF_NULL(sig);
1070 
1072  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1073  "content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; "
1074  "flowbits:unset,TEST.one; rev:4; priority:3; sid:7;)");
1075  FAIL_IF_NULL(sig);
1076 
1078  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1079  "offset:10; depth:4; pcre:\"/220[- ]/\"; flowbits:toggle,TEST.one; rev:4; priority:1; "
1080  "pktvar:http_host,\"www.oisf.net\"; sid:8;)");
1081  FAIL_IF_NULL(sig);
1082 
1084  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1085  "content:\"220\"; offset:10; depth:4; rev:4; flowbits:set,TEST.one; "
1086  "flowbits:noalert; pktvar:http_host,\"www.oisf.net\"; sid:9;)");
1087  FAIL_IF_NULL(sig);
1088 
1090  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1091  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:10;)");
1092  FAIL_IF_NULL(sig);
1093 
1095  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1096  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:11;)");
1097  FAIL_IF_NULL(sig);
1098 
1100  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1101  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:12;)");
1102  FAIL_IF_NULL(sig);
1103 
1105  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1106  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; flowbits:isnotset,TEST.one; sid:13;)");
1107  FAIL_IF_NULL(sig);
1108 
1110  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1111  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; flowbits:set,TEST.one; sid:14;)");
1112  FAIL_IF_NULL(sig);
1113 
1114  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1115  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1116  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1117  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1118  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1120 
1121  sig = de_ctx->sig_list;
1122 
1123 #ifdef DEBUG
1124  while (sig != NULL) {
1125  printf("sid: %d\n", sig->id);
1126  sig = sig->next;
1127  }
1128 #endif
1129 
1130  sig = de_ctx->sig_list;
1131 
1132  FAIL_IF_NOT(sig->id == 3);
1133  sig = sig->next;
1134 
1135  FAIL_IF_NOT(sig->id == 8);
1136  sig = sig->next;
1137  FAIL_IF_NOT(sig->id == 9);
1138  sig = sig->next;
1139  FAIL_IF_NOT(sig->id == 7);
1140  sig = sig->next;
1141  FAIL_IF_NOT(sig->id == 14);
1142  sig = sig->next;
1143  FAIL_IF_NOT(sig->id == 6);
1144  sig = sig->next;
1145  FAIL_IF_NOT(sig->id == 4);
1146  sig = sig->next;
1147  FAIL_IF_NOT(sig->id == 13);
1148  sig = sig->next;
1149  FAIL_IF_NOT(sig->id == 2);
1150  sig = sig->next;
1151  FAIL_IF_NOT(sig->id == 5);
1152  sig = sig->next;
1153  FAIL_IF_NOT(sig->id == 1);
1154  sig = sig->next;
1155  FAIL_IF_NOT(sig->id == 10);
1156  sig = sig->next;
1157  FAIL_IF_NOT(sig->id == 11);
1158  sig = sig->next;
1159  FAIL_IF_NOT(sig->id == 12);
1160 
1161  sig = sig->next;
1162 
1164 
1165  PASS;
1166 }
1167 
1168 static int SCSigOrderingTest04(void)
1169 {
1170 
1171  Signature *sig = NULL;
1172 
1174  FAIL_IF(de_ctx == NULL);
1175 
1177  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1178  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1179  FAIL_IF_NULL(sig);
1180 
1182  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1183  "pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; content:\"220\"; "
1184  "offset:10; rev:4; priority:3; sid:2;)");
1185  FAIL_IF_NULL(sig);
1186 
1188  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1189  "content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: "
1190  "(?P<flow_http_host>.*)\\r\\n/m\"; rev:4; priority:3; sid:3;)");
1191  FAIL_IF_NULL(sig);
1192 
1194  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1195  "offset:10; depth:4; pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; rev:4; "
1196  "priority:3; flowvar:http_host,\"www.oisf.net\"; sid:4;)");
1197  FAIL_IF_NULL(sig);
1198 
1200  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1201  "offset:11; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1202  "pcre:\"/220[- ]/\"; rev:4; priority:3; sid:5;)");
1203  FAIL_IF_NULL(sig);
1204 
1206  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1207  "offset:11; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1208  "pktvar:http_host,\"www.oisf.net\"; rev:4; priority:1; sid:6;)");
1209  FAIL_IF_NULL(sig);
1210 
1212  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1213  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; flowvar:http_host,\"www.oisf.net\"; "
1214  "pktvar:http_host,\"www.oisf.net\"; priority:1; sid:7;)");
1215  FAIL_IF_NULL(sig);
1216 
1218  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1219  "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1220  "flowvar:http_host,\"www.oisf.net\"; sid:8;)");
1221  FAIL_IF_NULL(sig);
1222 
1224  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1225  "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1226  "flowvar:http_host,\"www.oisf.net\"; sid:9;)");
1227  FAIL_IF_NULL(sig);
1228 
1229  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1230  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1231  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1232  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1233  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1235 
1236  sig = de_ctx->sig_list;
1237 
1238 #ifdef DEBUG
1239  while (sig != NULL) {
1240  printf("sid: %d\n", sig->id);
1241  sig = sig->next;
1242  }
1243 #endif
1244 
1245  sig = de_ctx->sig_list;
1246 
1247  /* flowvar set */
1248  sig = sig->next;
1249  FAIL_IF_NOT(sig->id == 3);
1250  sig = sig->next;
1251  FAIL_IF_NOT(sig->id == 4);
1252  sig = sig->next;
1253  FAIL_IF_NOT(sig->id == 7);
1254  sig = sig->next;
1255  FAIL_IF_NOT(sig->id == 8);
1256  sig = sig->next;
1257  FAIL_IF_NOT(sig->id == 9);
1258  sig = sig->next;
1259 
1260  /* pktvar */
1261 
1262  FAIL_IF_NOT(sig->id == 5);
1263  sig = sig->next;
1264  FAIL_IF_NOT(sig->id == 6);
1265  sig = sig->next;
1266 
1267  FAIL_IF_NOT(sig->id == 1);
1268  sig = sig->next;
1269 
1271 
1272  PASS;
1273 }
1274 
1275 static int SCSigOrderingTest05(void)
1276 {
1277  Signature *sig = NULL;
1278 
1280  FAIL_IF(de_ctx == NULL);
1281 
1283  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1284  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1285  FAIL_IF_NULL(sig);
1286 
1288  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1289  "pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; content:\"220\"; "
1290  "offset:10; rev:4; priority:3; sid:2;)");
1291  FAIL_IF_NULL(sig);
1292 
1294  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1295  "content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: "
1296  "(?P<pkt_http_host>.*)\\r\\n/m\"; rev:4; priority:3; sid:3;)");
1297  FAIL_IF_NULL(sig);
1298 
1300  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1301  "offset:10; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; rev:4; "
1302  "priority:3; pktvar:http_host,\"www.oisf.net\"; sid:4;)");
1303  FAIL_IF_NULL(sig);
1304 
1306  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1307  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:5;)");
1308  FAIL_IF_NULL(sig);
1309 
1311  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1312  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:6;)");
1313  FAIL_IF_NULL(sig);
1314 
1316  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1317  "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1318  "pktvar:http_host,\"www.oisf.net\"; sid:7;)");
1319  FAIL_IF_NULL(sig);
1320 
1322  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1323  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; "
1324  "pktvar:http_host,\"www.oisf.net\"; sid:8;)");
1325  FAIL_IF_NULL(sig);
1326 
1327  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1328  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1329  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1330  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1331  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1333 
1334  sig = de_ctx->sig_list;
1335 
1336  //#ifdef DEBUG
1337  while (sig != NULL) {
1338  printf("sid: %d\n", sig->id);
1339  sig = sig->next;
1340  }
1341  //#endif
1342 
1343  sig = de_ctx->sig_list;
1344 
1345  /* pktvar set */
1346  FAIL_IF_NOT(sig->id == 2);
1347  sig = sig->next;
1348  FAIL_IF_NOT(sig->id == 3);
1349  sig = sig->next;
1350  FAIL_IF_NOT(sig->id == 4);
1351  sig = sig->next;
1352  /* pktvar read */
1353  FAIL_IF_NOT(sig->id == 7);
1354  sig = sig->next;
1355  FAIL_IF_NOT(sig->id == 8);
1356  sig = sig->next;
1357  FAIL_IF_NOT(sig->id == 1);
1358  sig = sig->next;
1359  FAIL_IF_NOT(sig->id == 5);
1360  sig = sig->next;
1361  FAIL_IF_NOT(sig->id == 6);
1362  sig = sig->next;
1363 
1365 
1366  PASS;
1367 }
1368 
1369 static int SCSigOrderingTest06(void)
1370 {
1371 
1372  Signature *sig = NULL;
1373 
1376 
1378  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1379  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1380  FAIL_IF_NULL(sig);
1381 
1383  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1384  "content:\"220\"; offset:10; rev:4; priority:2; sid:2;)");
1385  FAIL_IF_NULL(sig);
1386 
1388  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1389  "content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:3;)");
1390  FAIL_IF_NULL(sig);
1391 
1393  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1394  "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1395  FAIL_IF_NULL(sig);
1396 
1398  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1399  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1400  FAIL_IF_NULL(sig);
1401 
1403  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1404  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1405  FAIL_IF_NULL(sig);
1407  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1408  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1409  FAIL_IF_NULL(sig);
1410 
1412  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1413  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1414  FAIL_IF_NULL(sig);
1415 
1416  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1417  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1418  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1419  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1420  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1422 
1423  sig = de_ctx->sig_list;
1424 
1425 #ifdef DEBUG
1426  while (sig != NULL) {
1427  printf("sid: %d\n", sig->id);
1428  sig = sig->next;
1429  }
1430 #endif
1431 
1432  sig = de_ctx->sig_list;
1433 
1434  FAIL_IF_NOT(sig->id == 6);
1435  sig = sig->next;
1436  FAIL_IF_NOT(sig->id == 2);
1437  sig = sig->next;
1438  FAIL_IF_NOT(sig->id == 4);
1439  sig = sig->next;
1440  FAIL_IF_NOT(sig->id == 5);
1441  sig = sig->next;
1442  FAIL_IF_NOT(sig->id == 7);
1443  sig = sig->next;
1444  FAIL_IF_NOT(sig->id == 8);
1445  sig = sig->next;
1446  FAIL_IF_NOT(sig->id == 1);
1447  sig = sig->next;
1448  FAIL_IF_NOT(sig->id == 3);
1449  sig = sig->next;
1450 
1452 
1453  PASS;
1454 }
1455 static int SCSigOrderingTest07(void)
1456 {
1457 
1458  Signature *sig = NULL;
1459 
1461  FAIL_IF(de_ctx == NULL);
1462 
1464  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1465  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1; rev:4;)");
1466  FAIL_IF_NULL(sig);
1467 
1469  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1470  "content:\"220\"; offset:10; sid:2; rev:4; priority:2;)");
1471  FAIL_IF_NULL(sig);
1472 
1474  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1475  "content:\"220\"; offset:10; depth:4; sid:3; rev:4; priority:3;)");
1476  FAIL_IF_NULL(sig);
1477 
1479  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1480  "content:\"220\"; offset:10; depth:4; sid:4; rev:4; priority:2;)");
1481  FAIL_IF_NULL(sig);
1482 
1484  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1485  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:5; rev:4; priority:2;)");
1486  FAIL_IF_NULL(sig);
1487 
1489  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1490  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:6; rev:4; priority:1;)");
1491  FAIL_IF_NULL(sig);
1492 
1494  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1495  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:7; rev:4; priority:2;)");
1496  FAIL_IF_NULL(sig);
1497 
1499  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1500  "offset:12; depth:4; pcre:\"/220[- ]/\"; sid:8; rev:4; priority:2;)");
1501  FAIL_IF_NULL(sig);
1502 
1503  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1504  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1505  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1506  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1507  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1509 
1510  sig = de_ctx->sig_list;
1511 
1512 #ifdef DEBUG
1513  while (sig != NULL) {
1514  printf("sid: %d\n", sig->id);
1515  sig = sig->next;
1516  }
1517 #endif
1518 
1519  sig = de_ctx->sig_list;
1520 
1521  FAIL_IF_NOT(sig->id == 2);
1522  sig = sig->next;
1523  FAIL_IF_NOT(sig->id == 4);
1524  sig = sig->next;
1525  FAIL_IF_NOT(sig->id == 5);
1526  sig = sig->next;
1527  FAIL_IF_NOT(sig->id == 7);
1528  sig = sig->next;
1529  FAIL_IF_NOT(sig->id == 6);
1530  sig = sig->next;
1531  FAIL_IF_NOT(sig->id == 8);
1532  sig = sig->next;
1533  FAIL_IF_NOT(sig->id == 1);
1534  sig = sig->next;
1535  FAIL_IF_NOT(sig->id == 3);
1536  sig = sig->next;
1537 
1539 
1540  PASS;
1541 }
1542 
1543 /**
1544  * \test Order with a different Action priority
1545  * (as specified from config)
1546  */
1547 static int SCSigOrderingTest08(void)
1548 {
1549 #ifdef HAVE_LIBNET11
1550 
1551  Signature *sig = NULL;
1552  extern uint8_t action_order_sigs[4];
1553 
1554  /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1559 
1561  FAIL_IF(de_ctx == NULL);
1562 
1564  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1565  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1; rev:4;)");
1566  FAIL_IF_NULL(sig);
1567 
1569  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1570  "content:\"220\"; offset:10; sid:2; rev:4; priority:2;)");
1571  FAIL_IF_NULL(sig);
1572 
1574  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1575  "content:\"220\"; offset:10; depth:4; sid:3; rev:4; priority:3;)");
1576  FAIL_IF_NULL(sig);
1577 
1579  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1580  "content:\"220\"; offset:10; depth:4; sid:4; rev:4; priority:2;)");
1581  FAIL_IF_NULL(sig);
1582 
1584  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1585  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:5; rev:4; priority:2;)");
1586  FAIL_IF_NULL(sig);
1587 
1589  "reject tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1590  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:6; rev:4; priority:1;)");
1591  FAIL_IF_NULL(sig);
1592 
1594  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; "
1595  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; sid:7; rev:4;)");
1596  FAIL_IF_NULL(sig);
1597 
1599  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1600  "offset:12; depth:4; pcre:\"/220[- ]/\"; sid:8; rev:4; priority:2;)");
1601  FAIL_IF_NULL(sig);
1602 
1603  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1604  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1605  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1606  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1607  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1609 
1610  sig = de_ctx->sig_list;
1611 
1612 #ifdef DEBUG
1613  while (sig != NULL) {
1614  printf("sid: %d\n", sig->id);
1615  sig = sig->next;
1616  }
1617 #endif
1618 
1619  sig = de_ctx->sig_list;
1620 
1621  FAIL_IF_NOT(sig->id == 6);
1622  sig = sig->next;
1623  FAIL_IF_NOT(sig->id == 8);
1624  sig = sig->next;
1625  FAIL_IF_NOT(sig->id == 1);
1626  sig = sig->next;
1627  FAIL_IF_NOT(sig->id == 3);
1628  sig = sig->next;
1629  FAIL_IF_NOT(sig->id == 2);
1630  sig = sig->next;
1631  FAIL_IF_NOT(sig->id == 4);
1632  sig = sig->next;
1633  FAIL_IF_NOT(sig->id == 5);
1634  sig = sig->next;
1635  FAIL_IF_NOT(sig->id == 7);
1636  sig = sig->next;
1637 
1638  /* Restore the default pre-order definition */
1643 
1645 
1646 #endif
1647  PASS;
1648 }
1649 
1650 /**
1651  * \test Order with a different Action priority
1652  * (as specified from config)
1653  */
1654 static int SCSigOrderingTest09(void)
1655 {
1656 
1657  Signature *sig = NULL;
1658  extern uint8_t action_order_sigs[4];
1659 
1660  /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1665 
1667  FAIL_IF(de_ctx == NULL);
1668 
1670  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1671  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1;)");
1672  FAIL_IF_NULL(sig);
1673 
1675  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1676  "content:\"220\"; offset:10; priority:2; sid:2;)");
1677  FAIL_IF_NULL(sig);
1678 
1680  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1681  "content:\"220\"; offset:10; depth:4; priority:3; sid:3;)");
1682  FAIL_IF_NULL(sig);
1683 
1685  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1686  "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1687  FAIL_IF_NULL(sig);
1688 
1690  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1691  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1692  FAIL_IF_NULL(sig);
1693 
1695  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1696  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1697  FAIL_IF_NULL(sig);
1698 
1700  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1701  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1702  FAIL_IF_NULL(sig);
1703 
1705  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1706  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1707  FAIL_IF_NULL(sig);
1708 
1709  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1710  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1711  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1712  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1713  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1715 
1716  sig = de_ctx->sig_list;
1717 
1718 #ifdef DEBUG
1719  while (sig != NULL) {
1720  printf("sid: %d\n", sig->id);
1721  sig = sig->next;
1722  }
1723 #endif
1724 
1725  sig = de_ctx->sig_list;
1726 
1727  FAIL_IF_NOT(sig->id == 6);
1728  sig = sig->next;
1729  FAIL_IF_NOT(sig->id == 7);
1730  sig = sig->next;
1731  FAIL_IF_NOT(sig->id == 8);
1732  sig = sig->next;
1733  FAIL_IF_NOT(sig->id == 1);
1734  sig = sig->next;
1735  FAIL_IF_NOT(sig->id == 3);
1736  sig = sig->next;
1737  FAIL_IF_NOT(sig->id == 2);
1738  sig = sig->next;
1739  FAIL_IF_NOT(sig->id == 4);
1740  sig = sig->next;
1741  FAIL_IF_NOT(sig->id == 5);
1742  sig = sig->next;
1743 
1744  /* Restore the default pre-order definition */
1749 
1751  PASS;
1752 }
1753 
1754 /**
1755  * \test Order with a different Action priority
1756  * (as specified from config)
1757  */
1758 static int SCSigOrderingTest10(void)
1759 {
1760 
1761  Signature *sig = NULL;
1762  extern uint8_t action_order_sigs[4];
1763 
1764  /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1769 
1771  FAIL_IF(de_ctx == NULL);
1772 
1774  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1775  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1776  FAIL_IF_NULL(sig);
1777 
1779  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1780  "content:\"220\"; offset:10; rev:4; priority:2; sid:2;)");
1781  FAIL_IF_NULL(sig);
1782 
1784  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1785  "content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:3;)");
1786  FAIL_IF_NULL(sig);
1787 
1789  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1790  "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1791  FAIL_IF_NULL(sig);
1792 
1794  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1795  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1796  FAIL_IF_NULL(sig);
1797 
1799  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1800  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1801  FAIL_IF_NULL(sig);
1802 
1804  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1805  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1806  FAIL_IF_NULL(sig);
1807 
1809  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1810  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1811  FAIL_IF_NULL(sig);
1812 
1813  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1814  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1815  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1816  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1817  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1819 
1820  sig = de_ctx->sig_list;
1821 
1822 #ifdef DEBUG
1823  while (sig != NULL) {
1824  printf("sid: %d\n", sig->id);
1825  sig = sig->next;
1826  }
1827 #endif
1828 
1829  sig = de_ctx->sig_list;
1830 
1831  FAIL_IF_NOT(sig->id == 2);
1832  sig = sig->next;
1833  FAIL_IF_NOT(sig->id == 4);
1834  sig = sig->next;
1835  FAIL_IF_NOT(sig->id == 5);
1836  sig = sig->next;
1837  FAIL_IF_NOT(sig->id == 8);
1838  sig = sig->next;
1839  FAIL_IF_NOT(sig->id == 1);
1840  sig = sig->next;
1841  FAIL_IF_NOT(sig->id == 3);
1842  sig = sig->next;
1843  FAIL_IF_NOT(sig->id == 6);
1844  sig = sig->next;
1845  FAIL_IF_NOT(sig->id == 7);
1846  sig = sig->next;
1847 
1848  /* Restore the default pre-order definition */
1853 
1855  PASS;
1856 }
1857 
1858 static int SCSigOrderingTest11(void)
1859 {
1860 
1861  Signature *sig = NULL;
1862 
1864  FAIL_IF(de_ctx == NULL);
1865 
1867  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering set\"; "
1868  "flowbits:isnotset,myflow1; rev:4; sid:1;)");
1869  FAIL_IF_NULL(sig);
1870 
1872  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering toggle\"; "
1873  "flowbits:toggle,myflow2; rev:4; sid:2;)");
1874  FAIL_IF_NULL(sig);
1875 
1877  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering unset\"; "
1878  "flowbits:isset, myflow1; flowbits:unset,myflow2; rev:4; priority:3; sid:3;)");
1879  FAIL_IF_NULL(sig);
1880 
1881  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1882  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1883  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1884  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1885  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1887 
1888  sig = de_ctx->sig_list;
1889 
1890 #ifdef DEBUG
1891  while (sig != NULL) {
1892  printf("sid: %d\n", sig->id);
1893  sig = sig->next;
1894  }
1895 #endif
1896 
1897  sig = de_ctx->sig_list;
1898 
1899  FAIL_IF_NOT(sig->id == 2);
1900  sig = sig->next;
1901  FAIL_IF_NOT(sig->id == 3);
1902  sig = sig->next;
1903  FAIL_IF_NOT(sig->id == 1);
1904  sig = sig->next;
1905 
1907  PASS;
1908 }
1909 
1910 static int SCSigOrderingTest12(void)
1911 {
1912  Signature *sig = NULL;
1913  Packet *p = NULL;
1914  uint8_t buf[] = "test message";
1915  Flow f;
1916 
1917  FLOW_INITIALIZE(&f);
1918  f.flags |= FLOW_IPV4;
1920  f.proto = IPPROTO_TCP;
1921 
1923  FAIL_IF(de_ctx == NULL);
1924  de_ctx->flags |= DE_QUIET;
1925 
1926  const char *sigs[2];
1927  sigs[0] = "alert tcp any any -> any any (content:\"test\"; dsize:>0; flowbits:isset,one; flowbits:set,two; sid:1;)";
1928  sigs[1] = "alert tcp any any -> any any (content:\"test\"; dsize:>0; flowbits:set,one; sid:2;)";
1929  UTHAppendSigs(de_ctx, sigs, 2);
1930 
1931  sig = de_ctx->sig_list;
1932  FAIL_IF_NULL(sig);
1933  FAIL_IF_NULL(sig->next);
1934  FAIL_IF_NOT_NULL(sig->next->next);
1935  FAIL_IF(de_ctx->signum != 2);
1936 
1938  p = UTHBuildPacket(buf, sizeof(buf), IPPROTO_TCP);
1939  FAIL_IF_NULL(p);
1940 
1941  p->flow = &f;
1945 
1946  UTHMatchPackets(de_ctx, &p, 1);
1947 
1948  uint32_t sids[2] = {1, 2};
1949  uint32_t results[2] = {1, 1};
1950  FAIL_IF_NOT(UTHCheckPacketMatchResults(p, sids, results, 2));
1951 
1952  UTHFreePackets(&p, 1);
1953 
1955 
1956  FlowShutdown();
1957 
1958  PASS;
1959 }
1960 
1961 /** \test Bug 1061 */
1962 static int SCSigOrderingTest13(void)
1963 {
1964 
1965  Signature *sig = NULL;
1966 
1968  FAIL_IF(de_ctx == NULL);
1969 
1970  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:isset,bit1; flowbits:set,bit2; flowbits:set,bit3; sid:6;)");
1971  FAIL_IF_NULL(sig);
1972  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:set,bit1; flowbits:set,bit2; sid:7;)");
1973  FAIL_IF_NULL(sig);
1974  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:isset,bit1; flowbits:isset,bit2; flowbits:isset,bit3; sid:5;)");
1975  FAIL_IF_NULL(sig);
1976 
1977  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1979 
1980 #ifdef DEBUG
1981  sig = de_ctx->sig_list;
1982  while (sig != NULL) {
1983  printf("sid: %d\n", sig->id);
1984  sig = sig->next;
1985  }
1986 #endif
1987 
1988  sig = de_ctx->sig_list;
1989 
1990  FAIL_IF_NOT(sig->id == 7);
1991  sig = sig->next;
1992  FAIL_IF_NOT(sig->id == 6);
1993  sig = sig->next;
1994  FAIL_IF_NOT(sig->id == 5);
1995  sig = sig->next;
1996 
1998  PASS;
1999 }
2000 
2001 #endif
2002 
2004 {
2005 
2006 #ifdef UNITTESTS
2007  UtRegisterTest("SCSigOrderingTest01", SCSigOrderingTest01);
2008  UtRegisterTest("SCSigOrderingTest02", SCSigOrderingTest02);
2009  UtRegisterTest("SCSigOrderingTest03", SCSigOrderingTest03);
2010  UtRegisterTest("SCSigOrderingTest04", SCSigOrderingTest04);
2011  UtRegisterTest("SCSigOrderingTest05", SCSigOrderingTest05);
2012  UtRegisterTest("SCSigOrderingTest06", SCSigOrderingTest06);
2013  UtRegisterTest("SCSigOrderingTest07", SCSigOrderingTest07);
2014  UtRegisterTest("SCSigOrderingTest08", SCSigOrderingTest08);
2015  UtRegisterTest("SCSigOrderingTest09", SCSigOrderingTest09);
2016  UtRegisterTest("SCSigOrderingTest10", SCSigOrderingTest10);
2017  UtRegisterTest("SCSigOrderingTest11", SCSigOrderingTest11);
2018  UtRegisterTest("SCSigOrderingTest12", SCSigOrderingTest12);
2019  UtRegisterTest("SCSigOrderingTest13", SCSigOrderingTest13);
2020 #endif
2021 }
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:1264
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:510
Flow_
Flow data structure.
Definition: flow.h:356
FLOWINT_MODIFIER_NOTSET
@ FLOWINT_MODIFIER_NOTSET
Definition: detect-flowint.h:43
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:855
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:2003
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:504
action_order_sigs
uint8_t action_order_sigs[4]
Definition: util-action.c:40
SCSigSignatureWrapper_::sig
Signature * sig
Definition: detect-engine-sigorder.c:89
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:64
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:63
DETECT_FLOWVAR
@ DETECT_FLOWVAR
Definition: detect-engine-register.h:61
SCSigOrderSignatures
void SCSigOrderSignatures(DetectEngineCtx *de_ctx)
Orders the signatures.
Definition: detect-engine-sigorder.c:763
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:835
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:65
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:473
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:72
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:512
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:60
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:1261
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:66
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