// depends on includes installed in framework/snort_api.h
// see framework/plugins.h
-#define BASE_API_VERSION 20
+#define BASE_API_VERSION 21
// set the reserved field to this to be future proof
#define API_RESERVED 0
class Module;
// this is the current version of the api
-#define IPSAPI_VERSION ((BASE_API_VERSION << 16) | 2)
+#define IPSAPI_VERSION ((BASE_API_VERSION << 16) | 3)
enum CursorActionType
{
BaseApi base;
RuleOptType type;
- unsigned max_per_rule; // max instances of this keyword per IPS rule
- unsigned protos; // bitmask of PROTO_BIT_* from decode_data.h
+ int max_per_rule; // max instances of this keyword per IPS rule, 0 - no limits, negative - generate a warning
+ unsigned protos; // bitmask of PROTO_BIT_* from decode_data.h
IpsOptFunc pinit;
IpsOptFunc pterm;
};
}
#endif
-
//IpsApi struct
OPT_TYPE_DETECTION, //RuleOptType
- 1, //max per rule
+ -1,//max per rule
0, //IpsOptFunc protos
nullptr, //IpsOptFunc pinit
nullptr, //IpsOptFunc pterm
mod_dtor
},
OPT_TYPE_DETECTION,
- 1, PROTO_BIT__TCP|PROTO_BIT__UDP,
+ -1, PROTO_BIT__TCP|PROTO_BIT__UDP,
nullptr,
nullptr,
nullptr,
opt->init = true;
}
- if ( opt->api->max_per_rule && (++opt->count > opt->api->max_per_rule) )
+ unsigned max = std::abs(opt->api->max_per_rule);
+ if ( max && (++opt->count > max) )
{
- ParseError("%s allowed only %u time(s) per rule",
- opt->api->base.name, opt->api->max_per_rule);
- return false;
+ if ( opt->api->max_per_rule > 0 )
+ {
+ ParseError("%s allowed only %u time(s) per rule", opt->api->base.name, max);
+ return false;
+ }
+
+ bool is_first_excessive_opt = (opt->count - max) == 1;
+ if ( is_first_excessive_opt )
+ ParseWarning(WARN_RULES, "for best performance, all %s options could be consolidated",
+ opt->api->base.name);
}
// FIXIT-M allow service too