]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Add dsize check to prefilter stage
authorVictor Julien <victor@inliniac.net>
Sat, 6 Oct 2012 18:00:22 +0000 (20:00 +0200)
committerVictor Julien <victor@inliniac.net>
Mon, 8 Oct 2012 08:45:52 +0000 (10:45 +0200)
Many sigs with dsize have a weak fast_pattern. Those patterns
are likely to match. By filtering on dsize early, we safe a lot
of cycles later.

src/detect.c
src/detect.h

index 834ecf5d1cd1c13c36f3bb90c2d707db7f028f90..692f62fa11a8de269724c13764d964ebe7f977a5 100644 (file)
@@ -768,20 +768,30 @@ static inline int SigMatchSignaturesBuildMatchArrayAddSignature(DetectEngineThre
         Packet *p, SignatureHeader *s, uint16_t alproto)
 {
     /* if the sig has alproto and the session as well they should match */
-    if (s->flags & SIG_FLAG_APPLAYER && s->alproto != ALPROTO_UNKNOWN && s->alproto != alproto) {
-        if (s->alproto == ALPROTO_DCERPC) {
-            if (alproto != ALPROTO_SMB && alproto != ALPROTO_SMB2) {
-                SCLogDebug("DCERPC sig, alproto not SMB or SMB2");
+    if (likely(s->flags & SIG_FLAG_APPLAYER)) {
+        if (s->alproto != ALPROTO_UNKNOWN && s->alproto != alproto) {
+            if (s->alproto == ALPROTO_DCERPC) {
+                if (alproto != ALPROTO_SMB && alproto != ALPROTO_SMB2) {
+                    SCLogDebug("DCERPC sig, alproto not SMB or SMB2");
+                    return 0;
+                }
+            } else {
+                SCLogDebug("alproto mismatch");
                 return 0;
             }
-        } else {
-            SCLogDebug("alproto mismatch");
+        }
+    }
+
+    if (unlikely(s->flags & SIG_FLAG_DSIZE)) {
+        if (likely(p->payload_len < s->dsize_low || p->payload_len > s->dsize_high)) {
+            SCLogDebug("kicked out as p->payload_len %u, dsize low %u, hi %u",
+                    p->payload_len, s->dsize_low, s->dsize_high);
             return 0;
         }
     }
 
     /* check for a pattern match of the one pattern in this sig. */
-    if (s->flags & (SIG_FLAG_MPM_PACKET|SIG_FLAG_MPM_STREAM|SIG_FLAG_MPM_HTTP))
+    if (likely(s->flags & (SIG_FLAG_MPM_PACKET|SIG_FLAG_MPM_STREAM|SIG_FLAG_MPM_HTTP)))
     {
         /* filter out sigs that want pattern matches, but
          * have no matches */
@@ -2628,6 +2638,10 @@ static void SigInitStandardMpmFactoryContexts(DetectEngineCtx *de_ctx)
     return;
 }
 
+/** \brief get max dsize "depth"
+ *  \param s signature to get dsize value from
+ *  \retval depth or negative value
+ */
 static int SigParseGetMaxDsize(Signature *s) {
     if (s->flags & SIG_FLAG_DSIZE && s->dsize_sm != NULL) {
         DetectDsizeData *dd = (DetectDsizeData *)s->dsize_sm->ctx;
@@ -2646,18 +2660,55 @@ static int SigParseGetMaxDsize(Signature *s) {
     SCReturnInt(-1);
 }
 
+/** \brief set prefilter dsize pair
+ *  \param s signature to get dsize value from
+ */
+static void SigParseSetDsizePair(Signature *s) {
+    if (s->flags & SIG_FLAG_DSIZE && s->dsize_sm != NULL) {
+        DetectDsizeData *dd = (DetectDsizeData *)s->dsize_sm->ctx;
+
+        uint16_t low = 0;
+        uint16_t high = 65535;
+
+        switch (dd->mode) {
+            case DETECTDSIZE_LT:
+                low = 0;
+                high = dd->dsize;
+                break;
+            case DETECTDSIZE_EQ:
+                low = dd->dsize;
+                high = dd->dsize;
+                break;
+            case DETECTDSIZE_RA:
+                low = dd->dsize;
+                high = dd->dsize2;
+                break;
+            case DETECTDSIZE_GT:
+                low = dd->dsize;
+                high = 65535;
+                break;
+        }
+        s->dsize_low = low;
+        s->dsize_high = high;
+
+        SCLogDebug("low %u, high %u", low, high);
+    }
+}
+
 /**
  *  \brief Apply dsize as depth to content matches in the rule
+ *  \param s signature to get dsize value from
  */
-static int SigParseApplyDsizeToContent(Signature *s) {
+static void SigParseApplyDsizeToContent(Signature *s) {
     SCEnter();
 
     if (s->flags & SIG_FLAG_DSIZE) {
-        int dsize = SigParseGetMaxDsize(s);
+        SigParseSetDsizePair(s);
 
+        int dsize = SigParseGetMaxDsize(s);
         if (dsize < 0) {
             /* nothing to do */
-            return 0;
+            return;
         }
 
         SigMatch *sm = s->sm_lists[DETECT_SM_LIST_PMATCH];
@@ -2678,8 +2729,6 @@ static int SigParseApplyDsizeToContent(Signature *s) {
             }
         }
     }
-
-    SCReturnInt(0);
 }
 
 /**
index 545d05674aadbb8a302b40a17086a53d4805de60..7b0eb7841fcc5851489f57c0627628e021e9fda7 100644 (file)
@@ -322,30 +322,26 @@ typedef struct SignatureHeader_ {
     union {
         struct {
             uint32_t flags;
-            uint16_t mpm_pattern_id_div_8;
-            uint8_t mpm_pattern_id_mod_8;
-            SignatureMask mask;
+            uint16_t alproto;
+            uint16_t dsize_low;
         };
         uint64_t hdr_copy1;
     };
     union {
         struct {
-            uint16_t alproto;
-            SigIntId num; /**< signature number, internal id */
+            uint16_t dsize_high;
+            uint16_t mpm_pattern_id_div_8;
         };
         uint32_t hdr_copy2;
     };
     union {
         struct {
-            SigIntId order_id;
-
-            /** inline -- action */
-            uint8_t action;
-            uint8_t file_flags;
+            uint8_t mpm_pattern_id_mod_8;
+            SignatureMask mask;
+            SigIntId num; /**< signature number, internal id */
         };
         uint32_t hdr_copy3;
     };
-
     /** pointer to the full signature */
     struct Signature_ *full_sig;
 } SignatureHeader;
@@ -364,67 +360,60 @@ typedef struct Signature_ {
     union {
         struct {
             uint32_t flags;
-            uint16_t mpm_pattern_id_div_8;
-            uint8_t mpm_pattern_id_mod_8;
-            SignatureMask mask;
+            uint16_t alproto;
+            uint16_t dsize_low;
         };
         uint64_t hdr_copy1;
     };
     union {
         struct {
-            uint16_t alproto;
-            SigIntId num; /**< signature number, internal id */
+            uint16_t dsize_high;
+            uint16_t mpm_pattern_id_div_8;
         };
         uint32_t hdr_copy2;
     };
     union {
         struct {
-            SigIntId order_id;
-
-            /** inline -- action */
-            uint8_t action;
-            uint8_t file_flags;
+            uint8_t mpm_pattern_id_mod_8;
+            SignatureMask mask;
+            SigIntId num; /**< signature number, internal id */
         };
         uint32_t hdr_copy3;
     };
 
-    /* the fast pattern added from this signature */
-    SigMatch *mpm_sm;
+    SigIntId order_id;
+
+    /** inline -- action */
+    uint8_t action;
+    uint8_t file_flags;
 
     /** ipv4 match arrays */
-    DetectMatchAddressIPv4 *addr_dst_match4;
     uint16_t addr_dst_match4_cnt;
-    DetectMatchAddressIPv4 *addr_src_match4;
     uint16_t addr_src_match4_cnt;
+    DetectMatchAddressIPv4 *addr_dst_match4;
+    DetectMatchAddressIPv4 *addr_src_match4;
     /** ipv6 match arrays */
     DetectMatchAddressIPv6 *addr_dst_match6;
-    uint16_t addr_dst_match6_cnt;
     DetectMatchAddressIPv6 *addr_src_match6;
+    uint16_t addr_dst_match6_cnt;
     uint16_t addr_src_match6_cnt;
 
+    uint32_t id;  /**< sid, set by the 'sid' rule keyword */
     /** port settings for this signature */
     DetectPort *sp, *dp;
 
     /** addresses, ports and proto this sig matches on */
     DetectProto proto;
 
+    /** classification id **/
+    uint8_t class;
+    uint32_t gid; /**< generator id */
+
     /** netblocks and hosts specified at the sid, in CIDR format */
     IPOnlyCIDRItem *CidrSrc, *CidrDst;
 
-    /* helper for init phase */
-    uint16_t mpm_content_maxlen;
-    uint16_t mpm_uricontent_maxlen;
-
-    /** number of sigmatches in the match and pmatch list */
-    uint16_t sm_cnt;
-
-    uint32_t id;  /**< sid, set by the 'sid' rule keyword */
-    uint32_t gid; /**< generator id */
     uint32_t rev;
 
-    /** classification id **/
-    uint8_t class;
-
     int prio;
 
     char *msg;
@@ -453,8 +442,16 @@ typedef struct Signature_ {
 
     /* used to hold flags that are predominantly used during init */
     uint32_t init_flags;
+    /** number of sigmatches in the match and pmatch list */
+    uint16_t sm_cnt;
 
     SigMatch *dsize_sm;
+    /* the fast pattern added from this signature */
+    SigMatch *mpm_sm;
+    /* helper for init phase */
+    uint16_t mpm_content_maxlen;
+    uint16_t mpm_uricontent_maxlen;
+
 
     /** ptr to the next sig in the list */
     struct Signature_ *next;