From fd7b6db22d224609617f5b3085057d83acf2ebbc Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Fri, 13 Jul 2012 15:44:31 +0200 Subject: [PATCH] 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-ipproto.c | 8 ++++++-- src/detect.c | 9 +++++++++ 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/detect-engine-iponly.c b/src/detect-engine-iponly.c index 07887a7a9b..21cafc735f 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 4af96b8c1d..9528964672 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 d9f6a3aa06..4edfe3b533 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-ipproto.c b/src/detect-ipproto.c index 68d56e1ab2..419f2d67ba 100644 --- a/src/detect-ipproto.c +++ b/src/detect-ipproto.c @@ -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)); } diff --git a/src/detect.c b/src/detect.c index 67104d72ca..224f325a9e 100644 --- a/src/detect.c +++ b/src/detect.c @@ -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;