]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
update pmp to return whole set of matches, rather than a single match.
authorAnoop Saldanha <anoopsaldanha@gmail.com>
Sat, 3 Aug 2013 19:22:45 +0000 (00:52 +0530)
committerAnoop Saldanha <anoopsaldanha@gmail.com>
Sun, 29 Sep 2013 17:43:07 +0000 (23:13 +0530)
src/app-layer-detect-proto.c
src/app-layer-detect-proto.h

index 231c8f767395c70128de5952325983e8e2232aa9..367de788ba68a67033f50deffa3b35bdb2308eaa 100644 (file)
@@ -354,14 +354,18 @@ void AppLayerDetectProtoThreadInit(void) {
  *  \param buflen Lenght of the buffer
  *  \param flags Flags.
  *
- *  \retval proto App Layer proto, or ALPROTO_UNKNOWN if unknown
+ *  \retval pm_matches Returns the no of alproto matches.
  */
 uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *ctx,
                                         AlpProtoDetectThreadCtx *tctx,
                                         uint8_t *buf, uint16_t buflen,
-                                        uint8_t flags, uint8_t ipproto) {
+                                        uint8_t flags, uint8_t ipproto,
+                                        uint16_t *pm_results) {
     SCEnter();
 
+    uint16_t pm_matches = 0;
+    pm_results[0] = ALPROTO_UNKNOWN;
+
     AlpProtoDetectDirection *dir;
     AlpProtoDetectDirectionThread *tdir;
 
@@ -374,7 +378,7 @@ uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *ctx,
     }
 
     if (dir->id == 0) {
-        SCReturnUInt(ALPROTO_UNKNOWN);
+        SCReturnUInt(pm_matches);
     }
 
     /* see if we can limit the data we inspect */
@@ -382,39 +386,33 @@ uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *ctx,
     if (searchlen > dir->max_len)
         searchlen = dir->max_len;
 
-    uint16_t proto = ALPROTO_UNKNOWN;
-    uint32_t cnt = 0;
+    uint32_t search_cnt = 0;
 
     /* do the mpm search */
-    cnt = mpm_table[dir->mpm_ctx.mpm_type].Search(&dir->mpm_ctx,
-                                                &tdir->mpm_ctx,
-                                                &tdir->pmq, buf,
-                                                searchlen);
-    SCLogDebug("search cnt %" PRIu32 "", cnt);
-    if (cnt == 0) {
-        proto = ALPROTO_UNKNOWN;
-        goto end;
-    }
-
-    /* We just work with the first match */
-    uint16_t patid = tdir->pmq.pattern_id_array[0];
-    SCLogDebug("array count is %"PRIu32" patid %"PRIu16"",
-            tdir->pmq.pattern_id_array_cnt, patid);
-
-    AlpProtoSignature *s = ctx->map[patid];
-    if (s == NULL) {
+    search_cnt = mpm_table[dir->mpm_ctx.mpm_type].Search(&dir->mpm_ctx,
+                                                         &tdir->mpm_ctx,
+                                                         &tdir->pmq, buf,
+                                                         searchlen);
+    SCLogDebug("search cnt %" PRIu32 "", search_cnt);
+    if (search_cnt == 0)
         goto end;
-    }
-    uint8_t s_cnt = 1;
-
-    while (proto == ALPROTO_UNKNOWN && s != NULL) {
-        proto = AlpProtoMatchSignature(s, buf, buflen, ipproto);
 
-        s = s->map_next;
-        if (s == NULL && s_cnt < tdir->pmq.pattern_id_array_cnt) {
-            patid = tdir->pmq.pattern_id_array[s_cnt];
-            s = ctx->map[patid];
-            s_cnt++;
+    /* alproto bit field */
+    uint8_t pm_results_bf[ALPROTO_MAX / 8];
+    memset(pm_results_bf, 0, sizeof(pm_results_bf));
+
+    for (uint8_t s_cnt = 0; s_cnt < search_cnt; s_cnt++) {
+        AlpProtoSignature *s = ctx->map[tdir->pmq.pattern_id_array[s_cnt]];
+        SCLogDebug("array count is %"PRIu32" patid %"PRIu16"",
+                   tdir->pmq.pattern_id_array_cnt,
+                   tdir->pmq.pattern_id_array[s_cnt]);
+        while (s != NULL) {
+            uint16_t proto = AlpProtoMatchSignature(s, buf, buflen, ipproto);
+            if (proto != ALPROTO_UNKNOWN && !(pm_results_bf[proto / 8] & (1 << (proto % 8))) ) {
+                pm_results[pm_matches++] = proto;
+                pm_results_bf[proto / 8] |= 1 << (proto % 8);
+            }
+            s = s->map_next;
         }
     }
 
@@ -479,7 +477,7 @@ end:
             break;
     }
 #endif
-    SCReturnUInt(proto);
+    SCReturnUInt(pm_matches);
 }
 
 /**
@@ -581,8 +579,6 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx,
                                 uint8_t *buf, uint32_t buflen,
                                 uint8_t flags, uint8_t ipproto)
 {
-    uint16_t alproto = ALPROTO_UNKNOWN;
-
     if (flags & STREAM_TOSERVER) {
         if (buflen >= alp_proto_ctx.toserver.max_len) {
             if (f->flags & FLOW_TS_PM_ALPROTO_DETECT_DONE) {
@@ -590,10 +586,11 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx,
                  * upto the probing parser */
                 ;
             } else {
-                alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen,
-                                                         flags, ipproto);
-                if (alproto != ALPROTO_UNKNOWN)
-                    return alproto;
+                uint16_t pm_results[ALPROTO_MAX];
+                if (AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen,
+                                                   flags, ipproto, pm_results) != 0) {
+                    return pm_results[0];
+                }
                 /* the alproto hasn't been detected at this point */
                 if (f->flags & FLOW_TS_PP_ALPROTO_DETECT_DONE) {
                     f->flags |= FLOW_TS_PM_PP_ALPROTO_DETECT_DONE;
@@ -602,10 +599,11 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx,
                 f->flags |= FLOW_TS_PM_ALPROTO_DETECT_DONE;
             }
         } else {
-            alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen,
-                                                     flags, ipproto);
-            if (alproto != ALPROTO_UNKNOWN)
-                return alproto;
+            uint16_t pm_results[ALPROTO_MAX];
+            if (AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen,
+                                               flags, ipproto, pm_results) != 0) {
+                return pm_results[0];
+            }
         }
         /* If we have reached here, the PM parser has failed to detect the
          * alproto */
@@ -618,10 +616,11 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx,
             if (f->flags & FLOW_TC_PM_ALPROTO_DETECT_DONE) {
                 ;
             } else {
-                alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen,
-                                                         flags, ipproto);
-                if (alproto != ALPROTO_UNKNOWN)
-                    return alproto;
+                uint16_t pm_results[ALPROTO_MAX];
+                if (AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen,
+                                                   flags, ipproto, pm_results) != 0) {
+                    return pm_results[0];
+                }
                 if (f->flags & FLOW_TC_PP_ALPROTO_DETECT_DONE) {
                     f->flags |= FLOW_TC_PM_PP_ALPROTO_DETECT_DONE;
                     return ALPROTO_UNKNOWN;
@@ -629,10 +628,11 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx,
                 f->flags |= FLOW_TC_PM_ALPROTO_DETECT_DONE;
             }
         } else {
-            alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen,
-                                                     flags, ipproto);
-            if (alproto != ALPROTO_UNKNOWN)
-                return alproto;
+            uint16_t pm_results[ALPROTO_MAX];
+            if (AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen,
+                                               flags, ipproto, pm_results) != 0) {
+                return pm_results[0];
+            }
         }
         return AppLayerDetectGetProtoProbingParser(ctx, f, buf, buflen,
                                                        flags, ipproto);
@@ -875,9 +875,10 @@ int AlpDetectTest05(void) {
     AlpProtoFinalizeGlobal(&ctx);
     AlpProtoFinalizeThread(&ctx, &tctx);
 
-    uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP);
-    if (proto != ALPROTO_HTTP) {
-        printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP);
+    uint16_t pm_results[ALPROTO_MAX];
+    AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
+    if (pm_results[0] != ALPROTO_HTTP) {
+        printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
         r = 0;
     }
 
@@ -921,9 +922,10 @@ int AlpDetectTest06(void) {
     AlpProtoFinalizeGlobal(&ctx);
     AlpProtoFinalizeThread(&ctx, &tctx);
 
-    uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP);
-    if (proto != ALPROTO_FTP) {
-        printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_FTP);
+    uint16_t pm_results[ALPROTO_MAX];
+    AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
+    if (pm_results[0] != ALPROTO_FTP) {
+        printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_FTP);
         r = 0;
     }
 
@@ -955,9 +957,10 @@ int AlpDetectTest07(void) {
     AlpProtoFinalizeGlobal(&ctx);
     AlpProtoFinalizeThread(&ctx, &tctx);
 
-    uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP);
-    if (proto != ALPROTO_UNKNOWN) {
-        printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_UNKNOWN);
+    uint16_t pm_results[ALPROTO_MAX];
+    AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
+    if (pm_results[0] != ALPROTO_UNKNOWN) {
+        printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_UNKNOWN);
         r = 0;
     }
 
@@ -1000,9 +1003,10 @@ int AlpDetectTest08(void) {
     AlpProtoFinalizeGlobal(&ctx);
     AlpProtoFinalizeThread(&ctx, &tctx);
 
-    uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP);
-    if (proto != ALPROTO_SMB) {
-        printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_SMB);
+    uint16_t pm_results[ALPROTO_MAX];
+    AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
+    if (pm_results[0] != ALPROTO_SMB) {
+        printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_SMB);
         r = 0;
     }
 
@@ -1042,9 +1046,10 @@ int AlpDetectTest09(void) {
     AlpProtoFinalizeGlobal(&ctx);
     AlpProtoFinalizeThread(&ctx, &tctx);
 
-    uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP);
-    if (proto != ALPROTO_SMB2) {
-        printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_SMB2);
+    uint16_t pm_results[ALPROTO_MAX];
+    AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
+    if (pm_results[0] != ALPROTO_SMB2) {
+        printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_SMB2);
         r = 0;
     }
 
@@ -1080,9 +1085,10 @@ int AlpDetectTest10(void) {
     AlpProtoFinalizeGlobal(&ctx);
     AlpProtoFinalizeThread(&ctx, &tctx);
 
-    uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP);
-    if (proto != ALPROTO_DCERPC) {
-        printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_DCERPC);
+    uint16_t pm_results[ALPROTO_MAX];
+    AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
+    if (pm_results[0] != ALPROTO_DCERPC) {
+        printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_DCERPC);
         r = 0;
     }
 
@@ -1122,15 +1128,16 @@ int AlpDetectTest11(void) {
     AlpProtoFinalizeGlobal(&ctx);
     AlpProtoFinalizeThread(&ctx, &tctx);
 
-    uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP);
-    if (proto == ALPROTO_HTTP) {
-        printf("proto %" PRIu8 " == %" PRIu8 ": ", proto, ALPROTO_HTTP);
+    uint16_t pm_results[ALPROTO_MAX];
+    AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
+    if (pm_results[0] == ALPROTO_HTTP) {
+        printf("proto %" PRIu8 " == %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
         r = 0;
     }
 
-    proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP);
-    if (proto != ALPROTO_HTTP) {
-        printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP);
+    AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP, pm_results);
+    if (pm_results[0] != ALPROTO_HTTP) {
+        printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
         r = 0;
     }
 
@@ -1211,15 +1218,16 @@ int AlpDetectTest13(void) {
     AlpProtoFinalizeGlobal(&ctx);
     AlpProtoFinalizeThread(&ctx, &tctx);
 
-    uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP);
-    if (proto == ALPROTO_HTTP) {
-        printf("proto %" PRIu8 " == %" PRIu8 ": ", proto, ALPROTO_HTTP);
+    uint16_t pm_results[ALPROTO_MAX];
+    AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
+    if (pm_results[0] == ALPROTO_HTTP) {
+        printf("proto %" PRIu8 " == %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
         r = 0;
     }
 
-    proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP);
-    if (proto == ALPROTO_HTTP) {
-        printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP);
+    AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP, pm_results);
+    if (pm_results[0] == ALPROTO_HTTP) {
+        printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
         r = 0;
     }
 
@@ -1262,15 +1270,16 @@ int AlpDetectTest14(void) {
     AlpProtoFinalizeGlobal(&ctx);
     AlpProtoFinalizeThread(&ctx, &tctx);
 
-    uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_UDP);
-    if (proto == ALPROTO_HTTP) {
-        printf("proto %" PRIu8 " == %" PRIu8 ": ", proto, ALPROTO_HTTP);
+    uint16_t pm_results[ALPROTO_MAX];
+    AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_UDP, pm_results);
+    if (pm_results[0] == ALPROTO_HTTP) {
+        printf("proto %" PRIu8 " == %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
         r = 0;
     }
 
-    proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_UDP);
-    if (proto != ALPROTO_HTTP) {
-        printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP);
+    AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_UDP, pm_results);
+    if (pm_results[0] != ALPROTO_HTTP) {
+        printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
         r = 0;
     }
 
index cfe254aca50bd5273e9c4b70b1bfc8d9851684d8..e482f0d351e46b0693eeefc8e9ab7abc00e24fa3 100644 (file)
@@ -84,10 +84,11 @@ void *AppLayerDetectProtoThread(void *td);
 
 void AppLayerDetectProtoThreadInit(void);
 
-uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *,
-                                        AlpProtoDetectThreadCtx *,
-                                        uint8_t *, uint16_t,
-                                        uint8_t, uint8_t);
+uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *ctx,
+                                        AlpProtoDetectThreadCtx *tctx,
+                                        uint8_t *buf, uint16_t buflen,
+                                        uint8_t flags, uint8_t ipproto,
+                                        uint16_t *pm_results);
 uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *, Flow *,
                                              uint8_t *, uint32_t,
                                              uint8_t, uint8_t);