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