]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
sig: Add ipv6 and ipv4 to list of protocols
authorEric Leblond <eric@regit.org>
Fri, 13 Jul 2012 13:44:31 +0000 (15:44 +0200)
committerVictor Julien <victor@inliniac.net>
Mon, 3 Sep 2012 14:14:37 +0000 (16:14 +0200)
With this patch it is possible to do:
 alert ipv6 any any -> any any
or
 alert ip4 any any -> any any
to match on IPv4 or IPv6 packets.

src/detect-engine-iponly.c
src/detect-engine-proto.c
src/detect-engine-proto.h
src/detect-ipproto.c
src/detect.c

index 07887a7a9b3c6c1496d665e84d8f6d7eff0025ed..21cafc735ffe3fff339f6ff067e23972844b7191 100644 (file)
@@ -1027,6 +1027,15 @@ void IPOnlyMatchPacket(ThreadVars *tv,
                 if (bitarray & 0x01) {
                     Signature *s = de_ctx->sig_array[u * 8 + i];
 
+                    if ((s->proto.flags & DETECT_PROTO_IPV4) && !PKT_IS_IPV4(p)) {
+                        SCLogDebug("ip version didn't match");
+                        continue;
+                    }
+                    if ((s->proto.flags & DETECT_PROTO_IPV6) && !PKT_IS_IPV6(p)) {
+                        SCLogDebug("ip version didn't match");
+                        continue;
+                    }
+
                     if (DetectProtoContainsProto(&s->proto, p->proto) == 0) {
                         SCLogDebug("proto didn't match");
                         continue;
index 4af96b8c1d2d39fe750bbdc8316765b1445e18f9..952896467220c329b95e1b499ec0feac658777ea 100644 (file)
@@ -115,6 +115,16 @@ int DetectProtoParse(DetectProto *dp, char *str)
         proto = IPPROTO_SCTP;
         dp->proto[proto / 8] |= 1 << (proto % 8);
         SCLogDebug("SCTP protocol detected");
+    } else if (strcasecmp(str,"ipv4") == 0 ||
+               strcasecmp(str,"ip4") == 0 ) {
+        dp->flags |= DETECT_PROTO_IPV4;
+        memset(dp->proto, 0xff, sizeof(dp->proto));
+        SCLogDebug("IPv4 protocol detected");
+    } else if (strcasecmp(str,"ipv6") == 0 ||
+               strcasecmp(str,"ip6") == 0 ) {
+        dp->flags |= DETECT_PROTO_IPV6;
+        memset(dp->proto, 0xff, sizeof(dp->proto));
+        SCLogDebug("IPv6 protocol detected");
     } else if (strcasecmp(str,"ip") == 0 ||
                strcasecmp(str,"pkthdr") == 0) {
         /* Proto "ip" is treated as an "any" */
index d9f6a3aa06624c6b87eeeb6ec5cc41aaca1a84de..4edfe3b5333b07c0771ca070a499bdc0011c76f6 100644 (file)
 #ifndef __DETECT_PROTO_H__
 #define __DETECT_PROTO_H__
 
-#define DETECT_PROTO_ANY            0x01 /**< Indicate that given protocol
+#define DETECT_PROTO_ANY            (1 << 0) /**< Indicate that given protocol
                                               is considered as IP */
-#define DETECT_PROTO_ONLY_PKT       0x02 /**< Indicate that we only care
+#define DETECT_PROTO_ONLY_PKT       (1 << 1) /**< Indicate that we only care
                                               about packet payloads. */
-#define DETECT_PROTO_ONLY_STREAM    0x04 /**< Indicate that we only care
+#define DETECT_PROTO_ONLY_STREAM    (1 << 2) /**< Indicate that we only care
                                               about stream payloads. */
+#define DETECT_PROTO_IPV4           (1 << 3) /**< IPv4 only */
+#define DETECT_PROTO_IPV6           (1 << 4) /**< IPv6 only */
 
 typedef struct DetectProto_ {
     uint8_t proto[256/8]; /**< bit array for 256 protocol bits */
index 68d56e1ab2b97b420d7f4fd56819a56c86b4b1e3..419f2d67ba0ca0487a8859abda73ae29c58d7119 100644 (file)
@@ -226,8 +226,12 @@ static int DetectIPProtoSetup(DetectEngineCtx *de_ctx, Signature *s, char *optst
         goto error;
     }
 
-    /* reset our "any" (or "ip") state */
-    if (s->proto.flags & DETECT_PROTO_ANY) {
+    /* Reset our "any" (or "ip") state: for ipv4, ipv6 and ip cases, the bitfield
+     * s->proto.proto have all bit set to 1 to be able to match any protocols. ipproto
+     * will refined the protocol list and thus it needs to reset the bitfield to zero
+     * before setting the value specified by the ip_proto keyword.
+     */
+    if (s->proto.flags & (DETECT_PROTO_ANY | DETECT_PROTO_IPV6 | DETECT_PROTO_IPV4)) {
         s->proto.flags &= ~DETECT_PROTO_ANY;
         memset(s->proto.proto, 0x00, sizeof(s->proto.proto));
     }
index 67104d72ca67c3dadaa30493b7dc5d5f641b5f81..224f325a9e74629a20c79162b2e6b77458b2b823 100644 (file)
@@ -1641,6 +1641,15 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
             }
         }
 
+        if ((s->proto.flags & DETECT_PROTO_IPV4) && !PKT_IS_IPV4(p)) {
+            SCLogDebug("ip version didn't match");
+            goto next;
+        }
+        if ((s->proto.flags & DETECT_PROTO_IPV6) && !PKT_IS_IPV6(p)) {
+            SCLogDebug("ip version didn't match");
+            goto next;
+        }
+
         if (DetectProtoContainsProto(&s->proto, IP_GET_IPPROTO(p)) == 0) {
             SCLogDebug("proto didn't match");
             goto next;