suricata
detect-engine-sigorder.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2013 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Anoop Saldanha <anoopsaldanha@gmail.com>
22  *
23  * Signature ordering part of the detection engine.
24  */
25 
26 #include "suricata-common.h"
27 #include "detect.h"
28 #include "detect-xbits.h"
29 #include "detect-flowbits.h"
30 #include "detect-flowint.h"
31 #include "detect-parse.h"
32 #include "detect-engine-sigorder.h"
33 #include "detect-pcre.h"
34 #include "detect-engine-build.h"
35 
36 #include "util-unittest.h"
37 #include "util-unittest-helper.h"
38 #include "util-debug.h"
39 #include "util-action.h"
40 #include "action-globals.h"
41 #include "flow-util.h"
42 #include "util-validate.h"
43 
44 #define DETECT_FLOWVAR_NOT_USED 1
45 #define DETECT_FLOWVAR_TYPE_READ 2
46 #define DETECT_FLOWVAR_TYPE_SET_READ 3
47 #define DETECT_FLOWVAR_TYPE_SET 4
48 
49 #define DETECT_PKTVAR_NOT_USED 1
50 #define DETECT_PKTVAR_TYPE_READ 2
51 #define DETECT_PKTVAR_TYPE_SET_READ 3
52 #define DETECT_PKTVAR_TYPE_SET 4
53 
54 #define DETECT_FLOWBITS_NOT_USED 1
55 #define DETECT_FLOWBITS_TYPE_READ 2
56 #define DETECT_FLOWBITS_TYPE_SET_READ 3
57 #define DETECT_FLOWBITS_TYPE_SET 4
58 
59 #define DETECT_FLOWINT_NOT_USED 1
60 #define DETECT_FLOWINT_TYPE_READ 2
61 #define DETECT_FLOWINT_TYPE_SET_READ 3
62 #define DETECT_FLOWINT_TYPE_SET 4
63 
64 #define DETECT_XBITS_NOT_USED 1
65 #define DETECT_XBITS_TYPE_READ 2
66 #define DETECT_XBITS_TYPE_SET_READ 3
67 #define DETECT_XBITS_TYPE_SET 4
68 
69 
70 /**
71  * \brief Registers a keyword-based, signature ordering function
72  *
73  * \param de_ctx Pointer to the detection engine context from which the
74  * signatures have to be ordered.
75  * \param FuncPtr Pointer to the signature ordering function. The prototype of
76  * the signature ordering function should accept a pointer to a
77  * SCSigSignatureWrapper as its argument and shouldn't return
78  * anything
79  */
80 static void SCSigRegisterSignatureOrderingFunc(DetectEngineCtx *de_ctx,
81  int (*SWCompare)(SCSigSignatureWrapper *sw1, SCSigSignatureWrapper *sw2))
82 {
83  SCSigOrderFunc *curr = NULL;
84  SCSigOrderFunc *prev = NULL;
85  SCSigOrderFunc *temp = NULL;
86 
87  curr = de_ctx->sc_sig_order_funcs;
88 
89  /* Walk to the end of the list, and leave prev pointing at the
90  last element. */
91  prev = curr;
92  while (curr != NULL) {
93  if (curr->SWCompare == SWCompare) {
94  /* Already specified this compare */
95  return;
96  }
97  prev = curr;
98  curr = curr->next;
99  }
100 
101  if ((temp = SCCalloc(1, sizeof(SCSigOrderFunc))) == NULL) {
102  FatalError("Fatal error encountered in SCSigRegisterSignatureOrderingFunc. Exiting...");
103  }
104 
105  temp->SWCompare = SWCompare;
106 
107  /* Append the new compare function at the end of the list. */
108  if (prev == NULL)
109  de_ctx->sc_sig_order_funcs = temp;
110  else
111  prev->next = temp;
112 
113  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  * debug asserts are here to guide scan-build */
522 static SCSigSignatureWrapper *SCSigOrder(SCSigSignatureWrapper *sw,
523  SCSigOrderFunc *cmp_func_list)
524 {
525  DEBUG_VALIDATE_BUG_ON(sw == NULL);
526 
527  SCSigSignatureWrapper *subA = NULL;
528  SCSigSignatureWrapper *subB = NULL;
529  SCSigSignatureWrapper *first;
530  SCSigSignatureWrapper *second;
531  SCSigSignatureWrapper *result = NULL;
532  SCSigSignatureWrapper *last = NULL;
533  SCSigSignatureWrapper *new = NULL;
534 
535  /* Divide input list into two sub-lists. */
536  while (sw != NULL) {
537  first = sw;
538  sw = sw->next;
539  /* Push the first element onto sub-list A */
540  first->next = subA;
541  subA = first;
542 
543  if (sw == NULL)
544  break;
545  second = sw;
546  sw = sw->next;
547  /* Push the second element onto sub-list B */
548  second->next = subB;
549  subB = second;
550  }
551  if (subB == NULL) {
552  /* Only zero or one element on the list. */
553  return subA;
554  }
555  DEBUG_VALIDATE_BUG_ON(subA == NULL);
556 
557  /* Now sort each list */
558  subA = SCSigOrder(subA, cmp_func_list);
559  subB = SCSigOrder(subB, cmp_func_list);
560  DEBUG_VALIDATE_BUG_ON(subA == NULL);
561  DEBUG_VALIDATE_BUG_ON(subB == NULL);
562 
563  /* Merge the two sorted lists. */
564  while (subA != NULL && subB != NULL) {
565  if (SCSigLessThan(subA, subB, cmp_func_list)) {
566  new = subA;
567  subA = subA->next;
568  } else {
569  new = subB;
570  subB = subB->next;
571  }
572  /* Push onto the end of the output list. */
573  new->next = NULL;
574  if (result == NULL) {
575  result = new;
576  last = new;
577  } else {
578  last->next = new;
579  last = new;
580  }
581  }
582  /* Attach the rest of any remaining list. Only one can be non-NULL here. */
583  if (subA == NULL)
584  last->next = subB;
585  else if (subB == NULL)
586  last->next = subA;
587 
588  return result;
589 }
590 
591 /**
592  * \brief Orders an incoming Signature based on its action
593  *
594  * \param de_ctx Pointer to the detection engine context from which the
595  * signatures have to be ordered.
596  * \param sw The new signature that has to be ordered based on its action
597  */
598 static int SCSigOrderByActionCompare(SCSigSignatureWrapper *sw1,
600 {
601  return ActionOrderVal(sw2->sig->action) - ActionOrderVal(sw1->sig->action);
602 }
603 
604 /**
605  * \brief Orders an incoming Signature based on its flowbits type
606  *
607  * \param de_ctx Pointer to the detection engine context from which the
608  * signatures have to be ordered.
609  * \param sw The new signature that has to be ordered based on its flowbits
610  */
611 static int SCSigOrderByFlowbitsCompare(SCSigSignatureWrapper *sw1,
613 {
614  return sw1->user[SC_RADIX_USER_DATA_FLOWBITS] -
616 }
617 
618 /**
619  * \brief Orders an incoming Signature based on its flowvar type
620  *
621  * \param de_ctx Pointer to the detection engine context from which the
622  * signatures have to be ordered.
623  * \param sw The new signature that has to be ordered based on its flowvar
624  */
625 static int SCSigOrderByFlowvarCompare(SCSigSignatureWrapper *sw1,
627 {
628  return sw1->user[SC_RADIX_USER_DATA_FLOWVAR] -
630 }
631 
632 /**
633  * \brief Orders an incoming Signature based on its pktvar type
634  *
635  * \param de_ctx Pointer to the detection engine context from which the
636  * signatures have to be ordered.
637  * \param sw The new signature that has to be ordered based on its pktvar
638  */
639 static int SCSigOrderByPktvarCompare(SCSigSignatureWrapper *sw1,
641 {
642  return sw1->user[SC_RADIX_USER_DATA_PKTVAR] -
644 }
645 
646 static int SCSigOrderByFlowintCompare(SCSigSignatureWrapper *sw1,
648 {
649  return sw1->user[SC_RADIX_USER_DATA_FLOWINT] -
651 }
652 
653 /**
654  * \brief Orders an incoming Signature based on its hostbits type
655  *
656  * \param de_ctx Pointer to the detection engine context from which the
657  * signatures have to be ordered.
658  * \param sw The new signature that has to be ordered based on its hostbits
659  */
660 static int SCSigOrderByHostbitsCompare(SCSigSignatureWrapper *sw1,
662 {
663  return sw1->user[SC_RADIX_USER_DATA_HOSTBITS] -
665 }
666 
667 /**
668  * \brief Orders an incoming Signature based on its ippairbits (xbits) type
669  *
670  * \param de_ctx Pointer to the detection engine context from which the
671  * signatures have to be ordered.
672  * \param sw The new signature that has to be ordered based on its bits
673  */
674 static int SCSigOrderByIPPairbitsCompare(SCSigSignatureWrapper *sw1,
676 {
677  return sw1->user[SC_RADIX_USER_DATA_IPPAIRBITS] -
679 }
680 
681 /**
682  * \brief Orders an incoming Signature based on its priority type
683  *
684  * \param de_ctx Pointer to the detection engine context from which the
685  * signatures have to be ordered.
686  * \param sw The new signature that has to be ordered based on its priority
687  */
688 static int SCSigOrderByPriorityCompare(SCSigSignatureWrapper *sw1,
690 {
691  if (sw1->sig->prio > sw2->sig->prio) {
692  return -1;
693  } else if (sw1->sig->prio < sw2->sig->prio) {
694  return 1;
695  }
696  return 0;
697 }
698 
699 /**
700  * \brief Creates a Wrapper around the Signature
701  *
702  * \param Pointer to the Signature to be wrapped
703  *
704  * \retval sw Pointer to the wrapper that holds the signature
705  */
706 static inline SCSigSignatureWrapper *SCSigAllocSignatureWrapper(Signature *sig)
707 {
708  SCSigSignatureWrapper *sw = NULL;
709 
710  if ((sw = SCCalloc(1, sizeof(SCSigSignatureWrapper))) == NULL)
711  return NULL;
712 
713  sw->sig = sig;
714 
715  /* Process data from the signature into a cache for further use by the
716  * sig_ordering module */
717  SCSigProcessUserDataForFlowbits(sw);
718  SCSigProcessUserDataForFlowvar(sw);
719  SCSigProcessUserDataForFlowint(sw);
720  SCSigProcessUserDataForPktvar(sw);
721  SCSigProcessUserDataForHostbits(sw);
722  SCSigProcessUserDataForIPPairbits(sw);
723 
724  return sw;
725 }
726 
727 /**
728  * \brief Orders the signatures
729  *
730  * \param de_ctx Pointer to the Detection Engine Context that holds the
731  * signatures to be ordered
732  */
734 {
735  if (de_ctx->sig_list == NULL) {
736  SCLogDebug("no signatures to order");
737  return;
738  }
739 
740  Signature *sig = NULL;
741  SCSigSignatureWrapper *sigw = NULL;
742  SCSigSignatureWrapper *sigw_list = NULL;
743 #ifdef DEBUG
744  int i = 0;
745 #endif
746  SCLogDebug("ordering signatures in memory");
747 
748  sig = de_ctx->sig_list;
749  while (sig != NULL) {
750  sigw = SCSigAllocSignatureWrapper(sig);
751  /* Push signature wrapper onto a list, order doesn't matter here. */
752  sigw->next = sigw_list;
753  sigw_list = sigw;
754 
755  sig = sig->next;
756 #ifdef DEBUG
757  i++;
758 #endif
759  }
760 
761  /* Sort the list */
762  sigw_list = SCSigOrder(sigw_list, de_ctx->sc_sig_order_funcs);
763 
764  SCLogDebug("Total Signatures to be processed by the"
765  "sigordering module: %d", i);
766 
767  /* Recreate the sig list in order */
768  de_ctx->sig_list = NULL;
769  sigw = sigw_list;
770 #ifdef DEBUG
771  i = 0;
772 #endif
773  while (sigw != NULL) {
774 #ifdef DEBUG
775  i++;
776 #endif
777  sigw->sig->next = NULL;
778  if (de_ctx->sig_list == NULL) {
779  /* First entry on the list */
780  de_ctx->sig_list = sigw->sig;
781  sig = de_ctx->sig_list;
782  } else {
783  sig->next = sigw->sig;
784  sig = sig->next;
785  }
786  SCSigSignatureWrapper *sigw_to_free = sigw;
787  sigw = sigw->next;
788  SCFree(sigw_to_free);
789  }
790 
791  SCLogDebug("total signatures reordered by the sigordering module: %d", i);
792 }
793 
794 /**
795  * \brief Lets you register the Signature ordering functions. The order in
796  * which the functions are registered shows the priority. The first
797  * function registered provides more priority than the function
798  * registered after it. To add a new registration function, register
799  * it by listing it in the correct position in the below sequence,
800  * based on the priority you would want to offer to that keyword.
801  *
802  * \param de_ctx Pointer to the detection engine context from which the
803  * signatures have to be ordered.
804  */
806 {
807  SCLogDebug("registering signature ordering functions");
808 
809  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
810  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
811  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowintCompare);
812  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
813  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
814  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByHostbitsCompare);
815  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByIPPairbitsCompare);
816  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
817 }
818 
819 /**
820  * \brief De-registers all the signature ordering functions registered
821  *
822  * \param de_ctx Pointer to the detection engine context from which the
823  * signatures were ordered.
824  */
826 {
827  SCSigOrderFunc *funcs;
828  void *temp;
829 
830  /* clean the memory alloted to the signature ordering funcs */
831  funcs = de_ctx->sc_sig_order_funcs;
832  while (funcs != NULL) {
833  temp = funcs;
834  funcs = funcs->next;
835  SCFree(temp);
836  }
837  de_ctx->sc_sig_order_funcs = NULL;
838 }
839 
840 /**********Unittests**********/
841 
846 
847 #ifdef UNITTESTS
848 
849 static int SCSigOrderingTest01(void)
850 {
851  SCSigOrderFunc *temp = NULL;
852  int i = 0;
853 
856 
857  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
858  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
859  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
860  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
861  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
862  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
863  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
864  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
865  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
866  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
867  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
868 
869  temp = de_ctx->sc_sig_order_funcs;
870  while (temp != NULL) {
871  i++;
872  temp = temp->next;
873  }
874 
876 
877  FAIL_IF_NOT(i == 5);
878 
879  PASS;
880 }
881 
882 static int SCSigOrderingTest02(void)
883 {
884  Signature *sig = NULL;
885 
887  FAIL_IF(de_ctx == NULL);
888 
890  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
891  FAIL_IF_NULL(sig);
892 
894  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:2;)");
895  FAIL_IF_NULL(sig);
896 
898  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:3;)");
899  FAIL_IF_NULL(sig);
900 
902  "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;)");
903  FAIL_IF_NULL(sig);
904 
906  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:5;)");
907  FAIL_IF_NULL(sig);
908 
910  "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;)");
911  FAIL_IF_NULL(sig);
912 
914  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:7;)");
915  FAIL_IF_NULL(sig);
916 
918  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
919  FAIL_IF_NULL(sig);
920 
922  "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;)");
923  FAIL_IF_NULL(sig);
924 
926  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:10;)");
927  FAIL_IF_NULL(sig);
928 
930  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:11;)");
931  FAIL_IF_NULL(sig);
932 
934  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:12;)");
935  FAIL_IF_NULL(sig);
936 
938  "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;)");
939  FAIL_IF_NULL(sig);
940 
942  "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;)");
943  FAIL_IF_NULL(sig);
944 
945  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
946  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
947  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
948  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
949  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
951 
952  sig = de_ctx->sig_list;
953 
954 #ifdef DEBUG
955  while (sig != NULL) {
956  printf("sid: %d\n", sig->id);
957  sig = sig->next;
958  }
959 #endif
960 
961  sig = de_ctx->sig_list;
962 
963  /* pass */
964  FAIL_IF_NOT(sig->id == 6);
965  sig = sig->next;
966  FAIL_IF_NOT(sig->id == 4);
967  sig = sig->next;
968  FAIL_IF_NOT(sig->id == 8);
969  sig = sig->next;
970  FAIL_IF_NOT(sig->id == 7);
971  sig = sig->next;
972  FAIL_IF_NOT(sig->id == 10);
973  sig = sig->next;
974 
975  /* drops */
976  FAIL_IF_NOT(sig->id == 9);
977  sig = sig->next;
978  FAIL_IF_NOT(sig->id == 13);
979  sig = sig->next;
980  FAIL_IF_NOT(sig->id == 2);
981  sig = sig->next;
982  FAIL_IF_NOT(sig->id == 3);
983  sig = sig->next;
984 
985  /* alerts */
986  FAIL_IF_NOT(sig->id == 14);
987  sig = sig->next;
988  FAIL_IF_NOT(sig->id == 5);
989  sig = sig->next;
990  FAIL_IF_NOT(sig->id == 1);
991  sig = sig->next;
992  FAIL_IF_NOT(sig->id == 11);
993  sig = sig->next;
994  FAIL_IF_NOT(sig->id == 12);
995  sig = sig->next;
996 
998  PASS;
999 }
1000 
1001 static int SCSigOrderingTest03(void)
1002 {
1003  Signature *sig = NULL;
1004 
1007 
1009  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1010  "offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:1;)");
1011  FAIL_IF_NULL(sig);
1012 
1014  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1015  "offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:2;)");
1016  FAIL_IF_NULL(sig);
1017 
1019  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1020  "offset:10; depth:4; pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; "
1021  "flowbits:unset,TEST.one; rev:4; priority:2; sid:3;)");
1022  FAIL_IF_NULL(sig);
1023 
1025  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1026  "offset:0; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1027  "flowbits:isset,TEST.one; rev:4; priority:1; sid:4;)");
1028  FAIL_IF_NULL(sig);
1029 
1031  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1032  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; priority:2; sid:5;)");
1033  FAIL_IF_NULL(sig);
1034 
1036  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1037  "content:\"220\"; offset:10; flowbits:isnotset,TEST.one; pcre:\"/^User-Agent: "
1038  "(?P<flow_http_host>.*)\\r\\n/m\"; rev:4; sid:6;)");
1039  FAIL_IF_NULL(sig);
1040 
1042  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1043  "content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; "
1044  "flowbits:unset,TEST.one; rev:4; priority:3; sid:7;)");
1045  FAIL_IF_NULL(sig);
1046 
1048  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1049  "offset:10; depth:4; pcre:\"/220[- ]/\"; flowbits:toggle,TEST.one; rev:4; priority:1; "
1050  "pktvar:http_host,\"www.oisf.net\"; sid:8;)");
1051  FAIL_IF_NULL(sig);
1052 
1054  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1055  "content:\"220\"; offset:10; depth:4; rev:4; flowbits:set,TEST.one; "
1056  "flowbits:noalert; pktvar:http_host,\"www.oisf.net\"; sid:9;)");
1057  FAIL_IF_NULL(sig);
1058 
1060  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1061  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:10;)");
1062  FAIL_IF_NULL(sig);
1063 
1065  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1066  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:11;)");
1067  FAIL_IF_NULL(sig);
1068 
1070  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1071  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:12;)");
1072  FAIL_IF_NULL(sig);
1073 
1075  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1076  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; flowbits:isnotset,TEST.one; sid:13;)");
1077  FAIL_IF_NULL(sig);
1078 
1080  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1081  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; flowbits:set,TEST.one; sid:14;)");
1082  FAIL_IF_NULL(sig);
1083 
1084  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1085  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1086  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1087  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1088  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1090 
1091  sig = de_ctx->sig_list;
1092 
1093 #ifdef DEBUG
1094  while (sig != NULL) {
1095  printf("sid: %d\n", sig->id);
1096  sig = sig->next;
1097  }
1098 #endif
1099 
1100  sig = de_ctx->sig_list;
1101 
1102  FAIL_IF_NOT(sig->id == 3);
1103  sig = sig->next;
1104 
1105  FAIL_IF_NOT(sig->id == 8);
1106  sig = sig->next;
1107  FAIL_IF_NOT(sig->id == 9);
1108  sig = sig->next;
1109  FAIL_IF_NOT(sig->id == 7);
1110  sig = sig->next;
1111  FAIL_IF_NOT(sig->id == 14);
1112  sig = sig->next;
1113  FAIL_IF_NOT(sig->id == 6);
1114  sig = sig->next;
1115  FAIL_IF_NOT(sig->id == 4);
1116  sig = sig->next;
1117  FAIL_IF_NOT(sig->id == 13);
1118  sig = sig->next;
1119  FAIL_IF_NOT(sig->id == 2);
1120  sig = sig->next;
1121  FAIL_IF_NOT(sig->id == 5);
1122  sig = sig->next;
1123  FAIL_IF_NOT(sig->id == 1);
1124  sig = sig->next;
1125  FAIL_IF_NOT(sig->id == 10);
1126  sig = sig->next;
1127  FAIL_IF_NOT(sig->id == 11);
1128  sig = sig->next;
1129  FAIL_IF_NOT(sig->id == 12);
1130 
1131  sig = sig->next;
1132 
1134 
1135  PASS;
1136 }
1137 
1138 static int SCSigOrderingTest04(void)
1139 {
1140 
1141  Signature *sig = NULL;
1142 
1144  FAIL_IF(de_ctx == NULL);
1145 
1147  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1148  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1149  FAIL_IF_NULL(sig);
1150 
1152  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1153  "pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; content:\"220\"; "
1154  "offset:10; rev:4; priority:3; sid:2;)");
1155  FAIL_IF_NULL(sig);
1156 
1158  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1159  "content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: "
1160  "(?P<flow_http_host>.*)\\r\\n/m\"; rev:4; priority:3; sid:3;)");
1161  FAIL_IF_NULL(sig);
1162 
1164  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1165  "offset:10; depth:4; pcre:\"/^User-Agent: (?P<flow_http_host>.*)\\r\\n/m\"; rev:4; "
1166  "priority:3; flowvar:http_host,\"www.oisf.net\"; sid:4;)");
1167  FAIL_IF_NULL(sig);
1168 
1170  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1171  "offset:11; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1172  "pcre:\"/220[- ]/\"; rev:4; priority:3; sid:5;)");
1173  FAIL_IF_NULL(sig);
1174 
1176  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1177  "offset:11; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; "
1178  "pktvar:http_host,\"www.oisf.net\"; rev:4; priority:1; sid:6;)");
1179  FAIL_IF_NULL(sig);
1180 
1182  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1183  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; flowvar:http_host,\"www.oisf.net\"; "
1184  "pktvar:http_host,\"www.oisf.net\"; priority:1; sid:7;)");
1185  FAIL_IF_NULL(sig);
1186 
1188  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1189  "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1190  "flowvar:http_host,\"www.oisf.net\"; sid:8;)");
1191  FAIL_IF_NULL(sig);
1192 
1194  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1195  "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1196  "flowvar:http_host,\"www.oisf.net\"; sid:9;)");
1197  FAIL_IF_NULL(sig);
1198 
1199  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1200  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1201  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1202  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1203  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1205 
1206  sig = de_ctx->sig_list;
1207 
1208 #ifdef DEBUG
1209  while (sig != NULL) {
1210  printf("sid: %d\n", sig->id);
1211  sig = sig->next;
1212  }
1213 #endif
1214 
1215  sig = de_ctx->sig_list;
1216 
1217  /* flowvar set */
1218  sig = sig->next;
1219  FAIL_IF_NOT(sig->id == 3);
1220  sig = sig->next;
1221  FAIL_IF_NOT(sig->id == 4);
1222  sig = sig->next;
1223  FAIL_IF_NOT(sig->id == 7);
1224  sig = sig->next;
1225  FAIL_IF_NOT(sig->id == 8);
1226  sig = sig->next;
1227  FAIL_IF_NOT(sig->id == 9);
1228  sig = sig->next;
1229 
1230  /* pktvar */
1231 
1232  FAIL_IF_NOT(sig->id == 5);
1233  sig = sig->next;
1234  FAIL_IF_NOT(sig->id == 6);
1235  sig = sig->next;
1236 
1237  FAIL_IF_NOT(sig->id == 1);
1238  sig = sig->next;
1239 
1241 
1242  PASS;
1243 }
1244 
1245 static int SCSigOrderingTest05(void)
1246 {
1247  Signature *sig = NULL;
1248 
1250  FAIL_IF(de_ctx == NULL);
1251 
1253  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1254  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1255  FAIL_IF_NULL(sig);
1256 
1258  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1259  "pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; content:\"220\"; "
1260  "offset:10; rev:4; priority:3; sid:2;)");
1261  FAIL_IF_NULL(sig);
1262 
1264  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1265  "content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: "
1266  "(?P<pkt_http_host>.*)\\r\\n/m\"; rev:4; priority:3; sid:3;)");
1267  FAIL_IF_NULL(sig);
1268 
1270  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1271  "offset:10; depth:4; pcre:\"/^User-Agent: (?P<pkt_http_host>.*)\\r\\n/m\"; rev:4; "
1272  "priority:3; pktvar:http_host,\"www.oisf.net\"; sid:4;)");
1273  FAIL_IF_NULL(sig);
1274 
1276  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1277  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:5;)");
1278  FAIL_IF_NULL(sig);
1279 
1281  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1282  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:6;)");
1283  FAIL_IF_NULL(sig);
1284 
1286  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1287  "content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; "
1288  "pktvar:http_host,\"www.oisf.net\"; sid:7;)");
1289  FAIL_IF_NULL(sig);
1290 
1292  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1293  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; "
1294  "pktvar:http_host,\"www.oisf.net\"; sid:8;)");
1295  FAIL_IF_NULL(sig);
1296 
1297  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1298  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1299  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1300  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1301  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1303 
1304  sig = de_ctx->sig_list;
1305 
1306  //#ifdef DEBUG
1307  while (sig != NULL) {
1308  printf("sid: %d\n", sig->id);
1309  sig = sig->next;
1310  }
1311  //#endif
1312 
1313  sig = de_ctx->sig_list;
1314 
1315  /* pktvar set */
1316  FAIL_IF_NOT(sig->id == 2);
1317  sig = sig->next;
1318  FAIL_IF_NOT(sig->id == 3);
1319  sig = sig->next;
1320  FAIL_IF_NOT(sig->id == 4);
1321  sig = sig->next;
1322  /* pktvar read */
1323  FAIL_IF_NOT(sig->id == 7);
1324  sig = sig->next;
1325  FAIL_IF_NOT(sig->id == 8);
1326  sig = sig->next;
1327  FAIL_IF_NOT(sig->id == 1);
1328  sig = sig->next;
1329  FAIL_IF_NOT(sig->id == 5);
1330  sig = sig->next;
1331  FAIL_IF_NOT(sig->id == 6);
1332  sig = sig->next;
1333 
1335 
1336  PASS;
1337 }
1338 
1339 static int SCSigOrderingTest06(void)
1340 {
1341 
1342  Signature *sig = NULL;
1343 
1346 
1348  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1349  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1350  FAIL_IF_NULL(sig);
1351 
1353  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1354  "content:\"220\"; offset:10; rev:4; priority:2; sid:2;)");
1355  FAIL_IF_NULL(sig);
1356 
1358  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1359  "content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:3;)");
1360  FAIL_IF_NULL(sig);
1361 
1363  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; "
1364  "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1365  FAIL_IF_NULL(sig);
1366 
1368  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1369  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1370  FAIL_IF_NULL(sig);
1371 
1373  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1374  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1375  FAIL_IF_NULL(sig);
1377  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1378  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1379  FAIL_IF_NULL(sig);
1380 
1382  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; "
1383  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1384  FAIL_IF_NULL(sig);
1385 
1386  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1387  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1388  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1389  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1390  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1392 
1393  sig = de_ctx->sig_list;
1394 
1395 #ifdef DEBUG
1396  while (sig != NULL) {
1397  printf("sid: %d\n", sig->id);
1398  sig = sig->next;
1399  }
1400 #endif
1401 
1402  sig = de_ctx->sig_list;
1403 
1404  FAIL_IF_NOT(sig->id == 6);
1405  sig = sig->next;
1406  FAIL_IF_NOT(sig->id == 2);
1407  sig = sig->next;
1408  FAIL_IF_NOT(sig->id == 4);
1409  sig = sig->next;
1410  FAIL_IF_NOT(sig->id == 5);
1411  sig = sig->next;
1412  FAIL_IF_NOT(sig->id == 7);
1413  sig = sig->next;
1414  FAIL_IF_NOT(sig->id == 8);
1415  sig = sig->next;
1416  FAIL_IF_NOT(sig->id == 1);
1417  sig = sig->next;
1418  FAIL_IF_NOT(sig->id == 3);
1419  sig = sig->next;
1420 
1422 
1423  PASS;
1424 }
1425 static int SCSigOrderingTest07(void)
1426 {
1427 
1428  Signature *sig = NULL;
1429 
1431  FAIL_IF(de_ctx == NULL);
1432 
1434  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1435  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1; rev:4;)");
1436  FAIL_IF_NULL(sig);
1437 
1439  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1440  "content:\"220\"; offset:10; sid:2; rev:4; priority:2;)");
1441  FAIL_IF_NULL(sig);
1442 
1444  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1445  "content:\"220\"; offset:10; depth:4; sid:3; rev:4; priority:3;)");
1446  FAIL_IF_NULL(sig);
1447 
1449  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1450  "content:\"220\"; offset:10; depth:4; sid:4; rev:4; priority:2;)");
1451  FAIL_IF_NULL(sig);
1452 
1454  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1455  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:5; rev:4; priority:2;)");
1456  FAIL_IF_NULL(sig);
1457 
1459  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1460  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:6; rev:4; priority:1;)");
1461  FAIL_IF_NULL(sig);
1462 
1464  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1465  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:7; rev:4; priority:2;)");
1466  FAIL_IF_NULL(sig);
1467 
1469  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1470  "offset:12; depth:4; pcre:\"/220[- ]/\"; sid:8; rev:4; priority:2;)");
1471  FAIL_IF_NULL(sig);
1472 
1473  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1474  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1475  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1476  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1477  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1479 
1480  sig = de_ctx->sig_list;
1481 
1482 #ifdef DEBUG
1483  while (sig != NULL) {
1484  printf("sid: %d\n", sig->id);
1485  sig = sig->next;
1486  }
1487 #endif
1488 
1489  sig = de_ctx->sig_list;
1490 
1491  FAIL_IF_NOT(sig->id == 2);
1492  sig = sig->next;
1493  FAIL_IF_NOT(sig->id == 4);
1494  sig = sig->next;
1495  FAIL_IF_NOT(sig->id == 5);
1496  sig = sig->next;
1497  FAIL_IF_NOT(sig->id == 7);
1498  sig = sig->next;
1499  FAIL_IF_NOT(sig->id == 6);
1500  sig = sig->next;
1501  FAIL_IF_NOT(sig->id == 8);
1502  sig = sig->next;
1503  FAIL_IF_NOT(sig->id == 1);
1504  sig = sig->next;
1505  FAIL_IF_NOT(sig->id == 3);
1506  sig = sig->next;
1507 
1509 
1510  PASS;
1511 }
1512 
1513 /**
1514  * \test Order with a different Action priority
1515  * (as specified from config)
1516  */
1517 static int SCSigOrderingTest08(void)
1518 {
1519 #ifdef HAVE_LIBNET11
1520 
1521  Signature *sig = NULL;
1522  extern uint8_t action_order_sigs[4];
1523 
1524  /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1529 
1531  FAIL_IF(de_ctx == NULL);
1532 
1534  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1535  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1; rev:4;)");
1536  FAIL_IF_NULL(sig);
1537 
1539  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1540  "content:\"220\"; offset:10; sid:2; rev:4; priority:2;)");
1541  FAIL_IF_NULL(sig);
1542 
1544  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1545  "content:\"220\"; offset:10; depth:4; sid:3; rev:4; priority:3;)");
1546  FAIL_IF_NULL(sig);
1547 
1549  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1550  "content:\"220\"; offset:10; depth:4; sid:4; rev:4; priority:2;)");
1551  FAIL_IF_NULL(sig);
1552 
1554  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1555  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:5; rev:4; priority:2;)");
1556  FAIL_IF_NULL(sig);
1557 
1559  "reject tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1560  "offset:11; depth:4; pcre:\"/220[- ]/\"; sid:6; rev:4; priority:1;)");
1561  FAIL_IF_NULL(sig);
1562 
1564  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; "
1565  "content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; sid:7; rev:4;)");
1566  FAIL_IF_NULL(sig);
1567 
1569  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1570  "offset:12; depth:4; pcre:\"/220[- ]/\"; sid:8; rev:4; priority:2;)");
1571  FAIL_IF_NULL(sig);
1572 
1573  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1574  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1575  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1576  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1577  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1579 
1580  sig = de_ctx->sig_list;
1581 
1582 #ifdef DEBUG
1583  while (sig != NULL) {
1584  printf("sid: %d\n", sig->id);
1585  sig = sig->next;
1586  }
1587 #endif
1588 
1589  sig = de_ctx->sig_list;
1590 
1591  FAIL_IF_NOT(sig->id == 6);
1592  sig = sig->next;
1593  FAIL_IF_NOT(sig->id == 8);
1594  sig = sig->next;
1595  FAIL_IF_NOT(sig->id == 1);
1596  sig = sig->next;
1597  FAIL_IF_NOT(sig->id == 3);
1598  sig = sig->next;
1599  FAIL_IF_NOT(sig->id == 2);
1600  sig = sig->next;
1601  FAIL_IF_NOT(sig->id == 4);
1602  sig = sig->next;
1603  FAIL_IF_NOT(sig->id == 5);
1604  sig = sig->next;
1605  FAIL_IF_NOT(sig->id == 7);
1606  sig = sig->next;
1607 
1608  /* Restore the default pre-order definition */
1613 
1615 
1616 #endif
1617  PASS;
1618 }
1619 
1620 /**
1621  * \test Order with a different Action priority
1622  * (as specified from config)
1623  */
1624 static int SCSigOrderingTest09(void)
1625 {
1626 
1627  Signature *sig = NULL;
1628  extern uint8_t action_order_sigs[4];
1629 
1630  /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1635 
1637  FAIL_IF(de_ctx == NULL);
1638 
1640  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1641  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1;)");
1642  FAIL_IF_NULL(sig);
1643 
1645  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1646  "content:\"220\"; offset:10; priority:2; sid:2;)");
1647  FAIL_IF_NULL(sig);
1648 
1650  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1651  "content:\"220\"; offset:10; depth:4; priority:3; sid:3;)");
1652  FAIL_IF_NULL(sig);
1653 
1655  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1656  "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1657  FAIL_IF_NULL(sig);
1658 
1660  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1661  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1662  FAIL_IF_NULL(sig);
1663 
1665  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1666  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1667  FAIL_IF_NULL(sig);
1668 
1670  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1671  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1672  FAIL_IF_NULL(sig);
1673 
1675  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1676  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1677  FAIL_IF_NULL(sig);
1678 
1679  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1680  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1681  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1682  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1683  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1685 
1686  sig = de_ctx->sig_list;
1687 
1688 #ifdef DEBUG
1689  while (sig != NULL) {
1690  printf("sid: %d\n", sig->id);
1691  sig = sig->next;
1692  }
1693 #endif
1694 
1695  sig = de_ctx->sig_list;
1696 
1697  FAIL_IF_NOT(sig->id == 6);
1698  sig = sig->next;
1699  FAIL_IF_NOT(sig->id == 7);
1700  sig = sig->next;
1701  FAIL_IF_NOT(sig->id == 8);
1702  sig = sig->next;
1703  FAIL_IF_NOT(sig->id == 1);
1704  sig = sig->next;
1705  FAIL_IF_NOT(sig->id == 3);
1706  sig = sig->next;
1707  FAIL_IF_NOT(sig->id == 2);
1708  sig = sig->next;
1709  FAIL_IF_NOT(sig->id == 4);
1710  sig = sig->next;
1711  FAIL_IF_NOT(sig->id == 5);
1712  sig = sig->next;
1713 
1714  /* Restore the default pre-order definition */
1719 
1721  PASS;
1722 }
1723 
1724 /**
1725  * \test Order with a different Action priority
1726  * (as specified from config)
1727  */
1728 static int SCSigOrderingTest10(void)
1729 {
1730 
1731  Signature *sig = NULL;
1732  extern uint8_t action_order_sigs[4];
1733 
1734  /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */
1739 
1741  FAIL_IF(de_ctx == NULL);
1742 
1744  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1745  "content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)");
1746  FAIL_IF_NULL(sig);
1747 
1749  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1750  "content:\"220\"; offset:10; rev:4; priority:2; sid:2;)");
1751  FAIL_IF_NULL(sig);
1752 
1754  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; "
1755  "content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:3;)");
1756  FAIL_IF_NULL(sig);
1757 
1759  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; "
1760  "content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)");
1761  FAIL_IF_NULL(sig);
1762 
1764  "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; "
1765  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)");
1766  FAIL_IF_NULL(sig);
1767 
1769  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; "
1770  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)");
1771  FAIL_IF_NULL(sig);
1772 
1774  "drop tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; "
1775  "offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)");
1776  FAIL_IF_NULL(sig);
1777 
1779  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; "
1780  "offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)");
1781  FAIL_IF_NULL(sig);
1782 
1783  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1784  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1785  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1786  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1787  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1789 
1790  sig = de_ctx->sig_list;
1791 
1792 #ifdef DEBUG
1793  while (sig != NULL) {
1794  printf("sid: %d\n", sig->id);
1795  sig = sig->next;
1796  }
1797 #endif
1798 
1799  sig = de_ctx->sig_list;
1800 
1801  FAIL_IF_NOT(sig->id == 2);
1802  sig = sig->next;
1803  FAIL_IF_NOT(sig->id == 4);
1804  sig = sig->next;
1805  FAIL_IF_NOT(sig->id == 5);
1806  sig = sig->next;
1807  FAIL_IF_NOT(sig->id == 8);
1808  sig = sig->next;
1809  FAIL_IF_NOT(sig->id == 1);
1810  sig = sig->next;
1811  FAIL_IF_NOT(sig->id == 3);
1812  sig = sig->next;
1813  FAIL_IF_NOT(sig->id == 6);
1814  sig = sig->next;
1815  FAIL_IF_NOT(sig->id == 7);
1816  sig = sig->next;
1817 
1818  /* Restore the default pre-order definition */
1823 
1825  PASS;
1826 }
1827 
1828 static int SCSigOrderingTest11(void)
1829 {
1830 
1831  Signature *sig = NULL;
1832 
1834  FAIL_IF(de_ctx == NULL);
1835 
1837  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering set\"; "
1838  "flowbits:isnotset,myflow1; rev:4; sid:1;)");
1839  FAIL_IF_NULL(sig);
1840 
1842  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering toggle\"; "
1843  "flowbits:toggle,myflow2; rev:4; sid:2;)");
1844  FAIL_IF_NULL(sig);
1845 
1847  "alert tcp any !21:902 -> any any (msg:\"Testing sigordering unset\"; "
1848  "flowbits:isset, myflow1; flowbits:unset,myflow2; rev:4; priority:3; sid:3;)");
1849  FAIL_IF_NULL(sig);
1850 
1851  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare);
1852  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1853  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
1854  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
1855  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
1857 
1858  sig = de_ctx->sig_list;
1859 
1860 #ifdef DEBUG
1861  while (sig != NULL) {
1862  printf("sid: %d\n", sig->id);
1863  sig = sig->next;
1864  }
1865 #endif
1866 
1867  sig = de_ctx->sig_list;
1868 
1869  FAIL_IF_NOT(sig->id == 2);
1870  sig = sig->next;
1871  FAIL_IF_NOT(sig->id == 3);
1872  sig = sig->next;
1873  FAIL_IF_NOT(sig->id == 1);
1874  sig = sig->next;
1875 
1877  PASS;
1878 }
1879 
1880 static int SCSigOrderingTest12(void)
1881 {
1882  Signature *sig = NULL;
1883  Packet *p = NULL;
1884  uint8_t buf[] = "test message";
1885  Flow f;
1886 
1887  FLOW_INITIALIZE(&f);
1888  f.flags |= FLOW_IPV4;
1890  f.proto = IPPROTO_TCP;
1891 
1893  FAIL_IF(de_ctx == NULL);
1894  de_ctx->flags |= DE_QUIET;
1895 
1896  const char *sigs[2];
1897  sigs[0] = "alert tcp any any -> any any (content:\"test\"; dsize:>0; flowbits:isset,one; flowbits:set,two; sid:1;)";
1898  sigs[1] = "alert tcp any any -> any any (content:\"test\"; dsize:>0; flowbits:set,one; sid:2;)";
1899  UTHAppendSigs(de_ctx, sigs, 2);
1900 
1901  sig = de_ctx->sig_list;
1902  FAIL_IF_NULL(sig);
1903  FAIL_IF_NULL(sig->next);
1904  FAIL_IF_NOT_NULL(sig->next->next);
1905  FAIL_IF(de_ctx->signum != 2);
1906 
1908  p = UTHBuildPacket(buf, sizeof(buf), IPPROTO_TCP);
1909  FAIL_IF_NULL(p);
1910 
1911  p->flow = &f;
1915 
1916  UTHMatchPackets(de_ctx, &p, 1);
1917 
1918  uint32_t sids[2] = {1, 2};
1919  uint32_t results[2] = {1, 1};
1921 
1922  UTHFreePackets(&p, 1);
1923 
1925 
1926  FlowShutdown();
1927 
1928  PASS;
1929 }
1930 
1931 /** \test Bug 1061 */
1932 static int SCSigOrderingTest13(void)
1933 {
1934 
1935  Signature *sig = NULL;
1936 
1938  FAIL_IF(de_ctx == NULL);
1939 
1940  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:isset,bit1; flowbits:set,bit2; flowbits:set,bit3; sid:6;)");
1941  FAIL_IF_NULL(sig);
1942  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:set,bit1; flowbits:set,bit2; sid:7;)");
1943  FAIL_IF_NULL(sig);
1944  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:isset,bit1; flowbits:isset,bit2; flowbits:isset,bit3; sid:5;)");
1945  FAIL_IF_NULL(sig);
1946 
1947  SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare);
1949 
1950 #ifdef DEBUG
1951  sig = de_ctx->sig_list;
1952  while (sig != NULL) {
1953  printf("sid: %d\n", sig->id);
1954  sig = sig->next;
1955  }
1956 #endif
1957 
1958  sig = de_ctx->sig_list;
1959 
1960  FAIL_IF_NOT(sig->id == 7);
1961  sig = sig->next;
1962  FAIL_IF_NOT(sig->id == 6);
1963  sig = sig->next;
1964  FAIL_IF_NOT(sig->id == 5);
1965  sig = sig->next;
1966 
1968  PASS;
1969 }
1970 
1971 #endif
1972 
1974 {
1975 
1976 #ifdef UNITTESTS
1977  UtRegisterTest("SCSigOrderingTest01", SCSigOrderingTest01);
1978  UtRegisterTest("SCSigOrderingTest02", SCSigOrderingTest02);
1979  UtRegisterTest("SCSigOrderingTest03", SCSigOrderingTest03);
1980  UtRegisterTest("SCSigOrderingTest04", SCSigOrderingTest04);
1981  UtRegisterTest("SCSigOrderingTest05", SCSigOrderingTest05);
1982  UtRegisterTest("SCSigOrderingTest06", SCSigOrderingTest06);
1983  UtRegisterTest("SCSigOrderingTest07", SCSigOrderingTest07);
1984  UtRegisterTest("SCSigOrderingTest08", SCSigOrderingTest08);
1985  UtRegisterTest("SCSigOrderingTest09", SCSigOrderingTest09);
1986  UtRegisterTest("SCSigOrderingTest10", SCSigOrderingTest10);
1987  UtRegisterTest("SCSigOrderingTest11", SCSigOrderingTest11);
1988  UtRegisterTest("SCSigOrderingTest12", SCSigOrderingTest12);
1989  UtRegisterTest("SCSigOrderingTest13", SCSigOrderingTest13);
1990 #endif
1991 }
DetectPcreData_::idx
uint8_t idx
Definition: detect-pcre.h:47
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:113
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:578
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:1022
FLOWINT_MODIFIER_ADD
@ FLOWINT_MODIFIER_ADD
Definition: detect-flowint.h:31
flow-util.h
SigFree
void SigFree(DetectEngineCtx *, Signature *)
Definition: detect-parse.c:1644
SCSigOrderFunc_::next
struct SCSigOrderFunc_ * next
Definition: detect-engine-sigorder.h:63
ACTION_PASS
#define ACTION_PASS
Definition: action-globals.h:34
ACTION_REJECT
#define ACTION_REJECT
Definition: action-globals.h:31
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DETECT_FLOWINT_TYPE_READ
#define DETECT_FLOWINT_TYPE_READ
Definition: detect-engine-sigorder.c:60
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
Flow_::proto
uint8_t proto
Definition: flow.h:373
FLOWINT_MODIFIER_NE
@ FLOWINT_MODIFIER_NE
Definition: detect-flowint.h:38
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:474
Flow_
Flow data structure.
Definition: flow.h:351
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
FLOWINT_MODIFIER_LE
@ FLOWINT_MODIFIER_LE
Definition: detect-flowint.h:36
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:836
DetectFlowintData_
Definition: detect-flowint.h:61
DetectXbitsData_::cmd
uint8_t cmd
Definition: detect-xbits.h:42
DetectFlowbitsData_::cmd
uint8_t cmd
Definition: detect-flowbits.h:37
DETECT_XBITS_TYPE_SET_READ
#define DETECT_XBITS_TYPE_SET_READ
Definition: detect-engine-sigorder.c:66
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2533
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:825
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:586
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:223
DE_QUIET
#define DE_QUIET
Definition: detect.h:321
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:340
SCSigRegisterSignatureOrderingTests
void SCSigRegisterSignatureOrderingTests(void)
Definition: detect-engine-sigorder.c:1973
FLOWINT_MODIFIER_NOTSET
@ FLOWINT_MODIFIER_NOTSET
Definition: detect-flowint.h:43
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:2620
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:468
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: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:665
DetectFlowbitsData_
Definition: detect-flowbits.h:35
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:537
UTHMatchPackets
int UTHMatchPackets(DetectEngineCtx *de_ctx, Packet **p, int num_packets)
Definition: util-unittest-helper.c:693
DETECT_SM_LIST_POSTMATCH
@ DETECT_SM_LIST_POSTMATCH
Definition: detect.h:121
DETECT_FLOWVAR_TYPE_SET
#define DETECT_FLOWVAR_TYPE_SET
Definition: detect-engine-sigorder.c:47
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
detect-xbits.h
DETECT_XBITS_CMD_ISNOTSET
#define DETECT_XBITS_CMD_ISNOTSET
Definition: detect-xbits.h:30
DETECT_XBITS_TYPE_READ
#define DETECT_XBITS_TYPE_READ
Definition: detect-engine-sigorder.c:65
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DETECT_FLOWINT
@ DETECT_FLOWINT
Definition: detect-engine-register.h:87
FLOWINT_MODIFIER_GT
@ FLOWINT_MODIFIER_GT
Definition: detect-flowint.h:40
DETECT_FLOWVAR
@ DETECT_FLOWVAR
Definition: detect-engine-register.h:85
SCSigOrderSignatures
void SCSigOrderSignatures(DetectEngineCtx *de_ctx)
Orders the signatures.
Definition: detect-engine-sigorder.c:733
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:805
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:351
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:111
DETECT_XBITS_NOT_USED
#define DETECT_XBITS_NOT_USED
Definition: detect-engine-sigorder.c:64
DETECT_XBITS
@ DETECT_XBITS
Definition: detect-engine-register.h:261
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:350
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:300
Signature_::action
uint8_t action
Definition: detect.h:608
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:437
detect-engine-build.h
type
uint16_t type
Definition: decode-vlan.c:107
SCSigOrderFunc_
Structure holding the signature ordering function used by the signature ordering module.
Definition: detect-engine-sigorder.h:59
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:662
DetectFlowintData_::modifier
uint8_t modifier
Definition: detect-flowint.h:70
DETECT_FLOWBITS_NOT_USED
#define DETECT_FLOWBITS_NOT_USED
Definition: detect-engine-sigorder.c:54
util-action.h
FLOWINT_MODIFIER_EQ
@ FLOWINT_MODIFIER_EQ
Definition: detect-flowint.h:37
DETECT_PKTVAR_TYPE_SET
#define DETECT_PKTVAR_TYPE_SET
Definition: detect-engine-sigorder.c:52
FLOWINT_MODIFIER_SET
@ FLOWINT_MODIFIER_SET
Definition: detect-flowint.h:30
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
FLOWINT_MODIFIER_SUB
@ FLOWINT_MODIFIER_SUB
Definition: detect-flowint.h:32
FLOWINT_MODIFIER_GE
@ FLOWINT_MODIFIER_GE
Definition: detect-flowint.h:39
SC_RADIX_USER_DATA_FLOWBITS
@ SC_RADIX_USER_DATA_FLOWBITS
Definition: detect-engine-sigorder.h:32
DetectPcreData_::captypes
uint8_t captypes[DETECT_PCRE_CAPTURE_MAX]
Definition: detect-pcre.h:48
Packet_::flow
struct Flow_ * flow
Definition: decode.h:476
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
suricata-common.h
SigMatch_::type
uint16_t type
Definition: detect.h:348
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:685
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:844
DETECT_FLOWBITS
@ DETECT_FLOWBITS
Definition: detect-engine-register.h:90
Signature_::prio
int prio
Definition: detect.h:631
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
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:628
DETECT_FLOWBITS_CMD_UNSET
#define DETECT_FLOWBITS_CMD_UNSET
Definition: detect-flowbits.h:30
Flow_::flags
uint32_t flags
Definition: flow.h:421
detect-parse.h
Signature_
Signature container.
Definition: detect.h:593
SigMatch_
a single match condition for a signature
Definition: detect.h:347
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:225
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2494
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:42
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:42
DETECT_XBITS_CMD_SET
#define DETECT_XBITS_CMD_SET
Definition: detect-xbits.h:27
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:838
FLOWINT_MODIFIER_ISSET
@ FLOWINT_MODIFIER_ISSET
Definition: detect-flowint.h:42
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:619
DETECT_XBITS_CMD_TOGGLE
#define DETECT_XBITS_CMD_TOGGLE
Definition: detect-xbits.h:28
Signature_::msg
char * msg
Definition: detect.h:651
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:450
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SC_RADIX_USER_DATA_FLOWVAR
@ SC_RADIX_USER_DATA_FLOWVAR
Definition: detect-engine-sigorder.h:33
DETECT_FLOWBITS_TYPE_SET
#define DETECT_FLOWBITS_TYPE_SET
Definition: detect-engine-sigorder.c:57
DetectEngineCtx_::signum
uint32_t signum
Definition: detect.h:856
DETECT_FLOWVAR_NOT_USED
#define DETECT_FLOWVAR_NOT_USED
Definition: detect-engine-sigorder.c:44
FLOWINT_MODIFIER_LT
@ FLOWINT_MODIFIER_LT
Definition: detect-flowint.h:35
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:103
VAR_TYPE_PKT_VAR
@ VAR_TYPE_PKT_VAR
Definition: util-var.h:32
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1019
DetectEngineCtx_::sc_sig_order_funcs
struct SCSigOrderFunc_ * sc_sig_order_funcs
Definition: detect.h:863
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: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:431