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;
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" */
#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 */
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));
}
}
}
+ 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;