Merge in SNORT/snort3 from ~ANOROKH/snort3:extr_notice_event to master
Squashed commit of the following:
commit
da9709af1b8edb7090a783471a78181ad880af28
Author: anorokh <anorokh@cisco.com>
Date: Tue Jun 10 12:59:25 2025 +0300
extractor: add context logging event for notice
** 'builtin' (internally-detected infraction is queued for further processing)
* triggered IPS rule, whether built-in or text or SO (notice)
** `ips_logging` (matched rules sent to IPS logging)
+ ** `context_logging` (matched rule in an IPS logger)
Common fields available for every service:
TCP Connection States:
The TCP connection state tracks both client and server states, each prefixed with CLT_ (for the client) and SRV_ (for the server).
-These states follow the TCP state machine as defined by the RFC, with the addition of TCP_MID_STREAM_SENT and TCP_MID_STREAM_REC to handle mid-stream traffic and TCP_STATE_NONE.
+These states follow the TCP state machine as defined by the RFC, with the addition of TCP_MID_STREAM_SENT
+and TCP_MID_STREAM_REC to handle mid-stream traffic and TCP_STATE_NONE.
OTH (Other Traffic):
The OTH state is used for all non-UDP and non-TCP traffic, as well as for error cases.
-* `history` - a string that tracks the connection's history. It uses letters to represent events, with uppercase letters denoting client-side events and lowercase letters for server-side events. Each letter appears only once for each direction, regardless of how many times the event occurs.
+* `history` - a string that tracks the connection's history. It uses letters to represent events, with
+uppercase letters denoting client-side events and lowercase letters for server-side events.
+Each letter appears only once for each direction, regardless of how many times the event occurs.
UDP Events: d: Packet with payload.
THREAD_LOCAL const snort::Connector::ID* IpsUserExtractor::log_id = nullptr;
-IpsUserExtractor::IpsUserExtractor(Extractor& i, uint32_t t, const vector<string>& fields)
+IpsUserExtractor::IpsUserExtractor(Extractor& i, uint32_t t, const vector<string>& fields, bool contextual)
: ExtractorEvent(ServiceType::IPS_USER, i, t)
{
for (const auto& f : fields)
continue;
}
- DataBus::subscribe_global(de_pub_key, DetectionEventIds::IPS_LOGGING, new IpsUser(*this, S_NAME), i.get_snort_config());
+ auto event = contextual ? DetectionEventIds::CONTEXT_LOGGING : DetectionEventIds::IPS_LOGGING;
+ DataBus::subscribe_global(de_pub_key, event, new IpsUser(*this, S_NAME), i.get_snort_config());
}
void IpsUserExtractor::internal_tinit(const snort::Connector::ID* service_id)
using VecGetFn = const std::vector<const char*>& (*) (const DataEvent*, const Flow*);
using VecField = DataField<const std::vector<const char*>&, const DataEvent*, const Flow*>;
- IpsUserExtractor(Extractor&, uint32_t tenant, const std::vector<std::string>& fields);
+ IpsUserExtractor(Extractor&, uint32_t tenant, const std::vector<std::string>& fields, bool contextual);
std::vector<const char*> get_field_names() const override;
void handle(DataEvent&, Flow*);
// events
{
"ips_logging",
+ "context_logging",
},
// fields
{
{
for (const auto& event : get_events())
{
- if (!strcmp("ips_logging", event.c_str()))
- handlers.push_back(new IpsUserExtractor(ins, tenant_id, get_fields()));
+ bool contextual = !strcmp("context_logging", event.c_str());
+ if (contextual or !strcmp("ips_logging", event.c_str()))
+ handlers.push_back(new IpsUserExtractor(ins, tenant_id, get_fields(), contextual));
}
}
{
enum : unsigned
{
- IPS_LOGGING,
- BUILTIN,
+ IPS_LOGGING, // before IPS loggers invoked
+ CONTEXT_LOGGING, // in an IPS logger
+ BUILTIN, // built-in event added in the event queue
MAX
};
};