suricata
detect-engine-sigorder.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2013 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \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 /**
71  * \brief Registers a keyword-based, signature ordering function
72  *
73  * \param de_ctx Pointer to the detection engine context from which the
74  * signatures have to be ordered.
75  * \param FuncPtr Pointer to the signature ordering function. The prototype of
76  * the signature ordering function should accept a pointer to a
77  * SCSigSignatureWrapper as its argument and shouldn't return
78  * anything
79  */
80 static void SCSigRegisterSignatureOrderingFunc(DetectEngineCtx *de_ctx,
81  int (*SWCompare)(SCSigSignatureWrapper *sw1, SCSigSignatureWrapper *sw2))
82 {
83  SCSigOrderFunc *curr = NULL;
84  SCSigOrderFunc *prev = NULL;
85  SCSigOrderFunc *temp = NULL;
86 
87  curr = de_ctx->sc_sig_order_funcs;
88 
89  /* Walk to the end of the list, and leave prev pointing at the
90  last element. */
91  prev = curr;
92  while (curr != NULL) {
93  if (curr->SWCompare == SWCompare) {
94  /* Already specified this compare */
95  return;
96  }
97  prev = curr;
98  curr = curr->next;
99  }
100 
101  if ((temp = SCCalloc(1, sizeof(SCSigOrderFunc))) == NULL) {
102  FatalError("Fatal error encountered in SCSigRegisterSignatureOrderingFunc. Exiting...");
103  }
104 
105  temp->SWCompare = SWCompare;
106 
107  /* Append the new compare function at the end of the list. */
108  if (prev == NULL)
109  de_ctx->sc_sig_order_funcs = temp;
110  else
111  prev->next = temp;
112 }
113 
114 /**
115  * \brief Returns the flowbit type set for this signature. If more than one
116  * flowbit has been set for the same rule, we return the flowbit type of
117  * the maximum priority/value, where priority/value is maximum for the
118  * ones that set the value and the lowest for ones that read the value.
119  * If no flowbit has been set for the rule, we return 0, which indicates
120  * the least value amongst flowbit types.
121  *
122  * \param sig Pointer to the Signature from which the flowbit value has to be
123  * returned.
124  *
125  * \retval flowbits The flowbits type for this signature if it is set; if it is
126  * not set, return 0
127  */
128 static inline int SCSigGetFlowbitsType(Signature *sig)
129 {
130  DetectFlowbitsData *fb = NULL;
131  int flowbits_user_type = DETECT_FLOWBITS_NOT_USED;
132  int read = 0;
133  int write = 0;
135 
136  while (sm != NULL) {
137  if (sm->type == DETECT_FLOWBITS) {
138  fb = (DetectFlowbitsData *)sm->ctx;
139  if (fb->cmd == DETECT_FLOWBITS_CMD_ISNOTSET ||
141  read++;
142  } else {
143 #ifdef DEBUG
144  BUG_ON(1);
145 #endif
146  }
147  }
148 
149  sm = sm->next;
150  }
151 
153  while (sm != NULL) {
154  if (sm->type == DETECT_FLOWBITS) {
155  fb = (DetectFlowbitsData *)sm->ctx;
156  if (fb->cmd == DETECT_FLOWBITS_CMD_SET ||
159  write++;
160  } else {
161 #ifdef DEBUG
162  BUG_ON(1);
163 #endif
164  }
165  }
166 
167  sm = sm->next;
168  }
169 
170  if (read > 0 && write == 0) {
171  flowbits_user_type = DETECT_FLOWBITS_TYPE_READ;
172  } else if (read == 0 && write > 0) {
173  flowbits_user_type = DETECT_FLOWBITS_TYPE_SET;
174  } else if (read > 0 && write > 0) {
175  flowbits_user_type = DETECT_FLOWBITS_TYPE_SET_READ;
176  }
177 
178  SCLogDebug("Sig %s typeval %d", sig->msg, flowbits_user_type);
179 
180  return flowbits_user_type;
181 }
182 
183 static inline int SCSigGetFlowintType(Signature *sig)
184 {
185  DetectFlowintData *fi = NULL;
186  int flowint_user_type = DETECT_FLOWINT_NOT_USED;
187  int read = 0;
188  int write = 0;
190 
191  while (sm != NULL) {
192  if (sm->type == DETECT_FLOWINT) {
193  fi = (DetectFlowintData *)sm->ctx;
194  if (fi->modifier == FLOWINT_MODIFIER_LT ||
195  fi->modifier == FLOWINT_MODIFIER_LE ||
196  fi->modifier == FLOWINT_MODIFIER_EQ ||
197  fi->modifier == FLOWINT_MODIFIER_NE ||
198  fi->modifier == FLOWINT_MODIFIER_GE ||
199  fi->modifier == FLOWINT_MODIFIER_GT ||
202  read++;
203  } else {
204 #ifdef DEBUG
205  BUG_ON(1);
206 #endif
207  }
208  }
209 
210  sm = sm->next;
211  }
212 
214  while (sm != NULL) {
215  if (sm->type == DETECT_FLOWINT) {
216  fi = (DetectFlowintData *)sm->ctx;
217  if (fi->modifier == FLOWINT_MODIFIER_SET ||
220  write++;
221  } else {
222 #ifdef DEBUG
223  BUG_ON(1);
224 #endif
225  }
226  }
227 
228  sm = sm->next;
229  }
230 
231  if (read > 0 && write == 0) {
232  flowint_user_type = DETECT_FLOWINT_TYPE_READ;
233  } else if (read == 0 && write > 0) {
234  flowint_user_type = DETECT_FLOWINT_TYPE_SET;
235  } else if (read > 0 && write > 0) {
236  flowint_user_type = DETECT_FLOWINT_TYPE_SET_READ;
237  }
238 
239  SCLogDebug("Sig %s typeval %d", sig->msg, flowint_user_type);
240 
241  return flowint_user_type;
242 }
243 
244 /**
245  * \brief Returns whether the flowvar set for this rule, sets the flowvar or
246  * reads the flowvar. If the rule sets the flowvar the function returns
247  * DETECT_FLOWVAR_TYPE_SET(3), if it reads the flowvar the function
248  * returns DETECT_FLOWVAR_TYPE_READ(2), and if flowvar is not used in this
249  * rule the function returns DETECT_FLOWVAR_NOT_USED(1)
250  *
251  * \param sig Pointer to the Signature from which the flowvar type has to be
252  * returned.
253  *
254  * \retval type DETECT_FLOWVAR_TYPE_SET(3) if the rule sets the flowvar,
255  * DETECT_FLOWVAR_TYPE_READ(2) if it reads, and
256  * DETECT_FLOWVAR_NOT_USED(1) if flowvar is not used.
257  */
258 static inline int SCSigGetFlowvarType(Signature *sig)
259 {
260  DetectPcreData *pd = NULL;
262  int read = 0;
263  int write = 0;
265 
266  while (sm != NULL) {
267  pd = (DetectPcreData *)sm->ctx;
268  if (sm->type == DETECT_PCRE) {
269  uint8_t x;
270  for (x = 0; x < pd->idx; x++) {
271  if (pd->captypes[x] == VAR_TYPE_FLOW_VAR) {
272  write++;
273  break;
274  }
275  }
276  }
277 
278  sm = sm->next;
279  }
280 
282  pd = NULL;
283  while (sm != NULL) {
284  if (sm->type == DETECT_FLOWVAR) {
285  read++;
286  }
287 
288  sm = sm->next;
289  }
290 
291  if (read > 0 && write == 0) {
293  } else if (read == 0 && write > 0) {
295  } else if (read > 0 && write > 0) {
297  }
298 
299  return type;
300 }
301 
302 /**
303  * \brief Returns whether the pktvar set for this rule, sets the flowvar or
304  * reads the pktvar. If the rule sets the pktvar the function returns
305  * DETECT_PKTVAR_TYPE_SET(3), if it reads the pktvar the function
306  * returns DETECT_PKTVAR_TYPE_READ(2), and if pktvar is not used in this
307  * rule the function returns DETECT_PKTVAR_NOT_USED(1)
308  *
309  * \param sig Pointer to the Signature from which the pktvar type has to be
310  * returned.
311  *
312  * \retval type DETECT_PKTVAR_TYPE_SET(3) if the rule sets the flowvar,
313  * DETECT_PKTVAR_TYPE_READ(2) if it reads, and
314  * DETECT_PKTVAR_NOT_USED(1) if pktvar is not used.
315  */
316 static inline int SCSigGetPktvarType(Signature *sig)
317 {
318  DetectPcreData *pd = NULL;
320  int read = 0;
321  int write = 0;
323 
324  while (sm != NULL) {
325  pd = (DetectPcreData *)sm->ctx;
326  if (sm->type == DETECT_PCRE) {
327  uint8_t x;
328  for (x = 0; x < pd->idx; x++) {
329  if (pd->captypes[x] == VAR_TYPE_PKT_VAR) {
330  write++;
331  break;
332  }
333  }
334  }
335 
336  sm = sm->next;
337  }
338 
340  pd = NULL;
341  while (sm != NULL) {
342  if (sm->type == DETECT_PKTVAR) {
343  read++;
344  }
345 
346  sm = sm->next;
347  }
348 
349  if (read > 0 && write == 0) {
351  } else if (read == 0 && write > 0) {
353  } else if (read > 0 && write > 0) {
355  }
356 
357  return type;
358 }
359 
360 /**
361  * \brief Returns the xbit type set for this signature. If more than one
362  * xbit has been set for the same rule, we return the xbit type of
363  * the maximum priority/value, where priority/value is maximum for the
364  * ones that set the value and the lowest for ones that read the value.
365  * If no xbit has been set for the rule, we return 0, which indicates
366  * the least value amongst xbit types.
367  *
368  * \param sig Pointer to the Signature from which the xbit value has to be
369  * returned.
370  *
371  * \retval xbits The xbits type for this signature if it is set; if it is
372  * not set, return 0
373  */
374 static inline int SCSigGetXbitsType(Signature *sig, enum VarTypes type)
375 {
376  DetectXbitsData *fb = NULL;
377  int xbits_user_type = DETECT_XBITS_NOT_USED;
378  int read = 0;
379  int write = 0;
381 
382  while (sm != NULL) {
383  if (sm->type == DETECT_XBITS) {
384  fb = (DetectXbitsData *)sm->ctx;
385  if (fb->type == type) {
386  if (fb->cmd == DETECT_XBITS_CMD_ISNOTSET ||
387  fb->cmd == DETECT_XBITS_CMD_ISSET) {
388  read++;
389  } else {
390 #ifdef DEBUG
391  BUG_ON(1);
392 #endif
393  }
394  }
395  }
396 
397  sm = sm->next;
398  }
399 
401  while (sm != NULL) {
402  if (sm->type == DETECT_HOSTBITS) {
403  fb = (DetectXbitsData *)sm->ctx;
404  if (fb->type == type) {
405  if (fb->cmd == DETECT_XBITS_CMD_SET ||
406  fb->cmd == DETECT_XBITS_CMD_UNSET ||
407  fb->cmd == DETECT_XBITS_CMD_TOGGLE) {
408  write++;
409  } else {
410 #ifdef DEBUG
411  BUG_ON(1);
412 #endif
413  }
414  }
415  }
416 
417  sm = sm->next;
418  }
419 
420  if (read > 0 && write == 0) {
421  xbits_user_type = DETECT_XBITS_TYPE_READ;
422  } else if (read == 0 && write > 0) {
423  xbits_user_type = DETECT_XBITS_TYPE_SET;
424  } else if (read > 0 && write > 0) {
425  xbits_user_type = DETECT_XBITS_TYPE_SET_READ;
426  }
427 
428  SCLogDebug("Sig %s typeval %d", sig->msg, xbits_user_type);
429 
430  return xbits_user_type;
431 }
432 
433 /**
434  * \brief Processes the flowbits data for this signature and caches it for
435  * future use. This is needed to optimize the sig_ordering module.
436  *
437  * \param sw The sigwrapper/signature for which the flowbits data has to be
438  * cached
439  */
440 static inline void SCSigProcessUserDataForFlowbits(SCSigSignatureWrapper *sw)
441 {
442  sw->user[SC_RADIX_USER_DATA_FLOWBITS] = SCSigGetFlowbitsType(sw->sig);
443 }
444 
445 /**
446  * \brief Processes the flowvar data for this signature and caches it for
447  * future use. This is needed to optimize the sig_ordering module.
448  *
449  * \param sw The sigwrapper/signature for which the flowvar data has to be
450  * cached
451  */
452 static inline void SCSigProcessUserDataForFlowvar(SCSigSignatureWrapper *sw)
453 {
454  sw->user[SC_RADIX_USER_DATA_FLOWVAR] = SCSigGetFlowvarType(sw->sig);
455 }
456 
457 static inline void SCSigProcessUserDataForFlowint(SCSigSignatureWrapper *sw)
458 {
459  sw->user[SC_RADIX_USER_DATA_FLOWINT] = SCSigGetFlowintType(sw->sig);
460 }
461 
462 /**
463  * \brief Processes the pktvar data for this signature and caches it for
464  * future use. This is needed to optimize the sig_ordering module.
465  *
466  * \param sw The sigwrapper/signature for which the pktvar data has to be
467  * cached
468  */
469 static inline void SCSigProcessUserDataForPktvar(SCSigSignatureWrapper *sw)
470 {
471  sw->user[SC_RADIX_USER_DATA_PKTVAR] = SCSigGetPktvarType(sw->sig);
472 }
473 
474 /**
475  * \brief Processes the hostbits data for this signature and caches it for
476  * future use. This is needed to optimize the sig_ordering module.
477  *
478  * \param sw The sigwrapper/signature for which the hostbits data has to be
479  * cached
480  */
481 static inline void SCSigProcessUserDataForHostbits(SCSigSignatureWrapper *sw)
482 {
483  sw->user[SC_RADIX_USER_DATA_HOSTBITS] = SCSigGetXbitsType(sw->sig, VAR_TYPE_HOST_BIT);
484 }
485 
486 /**
487  * \brief Processes the hostbits data for this signature and caches it for
488  * future use. This is needed to optimize the sig_ordering module.
489  *
490  * \param sw The sigwrapper/signature for which the hostbits data has to be
491  * cached
492  */
493 static inline void SCSigProcessUserDataForIPPairbits(SCSigSignatureWrapper *sw)
494 {
495  sw->user[SC_RADIX_USER_DATA_IPPAIRBITS] = SCSigGetXbitsType(sw->sig, VAR_TYPE_IPPAIR_BIT);
496 }
497 
498 /* Return 1 if sw1 comes before sw2 in the final list. */
499 static int SCSigLessThan(SCSigSignatureWrapper *sw1,
501  SCSigOrderFunc *cmp_func_list)
502 {
503  SCSigOrderFunc *funcs = cmp_func_list;
504 
505  while (funcs != NULL) {
506  int delta = funcs->SWCompare(sw1, sw2);
507  if (delta > 0)
508  return 1;
509  else if (delta < 0)
510  return 0;
511 
512  funcs = funcs->next;
513  }
514  // They are equal, so use sid as the final decider.
515  return sw1->sig->id < sw2->sig->id;
516 }
517 
518 /* Merge sort based on a list of compare functions
519  * debug asserts are here to guide scan-build */
520 static SCSigSignatureWrapper *SCSigOrder(SCSigSignatureWrapper *sw,
521  SCSigOrderFunc *cmp_func_list)
522 {
523  DEBUG_VALIDATE_BUG_ON(sw == NULL);
524 
525  SCSigSignatureWrapper *subA = NULL;
526  SCSigSignatureWrapper *subB = NULL;
527  SCSigSignatureWrapper *first;
528  SCSigSignatureWrapper *second;
529  SCSigSignatureWrapper *result = NULL;
530  SCSigSignatureWrapper *last = NULL;
531  SCSigSignatureWrapper *new = NULL;
532 
533  /* Divide input list into two sub-lists. */
534  while (sw != NULL) {
535  first = sw;
536  sw = sw->next;
537  /* Push the first element onto sub-list A */
538  first->next = subA;
539  subA = first;
540 
541  if (sw == NULL)
542  break;
543  second = sw;
544  sw = sw->next;
545  /* Push the second element onto sub-list B */
546  second->next = subB;
547  subB = second;
548  }
549  if (subB == NULL) {
550  /* Only zero or one element on the list. */
551  return subA;
552  }
553  DEBUG_VALIDATE_BUG_ON(subA == NULL);
554 
555  /* Now sort each list */
556  subA = SCSigOrder(subA, cmp_func_list);
557  subB = SCSigOrder(subB, cmp_func_list);
558  DEBUG_VALIDATE_BUG_ON(subA == NULL);
559  DEBUG_VALIDATE_BUG_ON(subB == NULL);
560 
561  /* Merge the two sorted lists. */
562  while (subA != NULL && subB != NULL) {
563  if (SCSigLessThan(subA, subB, cmp_func_list)) {
564  new = subA;
565  subA = subA->next;
566  } else {
567  new = subB;
568  subB = subB->next;
569  }
570  /* Push onto the end of the output list. */
571  new->next = NULL;
572  if (result == NULL) {
573  result = new;
574  last = new;
575  } else {
576  last->next = new;
577  last = new;
578  }
579  }
580  /* Attach the rest of any remaining list. Only one can be non-NULL here. */
581  if (subA == NULL)
582  last->next = subB;
583  else if (subB == NULL)
584  last->next = subA;
585 
586  return result;
587 }
588 
589 /**
590  * \brief Orders an incoming Signature based on its action
591  *
592  * \param de_ctx Pointer to the detection engine context from which the
593  * signatures have to be ordered.
594  * \param sw The new signature that has to be ordered based on its action
595  */
596 static int SCSigOrderByActionCompare(SCSigSignatureWrapper *sw1,
598 {
599  return ActionOrderVal(sw2->sig->action) - ActionOrderVal(sw1->sig->action);
600 }
601 
602 /**
603  * \brief Orders an incoming Signature based on its flowbits type
604  *
605  * \param de_ctx Pointer to the detection engine context from which the
606  * signatures have to be ordered.
607  * \param sw The new signature that has to be ordered based on its flowbits
608  */
609 static int SCSigOrderByFlowbitsCompare(SCSigSignatureWrapper *sw1,
611 {
612  return sw1->user[SC_RADIX_USER_DATA_FLOWBITS] -
614 }
615 
616 /**
617  * \brief Orders an incoming Signature based on its flowvar type
618  *
619  * \param de_ctx Pointer to the detection engine context from which the
620  * signatures have to be ordered.
621  * \param sw The new signature that has to be ordered based on its flowvar
622  */
623 static int SCSigOrderByFlowvarCompare(SCSigSignatureWrapper *sw1,
625 {
626  return sw1->user[SC_RADIX_USER_DATA_FLOWVAR] -
628 }
629 
630 /**
631  * \brief Orders an incoming Signature based on its pktvar type
632  *
633  * \param de_ctx Pointer to the detection engine context from which the
634  * signatures have to be ordered.
635  * \param sw The new signature that has to be ordered based on its pktvar
636  */
637 static int SCSigOrderByPktvarCompare(SCSigSignatureWrapper *sw1,
639 {
640  return sw1->user[SC_RADIX_USER_DATA_PKTVAR] -
642 }
643 
644 static int SCSigOrderByFlowintCompare(SCSigSignatureWrapper *sw1,
646 {
647  return sw1->user[SC_RADIX_USER_DATA_FLOWINT] -
649 }
650 
651 /**
652  * \brief Orders an incoming Signature based on its hostbits type
653  *
654  * \param de_ctx Pointer to the detection engine context from which the
655  * signatures have to be ordered.
656  * \param sw The new signature that has to be ordered based on its hostbits
657  */
658 static int SCSigOrderByHostbitsCompare(SCSigSignatureWrapper *sw1,
660 {
661  return sw1->user[SC_RADIX_USER_DATA_HOSTBITS] -
663 }
664 
665 /**
666  * \brief Orders an incoming Signature based on its ippairbits (xbits) type
667  *
668  * \param de_ctx Pointer to the detection engine context from which the
669  * signatures have to be ordered.
670  * \param sw The new signature that has to be ordered based on its bits
671  */
672 static int SCSigOrderByIPPairbitsCompare(SCSigSignatureWrapper *sw1,
674 {
675  return sw1->user[SC_RADIX_USER_DATA_IPPAIRBITS] -
677 }
678 
679 /**
680  * \brief Orders an incoming Signature based on its priority type
681  *
682  * \param de_ctx Pointer to the detection engine context from which the
683  * signatures have to be ordered.
684  * \param sw The new signature that has to be ordered based on its priority
685  */
686 static int SCSigOrderByPriorityCompare(SCSigSignatureWrapper *sw1,
688 {
689  if (sw1->sig->prio > sw2->sig->prio) {
690  return -1;
691  } else if (sw1->sig->prio < sw2->sig->prio) {
692  return 1;
693  }
694  return 0;
695 }
696 
697 /**
698  * \brief Creates a Wrapper around the Signature
699  *
700  * \param Pointer to the Signature to be wrapped
701  *
702  * \retval sw Pointer to the wrapper that holds the signature
703  */
704 static inline SCSigSignatureWrapper *SCSigAllocSignatureWrapper(Signature *sig)
705 {
706  SCSigSignatureWrapper *sw = NULL;
707 
708  if ((sw = SCCalloc(1, sizeof(SCSigSignatureWrapper))) == NULL)
709  return NULL;
710 
711  sw->sig = sig;
712 
713  /* Process data from the signature into a cache for further use by the
714  * sig_ordering module */
715  SCSigProcessUserDataForFlowbits(sw);
716  SCSigProcessUserDataForFlowvar(sw);
717  SCSigProcessUserDataForFlowint(sw);
718  SCSigProcessUserDataForPktvar(sw);
719  SCSigProcessUserDataForHostbits(sw);
720  SCSigProcessUserDataForIPPairbits(sw);
721 
722  return sw;
723 }
724 
725 /**
726  * \brief Orders the signatures
727  *
728  * \param de_ctx Pointer to the Detection Engine Context that holds the
729  * signatures to be ordered
730  */
732 {
733  if (de_ctx->sig_list == NULL) {
734  SCLogDebug("no signatures to order");
735  return;
736  }
737 
738  Signature *sig = NULL;
739  SCSigSignatureWrapper *sigw = NULL;
740  SCSigSignatureWrapper *sigw_list = NULL;
741 #ifdef DEBUG
742  int i = 0;
743 #endif
744  SCLogDebug("ordering signatures in memory");
745 
746  sig = de_ctx->sig_list;
747  while (sig != NULL) {
748  sigw = SCSigAllocSignatureWrapper(sig);
749  /* Push signature wrapper onto a list, order doesn't matter here. */
750  sigw->next = sigw_list;
751  sigw_list = sigw;
752 
753  sig = sig->next;
754 #ifdef DEBUG
755  i++;
756 #endif
757  }
758 
759  /* Sort the list */
760  sigw_list = SCSigOrder(sigw_list, de_ctx->sc_sig_order_funcs);
761 
762  SCLogDebug("Total Signatures to be processed by the"
763  "sigordering module: %d", i);
764 
765  /* Recreate the sig list in order */
766  de_ctx->sig_list = NULL;
767  sigw = sigw_list;
768 #ifdef DEBUG
769  i = 0;
770 #endif
771  while (sigw != NULL) {
772 #ifdef DEBUG
773  i++;
774 #endif
775  sigw->sig->next = NULL;
776  if (de_ctx->sig_list == NULL) {
777  /* First entry on the list */
778  de_ctx->sig_list = sigw->sig;
779  sig = de_ctx->sig_list;
780  } else {
781  sig->next = sigw->sig;
782  sig = sig->next;
783  }
784  SCSigSignatureWrapper *sigw_to_free = sigw;
785  sigw = sigw->next;
786  SCFree(sigw_to_free);
787  }
788 
789  SCLogDebug("total signatures reordered by the sigordering module: %d", i);
790 }
791 
792 /**
793  * \brief Lets you register the Signature ordering functions. The order in
794  * which the functions are registered shows the priority. The first
795  * function registered provides more priority than the function
796  * registered after it. To add a new registration function, register
797  * it by listing it in the correct position in the below sequence,
798  * based on the priority you would want to offer to that keyword.
799  *
800  * \param de_ctx Pointer to the detection engine context from which the
801  * signatures have to be ordered.
802  */
804 {
805  SCLogDebug("registering signature ordering functions");
806 
807  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
808  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
809  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowintCompare);
810  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
811  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
812  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByHostbitsCompare);
813  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByIPPairbitsCompare);
814  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
815 }
816 
817 /**
818  * \brief De-registers all the signature ordering functions registered
819  *
820  * \param de_ctx Pointer to the detection engine context from which the
821  * signatures were ordered.
822  */
824 {
825  SCSigOrderFunc *funcs;
826  void *temp;
827 
828  /* clean the memory alloted to the signature ordering funcs */
829  funcs = de_ctx->sc_sig_order_funcs;
830  while (funcs != NULL) {
831  temp = funcs;
832  funcs = funcs->next;
833  SCFree(temp);
834  }
835  de_ctx->sc_sig_order_funcs = NULL;
836 }
837 
838 /**********Unittests**********/
839 
844 
845 #ifdef UNITTESTS
846 
847 static int SCSigOrderingTest01(void)
848 {
849  SCSigOrderFunc *temp = NULL;
850  int i = 0;
851 
854 
855  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
856  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
857  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
858  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
859  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
860  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
861  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
862  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
863  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
864  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
865  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
866 
867  temp = de_ctx->sc_sig_order_funcs;
868  while (temp != NULL) {
869  i++;
870  temp = temp->next;
871  }
872 
874 
875  FAIL_IF_NOT(i == 5);
876 
877  PASS;
878 }
879 
880 static int SCSigOrderingTest02(void)
881 {
882  Signature *sig = NULL;
883 
885  FAIL_IF(de_ctx == NULL);
886 
888  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
889  FAIL_IF_NULL(sig);
890 
892  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:2;)");
893  FAIL_IF_NULL(sig);
894 
896  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:3;)");
897  FAIL_IF_NULL(sig);
898 
900  "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;)");
901  FAIL_IF_NULL(sig);
902 
904  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:5;)");
905  FAIL_IF_NULL(sig);
906 
908  "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;)");
909  FAIL_IF_NULL(sig);
910 
912  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:7;)");
913  FAIL_IF_NULL(sig);
914 
916  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
917  FAIL_IF_NULL(sig);
918 
920  "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;)");
921  FAIL_IF_NULL(sig);
922 
924  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:10;)");
925  FAIL_IF_NULL(sig);
926 
928  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:11;)");
929  FAIL_IF_NULL(sig);
930 
932  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:12;)");
933  FAIL_IF_NULL(sig);
934 
936  "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;)");
937  FAIL_IF_NULL(sig);
938 
940  "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;)");
941  FAIL_IF_NULL(sig);
942 
943  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
944  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
945  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
946  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
947  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
949 
950  sig = de_ctx->sig_list;
951 
952 #ifdef DEBUG
953  while (sig != NULL) {
954  printf("sid: %d\n", sig->id);
955  sig = sig->next;
956  }
957 #endif
958 
959  sig = de_ctx->sig_list;
960 
961  /* pass */
962  FAIL_IF_NOT(sig->id == 6);
963  sig = sig->next;
964  FAIL_IF_NOT(sig->id == 4);
965  sig = sig->next;
966  FAIL_IF_NOT(sig->id == 8);
967  sig = sig->next;
968  FAIL_IF_NOT(sig->id == 7);
969  sig = sig->next;
970  FAIL_IF_NOT(sig->id == 10);
971  sig = sig->next;
972 
973  /* drops */
974  FAIL_IF_NOT(sig->id == 9);
975  sig = sig->next;
976  FAIL_IF_NOT(sig->id == 13);
977  sig = sig->next;
978  FAIL_IF_NOT(sig->id == 2);
979  sig = sig->next;
980  FAIL_IF_NOT(sig->id == 3);
981  sig = sig->next;
982 
983  /* alerts */
984  FAIL_IF_NOT(sig->id == 14);
985  sig = sig->next;
986  FAIL_IF_NOT(sig->id == 5);
987  sig = sig->next;
988  FAIL_IF_NOT(sig->id == 1);
989  sig = sig->next;
990  FAIL_IF_NOT(sig->id == 11);
991  sig = sig->next;
992  FAIL_IF_NOT(sig->id == 12);
993  sig = sig->next;
994 
996  PASS;
997 }
998 
999 static int SCSigOrderingTest03(void)
1000 {
1001  Signature *sig = NULL;
1002 
1005 
1007  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1008  "offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:1;)");
1009  FAIL_IF_NULL(sig);
1010 
1012  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1013  "offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:2;)");
1014  FAIL_IF_NULL(sig);
1015 
1017  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1018  "offset:10; depth:4; pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; "
1019  "flowbits:unset,TEST.one; rev:4; priority:2; sid:3;)");
1020  FAIL_IF_NULL(sig);
1021 
1023  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1024  "offset:0; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1025  "flowbits:isset,TEST.one; rev:4; priority:1; sid:4;)");
1026  FAIL_IF_NULL(sig);
1027 
1029  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1030  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; priority:2; sid:5;)");
1031  FAIL_IF_NULL(sig);
1032 
1034  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1035  "content:\"220\"; offset:10; flowbits:isnotset,TEST.one; pcre:\"/^User-Agent: "
1036  "(?P<flow_http_host>.*)\\r\\n/m\"; rev:4; sid:6;)");
1037  FAIL_IF_NULL(sig);
1038 
1040  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1041  "content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; "
1042  "flowbits:unset,TEST.one; rev:4; priority:3; sid:7;)");
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:\"/220[- ]/\"; flowbits:toggle,TEST.one; rev:4; priority:1; "
1048  "pktvar:http_host,\"www.oisf.net\"; sid:8;)");
1049  FAIL_IF_NULL(sig);
1050 
1052  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1053  "content:\"220\"; offset:10; depth:4; rev:4; flowbits:set,TEST.one; "
1054  "flowbits:noalert; pktvar:http_host,\"www.oisf.net\"; sid:9;)");
1055  FAIL_IF_NULL(sig);
1056 
1058  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1059  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:10;)");
1060  FAIL_IF_NULL(sig);
1061 
1063  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1064  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:11;)");
1065  FAIL_IF_NULL(sig);
1066 
1068  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1069  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:12;)");
1070  FAIL_IF_NULL(sig);
1071 
1073  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1074  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; flowbits:isnotset,TEST.one; sid:13;)");
1075  FAIL_IF_NULL(sig);
1076 
1078  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1079  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; flowbits:set,TEST.one; sid:14;)");
1080  FAIL_IF_NULL(sig);
1081 
1082  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1083  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1084  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1085  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1086  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1088 
1089  sig = de_ctx->sig_list;
1090 
1091 #ifdef DEBUG
1092  while (sig != NULL) {
1093  printf("sid: %d\n", sig->id);
1094  sig = sig->next;
1095  }
1096 #endif
1097 
1098  sig = de_ctx->sig_list;
1099 
1100  FAIL_IF_NOT(sig->id == 3);
1101  sig = sig->next;
1102 
1103  FAIL_IF_NOT(sig->id == 8);
1104  sig = sig->next;
1105  FAIL_IF_NOT(sig->id == 9);
1106  sig = sig->next;
1107  FAIL_IF_NOT(sig->id == 7);
1108  sig = sig->next;
1109  FAIL_IF_NOT(sig->id == 14);
1110  sig = sig->next;
1111  FAIL_IF_NOT(sig->id == 6);
1112  sig = sig->next;
1113  FAIL_IF_NOT(sig->id == 4);
1114  sig = sig->next;
1115  FAIL_IF_NOT(sig->id == 13);
1116  sig = sig->next;
1117  FAIL_IF_NOT(sig->id == 2);
1118  sig = sig->next;
1119  FAIL_IF_NOT(sig->id == 5);
1120  sig = sig->next;
1121  FAIL_IF_NOT(sig->id == 1);
1122  sig = sig->next;
1123  FAIL_IF_NOT(sig->id == 10);
1124  sig = sig->next;
1125  FAIL_IF_NOT(sig->id == 11);
1126  sig = sig->next;
1127  FAIL_IF_NOT(sig->id == 12);
1128 
1129  sig = sig->next;
1130 
1132 
1133  PASS;
1134 }
1135 
1136 static int SCSigOrderingTest04(void)
1137 {
1138 
1139  Signature *sig = NULL;
1140 
1142  FAIL_IF(de_ctx == NULL);
1143 
1145  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1146  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1147  FAIL_IF_NULL(sig);
1148 
1150  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1151  "pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; content:\"220\"; "
1152  "offset:10; rev:4; priority:3; sid:2;)");
1153  FAIL_IF_NULL(sig);
1154 
1156  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1157  "content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: "
1158  "(?P<flow_http_host>.*)\\r\\n/m\"; rev:4; priority:3; sid:3;)");
1159  FAIL_IF_NULL(sig);
1160 
1162  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1163  "offset:10; depth:4; pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; rev:4; "
1164  "priority:3; flowvar:http_host,\"www.oisf.net\"; sid:4;)");
1165  FAIL_IF_NULL(sig);
1166 
1168  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1169  "offset:11; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1170  "pcre:\"/220[- ]/\"; rev:4; priority:3; sid:5;)");
1171  FAIL_IF_NULL(sig);
1172 
1174  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1175  "offset:11; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1176  "pktvar:http_host,\"www.oisf.net\"; rev:4; priority:1; sid:6;)");
1177  FAIL_IF_NULL(sig);
1178 
1180  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1181  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; flowvar:http_host,\"www.oisf.net\"; "
1182  "pktvar:http_host,\"www.oisf.net\"; priority:1; sid:7;)");
1183  FAIL_IF_NULL(sig);
1184 
1186  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1187  "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1188  "flowvar:http_host,\"www.oisf.net\"; sid:8;)");
1189  FAIL_IF_NULL(sig);
1190 
1192  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1193  "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1194  "flowvar:http_host,\"www.oisf.net\"; sid:9;)");
1195  FAIL_IF_NULL(sig);
1196 
1197  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1198  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1199  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1200  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1201  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1203 
1204  sig = de_ctx->sig_list;
1205 
1206 #ifdef DEBUG
1207  while (sig != NULL) {
1208  printf("sid: %d\n", sig->id);
1209  sig = sig->next;
1210  }
1211 #endif
1212 
1213  sig = de_ctx->sig_list;
1214 
1215  /* flowvar set */
1216  sig = sig->next;
1217  FAIL_IF_NOT(sig->id == 3);
1218  sig = sig->next;
1219  FAIL_IF_NOT(sig->id == 4);
1220  sig = sig->next;
1221  FAIL_IF_NOT(sig->id == 7);
1222  sig = sig->next;
1223  FAIL_IF_NOT(sig->id == 8);
1224  sig = sig->next;
1225  FAIL_IF_NOT(sig->id == 9);
1226  sig = sig->next;
1227 
1228  /* pktvar */
1229 
1230  FAIL_IF_NOT(sig->id == 5);
1231  sig = sig->next;
1232  FAIL_IF_NOT(sig->id == 6);
1233  sig = sig->next;
1234 
1235  FAIL_IF_NOT(sig->id == 1);
1236  sig = sig->next;
1237 
1239 
1240  PASS;
1241 }
1242 
1243 static int SCSigOrderingTest05(void)
1244 {
1245  Signature *sig = NULL;
1246 
1248  FAIL_IF(de_ctx == NULL);
1249 
1251  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1252  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1253  FAIL_IF_NULL(sig);
1254 
1256  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1257  "pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; content:\"220\"; "
1258  "offset:10; rev:4; priority:3; sid:2;)");
1259  FAIL_IF_NULL(sig);
1260 
1262  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1263  "content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: "
1264  "(?P<pkt_http_host>.*)\\r\\n/m\"; rev:4; priority:3; sid:3;)");
1265  FAIL_IF_NULL(sig);
1266 
1268  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1269  "offset:10; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; rev:4; "
1270  "priority:3; pktvar:http_host,\"www.oisf.net\"; sid:4;)");
1271  FAIL_IF_NULL(sig);
1272 
1274  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1275  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:5;)");
1276  FAIL_IF_NULL(sig);
1277 
1279  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1280  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:6;)");
1281  FAIL_IF_NULL(sig);
1282 
1284  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1285  "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1286  "pktvar:http_host,\"www.oisf.net\"; sid:7;)");
1287  FAIL_IF_NULL(sig);
1288 
1290  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1291  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; "
1292  "pktvar:http_host,\"www.oisf.net\"; sid:8;)");
1293  FAIL_IF_NULL(sig);
1294 
1295  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1296  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1297  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1298  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1299  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1301 
1302  sig = de_ctx->sig_list;
1303 
1304  //#ifdef DEBUG
1305  while (sig != NULL) {
1306  printf("sid: %d\n", sig->id);
1307  sig = sig->next;
1308  }
1309  //#endif
1310 
1311  sig = de_ctx->sig_list;
1312 
1313  /* pktvar set */
1314  FAIL_IF_NOT(sig->id == 2);
1315  sig = sig->next;
1316  FAIL_IF_NOT(sig->id == 3);
1317  sig = sig->next;
1318  FAIL_IF_NOT(sig->id == 4);
1319  sig = sig->next;
1320  /* pktvar read */
1321  FAIL_IF_NOT(sig->id == 7);
1322  sig = sig->next;
1323  FAIL_IF_NOT(sig->id == 8);
1324  sig = sig->next;
1325  FAIL_IF_NOT(sig->id == 1);
1326  sig = sig->next;
1327  FAIL_IF_NOT(sig->id == 5);
1328  sig = sig->next;
1329  FAIL_IF_NOT(sig->id == 6);
1330  sig = sig->next;
1331 
1333 
1334  PASS;
1335 }
1336 
1337 static int SCSigOrderingTest06(void)
1338 {
1339 
1340  Signature *sig = NULL;
1341 
1344 
1346  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1347  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1348  FAIL_IF_NULL(sig);
1349 
1351  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1352  "content:\"220\"; offset:10; rev:4; priority:2; sid:2;)");
1353  FAIL_IF_NULL(sig);
1354 
1356  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1357  "content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:3;)");
1358  FAIL_IF_NULL(sig);
1359 
1361  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1362  "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1363  FAIL_IF_NULL(sig);
1364 
1366  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1367  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1368  FAIL_IF_NULL(sig);
1369 
1371  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1372  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1373  FAIL_IF_NULL(sig);
1375  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1376  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1377  FAIL_IF_NULL(sig);
1378 
1380  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1381  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1382  FAIL_IF_NULL(sig);
1383 
1384  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1385  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1386  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1387  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1388  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1390 
1391  sig = de_ctx->sig_list;
1392 
1393 #ifdef DEBUG
1394  while (sig != NULL) {
1395  printf("sid: %d\n", sig->id);
1396  sig = sig->next;
1397  }
1398 #endif
1399 
1400  sig = de_ctx->sig_list;
1401 
1402  FAIL_IF_NOT(sig->id == 6);
1403  sig = sig->next;
1404  FAIL_IF_NOT(sig->id == 2);
1405  sig = sig->next;
1406  FAIL_IF_NOT(sig->id == 4);
1407  sig = sig->next;
1408  FAIL_IF_NOT(sig->id == 5);
1409  sig = sig->next;
1410  FAIL_IF_NOT(sig->id == 7);
1411  sig = sig->next;
1412  FAIL_IF_NOT(sig->id == 8);
1413  sig = sig->next;
1414  FAIL_IF_NOT(sig->id == 1);
1415  sig = sig->next;
1416  FAIL_IF_NOT(sig->id == 3);
1417  sig = sig->next;
1418 
1420 
1421  PASS;
1422 }
1423 static int SCSigOrderingTest07(void)
1424 {
1425 
1426  Signature *sig = NULL;
1427 
1429  FAIL_IF(de_ctx == NULL);
1430 
1432  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1433  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1; rev:4;)");
1434  FAIL_IF_NULL(sig);
1435 
1437  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1438  "content:\"220\"; offset:10; sid:2; rev:4; priority:2;)");
1439  FAIL_IF_NULL(sig);
1440 
1442  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1443  "content:\"220\"; offset:10; depth:4; sid:3; rev:4; priority:3;)");
1444  FAIL_IF_NULL(sig);
1445 
1447  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1448  "content:\"220\"; offset:10; depth:4; sid:4; rev:4; priority:2;)");
1449  FAIL_IF_NULL(sig);
1450 
1452  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1453  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:5; rev:4; priority:2;)");
1454  FAIL_IF_NULL(sig);
1455 
1457  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1458  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:6; rev:4; priority:1;)");
1459  FAIL_IF_NULL(sig);
1460 
1462  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1463  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:7; rev:4; priority:2;)");
1464  FAIL_IF_NULL(sig);
1465 
1467  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1468  "offset:12; depth:4; pcre:\"/220[- ]/\"; sid:8; rev:4; priority:2;)");
1469  FAIL_IF_NULL(sig);
1470 
1471  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1472  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1473  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1474  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1475  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1477 
1478  sig = de_ctx->sig_list;
1479 
1480 #ifdef DEBUG
1481  while (sig != NULL) {
1482  printf("sid: %d\n", sig->id);
1483  sig = sig->next;
1484  }
1485 #endif
1486 
1487  sig = de_ctx->sig_list;
1488 
1489  FAIL_IF_NOT(sig->id == 2);
1490  sig = sig->next;
1491  FAIL_IF_NOT(sig->id == 4);
1492  sig = sig->next;
1493  FAIL_IF_NOT(sig->id == 5);
1494  sig = sig->next;
1495  FAIL_IF_NOT(sig->id == 7);
1496  sig = sig->next;
1497  FAIL_IF_NOT(sig->id == 6);
1498  sig = sig->next;
1499  FAIL_IF_NOT(sig->id == 8);
1500  sig = sig->next;
1501  FAIL_IF_NOT(sig->id == 1);
1502  sig = sig->next;
1503  FAIL_IF_NOT(sig->id == 3);
1504  sig = sig->next;
1505 
1507 
1508  PASS;
1509 }
1510 
1511 /**
1512  * \test Order with a different Action priority
1513  * (as specified from config)
1514  */
1515 static int SCSigOrderingTest08(void)
1516 {
1517 #ifdef HAVE_LIBNET11
1518 
1519  Signature *sig = NULL;
1520  extern uint8_t action_order_sigs[4];
1521 
1522  /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1527 
1529  FAIL_IF(de_ctx == NULL);
1530 
1532  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1533  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1; rev:4;)");
1534  FAIL_IF_NULL(sig);
1535 
1537  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1538  "content:\"220\"; offset:10; sid:2; rev:4; priority:2;)");
1539  FAIL_IF_NULL(sig);
1540 
1542  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1543  "content:\"220\"; offset:10; depth:4; sid:3; rev:4; priority:3;)");
1544  FAIL_IF_NULL(sig);
1545 
1547  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1548  "content:\"220\"; offset:10; depth:4; sid:4; rev:4; priority:2;)");
1549  FAIL_IF_NULL(sig);
1550 
1552  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1553  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:5; rev:4; priority:2;)");
1554  FAIL_IF_NULL(sig);
1555 
1557  "reject tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1558  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:6; rev:4; priority:1;)");
1559  FAIL_IF_NULL(sig);
1560 
1562  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; "
1563  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; sid:7; rev:4;)");
1564  FAIL_IF_NULL(sig);
1565 
1567  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1568  "offset:12; depth:4; pcre:\"/220[- ]/\"; sid:8; rev:4; priority:2;)");
1569  FAIL_IF_NULL(sig);
1570 
1571  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1572  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1573  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1574  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1575  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1577 
1578  sig = de_ctx->sig_list;
1579 
1580 #ifdef DEBUG
1581  while (sig != NULL) {
1582  printf("sid: %d\n", sig->id);
1583  sig = sig->next;
1584  }
1585 #endif
1586 
1587  sig = de_ctx->sig_list;
1588 
1589  FAIL_IF_NOT(sig->id == 6);
1590  sig = sig->next;
1591  FAIL_IF_NOT(sig->id == 8);
1592  sig = sig->next;
1593  FAIL_IF_NOT(sig->id == 1);
1594  sig = sig->next;
1595  FAIL_IF_NOT(sig->id == 3);
1596  sig = sig->next;
1597  FAIL_IF_NOT(sig->id == 2);
1598  sig = sig->next;
1599  FAIL_IF_NOT(sig->id == 4);
1600  sig = sig->next;
1601  FAIL_IF_NOT(sig->id == 5);
1602  sig = sig->next;
1603  FAIL_IF_NOT(sig->id == 7);
1604  sig = sig->next;
1605 
1606  /* Restore the default pre-order definition */
1611 
1613 
1614 #endif
1615  PASS;
1616 }
1617 
1618 /**
1619  * \test Order with a different Action priority
1620  * (as specified from config)
1621  */
1622 static int SCSigOrderingTest09(void)
1623 {
1624 
1625  Signature *sig = NULL;
1626  extern uint8_t action_order_sigs[4];
1627 
1628  /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1633 
1635  FAIL_IF(de_ctx == NULL);
1636 
1638  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1639  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1;)");
1640  FAIL_IF_NULL(sig);
1641 
1643  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1644  "content:\"220\"; offset:10; priority:2; sid:2;)");
1645  FAIL_IF_NULL(sig);
1646 
1648  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1649  "content:\"220\"; offset:10; depth:4; priority:3; sid:3;)");
1650  FAIL_IF_NULL(sig);
1651 
1653  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1654  "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1655  FAIL_IF_NULL(sig);
1656 
1658  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1659  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1660  FAIL_IF_NULL(sig);
1661 
1663  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1664  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1665  FAIL_IF_NULL(sig);
1666 
1668  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1669  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1670  FAIL_IF_NULL(sig);
1671 
1673  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1674  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1675  FAIL_IF_NULL(sig);
1676 
1677  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1678  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1679  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1680  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1681  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1683 
1684  sig = de_ctx->sig_list;
1685 
1686 #ifdef DEBUG
1687  while (sig != NULL) {
1688  printf("sid: %d\n", sig->id);
1689  sig = sig->next;
1690  }
1691 #endif
1692 
1693  sig = de_ctx->sig_list;
1694 
1695  FAIL_IF_NOT(sig->id == 6);
1696  sig = sig->next;
1697  FAIL_IF_NOT(sig->id == 7);
1698  sig = sig->next;
1699  FAIL_IF_NOT(sig->id == 8);
1700  sig = sig->next;
1701  FAIL_IF_NOT(sig->id == 1);
1702  sig = sig->next;
1703  FAIL_IF_NOT(sig->id == 3);
1704  sig = sig->next;
1705  FAIL_IF_NOT(sig->id == 2);
1706  sig = sig->next;
1707  FAIL_IF_NOT(sig->id == 4);
1708  sig = sig->next;
1709  FAIL_IF_NOT(sig->id == 5);
1710  sig = sig->next;
1711 
1712  /* Restore the default pre-order definition */
1717 
1719  PASS;
1720 }
1721 
1722 /**
1723  * \test Order with a different Action priority
1724  * (as specified from config)
1725  */
1726 static int SCSigOrderingTest10(void)
1727 {
1728 
1729  Signature *sig = NULL;
1730  extern uint8_t action_order_sigs[4];
1731 
1732  /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1737 
1739  FAIL_IF(de_ctx == NULL);
1740 
1742  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1743  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1744  FAIL_IF_NULL(sig);
1745 
1747  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1748  "content:\"220\"; offset:10; rev:4; priority:2; sid:2;)");
1749  FAIL_IF_NULL(sig);
1750 
1752  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1753  "content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:3;)");
1754  FAIL_IF_NULL(sig);
1755 
1757  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1758  "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1759  FAIL_IF_NULL(sig);
1760 
1762  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1763  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1764  FAIL_IF_NULL(sig);
1765 
1767  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1768  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1769  FAIL_IF_NULL(sig);
1770 
1772  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1773  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1774  FAIL_IF_NULL(sig);
1775 
1777  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1778  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1779  FAIL_IF_NULL(sig);
1780 
1781  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1782  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1783  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1784  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1785  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1787 
1788  sig = de_ctx->sig_list;
1789 
1790 #ifdef DEBUG
1791  while (sig != NULL) {
1792  printf("sid: %d\n", sig->id);
1793  sig = sig->next;
1794  }
1795 #endif
1796 
1797  sig = de_ctx->sig_list;
1798 
1799  FAIL_IF_NOT(sig->id == 2);
1800  sig = sig->next;
1801  FAIL_IF_NOT(sig->id == 4);
1802  sig = sig->next;
1803  FAIL_IF_NOT(sig->id == 5);
1804  sig = sig->next;
1805  FAIL_IF_NOT(sig->id == 8);
1806  sig = sig->next;
1807  FAIL_IF_NOT(sig->id == 1);
1808  sig = sig->next;
1809  FAIL_IF_NOT(sig->id == 3);
1810  sig = sig->next;
1811  FAIL_IF_NOT(sig->id == 6);
1812  sig = sig->next;
1813  FAIL_IF_NOT(sig->id == 7);
1814  sig = sig->next;
1815 
1816  /* Restore the default pre-order definition */
1821 
1823  PASS;
1824 }
1825 
1826 static int SCSigOrderingTest11(void)
1827 {
1828 
1829  Signature *sig = NULL;
1830 
1832  FAIL_IF(de_ctx == NULL);
1833 
1835  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering set\"; "
1836  "flowbits:isnotset,myflow1; rev:4; sid:1;)");
1837  FAIL_IF_NULL(sig);
1838 
1840  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering toggle\"; "
1841  "flowbits:toggle,myflow2; rev:4; sid:2;)");
1842  FAIL_IF_NULL(sig);
1843 
1845  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering unset\"; "
1846  "flowbits:isset, myflow1; flowbits:unset,myflow2; rev:4; priority:3; sid:3;)");
1847  FAIL_IF_NULL(sig);
1848 
1849  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1850  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1851  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1852  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1853  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1855 
1856  sig = de_ctx->sig_list;
1857 
1858 #ifdef DEBUG
1859  while (sig != NULL) {
1860  printf("sid: %d\n", sig->id);
1861  sig = sig->next;
1862  }
1863 #endif
1864 
1865  sig = de_ctx->sig_list;
1866 
1867  FAIL_IF_NOT(sig->id == 2);
1868  sig = sig->next;
1869  FAIL_IF_NOT(sig->id == 3);
1870  sig = sig->next;
1871  FAIL_IF_NOT(sig->id == 1);
1872  sig = sig->next;
1873 
1875  PASS;
1876 }
1877 
1878 static int SCSigOrderingTest12(void)
1879 {
1880  Signature *sig = NULL;
1881  Packet *p = NULL;
1882  uint8_t buf[] = "test message";
1883  Flow f;
1884 
1885  FLOW_INITIALIZE(&f);
1886  f.flags |= FLOW_IPV4;
1888  f.proto = IPPROTO_TCP;
1889 
1891  FAIL_IF(de_ctx == NULL);
1892  de_ctx->flags |= DE_QUIET;
1893 
1894  const char *sigs[2];
1895  sigs[0] = "alert tcp any any -> any any (content:\"test\"; dsize:>0; flowbits:isset,one; flowbits:set,two; sid:1;)";
1896  sigs[1] = "alert tcp any any -> any any (content:\"test\"; dsize:>0; flowbits:set,one; sid:2;)";
1897  UTHAppendSigs(de_ctx, sigs, 2);
1898 
1899  sig = de_ctx->sig_list;
1900  FAIL_IF_NULL(sig);
1901  FAIL_IF_NULL(sig->next);
1902  FAIL_IF_NOT_NULL(sig->next->next);
1903  FAIL_IF(de_ctx->signum != 2);
1904 
1906  p = UTHBuildPacket(buf, sizeof(buf), IPPROTO_TCP);
1907  FAIL_IF_NULL(p);
1908 
1909  p->flow = &f;
1913 
1914  UTHMatchPackets(de_ctx, &p, 1);
1915 
1916  uint32_t sids[2] = {1, 2};
1917  uint32_t results[2] = {1, 1};
1918  FAIL_IF_NOT(UTHCheckPacketMatchResults(p, sids, results, 2));
1919 
1920  UTHFreePackets(&p, 1);
1921 
1923 
1924  FlowShutdown();
1925 
1926  PASS;
1927 }
1928 
1929 /** \test Bug 1061 */
1930 static int SCSigOrderingTest13(void)
1931 {
1932 
1933  Signature *sig = NULL;
1934 
1936  FAIL_IF(de_ctx == NULL);
1937 
1938  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:isset,bit1; flowbits:set,bit2; flowbits:set,bit3; sid:6;)");
1939  FAIL_IF_NULL(sig);
1940  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:set,bit1; flowbits:set,bit2; sid:7;)");
1941  FAIL_IF_NULL(sig);
1942  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:isset,bit1; flowbits:isset,bit2; flowbits:isset,bit3; sid:5;)");
1943  FAIL_IF_NULL(sig);
1944 
1945  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1947 
1948 #ifdef DEBUG
1949  sig = de_ctx->sig_list;
1950  while (sig != NULL) {
1951  printf("sid: %d\n", sig->id);
1952  sig = sig->next;
1953  }
1954 #endif
1955 
1956  sig = de_ctx->sig_list;
1957 
1958  FAIL_IF_NOT(sig->id == 7);
1959  sig = sig->next;
1960  FAIL_IF_NOT(sig->id == 6);
1961  sig = sig->next;
1962  FAIL_IF_NOT(sig->id == 5);
1963  sig = sig->next;
1964 
1966  PASS;
1967 }
1968 
1969 #endif
1970 
1972 {
1973 
1974 #ifdef UNITTESTS
1975  UtRegisterTest("SCSigOrderingTest01", SCSigOrderingTest01);
1976  UtRegisterTest("SCSigOrderingTest02", SCSigOrderingTest02);
1977  UtRegisterTest("SCSigOrderingTest03", SCSigOrderingTest03);
1978  UtRegisterTest("SCSigOrderingTest04", SCSigOrderingTest04);
1979  UtRegisterTest("SCSigOrderingTest05", SCSigOrderingTest05);
1980  UtRegisterTest("SCSigOrderingTest06", SCSigOrderingTest06);
1981  UtRegisterTest("SCSigOrderingTest07", SCSigOrderingTest07);
1982  UtRegisterTest("SCSigOrderingTest08", SCSigOrderingTest08);
1983  UtRegisterTest("SCSigOrderingTest09", SCSigOrderingTest09);
1984  UtRegisterTest("SCSigOrderingTest10", SCSigOrderingTest10);
1985  UtRegisterTest("SCSigOrderingTest11", SCSigOrderingTest11);
1986  UtRegisterTest("SCSigOrderingTest12", SCSigOrderingTest12);
1987  UtRegisterTest("SCSigOrderingTest13", SCSigOrderingTest13);
1988 #endif
1989 }
DetectPcreData_::idx
uint8_t idx
Definition: detect-pcre.h:47
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:586
DETECT_FLOWINT_TYPE_SET
#define DETECT_FLOWINT_TYPE_SET
Definition: detect-engine-sigorder.c:62
SC_RADIX_USER_DATA_PKTVAR
@ SC_RADIX_USER_DATA_PKTVAR
Definition: detect-engine-sigorder.h:34
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1264
flow-util.h
SigFree
void SigFree(DetectEngineCtx *, Signature *)
Definition: detect-parse.c:1628
SCSigOrderFunc_::next
struct SCSigOrderFunc_ * next
Definition: detect-engine-sigorder.h:63
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
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:841
DetectFlowintData_
Definition: detect-flowint.h:61
DetectXbitsData_::cmd
uint8_t cmd
Definition: detect-xbits.h:42
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:2611
SCSigSignatureWrapper_::next
struct SCSigSignatureWrapper_ * next
Definition: detect-engine-sigorder.h:52
detect-flowint.h
SCSigSignatureOrderingModuleCleanup
void SCSigSignatureOrderingModuleCleanup(DetectEngineCtx *de_ctx)
De-registers all the signature ordering functions registered.
Definition: detect-engine-sigorder.c:823
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:1971
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:2587
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.h:47
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:673
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:731
detect.h
DETECT_FLOWBITS_TYPE_SET_READ
#define DETECT_FLOWBITS_TYPE_SET_READ
Definition: detect-engine-sigorder.c:56
SCSigSignatureWrapper_
Signature wrapper used by signature ordering module while ordering signatures.
Definition: detect-engine-sigorder.h:45
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:803
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:616
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_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
SCSigOrderFunc_
Structure holding the signature ordering function used by the signature ordering module.
Definition: detect-engine-sigorder.h:59
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:670
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
SC_RADIX_USER_DATA_IPPAIRBITS
@ SC_RADIX_USER_DATA_IPPAIRBITS
Definition: detect-engine-sigorder.h:37
SC_RADIX_USER_DATA_FLOWBITS
@ SC_RADIX_USER_DATA_FLOWBITS
Definition: detect-engine-sigorder.h:32
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:849
DETECT_FLOWBITS
@ DETECT_FLOWBITS
Definition: detect-engine-register.h:60
Signature_::prio
int prio
Definition: detect.h:639
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.h:61
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:636
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:601
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:2572
SC_RADIX_USER_DATA_FLOWINT
@ SC_RADIX_USER_DATA_FLOWINT
Definition: detect-engine-sigorder.h:35
VarTypes
VarTypes
Definition: util-var.h:28
SCSigSignatureWrapper_::user
int user[SC_RADIX_USER_DATA_MAX]
Definition: detect-engine-sigorder.h:50
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:843
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:659
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
SC_RADIX_USER_DATA_HOSTBITS
@ SC_RADIX_USER_DATA_HOSTBITS
Definition: detect-engine-sigorder.h:36
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:455
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SC_RADIX_USER_DATA_FLOWVAR
@ SC_RADIX_USER_DATA_FLOWVAR
Definition: detect-engine-sigorder.h:33
DETECT_FLOWBITS_TYPE_SET
#define DETECT_FLOWBITS_TYPE_SET
Definition: detect-engine-sigorder.c:57
FLOWINT_MODIFIER_SET
@ FLOWINT_MODIFIER_SET
Definition: detect-flowint.h:30
DetectEngineCtx_::signum
uint32_t signum
Definition: detect.h:861
DETECT_FLOWVAR_NOT_USED
#define DETECT_FLOWVAR_NOT_USED
Definition: detect-engine-sigorder.c:44
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:868
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