diff --git a/src/RuleCondition.cc b/src/RuleCondition.cc index 40ef5f0ad1..9df70f118b 100644 --- a/src/RuleCondition.cc +++ b/src/RuleCondition.cc @@ -89,6 +89,10 @@ bool RuleConditionPayloadSize::DoMatch(Rule* rule, RuleEndpointState* state, // on the pure rules now. return false; + if ( state->PayloadSize() == 0 ) + // We are interested in the first non-empty chunk. + return false; + uint32 payload_size = uint32(state->PayloadSize()); switch ( comp ) { diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index c88bb77a4f..3ee7306fb5 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -144,7 +144,7 @@ bool RuleHdrTest::operator==(const RuleHdrTest& h) void RuleHdrTest::PrintDebug() { static const char* str_comp[] = { "<=", ">=", "<", ">", "==", "!=" }; - static const char* str_prot[] = { "", "ip", "icmp", "tcp", "udp" }; + static const char* str_prot[] = { "", "ip", "ipv6", "icmp", "icmpv6", "tcp", "udp", "next", "ipsrc", "ipdst" }; fprintf(stderr, " RuleHdrTest %s[%d:%d] %s", str_prot[prot], offset, size, str_comp[comp]); @@ -1095,10 +1095,10 @@ void RuleMatcher::ExecRule(Rule* rule, RuleEndpointState* state, bool eos) void RuleMatcher::ClearEndpointState(RuleEndpointState* state) { - state->payload_size = -1; - ExecPureRules(state, 1); + state->payload_size = -1; + loop_over_list(state->matchers, j) state->matchers[j]->state->Clear(); } diff --git a/src/RuleMatcher.h b/src/RuleMatcher.h index b16a1556f9..23b7e6d731 100644 --- a/src/RuleMatcher.h +++ b/src/RuleMatcher.h @@ -72,6 +72,7 @@ extern uint32 id_to_uint(const char* id); class RuleHdrTest { public: + // Note: Adapt RuleHdrTest::PrintDebug() when changing these enums. enum Comp { LE, GE, LT, GT, EQ, NE }; enum Prot { NOPROT, IP, IPv6, ICMP, ICMPv6, TCP, UDP, NEXT, IPSrc, IPDst }; diff --git a/src/rule-parse.y b/src/rule-parse.y index 32ada02cb3..3e9c8d7ddf 100644 --- a/src/rule-parse.y +++ b/src/rule-parse.y @@ -14,7 +14,7 @@ extern void end_PS(); Rule* current_rule = 0; const char* current_rule_file = 0; -static uint8_t mask_to_len(uint32_t mask) +static uint8_t ip4_mask_to_len(uint32_t mask) { if ( mask == 0xffffffff ) return 32; @@ -23,7 +23,7 @@ static uint8_t mask_to_len(uint32_t mask) uint8_t len; for ( len = 0; len < 32 && (! (x & (1 << len))); ++len ); - return len; + return 32 - len; } %} @@ -315,7 +315,7 @@ prefix_value: TOK_IP { $$ = new IPPrefix(IPAddr(IPv4, &($1.val), IPAddr::Host), - mask_to_len($1.mask)); + ip4_mask_to_len($1.mask)); } | TOK_IP6 ; diff --git a/testing/btest/Baseline/signatures.dst-ip-cidr-v4/output b/testing/btest/Baseline/signatures.dst-ip-cidr-v4/output new file mode 100644 index 0000000000..eb07f77921 --- /dev/null +++ b/testing/btest/Baseline/signatures.dst-ip-cidr-v4/output @@ -0,0 +1,6 @@ +match, foo +match, foo +match, foo +match, foo +match, foo +match, foo diff --git a/testing/btest/Baseline/signatures.udp-payload-size/output b/testing/btest/Baseline/signatures.udp-payload-size/output new file mode 100644 index 0000000000..2ae3bbde9f --- /dev/null +++ b/testing/btest/Baseline/signatures.udp-payload-size/output @@ -0,0 +1,6 @@ +match, foo2 +match, foo2 +match, foo2 +match, foo2 +match, foo2 +match, foo2 diff --git a/testing/btest/Traces/ntp.pcap b/testing/btest/Traces/ntp.pcap new file mode 100644 index 0000000000..cc80d04afd Binary files /dev/null and b/testing/btest/Traces/ntp.pcap differ diff --git a/testing/btest/signatures/dst-ip-cidr-v4.bro b/testing/btest/signatures/dst-ip-cidr-v4.bro new file mode 100644 index 0000000000..e86a746e54 --- /dev/null +++ b/testing/btest/signatures/dst-ip-cidr-v4.bro @@ -0,0 +1,17 @@ +# @TEST-EXEC: bro -r $TRACES/ntp.pcap %INPUT >output +# @TEST-EXEC: btest-diff output + +@TEST-START-FILE a.sig +signature foo { + dst-ip == 17.0.0.0/8 + ip-proto == udp + event "match" +} +@TEST-END-FILE + +event signature_match(state: signature_state, msg: string, data: string) + { + print "match", state$sig_id; + } + +@load-sigs ./a.sig diff --git a/testing/btest/signatures/udp-payload-size.bro b/testing/btest/signatures/udp-payload-size.bro new file mode 100644 index 0000000000..efc5411feb --- /dev/null +++ b/testing/btest/signatures/udp-payload-size.bro @@ -0,0 +1,23 @@ +# @TEST-EXEC: bro -r $TRACES/ntp.pcap %INPUT >output +# @TEST-EXEC: btest-diff output + +@TEST-START-FILE a.sig +signature foo1 { + ip-proto == udp + payload-size < 1 + event "match" +} + +signature foo2 { + ip-proto == udp + payload-size > 0 + event "match" +} +@TEST-END-FILE + +event signature_match(state: signature_state, msg: string, data: string) + { + print "match", state$sig_id; + } + +@load-sigs ./a.sig