]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
fix(more like a feature update) for bug #708.
authorAnoop Saldanha <anoopsaldanha@gmail.com>
Tue, 15 Jan 2013 18:00:19 +0000 (23:30 +0530)
committerVictor Julien <victor@inliniac.net>
Thu, 21 Feb 2013 10:17:31 +0000 (11:17 +0100)
Add support for flowint based sig ordering.

src/detect-engine-sigorder.c
src/detect-engine-sigorder.h

index 5dbcf9fe90143d852f6cab121da20af58e68f271..5cffa1770f58f1708d99251a9e5f3b2b2ccbc8f8 100644 (file)
@@ -26,6 +26,7 @@
 #include "suricata-common.h"
 #include "detect.h"
 #include "detect-flowbits.h"
+#include "detect-flowint.h"
 #include "detect-engine-sigorder.h"
 #include "detect-pcre.h"
 
 #define DETECT_FLOWBITS_TYPE_READ 2
 #define DETECT_FLOWBITS_TYPE_SET  3
 
+#define DETECT_FLOWINT_NOT_USED  1
+#define DETECT_FLOWINT_TYPE_READ 2
+#define DETECT_FLOWINT_TYPE_SET  3
+
 
 /**
  * \brief Registers a keyword-based, signature ordering function
@@ -150,6 +155,53 @@ static inline int SCSigGetFlowbitsType(Signature *sig)
     return flowbits_user_type;
 }
 
+static inline int SCSigGetFlowintType(Signature *sig)
+{
+    SigMatch *sm = sig->sm_lists[DETECT_SM_LIST_MATCH];
+    DetectFlowintData *fi = NULL;
+    int modifier = FLOWINT_MODIFIER_UNKNOWN;
+    int flowint_user_type = DETECT_FLOWINT_NOT_USED;
+
+    while (sm != NULL) {
+        if (sm->type == DETECT_FLOWINT) {
+            fi = (DetectFlowintData *)sm->ctx;
+            if (modifier > fi->modifier)
+                modifier = fi->modifier;
+        }
+
+        sm = sm->next;
+    }
+
+    sm = sig->sm_lists[DETECT_SM_LIST_POSTMATCH];
+    while (sm != NULL) {
+        if (sm->type == DETECT_FLOWINT) {
+            fi = (DetectFlowintData *)sm->ctx;
+            if (modifier > fi->modifier)
+                modifier = fi->modifier;
+        }
+
+        sm = sm->next;
+    }
+
+    if (modifier == FLOWINT_MODIFIER_SET ||
+        modifier == FLOWINT_MODIFIER_ADD ||
+        modifier == FLOWINT_MODIFIER_SUB) {
+        flowint_user_type = DETECT_FLOWINT_TYPE_SET;
+    } else if (modifier == FLOWINT_MODIFIER_LT ||
+               modifier == FLOWINT_MODIFIER_LE ||
+               modifier == FLOWINT_MODIFIER_EQ ||
+               modifier == FLOWINT_MODIFIER_NE ||
+               modifier == FLOWINT_MODIFIER_GE ||
+               modifier == FLOWINT_MODIFIER_GT ||
+               modifier == FLOWINT_MODIFIER_ISSET) {
+        flowint_user_type = DETECT_FLOWINT_TYPE_READ;
+    }
+
+    SCLogDebug("Sig %s typeval %d", sig->msg, flowint_user_type);
+
+    return flowint_user_type;
+}
+
 /**
  * \brief Returns whether the flowvar set for this rule, sets the flowvar or
  *        reads the flowvar.  If the rule sets the flowvar the function returns
@@ -268,6 +320,13 @@ static inline void SCSigProcessUserDataForFlowvar(SCSigSignatureWrapper *sw)
     return;
 }
 
+static inline void SCSigProcessUserDataForFlowint(SCSigSignatureWrapper *sw)
+{
+    *((int *)(sw->user[SC_RADIX_USER_DATA_FLOWINT])) = SCSigGetFlowintType(sw->sig);
+
+    return;
+}
+
 /**
  * \brief Processes the pktvar data for this signature and caches it for
  *        future use.  This is needed to optimize the sig_ordering module.
@@ -719,6 +778,109 @@ static void SCSigOrderByPktvar(DetectEngineCtx *de_ctx,
     return;
 }
 
+static void SCSigOrderByFlowint(DetectEngineCtx *de_ctx,
+                                SCSigSignatureWrapper *sw)
+{
+    SCSigSignatureWrapper *min = NULL;
+    SCSigSignatureWrapper *max = NULL;
+    SCSigSignatureWrapper *prev = NULL;
+
+    if (sw == NULL)
+        return;
+
+    if (de_ctx->sc_sig_sig_wrapper == NULL) {
+        de_ctx->sc_sig_sig_wrapper = sw;
+        sw->min = NULL;
+        sw->max = NULL;
+        return;
+    }
+
+    min = sw->min;
+    max = sw->max;
+    if (min == NULL)
+        min = de_ctx->sc_sig_sig_wrapper;
+    else
+        min = min->next;
+
+    while (min != max) {
+        prev = min;
+        /* the sorting logic */
+        if ( *((int *)(sw->user[SC_RADIX_USER_DATA_FLOWINT])) <=
+             *((int *)(min->user[SC_RADIX_USER_DATA_FLOWINT])) ) {
+            min = min->next;
+            continue;
+        }
+
+        if (min->prev == sw)
+            break;
+
+        if (sw->next != NULL)
+            sw->next->prev = sw->prev;
+        if (sw->prev != NULL)
+            sw->prev->next = sw->next;
+        if (de_ctx->sc_sig_sig_wrapper == sw)
+            de_ctx->sc_sig_sig_wrapper = sw->next;
+
+        sw->next = min;
+        sw->prev = min->prev;
+
+        if (min->prev != NULL)
+            min->prev->next = sw;
+        else
+            de_ctx->sc_sig_sig_wrapper = sw;
+
+        min->prev = sw;
+
+        break;
+    }
+
+    if (min == max && prev != sw) {
+        if (sw->next != NULL) {
+            sw->next->prev = sw->prev;
+        }
+        if (sw->prev != NULL) {
+            sw->prev->next = sw->next;
+        }
+
+        if (min == NULL) {
+            if (prev != NULL)
+                prev->next = sw;
+            sw->prev = prev;
+            sw->next = NULL;
+        } else {
+            sw->prev = min->prev;
+            sw->next = min;
+            if (min->prev != NULL)
+                min->prev->next = sw;
+            min->prev = sw;
+        }
+    }
+
+    /* set the min signature for this keyword, for the next ordering function */
+    min = sw;
+    while (min != NULL && min != sw->min) {
+        if ( *((int *)(sw->user[SC_RADIX_USER_DATA_FLOWINT])) !=
+             *((int *)(min->user[SC_RADIX_USER_DATA_FLOWINT])) )
+            break;
+
+        min = min->prev;
+    }
+    sw->min = min;
+
+    /* set the max signature for this keyword + 1, for the next ordering func */
+    max = sw;
+    while (max != NULL && max != sw->max) {
+        if ( *((int *)(sw->user[SC_RADIX_USER_DATA_FLOWINT])) !=
+             *((int *)(max->user[SC_RADIX_USER_DATA_FLOWINT])) )
+            break;
+
+        max = max->next;
+    }
+    sw->max = max;
+
+    return;
+}
+
 /**
  * \brief Orders an incoming Signature based on its priority type
  *
@@ -862,6 +1024,7 @@ static inline SCSigSignatureWrapper *SCSigAllocSignatureWrapper(Signature *sig)
      * sig_ordering module */
     SCSigProcessUserDataForFlowbits(sw);
     SCSigProcessUserDataForFlowvar(sw);
+    SCSigProcessUserDataForFlowint(sw);
     SCSigProcessUserDataForPktvar(sw);
 
     return sw;
@@ -939,6 +1102,7 @@ void SCSigRegisterSignatureOrderingFuncs(DetectEngineCtx *de_ctx)
 
     SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByAction);
     SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbits);
+    SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowint);
     SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvar);
     SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvar);
     SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriority);
index 43d0384c04567672f7485017b1304a379b41c3d0..030a19656d34621934043e493c9af4c2b653717c 100644 (file)
@@ -32,6 +32,7 @@ typedef enum{
     SC_RADIX_USER_DATA_FLOWBITS,
     SC_RADIX_USER_DATA_FLOWVAR,
     SC_RADIX_USER_DATA_PKTVAR,
+    SC_RADIX_USER_DATA_FLOWINT,
     SC_RADIX_USER_DATA_MAX
 } SCRadixUserDataType;