From 3688aa2a76959373199d1452ff80091e6b9fe20a Mon Sep 17 00:00:00 2001
From: Eric Leblond <eric@regit.org>
Date: Fri, 13 Jul 2012 15:44:31 +0200
Subject: [PATCH 1/2] sig: Add ipv6 and ipv4 to list of protocols

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 |    9 +++++++++
 src/detect-engine-proto.c  |   10 ++++++++++
 src/detect-engine-proto.h  |    8 +++++---
 src/detect.c               |    9 +++++++++
 4 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/src/detect-engine-iponly.c b/src/detect-engine-iponly.c
index 07887a7..21cafc7 100644
--- a/src/detect-engine-iponly.c
+++ b/src/detect-engine-iponly.c
@@ -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;
diff --git a/src/detect-engine-proto.c b/src/detect-engine-proto.c
index 4af96b8..9528964 100644
--- a/src/detect-engine-proto.c
+++ b/src/detect-engine-proto.c
@@ -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" */
diff --git a/src/detect-engine-proto.h b/src/detect-engine-proto.h
index d9f6a3a..097e614 100644
--- a/src/detect-engine-proto.h
+++ b/src/detect-engine-proto.h
@@ -24,12 +24,14 @@
 #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 */
diff --git a/src/detect.c b/src/detect.c
index 920f3b0..ed7884e 100644
--- a/src/detect.c
+++ b/src/detect.c
@@ -1617,6 +1617,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;
-- 
1.7.10.4

