#endif
#include <assert.h>
+#include "events/event_queue.h"
+#include "events/sfeventq.h"
+#include "main/snort_config.h"
#ifdef UNIT_TEST
#include "catch/catch.hpp"
{
packet = new Packet(false);
pkth = new DAQ_PktHdr_t;
+ buf = new uint8_t[65536]; // FIXIT-H use codec max or let pkt do it
+
+ const EventQueueConfig* qc = snort_conf->event_queue_config;
+ equeue = sfeventq_new(qc->max_events, qc->log_events, sizeof(EventNode));
}
IpsContext::~IpsContext()
if ( p )
delete p;
+ sfeventq_free(equeue);
+
+ delete buf;
delete pkth;
delete packet;
}
public:
Packet* packet;
DAQ_PktHdr_t* pkth;
+ uint8_t* buf;
+ struct SF_EVENTQ* equeue;
private:
std::vector<IpsContextData*> data;
#include "detection/fp_detect.h"
#include "filters/sfthreshold.h"
#include "log/messages.h"
+#include "main/snort.h"
#include "parser/parser.h"
#include "utils/stats.h"
#include "utils/util.h"
#include "sfeventq.h"
-typedef struct s_SNORT_EVENTQ_USER
-{
- void* pkt;
-} SNORT_EVENTQ_USER;
-
-#define NUM_EVENT_QUEUES 3
-static THREAD_LOCAL SF_EVENTQ* event_queue[NUM_EVENT_QUEUES];
-
-static THREAD_LOCAL unsigned qIndex = 0;
static THREAD_LOCAL unsigned s_events = 0;
-static THREAD_LOCAL unsigned qOverflow = 0;
-
-//-------------------------------------------------
-// the push/pop methods ensure that qIndex stays in
-// bounds and that it is only popped after it was
-// successfully pushed.
-void SnortEventqPush()
-{
- if ( qIndex < NUM_EVENT_QUEUES-1 )
- qIndex++;
- else
- qOverflow++;
-}
-
-void SnortEventqPop()
-{
- if ( qOverflow > 0 )
- qOverflow--;
- else if ( qIndex > 0 )
- qIndex--;
-}
//-------------------------------------------------
/*
return 0;
}
- EventNode* en = (EventNode*)sfeventq_event_alloc(event_queue[qIndex]);
+ SF_EVENTQ* pq = Snort::get_event_queue();
+ EventNode* en = (EventNode*)sfeventq_event_alloc(pq);
if ( !en )
return -1;
en->otn = otn;
en->rtn = rtn;
- if ( sfeventq_add(event_queue[qIndex], en) )
+ if ( sfeventq_add(pq, en) )
return -1;
s_events++;
if ( !otn )
return 0;
- EventNode* en = (EventNode*)sfeventq_event_alloc(event_queue[qIndex]);
+ SF_EVENTQ* pq = Snort::get_event_queue();
+ EventNode* en = (EventNode*)sfeventq_event_alloc(pq);
if ( !en )
return -1;
en->rtn = nullptr; // lookup later after ips policy selection
en->type = type;
- if ( sfeventq_add(event_queue[qIndex], en) )
+ if ( sfeventq_add(pq, en) )
return -1;
s_events++;
return ( otn != nullptr );
}
-void SnortEventqNew(EventQueueConfig* eq_config)
-{
- int i;
-
- for ( i = 0; i < NUM_EVENT_QUEUES; i++ )
- {
- event_queue[i] = sfeventq_new(eq_config->max_events,
- eq_config->log_events, sizeof(EventNode));
-
- if (event_queue[i] == NULL)
- FatalError("Failed to initialize Snort event queue.\n");
- }
-}
-
-void SnortEventqFree()
-{
- int i;
- for ( i = 0; i < NUM_EVENT_QUEUES; i++ )
- sfeventq_free(event_queue[i]);
-}
-
static int LogSnortEvents(void* event, void* user)
{
if ( !event || !user )
if ( s_events > 0 )
s_events--;
- SNORT_EVENTQ_USER* snort_user = (SNORT_EVENTQ_USER*)user;
-
- fpLogEvent(en->rtn, en->otn, (Packet*)snort_user->pkt);
-
+ fpLogEvent(en->rtn, en->otn, (Packet*)user);
sfthreshold_reset();
return 0;
}
/*
-** NAME
-** SnortEventqLog::
-*/
-/**
** We return whether we logged events or not. We've add a eventq user
** structure so we can track whether the events logged were rule events
** or preprocessor/decoder events. The reason being that we don't want
** to flush a TCP stream for preprocessor/decoder events, and cause
** early flushing of the stream.
-**
-** @return 1 logged events
-** @return 0 did not log events or logged only decoder/preprocessor events
*/
int SnortEventqLog(Packet* p)
{
- SNORT_EVENTQ_USER user;
- user.pkt = (void*)p;
- sfeventq_action(event_queue[qIndex], LogSnortEvents, (void*)&user);
+ SF_EVENTQ* pq = Snort::get_event_queue();
+ sfeventq_action(pq, LogSnortEvents, (void*)p);
return 0;
}
void SnortEventqReset()
{
- sfeventq_reset(event_queue[qIndex]);
+ SF_EVENTQ* pq = Snort::get_event_queue();
+ sfeventq_reset(pq);
reset_counts();
}
#define SNORT_EVENTQ_PRIORITY 1
#define SNORT_EVENTQ_CONTENT_LEN 2
-struct Packet;
-struct OptTreeNode;
-
struct EventQueueConfig
{
int max_events;
EventQueueConfig* EventQueueConfigNew();
void EventQueueConfigFree(EventQueueConfig*);
-void SnortEventqNew(EventQueueConfig*);
-void SnortEventqFree();
-
SO_PUBLIC void SnortEventqReset();
void SnortEventqResetCounts();
SO_PUBLIC int SnortEventqAdd(uint32_t gid, uint32_t sid, RuleType = RULE_TYPE__NONE);
SO_PUBLIC bool event_is_enabled(uint32_t gid, uint32_t sid);
-SO_PUBLIC void SnortEventqPush();
-SO_PUBLIC void SnortEventqPop();
-
#endif
#ifndef SFEVENTQ_H
#define SFEVENTQ_H
-typedef struct s_SF_EVENTQ_NODE
+struct SF_EVENTQ_NODE
{
void* event;
- struct s_SF_EVENTQ_NODE* prev;
- struct s_SF_EVENTQ_NODE* next;
-} SF_EVENTQ_NODE;
+ SF_EVENTQ_NODE* prev;
+ SF_EVENTQ_NODE* next;
+};
-typedef struct s_SF_EVENTQ
+struct SF_EVENTQ
{
/*
** Handles the actual ordering and memory
*/
int cur_nodes;
int cur_events;
-} SF_EVENTQ;
+};
SF_EVENTQ* sfeventq_new(int max_nodes, int log_nodes, int event_size);
void* sfeventq_event_alloc(SF_EVENTQ*);
#include "filters/rate_filter.h"
#include "filters/sfthreshold.h"
#include "flow/ha.h"
+#include "framework/endianness.h"
#include "framework/mpse.h"
#include "helpers/process.h"
#include "host_tracker/host_cache.h"
void Snort::thread_init_unprivileged()
{
// using dummy values until further integration
- const unsigned max_contexts = 5;
+ const unsigned max_contexts = 20;
const unsigned max_data = 1;
s_switcher = new ContextSwitcher(max_contexts);
// so it is done here instead of init()
Active::init(snort_conf);
- SnortEventqNew(snort_conf->event_queue_config);
-
InitTag();
-
EventTrace_Init();
detection_filter_init(snort_conf->detection_filter_config);
CleanupTag();
FileService::thread_term();
- SnortEventqFree();
Active::term();
delete s_switcher;
}
+DetectionContext::DetectionContext()
+{
+ s_switcher->interrupt();
+}
+
+DetectionContext::~DetectionContext()
+{ Snort::clear_detect_packet(); }
+
+Packet* DetectionContext::get_packet()
+{ return Snort::get_detect_packet(); }
+
+SF_EVENTQ* Snort::get_event_queue()
+{
+ return s_switcher->get_context()->equeue;
+}
+
Packet* Snort::set_detect_packet()
{
+ // this approach is a hack until verified
+ // looks like we need to stay in the current context until
+ // rebuild is successful; any events while rebuilding will
+ // be logged against the current packet.
const IpsContext* c = s_switcher->interrupt();
Packet* p = c->packet;
+ s_switcher->complete();
+
p->pkth = c->pkth;
+ p->data = c->buf;
+ p->reset();
+ return p;
+}
+
+Packet* Snort::get_detect_packet()
+{
+ Packet* p = s_switcher->get_context()->packet;
return p;
}
void Snort::clear_detect_packet()
{
+ Packet* p = get_detect_packet();
+ SnortEventqLog(p);
+ SnortEventqReset();
+
+ if ( p->endianness )
+ {
+ delete p->endianness;
+ p->endianness = nullptr;
+ }
+
s_switcher->complete();
}
auto save_do_detect = do_detect;
auto save_do_detect_content = do_detect_content;
- SnortEventqPush();
+ DetectionContext dc;
main_hook(p);
- SnortEventqPop();
- DetectReset();
+ DetectReset(); // FIXIT-H context
do_detect = save_do_detect;
do_detect_content = save_do_detect_content;
s_switcher->start();
s_packet = s_switcher->get_context()->packet;
- {
- Profile eventq_profile(eventqPerfStats);
- SnortEventqReset();
- }
-
sfthreshold_reset();
ActionManager::reset_queue();
typedef void (* MainHook_f)(Packet*);
+class DetectionContext
+{
+public:
+ DetectionContext();
+ ~DetectionContext();
+
+ Packet* get_packet();
+};
+
class Snort
{
public:
static void capture_packet();
static Packet* set_detect_packet();
+ static Packet* get_detect_packet();
static void clear_detect_packet();
static void detect_rebuilt_packet(Packet*);
+ static struct SF_EVENTQ* get_event_queue();
+
static DAQ_Verdict process_packet(
Packet*, const DAQ_PktHdr_t*, const uint8_t* pkt, bool is_frag=false);
if ( num_layers > 0 )
return PacketManager::get_proto_name(layers[num_layers-1].prot_id);
- assert(false);
return "None";
default:
#include "dce_co.h"
#include "main/snort_debug.h"
+#include "main/snort.h"
#include "utils/util.h"
#include "dce_smb.h"
********************************************************************/
static void DCE2_CoReassemble(DCE2_SsnData* sd, DCE2_CoTracker* cot, DCE2_CoRpktType co_rtype)
{
+ DetectionContext dc;
+
DceRpcCoHdr* co_hdr = nullptr;
Packet* rpkt = dce_co_reassemble(sd,cot,co_rtype,&co_hdr);
if ( !rpkt )
return;
- /* Push packet onto stack */
- if (DCE2_PushPkt(rpkt,sd) != DCE2_RET__SUCCESS)
- {
- DebugMessage(DEBUG_DCE_COMMON, "Failed to push packet onto packet stack.\n");
- return;
- }
DCE2_CoSetRopts(sd, cot, co_hdr, rpkt);
DebugMessage(DEBUG_DCE_COMMON, "Reassembled CO fragmented packet:\n");
DCE2_PrintPktData(rpkt->data, rpkt->dsize);
DCE2_Detect(sd);
- DCE2_PopPkt(sd);
-
co_reassembled = 1;
}
********************************************************************/
static void DCE2_CoSegDecode(DCE2_SsnData* sd, DCE2_CoTracker* cot, DCE2_CoSeg* seg)
{
+ DetectionContext dc;
+
const uint8_t* frag_ptr = nullptr;
uint16_t frag_len = 0;
dce2CommonStats* dce_common_stats = dce_get_proto_stats_ptr(sd);
return;
}
- if (DCE2_PushPkt(rpkt,sd) != DCE2_RET__SUCCESS)
- {
- DebugMessage(DEBUG_DCE_COMMON, "Failed to push packet onto packet stack.\n");
- return;
- }
-
/* All is good. Decode the pdu */
DCE2_CoDecode(sd, cot, frag_ptr, frag_len);
* detection engine hasn't seen yet */
if (!co_reassembled)
DCE2_Detect(sd);
-
- DCE2_PopPkt(sd);
}
static DCE2_Ret DCE2_HandleSegmentation(DCE2_Buffer* seg_buf, const uint8_t* data_ptr,
#include "detection/detect.h"
#include "ips_options/extract.h"
#include "log/messages.h"
+#include "main/snort.h"
#include "utils/safec.h"
#include "dce_smb_utils.h"
#include "dce_udp.h"
THREAD_LOCAL int dce2_detected = 0;
-THREAD_LOCAL DCE2_CStack* dce2_pkt_stack = nullptr;
-THREAD_LOCAL int dce2_inspector_instances = 0;
static const char* dce2_get_policy_name(DCE2_Policy policy)
{
{
if (sd->trans == DCE2_TRANS_TYPE__TCP)
{
+ // FIXIT-M this doesn't look right; profile immediately goes out of scope
Profile profile(dce2_tcp_pstat_detect);
}
else if (sd->trans == DCE2_TRANS_TYPE__SMB)
// FIXIT-M add HTTP case when these are ported
// Same for all other instances of profiling
- SnortEventqPush();
snort_detect(pkt);
- SnortEventqPop();
dce2_detected = 1;
}
void DCE2_Detect(DCE2_SsnData* sd)
{
- Packet* top_pkt;
- top_pkt = (Packet*)DCE2_CStackTop(dce2_pkt_stack);
- if (top_pkt == nullptr)
- {
- DebugMessage(DEBUG_DCE_COMMON,"No packet on top of stack.\n");
+ DetectionContext dc;
+ Packet* top_pkt = dc.get_packet();
+
+ if ( !top_pkt->endianness )
return;
- }
- DebugMessage(DEBUG_DCE_COMMON, "Detecting ------------------------------------------------\n");
- DebugMessage(DEBUG_DCE_COMMON, " Rule options:\n");
+
DCE2_PrintRoptions(&sd->ropts);
DebugMessage(DEBUG_DCE_COMMON, "Payload:\n");
DCE2_PrintPktData(top_pkt->data, top_pkt->dsize);
+
if (sd->ropts.stub_data != nullptr)
{
DebugMessage(DEBUG_DCE_COMMON,"\nStub data:\n");
return true;
}
-static void dce_push_pkt_log(Packet* pkt,DCE2_SsnData* sd)
-{
- if (sd->trans == DCE2_TRANS_TYPE__TCP)
- {
- Profile profile(dce2_tcp_pstat_log);
- }
- else if (sd->trans == DCE2_TRANS_TYPE__SMB)
- {
- Profile profile(dce2_smb_pstat_log);
- }
- else
- {
- Profile profile(dce2_udp_pstat_log);
- }
-
- SnortEventqPush();
- SnortEventqLog(pkt);
- SnortEventqReset();
- SnortEventqPop();
-}
-
-// FIXIT-L revisit packet stack since it may not be needed
-
-DCE2_Ret DCE2_PushPkt(Packet* p,DCE2_SsnData* sd)
-{
- Packet* top_pkt;
- top_pkt = (Packet*)DCE2_CStackTop(dce2_pkt_stack);
-
- if (top_pkt != nullptr)
- {
- dce_push_pkt_log(top_pkt,sd);
- }
- if (DCE2_CStackPush(dce2_pkt_stack, (void*)p) != DCE2_RET__SUCCESS)
- return DCE2_RET__ERROR;
-
- return DCE2_RET__SUCCESS;
-}
-
-void DCE2_PopPkt(DCE2_SsnData* sd)
-{
- Packet* pop_pkt = (Packet*)DCE2_CStackPop(dce2_pkt_stack);
-
- if (sd->trans == DCE2_TRANS_TYPE__TCP)
- {
- Profile profile(dce2_tcp_pstat_log);
- }
- else if (sd->trans == DCE2_TRANS_TYPE__UDP)
- {
- Profile profile(dce2_udp_pstat_log);
- }
- else
- {
- Profile profile(dce2_smb_pstat_log);
- }
-
- if (pop_pkt == nullptr)
- {
- DebugMessage(DEBUG_DCE_COMMON, "No packet to pop off stack.\n");
- return;
- }
- SnortEventqPush();
- SnortEventqLog(pop_pkt);
- SnortEventqReset();
- SnortEventqPop();
-}
-
uint16_t DCE2_GetRpktMaxData(DCE2_SsnData* sd, DCE2_RpktType rtype)
{
Packet* p = sd->wire_pkt;
DebugFormat(DEBUG_DCE_COMMON,"Invalid reassembly packet type: %d\n",rtype);
return 0;
}
- return (DCE2_REASSEMBLY_BUF_SIZE - overhead);
+ return (Packet::max_dsize - overhead);
}
static void dce2_fill_rpkt_info(Packet* rpkt, Packet* p)
Packet* DCE2_GetRpkt(Packet* p,DCE2_RpktType rpkt_type,
const uint8_t* data, uint32_t data_len)
{
- Packet* rpkt = nullptr;
+ Packet* rpkt = Snort::set_detect_packet();
+ rpkt->endianness = new DceEndianness();
uint16_t data_overhead = 0;
switch (rpkt_type)
{
case DCE2_RPKT_TYPE__SMB_SEG:
- rpkt = dce2_smb_rpkt[rpkt_type - DCE2_SMB_RPKT_TYPE_START];
dce2_fill_rpkt_info(rpkt, p);
rpkt->pseudo_type = PSEUDO_PKT_SMB_SEG;
break;
case DCE2_RPKT_TYPE__SMB_TRANS:
- rpkt = dce2_smb_rpkt[rpkt_type - DCE2_SMB_RPKT_TYPE_START];
dce2_fill_rpkt_info(rpkt, p);
rpkt->pseudo_type = PSEUDO_PKT_SMB_TRANS;
if (DCE2_SsnFromClient(p))
break;
case DCE2_RPKT_TYPE__SMB_CO_SEG:
- rpkt = dce2_smb_rpkt[rpkt_type - DCE2_SMB_RPKT_TYPE_START];
dce2_fill_rpkt_info(rpkt, p);
rpkt->pseudo_type = PSEUDO_PKT_DCE_SEG;
if (DCE2_SsnFromClient(p))
break;
case DCE2_RPKT_TYPE__SMB_CO_FRAG:
- rpkt = dce2_smb_rpkt[rpkt_type - DCE2_SMB_RPKT_TYPE_START];
dce2_fill_rpkt_info(rpkt, p);
rpkt->pseudo_type = PSEUDO_PKT_DCE_FRAG;
if (DCE2_SsnFromClient(p))
break;
case DCE2_RPKT_TYPE__UDP_CL_FRAG:
- rpkt = dce2_udp_rpkt;
dce2_fill_rpkt_info(rpkt, p);
rpkt->pseudo_type = PSEUDO_PKT_DCE_FRAG;
data_overhead = DCE2_MOCK_HDR_LEN__CL;
case DCE2_RPKT_TYPE__TCP_CO_SEG:
case DCE2_RPKT_TYPE__TCP_CO_FRAG:
- rpkt = dce2_tcp_rpkt[rpkt_type - DCE2_TCP_RPKT_TYPE_START];
dce2_fill_rpkt_info(rpkt, p);
+
if (rpkt_type == DCE2_RPKT_TYPE__TCP_CO_FRAG)
{
rpkt->pseudo_type = PSEUDO_PKT_DCE_FRAG;
return nullptr;
}
- if ((data_overhead + data_len) > DCE2_REASSEMBLY_BUF_SIZE)
- data_len -= (data_overhead + data_len) - DCE2_REASSEMBLY_BUF_SIZE;
+ if ((data_overhead + data_len) > Packet::max_dsize)
+ data_len -= (data_overhead + data_len) - Packet::max_dsize;
- if (data_len > DCE2_REASSEMBLY_BUF_SIZE - data_overhead)
+ if (data_len > Packet::max_dsize - data_overhead)
return nullptr;
memcpy_s((void*)(rpkt->data + data_overhead),
- DCE2_REASSEMBLY_BUF_SIZE - data_overhead, data, data_len);
+ Packet::max_dsize - data_overhead, data, data_len);
rpkt->dsize = data_len + data_overhead;
return rpkt;
return DCE2_RET__ERROR;
// FIXIT-L PORT_IF_NEEDED packet size and hdr check
- const uint8_t* pkt_data_end = rpkt->data + DCE2_REASSEMBLY_BUF_SIZE;
+ const uint8_t* pkt_data_end = rpkt->data + Packet::max_dsize;
const uint8_t* payload_end = rpkt->data + rpkt->dsize;
if ((payload_end + data_len) > pkt_data_end)
data_len = pkt_data_end - payload_end;
- if (data_len > DCE2_REASSEMBLY_BUF_SIZE - rpkt->dsize)
+ if (data_len > Packet::max_dsize - rpkt->dsize)
return DCE2_RET__ERROR;
- memcpy_s((void*)(payload_end), DCE2_REASSEMBLY_BUF_SIZE - rpkt->dsize,
+ memcpy_s((void*)(payload_end), Packet::max_dsize - rpkt->dsize,
data, data_len);
rpkt->dsize += (uint16_t)data_len;
extern const InspectApi dce2_tcp_api;
extern const InspectApi dce2_udp_api;
extern THREAD_LOCAL int dce2_detected;
-extern THREAD_LOCAL int dce2_inspector_instances;
-extern THREAD_LOCAL DCE2_CStack* dce2_pkt_stack;
#define GID_DCE2 133
-#define DCE2_PKT_STACK__SIZE 10
-#define DCE2_REASSEMBLY_BUF_SIZE 65535u
enum DCE2_Policy
{
void print_dce2_co_config(dce2CoProtoConf&);
bool dce2_paf_abort(Flow*, DCE2_SsnData*);
void DCE2_Detect(DCE2_SsnData*);
-Packet* DCE2_GetRpkt(Packet*, DCE2_RpktType,
- const uint8_t*, uint32_t);
-DCE2_Ret DCE2_PushPkt(Packet*,DCE2_SsnData*);
-void DCE2_PopPkt(DCE2_SsnData*);
+Packet* DCE2_GetRpkt(Packet*, DCE2_RpktType, const uint8_t*, uint32_t);
uint16_t DCE2_GetRpktMaxData(DCE2_SsnData*, DCE2_RpktType);
DCE2_Ret DCE2_AddDataToRpkt(Packet*, const uint8_t*, uint32_t);
DCE2_SsnData* get_dce2_session_data(Packet*);
#include "dce_smb_utils.h"
#include "dce_smb2.h"
-THREAD_LOCAL int dce2_smb_inspector_instances = 0;
-
THREAD_LOCAL dce2SmbStats dce2_smb_stats;
-THREAD_LOCAL Packet* dce2_smb_rpkt[DCE2_SMB_RPKT_TYPE_MAX] = { nullptr, nullptr, nullptr,
- nullptr };
// used here
THREAD_LOCAL ProfileStats dce2_smb_pstat_main;
}
dce2_smb_sess = dce2_handle_smb_session(p, &config);
+
if (dce2_smb_sess)
{
- //FIXIT-L evaluate moving pushpkt out of session pstats
- if (DCE2_PushPkt(p,&dce2_smb_sess->sd) != DCE2_RET__SUCCESS)
- {
- DebugMessage(DEBUG_DCE_SMB, "Failed to push packet onto packet stack.\n");
- return;
- }
p->packet_flags |= PKT_ALLOW_MULTIPLE_DETECT;
dce2_detected = 0;
DCE2_Detect(&dce2_smb_sess->sd);
DCE2_ResetRopts(&dce2_smb_sess->sd.ropts);
- DCE2_PopPkt(&dce2_smb_sess->sd);
delete p->endianness;
p->endianness = nullptr;
delete p;
}
-static void dce2_smb_thread_init()
-{
- if (dce2_inspector_instances == 0)
- {
- dce2_pkt_stack = DCE2_CStackNew(DCE2_PKT_STACK__SIZE, nullptr);
- }
- if (dce2_smb_inspector_instances == 0)
- {
- for (int i=0; i < DCE2_SMB_RPKT_TYPE_MAX; i++)
- {
- Packet* p = (Packet*)snort_calloc(sizeof(Packet));
- p->data = (uint8_t*)snort_calloc(DCE2_REASSEMBLY_BUF_SIZE);
- p->endianness = (Endianness*)new DceEndianness();
- p->dsize = DCE2_REASSEMBLY_BUF_SIZE;
- dce2_smb_rpkt[i] = p;
- }
- }
- dce2_smb_inspector_instances++;
- dce2_inspector_instances++;
-}
-
-static void dce2_smb_thread_term()
-{
- dce2_inspector_instances--;
- dce2_smb_inspector_instances--;
-
- if (dce2_smb_inspector_instances == 0)
- {
- for (int i=0; i<DCE2_SMB_RPKT_TYPE_MAX; i++)
- {
- if ( dce2_smb_rpkt[i] != nullptr )
- {
- Packet* p = dce2_smb_rpkt[i];
- if (p->data)
- {
- snort_free((void*)p->data);
- }
- delete p->endianness;
- snort_free(p);
- dce2_smb_rpkt[i] = nullptr;
- }
- }
- }
- if (dce2_inspector_instances == 0)
- {
- DCE2_CStackDestroy(dce2_pkt_stack);
- dce2_pkt_stack = nullptr;
- }
-}
-
const InspectApi dce2_smb_api =
{
{
"dce_smb",
dce2_smb_init,
nullptr, // pterm
- dce2_smb_thread_init, // tinit
- dce2_smb_thread_term, // tterm
+ nullptr, // tinit
+ nullptr, // tterm
dce2_smb_ctor,
dce2_smb_dtor,
nullptr, // ssn
};
extern THREAD_LOCAL dce2SmbStats dce2_smb_stats;
-extern THREAD_LOCAL Packet* dce2_smb_rpkt[DCE2_SMB_RPKT_TYPE_MAX];
extern THREAD_LOCAL ProfileStats dce2_smb_pstat_main;
extern THREAD_LOCAL ProfileStats dce2_smb_pstat_session;
extern THREAD_LOCAL ProfileStats dce2_smb_pstat_new_session;
Packet* p = ssd->sd.wire_pkt;
const uint8_t* data_ptr = p->data;
uint16_t data_len = p->dsize;
- Smb2Hdr* smb_hdr;
if (!FileService::is_file_service_enabled())
return;
if (p->is_pdu_start())
{
uint32_t next_command_offset;
- smb_hdr = (Smb2Hdr*)(data_ptr + sizeof(NbssHdr));
+ Smb2Hdr* smb_hdr = (Smb2Hdr*)(data_ptr + sizeof(NbssHdr));
next_command_offset = alignedNtohl(&(smb_hdr->next_command));
if (next_command_offset + sizeof(NbssHdr) > p->dsize)
{
return DCE2_RET__ERROR;
}
- DebugMessage(DEBUG_DCE_SMB,
- "Reassembled WriteAndX raw mode request\n");
+ DebugMessage(DEBUG_DCE_SMB, "Reassembled WriteAndX raw mode request\n");
DCE2_PrintPktData(rpkt->data, rpkt->dsize);
(void)DCE2_SmbProcessRequestData(ssd, fid, data_ptr, data_len, 0);
- DCE2_SmbReturnRpkt(ssd);
DCE2_BufferEmpty(ftracker->fp_writex_raw->buf);
}
}
status = DCE2_SmbProcessResponseData(ssd, data_ptr, data_len);
- DCE2_SmbReturnRpkt(ssd);
-
if (status != DCE2_RET__SUCCESS)
return status;
}
status = DCE2_SmbTransactionReq(ssd, ttracker, data_ptr, data_len,
DCE2_BufferData(ttracker->pbuf), DCE2_BufferLength(ttracker->pbuf));
-
- DCE2_SmbReturnRpkt(ssd);
}
break;
return nullptr;
}
- if (DCE2_PushPkt(rpkt, &ssd->sd) != DCE2_RET__SUCCESS)
- {
- DebugFormat(DEBUG_DCE_SMB,
- "%s(%d) Failed to push packet onto packet stack.",
- __FILE__, __LINE__);
- return nullptr;
- }
-
*data = rpkt->data;
*data_len = rpkt->dsize;
return;
dce_alert(GID_DCE2, rule_id, (dce2CommonStats*)&dce2_smb_stats);
-
- DCE2_SmbReturnRpkt(ssd);
}
static void DCE2_SmbResetFileChunks(DCE2_SmbFileTracker* ftracker)
}
if ((file_data_depth != -1) &&
- ((ftracker->ff_file_offset == ftracker->ff_bytes_processed)
- && ((file_data_depth == 0) || (ftracker->ff_bytes_processed < (uint64_t)file_data_depth))))
+ ((ftracker->ff_file_offset == ftracker->ff_bytes_processed) &&
+ ((file_data_depth == 0) || (ftracker->ff_bytes_processed < (uint64_t)file_data_depth))))
{
set_file_data((uint8_t*)data_ptr,
(data_len > UINT16_MAX) ? UINT16_MAX : (uint16_t)data_len);
void DCE2_FileDetect()
{
- Packet* top_pkt = (Packet*)DCE2_CStackTop(dce2_pkt_stack);
- if (top_pkt == nullptr)
- {
- DebugMessage(DEBUG_DCE_SMB,"No packet on top of stack.\n");
- return;
- }
- DebugMessage(DEBUG_DCE_SMB, "Detecting ------------------------------------------------\n");
+ Packet* top_pkt = Snort::set_detect_packet();
+ DetectionContext dc;
+
DebugMessage(DEBUG_DCE_SMB, "Payload:\n");
DCE2_PrintPktData(top_pkt->data, top_pkt->dsize);
Profile profile(dce2_smb_pstat_smb_file_detect);
- SnortEventqPush();
snort_detect(top_pkt);
- SnortEventqPop();
// Reset file data pointer after detecting
set_file_data(nullptr, 0);
dce2_detected = 1;
- DebugMessage(DEBUG_DCE_SMB, "----------------------------------------------------------\n");
}
static void DCE2_SmbSetNewFileAPIFileTracker(DCE2_SmbSsnData* ssd)
return false;
}
-inline void DCE2_SmbReturnRpkt(DCE2_SmbSsnData* ssd)
-{
- DCE2_PopPkt(&ssd->sd);
-}
-
inline DCE2_Buffer** DCE2_SmbGetSegBuffer(DCE2_SmbSsnData* ssd)
{
if (DCE2_SsnFromServer(ssd->sd.wire_pkt))
DCE2_CoCleanTracker(&dce2_tcp_session.co_tracker);
}
-THREAD_LOCAL int dce2_tcp_inspector_instances = 0;
-
-// FIXIT-L currently using separate buffers for segment and fragment reassembly
-// as in Snort2x code. Doesn't seem necessary for TCP but may be the case for
-// SMB/HTTP ..keeping logic consistent for now
-THREAD_LOCAL Packet* dce2_tcp_rpkt[DCE2_TCP_RPKT_TYPE_MAX] = { nullptr, nullptr };
-
THREAD_LOCAL dce2TcpStats dce2_tcp_stats;
THREAD_LOCAL ProfileStats dce2_tcp_pstat_main;
if (dce2_tcp_sess)
{
- // FIXIT-L evaluate moving pushpkt out of session pstats
- if (DCE2_PushPkt(p,&dce2_tcp_sess->sd) != DCE2_RET__SUCCESS)
- {
- DebugMessage(DEBUG_DCE_TCP, "Failed to push packet onto packet stack.\n");
- return;
- }
p->packet_flags |= PKT_ALLOW_MULTIPLE_DETECT;
dce2_detected = 0;
dce2_tcp_stats.tcp_pkts++;
- p->endianness = (Endianness*)new DceEndianness();
- DCE2_CoProcess(
- &dce2_tcp_sess->sd, &dce2_tcp_sess->co_tracker, p->data, p->dsize);
+ p->endianness = new DceEndianness();
+ DCE2_CoProcess(&dce2_tcp_sess->sd, &dce2_tcp_sess->co_tracker, p->data, p->dsize);
if (!dce2_detected)
DCE2_Detect(&dce2_tcp_sess->sd);
DCE2_ResetRopts(&dce2_tcp_sess->sd.ropts);
- DCE2_PopPkt(&dce2_tcp_sess->sd);
delete p->endianness;
p->endianness = nullptr;
Dce2TcpFlowData::init();
}
-static void dce2_tcp_thread_init()
-{
- if (dce2_inspector_instances == 0)
- {
- dce2_pkt_stack = DCE2_CStackNew(DCE2_PKT_STACK__SIZE, nullptr);
- }
- if (dce2_tcp_inspector_instances == 0)
- {
- for (int i=0; i < DCE2_TCP_RPKT_TYPE_MAX; i++)
- {
- Packet* p = (Packet*)snort_calloc(sizeof(Packet));
- p->data = (uint8_t*)snort_calloc(DCE2_REASSEMBLY_BUF_SIZE);
- p->endianness = (Endianness*)new DceEndianness();
- p->dsize = DCE2_REASSEMBLY_BUF_SIZE;
- dce2_tcp_rpkt[i] = p;
- }
- }
- dce2_tcp_inspector_instances++;
- dce2_inspector_instances++;
-}
-
-static void dce2_tcp_thread_term()
-{
- dce2_inspector_instances--;
- dce2_tcp_inspector_instances--;
-
- if (dce2_tcp_inspector_instances == 0)
- {
- for (int i=0; i<DCE2_TCP_RPKT_TYPE_MAX; i++)
- {
- if ( dce2_tcp_rpkt[i] != nullptr )
- {
- Packet* p = dce2_tcp_rpkt[i];
- if (p->data)
- {
- snort_free((void*)p->data);
- }
- delete p->endianness;
- snort_free(p);
- dce2_tcp_rpkt[i] = nullptr;
- }
- }
- }
- if (dce2_inspector_instances == 0)
- {
- DCE2_CStackDestroy(dce2_pkt_stack);
- dce2_pkt_stack = nullptr;
- }
-}
-
const InspectApi dce2_tcp_api =
{
{
"dce_tcp",
dce2_tcp_init,
nullptr, // pterm
- dce2_tcp_thread_init, // tinit
- dce2_tcp_thread_term, // tterm
+ nullptr, // tinit
+ nullptr, // tterm
dce2_tcp_ctor,
dce2_tcp_dtor,
nullptr, // ssn
#define DCE2_TCP_NAME "dce_tcp"
#define DCE2_TCP_HELP "dce over tcp inspection"
-#define DCE2_TCP_RPKT_TYPE_MAX 2
-#define DCE2_TCP_RPKT_TYPE_START 5
struct dce2TcpStats
{
};
extern THREAD_LOCAL dce2TcpStats dce2_tcp_stats;
-extern THREAD_LOCAL Packet* dce2_tcp_rpkt[DCE2_TCP_RPKT_TYPE_MAX];
extern THREAD_LOCAL ProfileStats dce2_tcp_pstat_main;
extern THREAD_LOCAL ProfileStats dce2_tcp_pstat_session;
extern THREAD_LOCAL ProfileStats dce2_tcp_pstat_new_session;
#include "dce_udp_module.h"
-THREAD_LOCAL int dce2_udp_inspector_instances = 0;
-
THREAD_LOCAL dce2UdpStats dce2_udp_stats;
THREAD_LOCAL ProfileStats dce2_udp_pstat_main;
THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_frag;
THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_reass;
-THREAD_LOCAL Packet* dce2_udp_rpkt = nullptr;
-
static void DCE2_ClCleanTracker(DCE2_ClTracker* clt)
{
if (clt == nullptr)
if (dce2_udp_sess)
{
- if (DCE2_PushPkt(p,&dce2_udp_sess->sd) != DCE2_RET__SUCCESS)
- {
- DebugMessage(DEBUG_DCE_UDP, "Failed to push packet onto packet stack.\n");
- return;
- }
p->packet_flags |= PKT_ALLOW_MULTIPLE_DETECT;
dce2_detected = 0;
- p->endianness = (Endianness*)new DceEndianness();
+ p->endianness = new DceEndianness();
dce2_udp_stats.udp_pkts++;
DCE2_ClProcess(&dce2_udp_sess->sd, &dce2_udp_sess->cl_tracker);
DCE2_Detect(&dce2_udp_sess->sd);
DCE2_ResetRopts(&dce2_udp_sess->sd.ropts);
- DCE2_PopPkt(&dce2_udp_sess->sd);
delete p->endianness;
p->endianness = nullptr;
Dce2UdpFlowData::init();
}
-static void dce2_udp_thread_init()
-{
- if (dce2_inspector_instances == 0)
- {
- dce2_pkt_stack = DCE2_CStackNew(DCE2_PKT_STACK__SIZE, nullptr);
- }
-
- if (dce2_udp_inspector_instances == 0)
- {
- dce2_udp_rpkt = (Packet*)snort_calloc(sizeof(Packet));
- dce2_udp_rpkt->data = (uint8_t*)snort_calloc(DCE2_REASSEMBLY_BUF_SIZE);
- dce2_udp_rpkt->endianness = (Endianness*)new DceEndianness();
- dce2_udp_rpkt->dsize = DCE2_REASSEMBLY_BUF_SIZE;
- }
-
- dce2_udp_inspector_instances++;
- dce2_inspector_instances++;
-}
-
-static void dce2_udp_thread_term()
-{
- dce2_inspector_instances--;
- dce2_udp_inspector_instances--;
-
- if (dce2_udp_inspector_instances == 0)
- {
- if ( dce2_udp_rpkt != nullptr )
- {
- if (dce2_udp_rpkt->data)
- {
- snort_free((void*)dce2_udp_rpkt->data);
- }
- delete dce2_udp_rpkt->endianness;
- snort_free(dce2_udp_rpkt);
- dce2_udp_rpkt = nullptr;
- }
- }
-
- if (dce2_inspector_instances == 0)
- {
- DCE2_CStackDestroy(dce2_pkt_stack);
- dce2_pkt_stack = nullptr;
- }
-}
-
const InspectApi dce2_udp_api =
{
{
"dce_udp",
dce2_udp_init,
nullptr, // pterm
- dce2_udp_thread_init, // tinit
- dce2_udp_thread_term, // tterm
+ nullptr, // tinit
+ nullptr, // tterm
dce2_udp_ctor,
dce2_udp_dtor,
nullptr, // ssn
extern THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_acts;
extern THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_frag;
extern THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_reass;
-extern THREAD_LOCAL Packet* dce2_udp_rpkt;
struct DceRpcClHdr /* Connectionless header */
{
#include "flow/session.h"
#include "main/snort_debug.h"
+#include "main/snort.h"
#include "utils/safec.h"
#include "utils/util.h"
// Reassembles fragments into reassembly buffer and copies to
// reassembly packet.
-static void DCE2_ClFragReassemble(DCE2_SsnData* sd, DCE2_ClActTracker* at, const
- DceRpcClHdr* cl_hdr)
+static void DCE2_ClFragReassemble(
+ DCE2_SsnData* sd, DCE2_ClActTracker* at, const DceRpcClHdr* cl_hdr)
{
+ DetectionContext dc;
+
uint8_t dce2_cl_rbuf[IP_MAXPACKET];
DCE2_ClFragTracker* ft = &at->frag_tracker;
uint8_t* rdata = dce2_cl_rbuf;
const uint8_t* stub_data = rpkt->data + DCE2_MOCK_HDR_LEN__CL;
- if (DCE2_PushPkt(rpkt, sd) != DCE2_RET__SUCCESS)
- {
- DebugFormat(DEBUG_DCE_UDP,
- "%s(%d) Failed to push packet onto packet stack.",
- __FILE__, __LINE__);
- return;
- }
-
/* Cache relevant values for rule option processing */
sd->ropts.first_frag = 1;
DCE2_CopyUuid(&sd->ropts.iface, &ft->iface, DCERPC_BO_FLAG__NONE);
sd->ropts.stub_data = stub_data;
DCE2_Detect(sd);
- DCE2_PopPkt(sd);
dce2_udp_stats.cl_frag_reassembled++;
}
if (!DCE2_BufferIsEmpty(*seg_buf))
{
- DCE2_SmbReturnRpkt(ssd);
DCE2_BufferDestroy(*seg_buf);
*seg_buf = nullptr;
}
break;
}
- dnp3_full_reassembly(config,dnp3_sess, p, pdu_start,
- pdu_length);
-
+ dnp3_full_reassembly(config, dnp3_sess, p, pdu_start, pdu_length);
bytes_processed += pdu_length;
}
#endif
encap_frag_cnt++;
- SnortEventqPush();
PacketManager::encode_set_pkt(p);
Snort::process_packet(dpkt, dpkt->pkth, dpkt->pkt, true);
- SnortEventqPop();
encap_frag_cnt--;
trace_log(stream_ip,
#include "flow/flow_key.h"
#include "flow/ha.h"
#include "flow/prune_stats.h"
+#include "main/snort.h"
#include "main/snort_config.h"
#include "main/snort_debug.h"
#include "packet_io/active.h"
if ( !flow_con )
return;
+ // FIXIT-H stream tcp needs to do this and prep pkt to handle
+ // shutdown alerts while rebuilding (during flush before a
+ // rebuilt packet is available)
+ Snort::set_detect_packet();
+ DetectionContext dc;
+
flow_con->purge_flows(PktType::IP);
flow_con->purge_flows(PktType::ICMP);
flow_con->purge_flows(PktType::TCP);
break;
}
- Snort::clear_detect_packet();
return bytes_processed;
}