using namespace snort;
using namespace std;
-static uint64_t get_orig_pkts(const DataEvent*, const Packet*, const Flow* f)
+static uint64_t get_orig_pkts(const DataEvent*, const Flow* f)
{
return f->flowstats.client_pkts;
}
-static uint64_t get_resp_pkts(const DataEvent*, const Packet*, const Flow* f)
+static uint64_t get_resp_pkts(const DataEvent*, const Flow* f)
{
return f->flowstats.server_pkts;
}
-static uint64_t get_duration(const DataEvent*, const Packet*, const Flow* f)
+static uint64_t get_duration(const DataEvent*, const Flow* f)
{
return f->last_data_seen - f->flowstats.start_time.tv_sec;
}
{"duration", get_duration}
};
-static const char* get_service(const DataEvent*, const Packet*, const Flow* f)
+static const char* get_service(const DataEvent*, const Flow* f)
{
SnortConfig* sc = SnortConfig::get_main_conf();
return sc->proto_ref->get_name(f->ssn_state.snort_protocol_id);
{PktType::ICMP, "ICMP"}
};
-static const char* get_proto(const DataEvent*, const Packet*, const Flow* f)
+static const char* get_proto(const DataEvent*, const Flow* f)
{
const auto& iter = pkttype_to_protocol.find(f->pkt_type);
return (iter != pkttype_to_protocol.end()) ? iter->second.c_str() : "";
if (flow->pkt_type < PktType::IP or flow->pkt_type > PktType::ICMP or !filter(flow))
return;
- Packet* packet = (DetectionEngine::get_context()) ? DetectionEngine::get_current_packet() : nullptr;
-
extractor_stats.total_event++;
logger->open_record();
- log(nts_fields, &event, packet, flow);
- log(sip_fields, &event, packet, flow);
- log(num_fields, &event, packet, flow);
- log(buf_fields, &event, packet, flow);
+ log(nts_fields, &event, flow);
+ log(sip_fields, &event, flow);
+ log(num_fields, &event, flow);
+ log(buf_fields, &event, flow);
logger->close_record(*log_id);
}
SECTION("unknown")
{
flow->pkt_type = PktType::NONE;
- const char* proto = get_proto(nullptr, nullptr, flow);
+ const char* proto = get_proto(nullptr, flow);
CHECK_FALSE(strcmp("", proto));
}
class ConnExtractor : public ExtractorEvent
{
public:
- using ConnNumGetFn = uint64_t (*) (const DataEvent*, const Packet*, const Flow*);
- using ConnNumField = DataField<uint64_t, const DataEvent*, const Packet*, const Flow*>;
+ using ConnNumGetFn = uint64_t (*) (const DataEvent*, const Flow*);
+ using ConnNumField = DataField<uint64_t, const DataEvent*, const Flow*>;
ConnExtractor(Extractor&, uint32_t tenant, const std::vector<std::string>& fields);
namespace req
{
-static pair<const char*, uint16_t> get_cmd(const DataEvent* event, const Packet*, const Flow*)
+static pair<const char*, uint16_t> get_cmd(const DataEvent* event, const Flow*)
{
const auto& req = ((const FtpRequestEvent*)event)->get_request();
return {req.cmd_begin, req.cmd_size};
}
-static pair<const char*, uint16_t> get_arg(const DataEvent* event, const Packet*, const Flow*)
+static pair<const char*, uint16_t> get_arg(const DataEvent* event, const Flow*)
{
const auto& req = ((const FtpRequestEvent*)event)->get_request();
return {req.param_begin, req.param_size};
}
-static pair<const char*, uint16_t> get_user(const DataEvent* event, const Packet*, const Flow*)
+static pair<const char*, uint16_t> get_user(const DataEvent* event, const Flow*)
{
const auto& req = ((const FtpRequestEvent*)event)->get_request();
const auto cmd = string(req.cmd_begin, req.cmd_size);
extractor_stats.total_event++;
- Packet* packet = DetectionEngine::get_current_packet();
-
logger->open_record();
- log(nts_fields, &event, packet, flow);
- log(sip_fields, &event, packet, flow);
- log(num_fields, &event, packet, flow);
- log(str_fields, &event, packet, flow, logger->is_strict());
+ log(nts_fields, &event, flow);
+ log(sip_fields, &event, flow);
+ log(num_fields, &event, flow);
+ log(str_fields, &event, flow, logger->is_strict());
logger->close_record(*log_id);
}
namespace resp
{
-static pair<const char*, uint16_t> get_code(const DataEvent* event, const Packet*, const Flow*)
+static pair<const char*, uint16_t> get_code(const DataEvent* event, const Flow*)
{
const auto& response = ((const FtpResponseEvent*)event)->get_response();
return {response.rsp_begin, response.rsp_size};
}
-static pair<const char*, uint16_t> get_msg(const DataEvent* event, const Packet*, const Flow*)
+static pair<const char*, uint16_t> get_msg(const DataEvent* event, const Flow*)
{
const auto& response = ((const FtpResponseEvent*)event)->get_response();
return {response.msg_begin, response.msg_size};
}
-static const SfIp& get_orig_ip(const DataEvent* event, const Packet*, const Flow*)
+static const SfIp& get_orig_ip(const DataEvent* event, const Flow*)
{
if (((const FtpResponseEvent*)event)->is_passive())
return ((const FtpResponseEvent*)event)->get_client_ip();
return ((const FtpResponseEvent*)event)->get_server_ip();
}
-static const SfIp& get_resp_ip(const DataEvent* event, const Packet*, const Flow*)
+static const SfIp& get_resp_ip(const DataEvent* event, const Flow*)
{
if (((const FtpResponseEvent*)event)->is_passive())
return ((const FtpResponseEvent*)event)->get_server_ip();
return ((const FtpResponseEvent*)event)->get_client_ip();
}
-static uint64_t get_resp_port(const DataEvent* event, const Packet*, const Flow*)
+static uint64_t get_resp_port(const DataEvent* event, const Flow*)
{
if (((const FtpResponseEvent*)event)->is_passive())
return (uint64_t)((const FtpResponseEvent*)event)->get_server_port();
return (uint64_t)((const FtpResponseEvent*)event)->get_client_port();
}
-static uint64_t get_file_size(const DataEvent* event, const Packet*, const Flow*)
+static uint64_t get_file_size(const DataEvent* event, const Flow*)
{
const auto& resp = ((const FtpResponseEvent*)event)->get_response();
const auto& code = string(resp.rsp_begin, resp.rsp_size);
return 0;
}
-static int8_t get_mode(const DataEvent* event, const Packet*, const Flow*)
+static int8_t get_mode(const DataEvent* event, const Flow*)
{
return ((const FtpResponseEvent*)event)->get_mode();
}
{ log_id = service_id; }
template<>
-void ExtractorEvent::log<vector<FtpResponseExtractor::SubField>, DataEvent*, Packet*, Flow*, bool>(
- const vector<FtpResponseExtractor::SubField>& fields, DataEvent* event, Packet* pkt, Flow* flow, bool strict)
+void ExtractorEvent::log<vector<FtpResponseExtractor::SubField>, DataEvent*, Flow*, bool>(
+ const vector<FtpResponseExtractor::SubField>& fields, DataEvent* event, Flow* flow, bool strict)
{
for (const auto& f : fields)
{
- const auto mode = f.get(event, pkt, flow);
+ const auto mode = f.get(event, flow);
if (mode != FTPP_XFER_NOT_SET)
mode == FTPP_XFER_PASSIVE ? logger->add_field(f.name, true) : logger->add_field(f.name, false);
else if (strict)
extractor_stats.total_event++;
- Packet* packet = DetectionEngine::get_current_packet();
-
logger->open_record();
- log(nts_fields, &event, packet, flow);
- log(sip_fields, &event, packet, flow);
- log(num_fields, &event, packet, flow);
- log(str_fields, &event, packet, flow, logger->is_strict());
- log(sub_fields, &event, packet, flow, logger->is_strict());
+ log(nts_fields, &event, flow);
+ log(sip_fields, &event, flow);
+ log(num_fields, &event, flow);
+ log(str_fields, &event, flow, logger->is_strict());
+ log(sub_fields, &event, flow, logger->is_strict());
logger->close_record(*log_id);
}
extractor_stats.total_event++;
- Packet* p = DetectionEngine::get_current_packet();
auto fd = ExtractorFlowData::get<FtpExtractorFlowData>(flow);
if (!fd)
{
// log existing flow data
owner.logger->open_record();
- owner.log(owner.nts_fields, &event, p, flow);
- owner.log(owner.sip_fields, &event, p, flow);
- owner.log(owner.num_fields, &event, p, flow);
+ owner.log(owner.nts_fields, &event, flow);
+ owner.log(owner.sip_fields, &event, flow);
+ owner.log(owner.num_fields, &event, flow);
owner.log(owner.fd_buf_fields, (const FtpExtractorFlowData*)fd);
owner.log(owner.fd_sip_fields, (const FtpExtractorFlowData*)fd);
owner.log(owner.fd_num_fields, (const FtpExtractorFlowData*)fd);
fd->cmd = cmd;
fd->arg = string(req.param_begin, req.param_size);
- fd->ts = p->pkth->ts;
+ const Packet* packet = ExtractorEvent::get_packet();
+
+ if (packet)
+ fd->ts = packet->pkth->ts;
+ else
+ snort::packet_gettimeofday(&fd->ts);
+
fd->has_data = true;
}
class FtpResponseExtractor : public ExtractorEvent
{
public:
- using SubGetFn = int8_t (*) (const DataEvent*, const Packet*, const Flow*);
- using SubField = DataField<int8_t, const DataEvent*, const Packet*, const Flow*>;
+ using SubGetFn = int8_t (*) (const DataEvent*, const Flow*);
+ using SubField = DataField<int8_t, const DataEvent*, const Flow*>;
FtpResponseExtractor(Extractor&, uint32_t tenant, const std::vector<std::string>& fields);
using namespace snort;
using namespace std;
-static const Field& get_method(const DataEvent* event, const Packet*, const Flow*)
+static const Field& get_method(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_method();
}
-static const Field& get_host(const DataEvent* event, const Packet*, const Flow*)
+static const Field& get_host(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_host_hdr();
}
-static const Field& get_user_agent(const DataEvent* event, const Packet*, const Flow*)
+static const Field& get_user_agent(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_user_agent();
}
-static const Field& get_uri(const DataEvent* event, const Packet*, const Flow*)
+static const Field& get_uri(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_uri();
}
-static const Field& get_referrer(const DataEvent* event, const Packet*, const Flow*)
+static const Field& get_referrer(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_referer_hdr();
}
-static const Field& get_origin(const DataEvent* event, const Packet*, const Flow*)
+static const Field& get_origin(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_origin_hdr();
}
-static const char* get_version(const DataEvent* event, const Packet*, const Flow*)
+static const char* get_version(const DataEvent* event, const Flow*)
{
HttpEnums::VersionId version = ((const HttpTransactionEndEvent*)event)->get_version();
const auto& iter = HttpEnums::VersionEnumToStr.find(version);
return iter != HttpEnums::VersionEnumToStr.end() ? iter->second : "";
}
-static const Field& get_stat_code(const DataEvent* event, const Packet*, const Flow*)
+static const Field& get_stat_code(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_stat_code();
}
-static const Field& get_stat_msg(const DataEvent* event, const Packet*, const Flow*)
+static const Field& get_stat_msg(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_stat_msg();
}
-static uint64_t get_trans_depth(const DataEvent* event, const Packet*, const Flow*)
+static uint64_t get_trans_depth(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_trans_depth();
}
-static uint64_t get_request_body_len(const DataEvent* event, const Packet*, const Flow*)
+static uint64_t get_request_body_len(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_request_body_len();
}
-static uint64_t get_response_body_len(const DataEvent* event, const Packet*, const Flow*)
+static uint64_t get_response_body_len(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_response_body_len();
}
-static uint64_t get_info_code(const DataEvent* event, const Packet*, const Flow*)
+static uint64_t get_info_code(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_info_code();
}
-static const Field& get_info_msg(const DataEvent* event, const Packet*, const Flow*)
+static const Field& get_info_msg(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_info_msg();
}
-static const char* get_proxied(const DataEvent* event, const Packet*, const Flow*)
+static const char* get_proxied(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_proxied().c_str();
}
-static const char* get_orig_filenames(const DataEvent* event, const Packet*, const Flow*)
+static const char* get_orig_filenames(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_filename(HttpCommon::SRC_CLIENT).c_str();
}
-static const char* get_resp_filenames(const DataEvent* event, const Packet*, const Flow*)
+static const char* get_resp_filenames(const DataEvent* event, const Flow*)
{
return ((const HttpTransactionEndEvent*)event)->get_filename(HttpCommon::SRC_SERVER).c_str();
}
{ log_id = service_id; }
template<>
-void ExtractorEvent::log<vector<HttpExtractor::SubField>, DataEvent*, Packet*, Flow*, bool>(
- const vector<HttpExtractor::SubField>& fields, DataEvent* event, Packet* pkt, Flow* flow, bool strict)
+void ExtractorEvent::log<vector<HttpExtractor::SubField>, DataEvent*, Flow*, bool>(
+ const vector<HttpExtractor::SubField>& fields, DataEvent* event, Flow* flow, bool strict)
{
for (const auto& f : fields)
{
- const auto& field = f.get(event, pkt, flow);
+ const auto& field = f.get(event, flow);
if (field.length() > 0)
logger->add_field(f.name, (const char*)field.start(), field.length());
else if (strict)
extractor_stats.total_event++;
- Packet* packet = DetectionEngine::get_current_packet();
-
logger->open_record();
- log(nts_fields, &event, packet, flow);
- log(sip_fields, &event, packet, flow);
- log(num_fields, &event, packet, flow);
- log(buf_fields, &event, packet, flow);
- log(sub_fields, &event, packet, flow, logger->is_strict());
+ log(nts_fields, &event, flow);
+ log(sip_fields, &event, flow);
+ log(num_fields, &event, flow);
+ log(buf_fields, &event, flow);
+ log(sub_fields, &event, flow, logger->is_strict());
logger->close_record(*log_id);
}
class HttpExtractor : public ExtractorEvent
{
public:
- using SubGetFn = const Field& (*) (const DataEvent*, const Packet*, const Flow*);
- using SubField = DataField<const Field&, const DataEvent*, const Packet*, const Flow*>;
+ using SubGetFn = const Field& (*) (const DataEvent*, const Flow*);
+ using SubField = DataField<const Field&, const DataEvent*, const Flow*>;
HttpExtractor(Extractor&, uint32_t tenant, const std::vector<std::string>& fields);
using Packet = snort::Packet;
using SfIp = snort::SfIp;
- using BufGetFn = const char* (*) (const DataEvent*, const Packet*, const Flow*);
- using BufField = DataField<const char*, const DataEvent*, const Packet*, const Flow*>;
- using SipGetFn = const SfIp& (*) (const DataEvent*, const Packet*, const Flow*);
- using SipField = DataField<const SfIp&, const DataEvent*, const Packet*, const Flow*>;
- using NumGetFn = uint64_t (*) (const DataEvent*, const Packet*, const Flow*);
- using NumField = DataField<uint64_t, const DataEvent*, const Packet*, const Flow*>;
- using NtsGetFn = struct timeval (*) (const DataEvent*, const Packet*, const Flow*);
- using NtsField = DataField<struct timeval, const DataEvent*, const Packet*, const Flow*>;
- using StrGetFn = std::pair<const char*, uint16_t> (*) (const DataEvent*, const Packet*, const Flow*);
- using StrField = DataField<std::pair<const char*, uint16_t>, const DataEvent*, const Packet*, const Flow*>;
+ using BufGetFn = const char* (*) (const DataEvent*, const Flow*);
+ using BufField = DataField<const char*, const DataEvent*, const Flow*>;
+ using SipGetFn = const SfIp& (*) (const DataEvent*, const Flow*);
+ using SipField = DataField<const SfIp&, const DataEvent*, const Flow*>;
+ using NumGetFn = uint64_t (*) (const DataEvent*, const Flow*);
+ using NumField = DataField<uint64_t, const DataEvent*, const Flow*>;
+ using NtsGetFn = struct timeval (*) (const DataEvent*, const Flow*);
+ using NtsField = DataField<struct timeval, const DataEvent*, const Flow*>;
+ using StrGetFn = std::pair<const char*, uint16_t> (*) (const DataEvent*, const Flow*);
+ using StrField = DataField<std::pair<const char*, uint16_t>, const DataEvent*, const Flow*>;
static snort::FlowHashKeyOps& get_hash()
{
return flow_key_ops;
}
+ static const snort::Packet* get_packet()
+ { return snort::DetectionEngine::get_context() ? snort::DetectionEngine::get_current_packet() : nullptr; }
+
virtual ~ExtractorEvent() {}
void tinit(ExtractorLogger*, const snort::Connector::ID*);
T& owner;
};
- static struct timeval get_timestamp(const DataEvent*, const Packet* p, const Flow*)
+ static struct timeval get_timestamp(const DataEvent*, const Flow*)
{
+ const Packet* p = ExtractorEvent::get_packet();
+
if (p != nullptr)
return p->pkth->ts;
return timestamp;
}
- static const SfIp& get_ip_src(const DataEvent*, const Packet*, const Flow* flow)
+ static const SfIp& get_ip_src(const DataEvent*, const Flow* flow)
{ return flow->flags.client_initiated ? flow->client_ip : flow->server_ip; }
- static const SfIp& get_ip_dst(const DataEvent*, const Packet*, const Flow* flow)
+ static const SfIp& get_ip_dst(const DataEvent*, const Flow* flow)
{ return flow->flags.client_initiated ? flow->server_ip : flow->client_ip; }
- static uint64_t get_ip_src_port(const DataEvent*, const Packet*, const Flow* flow)
+ static uint64_t get_ip_src_port(const DataEvent*, const Flow* flow)
{ return flow->client_port; }
- static uint64_t get_ip_dst_port(const DataEvent*, const Packet*, const Flow* flow)
+ static uint64_t get_ip_dst_port(const DataEvent*, const Flow* flow)
{ return flow->server_port; }
- static uint64_t get_pkt_num(const DataEvent*, const Packet* p, const Flow*)
- { return (p != nullptr) ? p->context->packet_number : 0; }
+ static uint64_t get_pkt_num(const DataEvent*, const Flow*)
+ {
+ const Packet* p = ExtractorEvent::get_packet();
+
+ if (p != nullptr)
+ return p->context->packet_number;
+
+ return 0;
+ }
- static uint64_t get_uid(const DataEvent*, const Packet*, const Flow* flow)
+ static uint64_t get_uid(const DataEvent*, const Flow* flow)
{ return ExtractorEvent::get_hash().do_hash((const unsigned char*)flow->key, 0); }
template<typename T, class... Context>
logger->add_field(f.name, f.get(context...));
}
- void log(const std::vector<StrField>& fields, DataEvent* event, Packet* pkt, Flow* flow, bool strict)
+ void log(const std::vector<StrField>& fields, DataEvent* event, Flow* flow, bool strict)
{
for (const auto& f : fields)
{
- const auto& str = f.get(event, pkt, flow);
+ const auto& str = f.get(event, flow);
if (str.second > 0)
logger->add_field(f.name, (const char*)str.first, str.second);
else if (strict)
const FTP_CLIENT_REQ& get_request() const
{ return session.client.request; }
- uint64_t get_client_port() const
- { return (uint64_t)session.clientPort; }
-
- const snort::SfIp& get_client_ip() const
- { return session.clientIP; }
-
private:
const FTP_SESSION& session;
};
CHECK(event.get_request().cmd_size == 4);
CHECK(param == "file.txt");
CHECK(event.get_request().param_size == 8);
-
- InetBuf src;
- sfip_ntop(&event.get_client_ip(), src, sizeof(src));
- std::string client = src;
- CHECK(client == "10.10.10.1");
- CHECK(event.get_client_port() == 40000);
}
TEST(pub_sub_ftp_events_test, ftp_response_event)