void ReplaceAction::exec(Packet* p, const OptTreeNode* otn)
{
+ p->active->rewrite_packet(p);
+
Actions::alert(p, otn);
}
event.ref_time.tv_sec = p->pkth->ts.tv_sec;
event.ref_time.tv_usec = p->pkth->ts.tv_usec;
event.update_event_id_and_ref(p->context->conf->get_event_log_id());
+ if (head and head->ruleListNode)
+ event.action_string = head->ruleListNode->name;
DetectionEngine::set_check_tags(false);
pc.log_pkts++;
event.ref_time.tv_sec = p->pkth->ts.tv_sec;
event.ref_time.tv_usec = p->pkth->ts.tv_usec;
event.update_event_id_and_ref(p->context->conf->get_event_log_id());
+ if (head and head->ruleListNode)
+ event.action_string = head->ruleListNode->name;
pc.total_alert_pkts++;
void Event::set_event(uint32_t gid, uint32_t sid, uint32_t rev,
uint32_t classification, uint32_t priority, uint16_t event_ref,
- uint16_t log_id, const struct timeval& tv)
+ uint16_t log_id, const struct timeval& tv, const std::string& act)
{
sig_info->gid = gid;
sig_info->sid = sid;
ref_time.tv_sec = tv.tv_sec;
ref_time.tv_usec = tv.tv_usec;
+ action_string = act;
}
SigInfo* sig_info = nullptr;
struct sf_timeval32 ref_time = { 0, 0 }; /* reference time for the event reference */
const char* alt_msg = nullptr;
+ std::string action_string;
Event() = default;
Event(SigInfo& si)
void set_event(uint32_t gid, uint32_t sid, uint32_t rev,
uint32_t classification, uint32_t priority, uint16_t event_ref,
- uint16_t log_id, const struct timeval& tv);
+ uint16_t log_id, const struct timeval& tv, const std::string& act = "");
private:
if ( act->session_was_blocked() ||
(p->flow && (p->flow->flow_state == Flow::FlowState::BLOCK)) )
{
- if ( !act->can_block() )
+ if ( !act->can_act() )
verdict = DAQ_VERDICT_PASS;
else if ( act->get_tunnel_bypass() )
{
}
// Second Pass, now with more side effects
- if ( act->packet_was_dropped() && act->can_block() )
+ if ( act->packet_was_dropped() && act->can_act() )
{
if ( verdict == DAQ_VERDICT_PASS )
verdict = DAQ_VERDICT_BLOCK;
int SFDAQ::inject(DAQ_Msg_h, int, const uint8_t*, uint32_t) { return -1; }
bool SFDAQ::can_inject() { return false; }
bool SFDAQ::can_inject_raw() { return false; }
+bool SFDAQ::can_replace() { return false; }
int SFDAQInstance::set_packet_verdict_reason(DAQ_Msg_h, uint8_t) { return 0; }
DetectionEngine::DetectionEngine() = default;
DetectionEngine::~DetectionEngine() = default;
{ "allow", "error", "error", "error" },
{ "hold", "error", "error", "error" },
{ "retry", "error", "error", "error" },
+ { "rewrite", "cant_rewrite", "would_rewrite", "force_rewrite" },
{ "drop", "cant_drop", "would_drop", "force_drop" },
{ "block", "cant_block", "would_block", "force_block" },
{ "reset", "cant_reset", "would_reset", "force_reset" },
active_status = AST_WOULD;
active_would_reason = WHD_INTERFACE_IDS;
}
+ else if ( active_action == ACT_REWRITE and !SFDAQ::can_replace() )
+ {
+ active_status = AST_WOULD;
+ active_would_reason = WHD_INTERFACE_IDS;
+ }
}
else if ( p->context->conf->inline_test_mode() )
{
else if ( force )
active_status = AST_FORCE;
else if ( active_status != AST_FORCE )
- {
update_status_actionable(p);
- }
}
void Active::daq_update_status(const Packet* p)
daq_update_status(p);
}
+void Active::rewrite_packet(const Packet* p, bool force)
+{
+ if ( active_action < ACT_REWRITE )
+ active_action = ACT_REWRITE;
+
+ update_status(p, force);
+}
+
bool Active::retry_packet(const Packet* p)
{
if (ACT_RETRY == active_action)
if ( reason != -1 )
p.daq_instance->set_packet_verdict_reason(p.daq_msg, reason);
}
-
// apply_delayed_action, in a big switch(action). Do away with these and
// use the actual (Base)Action objects.
enum ActiveActionType : uint8_t
- { ACT_TRUST, ACT_ALLOW, ACT_HOLD, ACT_RETRY, ACT_DROP, ACT_BLOCK, ACT_RESET, ACT_MAX };
+ { ACT_TRUST, ACT_ALLOW, ACT_HOLD, ACT_RETRY, ACT_REWRITE, ACT_DROP, ACT_BLOCK, ACT_RESET, ACT_MAX };
public:
void kill_session(Packet*, EncodeFlags = ENC_FLAG_FWD);
- bool can_block() const
+ bool can_act() const
{ return active_status == AST_ALLOW or active_status == AST_FORCE; }
const char* get_action_string() const
void drop_packet(const Packet*, bool force = false);
void daq_drop_packet(const Packet*);
+ void rewrite_packet(const Packet*, bool force = false);
bool retry_packet(const Packet*);
bool hold_packet(const Packet*);
void cancel_packet_hold();
table.get_field("event_reference", value);
self.set_event_reference(value);
- const char* s = nullptr;
- if ( table.get_field("alt_msg", s) && s ) // FIXIT-L shouldn't need both conditions
+ const char* s_alt_msg = nullptr;
+ if ( table.get_field("alt_msg", s_alt_msg) && s_alt_msg ) // FIXIT-L shouldn't need both conditions
{
- self.alt_msg = RawBufferIface.create(L, s).c_str();
+ self.alt_msg = RawBufferIface.create(L, s_alt_msg).c_str();
Lua::add_ref(L, &self, "alt_msg", lua_gettop(L));
lua_pop(L, 1);
}
+
+ const char* s_action_string = nullptr;
+ // FIXIT-L shouldn't need both conditions
+ if ( table.get_field("action_string", s_action_string) && s_action_string )
+ {
+ self.action_string = RawBufferIface.create(L, s_action_string);
+ Lua::add_ref(L, &self, "action_string", lua_gettop(L));
+ lua_pop(L, 1);
+ }
}
static void get_fields(lua_State* L, int tindex, Event& self)
if ( self.alt_msg )
table.set_field("alt_msg", self.alt_msg);
+
+ if ( !self.action_string.empty() )
+ table.set_field("action_string", self.action_string);
}
static const luaL_Reg methods[] =
static const char* get_action(uint8_t act)
{
- const char* acts[] = { "trust", "pass", "hold", "retry", "drop", "block", "reset" };
+ const char* acts[] = { "trust", "pass", "hold", "retry", "rewrite", "drop", "block", "reset" };
return lookup(acts, sizeof(acts)/sizeof(acts[0]), act);
}