#define ACTION_DROP_REJECT (ACTION_REJECT_ANY | ACTION_DROP)
+enum ActionScope {
+ ACTION_SCOPE_AUTO = 0,
+ ACTION_SCOPE_PACKET, /**< apply action to packet */
+ ACTION_SCOPE_FLOW, /**< apply drop/pass/accept action to flow */
+};
+
#endif /* SURICATA_ACTION_GLOBALS_H */
DEBUG_VALIDATE_BUG_ON(s->type == SIG_TYPE_NOT_SET);
DEBUG_VALIDATE_BUG_ON(s->type == SIG_TYPE_MAX);
- enum SignaturePropertyFlowAction flow_action = signature_properties[s->type].flow_action;
- if (flow_action == SIG_PROP_FLOW_ACTION_FLOW) {
+ if (s->action_scope == ACTION_SCOPE_FLOW) {
pa->flags |= PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW;
- } else if (flow_action == SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL) {
- if (pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH | PACKET_ALERT_FLAG_STREAM_MATCH)) {
+ } else if (s->action_scope == ACTION_SCOPE_AUTO) {
+ enum SignaturePropertyFlowAction flow_action =
+ signature_properties[s->type].flow_action;
+ if (flow_action == SIG_PROP_FLOW_ACTION_FLOW) {
pa->flags |= PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW;
+ } else if (flow_action == SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL) {
+ if (pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH | PACKET_ALERT_FLAG_STREAM_MATCH)) {
+ pa->flags |= PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW;
+ }
}
}
SCJbAppendString(ctx.js, "pass");
}
SCJbClose(ctx.js);
- enum SignaturePropertyFlowAction flow_action = signature_properties[s->type].flow_action;
- switch (flow_action) {
- case SIG_PROP_FLOW_ACTION_PACKET:
- SCJbSetString(ctx.js, "scope", "packet");
- break;
- case SIG_PROP_FLOW_ACTION_FLOW:
- SCJbSetString(ctx.js, "scope", "flow");
- break;
- case SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL:
- SCJbSetString(ctx.js, "scope", "flow_if_stateful");
- break;
+
+ if (s->action_scope == ACTION_SCOPE_AUTO) {
+ enum SignaturePropertyFlowAction flow_action = signature_properties[s->type].flow_action;
+ switch (flow_action) {
+ case SIG_PROP_FLOW_ACTION_PACKET:
+ SCJbSetString(ctx.js, "scope", "packet");
+ break;
+ case SIG_PROP_FLOW_ACTION_FLOW:
+ SCJbSetString(ctx.js, "scope", "flow");
+ break;
+ case SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL:
+ SCJbSetString(ctx.js, "scope", "flow_if_stateful");
+ break;
+ }
+ } else {
+ enum ActionScope as = s->action_scope;
+ switch (as) {
+ case ACTION_SCOPE_PACKET:
+ SCJbSetString(ctx.js, "scope", "packet");
+ break;
+ case ACTION_SCOPE_FLOW:
+ SCJbSetString(ctx.js, "scope", "flow");
+ break;
+ case ACTION_SCOPE_AUTO: /* should be unreachable */
+ break;
+ }
}
SCJbClose(ctx.js);
}
s->init_data->hook.sm_list = list;
- SCLogNotice("protocol:%s hook:%s: type:%s alproto:%u hook:%d", p, h,
+ SCLogDebug("protocol:%s hook:%s: type:%s alproto:%u hook:%d", p, h,
SignatureHookTypeToString(s->init_data->hook.type), s->init_data->hook.t.app.alproto,
s->init_data->hook.t.app.app_progress);
return 0;
* Signature.
* \retval -1 On failure.
*/
-static int SigParseAction(Signature *s, const char *action)
+static int SigParseAction(Signature *s, const char *action_in)
{
- uint8_t flags = ActionStringToFlags(action);
+ char action[32];
+ strlcpy(action, action_in, sizeof(action));
+ const char *a = action;
+ const char *o = NULL;
+
+ bool has_scope = strchr(action, ':') != NULL;
+ if (has_scope) {
+ char *xsaveptr = NULL;
+ a = strtok_r(action, ":", &xsaveptr);
+ o = strtok_r(NULL, ":", &xsaveptr);
+ SCLogDebug("a: '%s' o: '%s'", a, o);
+ }
+ if (a == NULL) {
+ SCLogError("invalid protocol specification '%s'", action_in);
+ return -1;
+ }
+
+ uint8_t flags = ActionStringToFlags(a);
if (flags == 0)
return -1;
+ /* parse scope, if any */
+ if (o) {
+ uint8_t scope_flags = 0;
+ if (flags & (ACTION_DROP | ACTION_PASS)) {
+ if (strcmp(o, "packet") == 0) {
+ scope_flags = (uint8_t)ACTION_SCOPE_PACKET;
+ } else if (strcmp(o, "flow") == 0) {
+ scope_flags = (uint8_t)ACTION_SCOPE_FLOW;
+ } else {
+ SCLogError("invalid action scope '%s' in action '%s': only 'packet' and 'flow' "
+ "allowed",
+ o, action_in);
+ return -1;
+ }
+ s->action_scope = scope_flags;
+ } else {
+ SCLogError("invalid action scope '%s' in action '%s': scope only supported for actions "
+ "'drop', 'pass' and 'reject'",
+ o, action_in);
+ return -1;
+ }
+ }
+
s->action = flags;
return 0;
}
/** addresses, ports and proto this sig matches on */
DetectProto proto;
+ /* scope setting for the action: enum ActionScope */
+ uint8_t action_scope;
+
/** ipv4 match arrays */
uint16_t addr_dst_match4_cnt;
uint16_t addr_src_match4_cnt;