assert(!busy.empty());
trace_logf(detection, TRACE_DETECTION_ENGINE, "%" PRIu64 " cs::complete %u (i=%zu, b=%zu)\n",
pc.total_from_daq, busy.back()->get_slot(), idle.size(), busy.size());
- idle.push_back(busy.back());
+ IpsContext* c = busy.back();
+ c->clear_context_data();
+ idle.push_back(c);
busy.pop_back();
return busy.empty() ? nullptr : busy.back();
}
IpsContextData* DetectionEngine::get_data(unsigned id)
{ return Snort::get_switcher()->get_context()->get_context_data(id); }
+IpsContextData* DetectionEngine::get_data(unsigned id, IpsContext* context)
+{
+ if ( context )
+ return context->get_context_data(id);
+
+ return DetectionEngine::get_data(id);
+}
+
void DetectionEngine::add_replacement(const std::string& s, unsigned off)
{
Replacement r;
static void set_data(unsigned id, IpsContextData*);
static IpsContextData* get_data(unsigned id);
+ static IpsContextData* get_data(unsigned id, IpsContext* context);
static void add_replacement(const std::string&, unsigned);
static bool get_replacement(std::string&, unsigned&);
for ( auto* p : data )
{
if ( p )
+ {
+ p->clear();
delete p;
+ }
}
sfeventq_free(equeue);
return data[id];
}
+void IpsContext::clear_context_data()
+{
+ for ( auto* p : data )
+ {
+ if ( p )
+ p->clear();
+ }
+}
+
//--------------------------------------------------------------------------
// unit tests
//--------------------------------------------------------------------------
static unsigned get_ips_id();
static unsigned get_max_id();
+ virtual void clear() {}
protected:
IpsContextData() = default;
void set_context_data(unsigned id, IpsContextData*);
IpsContextData* get_context_data(unsigned id) const;
+ void clear_context_data();
void set_slot(unsigned s)
{ slot = s; }
dce_co.h
dce_common.cc
dce_common.h
+ dce_context_data.cc
+ dce_context_data.h
dce_http_proxy.cc
dce_http_proxy_module.cc
dce_http_proxy_module.h
#include "log/messages.h"
#include "utils/safec.h"
+#include "dce_context_data.h"
#include "dce_http_proxy_module.h"
#include "dce_http_server_module.h"
#include "dce_smb_utils.h"
void DCE2_Detect(DCE2_SsnData* sd)
{
+ DceContextData::set_current_ropts(sd);
if ( using_rpkt )
{
using_rpkt = false;
snort::Packet* top_pkt = DetectionEngine::get_current_packet();
dce2_protocol_detect(sd, top_pkt);
/* Always reset rule option data after detecting */
- DCE2_ResetRopts(&sd->ropts);
+ DCE2_ResetRopts(sd , top_pkt);
}
-DCE2_SsnData* get_dce2_session_data(snort::Packet* p)
+DCE2_TransType get_dce2_trans_type(const snort::Packet* p)
{
DCE2_SmbSsnData* smb_data = get_dce2_smb_session_data(p->flow);
DCE2_SsnData* sd = (smb_data != nullptr) ? &(smb_data->sd) : nullptr;
if ((sd != nullptr) && (sd->trans == DCE2_TRANS_TYPE__SMB))
{
- return sd;
+ return DCE2_TRANS_TYPE__SMB;
}
DCE2_TcpSsnData* tcp_data = get_dce2_tcp_session_data(p->flow);
sd = (tcp_data != nullptr) ? &(tcp_data->sd) : nullptr;
if ((sd != nullptr) && (sd->trans == DCE2_TRANS_TYPE__TCP))
{
- return sd;
+ return DCE2_TRANS_TYPE__TCP;
}
DCE2_UdpSsnData* udp_data = get_dce2_udp_session_data(p->flow);
sd = (udp_data != nullptr) ? &(udp_data->sd) : nullptr;
if ((sd != nullptr) && (sd->trans == DCE2_TRANS_TYPE__UDP))
{
- return sd;
+ return DCE2_TRANS_TYPE__UDP;
}
- return nullptr;
+ return DCE2_TRANS_TYPE__NONE;
}
DceEndianness::DceEndianness()
#include "protocols/packet.h"
#include "dce_list.h"
+#include "dce_context_data.h"
extern const snort::InspectApi dce2_smb_api;
extern const snort::InspectApi dce2_tcp_api;
void reset();
};
-inline void DCE2_ResetRopts(DCE2_Roptions* ropts)
+inline void DCE2_ResetRopts(DCE2_SsnData* sd, snort::Packet* p)
{
- ropts->first_frag = DCE2_SENTINEL;
- ropts->opnum = DCE2_SENTINEL;
- ropts->stub_data = nullptr;
+ sd->ropts.first_frag = DCE2_SENTINEL;
+ sd->ropts.opnum = DCE2_SENTINEL;
+ sd->ropts.stub_data = nullptr;
+ DceContextData::clear_current_ropts(p, sd->trans);
}
inline void DCE2_SsnSetNoInspect(DCE2_SsnData* sd)
snort::Packet* DCE2_GetRpkt(snort::Packet*, DCE2_RpktType, const uint8_t*, uint32_t);
uint16_t DCE2_GetRpktMaxData(DCE2_SsnData*, DCE2_RpktType);
DCE2_Ret DCE2_AddDataToRpkt(snort::Packet*, const uint8_t*, uint32_t);
-DCE2_SsnData* get_dce2_session_data(snort::Packet*);
+DCE2_TransType get_dce2_trans_type(const snort::Packet* p);
#endif
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2018-2018 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+// dce_context_data.cc author Bhagya Tholpady <bbantwal@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "dce_context_data.h"
+
+#include "protocols/packet.h"
+
+#include "dce_utils.h"
+#include "dce_common.h"
+
+using namespace snort;
+
+unsigned DceContextData::smb_ips_id = 0;
+unsigned DceContextData::tcp_ips_id = 0;
+unsigned DceContextData::udp_ips_id = 0;
+
+void DceContextData::init(DCE2_TransType trans)
+{
+ set_ips_id(trans, IpsContextData::get_ips_id());
+}
+
+unsigned DceContextData::get_ips_id(DCE2_TransType trans)
+{
+ switch(trans)
+ {
+ case DCE2_TRANS_TYPE__SMB:
+ return DceContextData::smb_ips_id;
+ case DCE2_TRANS_TYPE__TCP:
+ return DceContextData::tcp_ips_id;
+ case DCE2_TRANS_TYPE__UDP:
+ return DceContextData::udp_ips_id;
+ default:
+ break;
+ }
+ return 0;
+}
+
+void DceContextData::set_ips_id(DCE2_TransType trans, unsigned id)
+{
+ switch(trans)
+ {
+ case DCE2_TRANS_TYPE__SMB:
+ DceContextData::smb_ips_id = id;
+ break;
+ case DCE2_TRANS_TYPE__TCP:
+ DceContextData::tcp_ips_id = id;
+ break;
+ case DCE2_TRANS_TYPE__UDP:
+ DceContextData::udp_ips_id = id;
+ break;
+ default:
+ break;
+ }
+ return;
+}
+
+DceContextData* DceContextData::get_current_data(const Packet* p)
+{
+ IpsContext* context = p ? p->context : nullptr;
+ unsigned ips_id = get_ips_id(get_dce2_trans_type(p));
+
+ if ( !ips_id )
+ return nullptr;
+
+ DceContextData* dcd = (DceContextData*)DetectionEngine::get_data(ips_id, context);
+
+ if ( !dcd )
+ return nullptr;
+
+ return dcd;
+}
+
+bool DceContextData::is_noinspect(const Packet* p)
+{
+ DceContextData* dcd = get_current_data(p);
+
+ if ( !dcd )
+ return true;
+
+ return dcd->no_inspect;
+}
+
+DCE2_Roptions* DceContextData::get_current_ropts(const Packet* p)
+{
+ DceContextData* dcd = get_current_data(p);
+
+ if ( !dcd )
+ return nullptr;
+
+ return dcd->current_ropts;
+}
+
+void DceContextData::set_current_ropts(DCE2_SsnData* sd)
+{
+ unsigned ips_id = get_ips_id(sd->trans);
+
+ if ( !ips_id )
+ return;
+
+ DceContextData* dcd = (DceContextData*)DetectionEngine::get_data(ips_id);
+
+ if ( !dcd )
+ {
+ dcd = new DceContextData;
+ DetectionEngine::set_data(ips_id, dcd);
+ }
+
+ if ( !dcd->current_ropts )
+ {
+ dcd->current_ropts = new DCE2_Roptions;
+ }
+
+ *(dcd->current_ropts) = sd->ropts;
+ dcd->no_inspect = DCE2_SsnNoInspect(sd);
+}
+
+void DceContextData::clear_current_ropts(IpsContext* context, DCE2_TransType trans)
+{
+ unsigned ips_id = get_ips_id(trans);
+
+ if ( !ips_id )
+ return;
+
+ DceContextData* dcd = (DceContextData*)DetectionEngine::get_data(ips_id, context);
+
+ if ( dcd )
+ {
+ dcd->clear();
+ }
+
+ return;
+}
+void DceContextData::clear_current_ropts(const Packet* p, DCE2_TransType trans)
+{
+ IpsContext* context = p ? p->context : nullptr;
+ clear_current_ropts(context, trans);
+}
+
+void DceContextData::clear()
+{
+ if ( current_ropts )
+ delete current_ropts;
+ current_ropts = nullptr;
+ no_inspect = false;
+}
+
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2018-2018 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+// dce_context_data.h author Bhagya Tholpady <bbantwal@cisco.com>
+
+#ifndef DCE_CONTEXT_DATA_H
+#define DCE_CONTEXT_DATA_H
+
+#include "detection/ips_context.h"
+#include "dce_utils.h"
+
+struct DCE2_Roptions;
+struct DCE2_SsnData;
+
+class DceContextData : public snort::IpsContextData
+{
+public:
+ void clear() override;
+
+ static unsigned smb_ips_id;
+ static unsigned tcp_ips_id;
+ static unsigned udp_ips_id;
+
+ DCE2_Roptions* current_ropts = nullptr;
+ bool no_inspect = false;
+
+ static void init(DCE2_TransType trans);
+ static unsigned get_ips_id(DCE2_TransType trans);
+ static void set_ips_id(DCE2_TransType trans, unsigned id);
+
+ static DceContextData* get_current_data(const snort::Packet* p);
+ static DCE2_Roptions* get_current_ropts(const snort::Packet* p);
+ static bool is_noinspect(const snort::Packet* p);
+ static void set_current_ropts(DCE2_SsnData* sd);
+ static void clear_current_ropts(const snort::Packet* p, DCE2_TransType trans);
+ static void clear_current_ropts(snort::IpsContext* context, DCE2_TransType trans);
+};
+
+#endif
+
#include "utils/util.h"
#include "packet_io/active.h"
+#include "dce_context_data.h"
#include "dce_smb_commands.h"
#include "dce_smb_module.h"
#include "dce_smb_paf.h"
void show(snort::SnortConfig*) override;
void eval(snort::Packet*) override;
+ void clear(snort::Packet*) override;
snort::StreamSplitter* get_splitter(bool c2s) override
{
return new Dce2SmbSplitter(c2s);
if (!dce2_detected)
DCE2_Detect(&dce2_smb_sess->sd);
- DCE2_ResetRopts(&dce2_smb_sess->sd.ropts);
-
delete p->endianness;
p->endianness = nullptr;
}
}
+void Dce2Smb::clear(snort::Packet* p)
+{
+ DCE2_SmbSsnData* dce2_smb_sess = get_dce2_smb_session_data(p->flow);
+ if ( dce2_smb_sess )
+ {
+ DCE2_ResetRopts(&dce2_smb_sess->sd, p);
+ }
+}
+
//-------------------------------------------------------------------------
// api stuff
//-------------------------------------------------------------------------
Dce2SmbFlowData::init();
DCE2_SmbInitGlobals();
DCE2_SmbInitDeletePdu();
+ DceContextData::init(DCE2_TRANS_TYPE__SMB);
}
static snort::Inspector* dce2_smb_ctor(snort::Module* m)
#include "detection/detection_engine.h"
#include "utils/util.h"
+#include "dce_context_data.h"
#include "dce_common.h"
#include "dce_tcp_module.h"
#include "dce_tcp_paf.h"
if ( dce2_tcp_sess )
{
DCE2_CoInitTracker(&dce2_tcp_sess->co_tracker);
- DCE2_ResetRopts(&dce2_tcp_sess->sd.ropts);
+ DCE2_ResetRopts(&dce2_tcp_sess->sd, p);
dce2_tcp_stats.tcp_sessions++;
void show(SnortConfig*) override;
void eval(Packet*) override;
+ void clear(Packet*) override;
StreamSplitter* get_splitter(bool c2s) override
{
return new Dce2TcpSplitter(c2s);
if (!dce2_detected)
DCE2_Detect(&dce2_tcp_sess->sd);
- DCE2_ResetRopts(&dce2_tcp_sess->sd.ropts);
-
delete p->endianness;
p->endianness = nullptr;
}
}
+void Dce2Tcp::clear(Packet* p)
+{
+ DCE2_TcpSsnData* dce2_tcp_sess = get_dce2_tcp_session_data(p->flow);
+ if ( dce2_tcp_sess )
+ {
+ DCE2_ResetRopts(&dce2_tcp_sess->sd, p);
+ }
+
+}
+
//-------------------------------------------------------------------------
// api stuff
//-------------------------------------------------------------------------
static void dce2_tcp_init()
{
Dce2TcpFlowData::init();
+ DceContextData::init(DCE2_TRANS_TYPE__TCP);
}
const InspectApi dce2_tcp_api =
#include "detection/detection_engine.h"
#include "utils/util.h"
+#include "dce_context_data.h"
#include "dce_udp_module.h"
using namespace snort;
DCE2_UdpSsnData* dce2_udp_sess = set_new_dce2_udp_session(p);
- DCE2_ResetRopts(&dce2_udp_sess->sd.ropts);
+ DCE2_ResetRopts(&dce2_udp_sess->sd, p);
dce2_udp_stats.udp_sessions++;
dce2_udp_sess->sd.trans = DCE2_TRANS_TYPE__UDP;
Dce2Udp(dce2UdpProtoConf&);
void show(SnortConfig*) override;
void eval(Packet*) override;
+ void clear(Packet*) override;
private:
dce2UdpProtoConf config;
if (!dce2_detected)
DCE2_Detect(&dce2_udp_sess->sd);
- DCE2_ResetRopts(&dce2_udp_sess->sd.ropts);
-
delete p->endianness;
p->endianness = nullptr;
}
}
+void Dce2Udp::clear(Packet* p)
+{
+ DCE2_UdpSsnData* dce2_udp_sess = get_dce2_udp_session_data(p->flow);
+ if ( dce2_udp_sess )
+ {
+ DCE2_ResetRopts(&dce2_udp_sess->sd, p);
+ }
+
+}
+
//-------------------------------------------------------------------------
// api stuff
//-------------------------------------------------------------------------
static void dce2_udp_init()
{
Dce2UdpFlowData::init();
+ DceContextData::init(DCE2_TRANS_TYPE__UDP);
}
const InspectApi dce2_udp_api =
return;
}
- DCE2_ResetRopts(&sd->ropts);
+ DCE2_ResetRopts(sd, nullptr);
if (!DceRpcClFrag(cl_hdr)) /* It's a full request */
{
return NO_MATCH;
}
- DCE2_SsnData* sd= get_dce2_session_data(p);
-
- if ((sd == nullptr) || DCE2_SsnNoInspect(sd))
+ if (DceContextData::is_noinspect(p))
{
return NO_MATCH;
}
- DCE2_Roptions* ropts = &sd->ropts;
+ DCE2_Roptions* ropts = DceContextData::get_current_ropts(p);
+
+ if ( !ropts )
+ return NO_MATCH;
if (ropts->first_frag == DCE2_SENTINEL)
{
return NO_MATCH;
}
- DCE2_SsnData* sd = get_dce2_session_data(p);
-
- if ((sd == nullptr) || DCE2_SsnNoInspect(sd))
+ if (DceContextData::is_noinspect(p))
{
return NO_MATCH;
}
- DCE2_Roptions* ropts = &sd->ropts;
+ DCE2_Roptions* ropts = DceContextData::get_current_ropts(p);
+
+ if ( !ropts )
+ return NO_MATCH;
if (ropts->opnum == DCE2_SENTINEL)
{
return NO_MATCH;
}
- DCE2_SsnData* sd = get_dce2_session_data(p);
-
- if ((sd == nullptr) || DCE2_SsnNoInspect(sd))
+ if (DceContextData::is_noinspect(p))
{
return NO_MATCH;
}
- DCE2_Roptions* ropts = &sd->ropts;
+ DCE2_Roptions* ropts = DceContextData::get_current_ropts(p);
+
+ if ( !ropts )
+ return NO_MATCH;
if (ropts->stub_data != nullptr)
{
dce2_smb_sess->rtracker.mid = DCE2_SENTINEL;
dce2_smb_sess->max_file_depth = snort::FileService::get_max_file_depth();
- DCE2_ResetRopts(&dce2_smb_sess->sd.ropts);
+ DCE2_ResetRopts(&dce2_smb_sess->sd, p);
dce2_smb_stats.smb_sessions++;