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