From: Russ Combs Date: Wed, 23 Jul 2014 19:25:06 +0000 (-0400) Subject: 104 X-Git-Tag: 3.0.0-233~1438^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=12c359a2002a19667de19d8281fa096656611cac;p=thirdparty%2Fsnort3.git 104 --- diff --git a/ChangeLog b/ChangeLog index 0229f6ef5..c200aa2a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +104 +-- changed configure --with-libpcre-* to --with-pcre-* for consistency +-- same for pcap (again!) +-- added stream_size and stream_reassemble ips options + 103 -- added modules to ips options -- removed ips option sameip which was obsoleted by 116:152 diff --git a/configure.ac b/configure.ac index 6d2cd56ca..44778fc99 100644 --- a/configure.ac +++ b/configure.ac @@ -424,7 +424,7 @@ fi # with foo #-------------------------------------------------------------------------- -AC_ARG_WITH(libpcap_includes, +AC_ARG_WITH(pcap_includes, [ --with-pcap-includes=DIR libpcap include directory], [with_libpcap_includes="$withval"],[with_libpcap_includes="no"]) @@ -432,7 +432,7 @@ if test "x$with_libpcap_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_libpcap_includes}" fi -AC_ARG_WITH(libpcap_libraries, +AC_ARG_WITH(pcap_libraries, [ --with-pcap-libraries=DIR libpcap library directory], [with_libpcap_libraries="$withval"],[with_libpcap_libraries="no"]) @@ -460,7 +460,7 @@ if test "x$with_luajit_libraries" != "xno"; then fi fi -AC_ARG_WITH(libpcre_includes, +AC_ARG_WITH(pcre_includes, [ --with-pcre-includes=DIR libpcre include directory], [with_libpcre_includes="$withval"],[with_libpcre_includes="no"]) @@ -471,7 +471,7 @@ else CPPFLAGS="${CPPFLAGS} `pcre-config --cflags`" fi -AC_ARG_WITH(libpcre_libraries, +AC_ARG_WITH(pcre_libraries, [ --with-pcre-libraries=DIR libpcre library directory], [with_libpcre_libraries="$withval"],[with_libpcre_libraries="no"]) diff --git a/src/network_inspectors/network_inspectors.cc b/src/network_inspectors/network_inspectors.cc index 7c1611541..7ca500c4f 100644 --- a/src/network_inspectors/network_inspectors.cc +++ b/src/network_inspectors/network_inspectors.cc @@ -33,6 +33,9 @@ extern const BaseApi* nin_stream_icmp; extern const BaseApi* nin_stream_tcp; extern const BaseApi* nin_stream_udp; +extern const BaseApi* ips_stream_reassemble; +extern const BaseApi* ips_stream_size; + #ifdef STATIC_INSPECTORS extern const BaseApi* nin_arp_spoof; extern const BaseApi* nin_port_scan_global; @@ -48,6 +51,10 @@ const BaseApi* network_inspectors[] = nin_stream_icmp, nin_stream_tcp, nin_stream_udp, + + ips_stream_reassemble, + ips_stream_size, + #ifdef STATIC_INSPECTORS nin_arp_spoof, nin_port_scan_global, diff --git a/src/stream/tcp/CMakeLists.txt b/src/stream/tcp/CMakeLists.txt index fdb94a11e..9bd7925fd 100644 --- a/src/stream/tcp/CMakeLists.txt +++ b/src/stream/tcp/CMakeLists.txt @@ -8,5 +8,7 @@ add_library( stream_tcp STATIC tcp_module.h tcp_session.cc tcp_session.h + ips_stream_reassemble.cc + ips_stream_size.cc ) diff --git a/src/stream/tcp/Makefile.am b/src/stream/tcp/Makefile.am index a4ca800dc..db0bebb70 100644 --- a/src/stream/tcp/Makefile.am +++ b/src/stream/tcp/Makefile.am @@ -10,7 +10,9 @@ stream_tcp.h \ tcp_module.cc \ tcp_module.h \ tcp_session.cc \ -tcp_session.h +tcp_session.h \ +ips_stream_reassemble.cc \ +ips_stream_size.cc AM_CXXFLAGS = @AM_CXXFLAGS@ diff --git a/src/stream/tcp/ips_stream_reassemble.cc b/src/stream/tcp/ips_stream_reassemble.cc new file mode 100644 index 000000000..8e5751288 --- /dev/null +++ b/src/stream/tcp/ips_stream_reassemble.cc @@ -0,0 +1,262 @@ +/**************************************************************************** + * Copyright (C) 2014 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. + * + ****************************************************************************/ + +// ips_stream_reassemble.cc author Russ Combs + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tcp_session.h" +#include "framework/ips_option.h" +#include "framework/module.h" +#include "framework/parameter.h" +#include "detection/detect.h" +#include "hash/sfhashfcn.h" +#include "time/profiler.h" + +//------------------------------------------------------------------------- +// stream_reassemble +//------------------------------------------------------------------------- + +#define IPS_REASS "stream_reassemble" + +static THREAD_LOCAL ProfileStats streamReassembleRuleOptionPerfStats; + +struct StreamReassembleRuleOptionData +{ + char enable; + char alert; + char direction; + char fastpath; +}; + +class ReassembleOption : public IpsOption +{ +public: + ReassembleOption(const StreamReassembleRuleOptionData& c) : + IpsOption(IPS_REASS) + { srod = c; }; + + uint32_t hash() const; + bool operator==(const IpsOption&) const; + + int eval(Cursor&, Packet*); + +private: + StreamReassembleRuleOptionData srod; +}; + +//------------------------------------------------------------------------- +// stream_reassemble option +//------------------------------------------------------------------------- + +uint32_t ReassembleOption::hash() const +{ + uint32_t a,b,c; + + a = srod.enable; + b = srod.direction; + c = srod.alert; + + mix(a,b,c); + + a = srod.fastpath; + + mix_str(a,b,c,get_name()); + final(a,b,c); + + return c; +} + +bool ReassembleOption::operator==(const IpsOption& ips) const +{ + if ( strcmp(get_name(), ips.get_name()) ) + return false; + + const ReassembleOption& rhs = (ReassembleOption&)ips; + + if ( (srod.enable == rhs.srod.enable) && + (srod.direction == rhs.srod.direction) && + (srod.alert == rhs.srod.alert) ) + return true; + + return false; +} + +int ReassembleOption::eval(Cursor&, Packet* pkt) +{ + if (!pkt->flow || !pkt->tcph) + return 0; + + PROFILE_VARS; + PREPROC_PROFILE_START(streamReassembleRuleOptionPerfStats); + + Flow *lwssn = (Flow*)pkt->flow; + TcpSession* tcpssn = (TcpSession*)lwssn->session; + + if ( !srod.enable ) /* Turn it off */ + { + if ( srod.direction & SSN_DIR_SERVER ) + tcpssn->server.flush_policy = STREAM_FLPOLICY_IGNORE; + + if ( srod.direction & SSN_DIR_CLIENT ) + tcpssn->client.flush_policy = STREAM_FLPOLICY_IGNORE; + } + else + { + // FIXIT PAF need to instantiate atom splitter? + // FIXIT PAF need to check for ips / on-data + if ( srod.direction & SSN_DIR_SERVER ) + tcpssn->server.flush_policy = STREAM_FLPOLICY_ON_ACK; + + if ( srod.direction & SSN_DIR_CLIENT ) + tcpssn->client.flush_policy = STREAM_FLPOLICY_ON_ACK; + } + + if (srod.fastpath) + { + /* Turn off inspection */ + lwssn->s5_state.ignore_direction |= srod.direction; + DisableInspection(pkt); + + /* TBD: Set TF_FORCE_FLUSH ? */ + } + + PREPROC_PROFILE_END(streamReassembleRuleOptionPerfStats); + + if (srod.alert) + return DETECTION_OPTION_MATCH; + + return DETECTION_OPTION_NO_ALERT; +} + +//------------------------------------------------------------------------- +// stream_reassemble module +//------------------------------------------------------------------------- + +static const Parameter reassemble_params[] = +{ + { "*action", Parameter::PT_ENUM, "disable|enable", nullptr, + "stop or start stream reassembly" }, + + { "*direction", Parameter::PT_ENUM, "client|server|both", nullptr, + "action applies to the given direction(s)" }, + + { "noalert", Parameter::PT_IMPLIED, nullptr, nullptr, + "don't alert when rule matches" }, + + { "fastpath", Parameter::PT_IMPLIED, nullptr, nullptr, + "optionally whitelist the remainder of the session" }, + + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } +}; + +class ReassembleModule : public Module +{ +public: + ReassembleModule() : Module(IPS_REASS, reassemble_params) { }; + + bool begin(const char*, int, SnortConfig*); + bool set(const char*, Value&, SnortConfig*); + + ProfileStats* get_profile() const + { return &streamReassembleRuleOptionPerfStats; }; + + StreamReassembleRuleOptionData srod; +}; + +bool ReassembleModule::begin(const char*, int, SnortConfig*) +{ + srod.enable = 0; + srod.direction = 0; + srod.alert = 1; + srod.fastpath = 0; + return true; +} + +bool ReassembleModule::set(const char*, Value& v, SnortConfig*) +{ + if ( v.is("*action") ) + srod.enable = v.get_long(); + + else if ( v.is("*direction") ) + srod.enable = v.get_long() + 1; + + else if ( v.is("noalert") ) + srod.alert = 0; + + else if ( v.is("fastpath") ) + srod.fastpath = 0; + + else + return false; + + return true; +} + +//------------------------------------------------------------------------- +// stream_reassemble api methods +//------------------------------------------------------------------------- + +static Module* reassemble_mod_ctor() +{ + return new ReassembleModule; +} + +static void mod_dtor(Module* m) +{ + delete m; +} + +static IpsOption* reassemble_ctor(Module* p, OptTreeNode*) +{ + ReassembleModule* m = (ReassembleModule*)p; + return new ReassembleOption(m->srod); +} + +static void opt_dtor(IpsOption* p) +{ + delete p; +} + +static const IpsApi reassemble_api = +{ + { + PT_IPS_OPTION, + IPS_REASS, + IPSAPI_PLUGIN_V0, + 0, + reassemble_mod_ctor, + mod_dtor + }, + OPT_TYPE_DETECTION, + 1, PROTO_BIT__TCP, + nullptr, + nullptr, + nullptr, + nullptr, + reassemble_ctor, + opt_dtor, + nullptr +}; + +const BaseApi* ips_stream_reassemble = &reassemble_api.base; + diff --git a/src/stream/tcp/ips_stream_size.cc b/src/stream/tcp/ips_stream_size.cc new file mode 100644 index 000000000..e24b2b0ec --- /dev/null +++ b/src/stream/tcp/ips_stream_size.cc @@ -0,0 +1,318 @@ +/**************************************************************************** + * Copyright (C) 2014 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. + * + ****************************************************************************/ + +// ips_stream_size.cc author Russ Combs + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tcp_session.h" +#include "framework/ips_option.h" +#include "framework/module.h" +#include "framework/parameter.h" +#include "detection/detect.h" +#include "hash/sfhashfcn.h" +#include "time/profiler.h" + +enum SsodOp +{ + SSOD_EQ = 1, + SSOD_NE, + SSOD_LT, + SSOD_GT, + SSOD_LE, + SSOD_GE, + SSOD_MAX +}; + +struct StreamSizeOptionData +{ + SsodOp opcode; + uint32_t size; + char direction; + + bool compare(uint32_t, uint32_t); +}; + +bool StreamSizeOptionData::compare(uint32_t size1, uint32_t size2) +{ + switch (opcode) + { + case SSOD_EQ: + return (size1 == size2); + + case SSOD_NE: + return (size1 != size2); + + case SSOD_LT: + return (size1 < size2); + + case SSOD_GT: + return (size1 > size2); + + case SSOD_LE: + return (size1 <= size2); + + case SSOD_GE: + return (size1 >= size2); + + default: + break; + } + return false; +} + +//------------------------------------------------------------------------- +// stream_size +//------------------------------------------------------------------------- + +#define IPS_SIZE "stream_size" + +static THREAD_LOCAL ProfileStats streamSizePerfStats; + +class SizeOption : public IpsOption +{ +public: + SizeOption(const StreamSizeOptionData& c) : + IpsOption(IPS_SIZE) + { ssod = c; }; + + uint32_t hash() const; + bool operator==(const IpsOption&) const; + + int eval(Cursor&, Packet*); + +private: + StreamSizeOptionData ssod; +}; + +//------------------------------------------------------------------------- +// stream_size option +//------------------------------------------------------------------------- + +uint32_t SizeOption::hash() const +{ + uint32_t a,b,c; + + a = ssod.direction; + b = ssod.opcode; + c = ssod.size; + + mix(a,b,c); + mix_str(a,b,c,get_name()); + final(a,b,c); + + return c; +} + +bool SizeOption::operator==(const IpsOption& ips) const +{ + if ( strcmp(get_name(), ips.get_name()) ) + return false; + + const SizeOption& rhs = (SizeOption&)ips; + + if ( (ssod.direction == rhs.ssod.direction) && + (ssod.opcode == rhs.ssod.opcode) && + (ssod.size == rhs.ssod.size) ) + return true; + + return false; +} + +int SizeOption::eval(Cursor&, Packet* pkt) +{ + if (!pkt->flow || !pkt->tcph) + return DETECTION_OPTION_NO_MATCH; + + PROFILE_VARS; + PREPROC_PROFILE_START(streamSizePerfStats); + + Flow *lwssn = (Flow*)pkt->flow; + TcpSession *tcpssn = (TcpSession*)lwssn->session; + + uint32_t client_size; + uint32_t server_size; + + if (tcpssn->client.l_nxt_seq > tcpssn->client.isn) + { + /* the normal case... */ + client_size = tcpssn->client.l_nxt_seq - tcpssn->client.isn; + } + else + { + /* the seq num wrapping case... */ + client_size = tcpssn->client.isn - tcpssn->client.l_nxt_seq; + } + if (tcpssn->server.l_nxt_seq > tcpssn->server.isn) + { + /* the normal case... */ + server_size = tcpssn->server.l_nxt_seq - tcpssn->server.isn; + } + else + { + /* the seq num wrapping case... */ + server_size = tcpssn->server.isn - tcpssn->server.l_nxt_seq; + } + + int result; + + switch (ssod.direction) + { + case SSN_DIR_CLIENT: + if ( ssod.compare(client_size, ssod.size) ) + result = DETECTION_OPTION_MATCH; + break; + + case SSN_DIR_SERVER: + if ( ssod.compare(server_size, ssod.size) ) + result = DETECTION_OPTION_MATCH; + break; + + case SSN_DIR_NONE: /* overloaded. really, its an 'either' */ + if ( ssod.compare(client_size, ssod.size) || + ssod.compare(server_size, ssod.size) ) + { + result = DETECTION_OPTION_MATCH; + } + break; + + case SSN_DIR_BOTH: + if ( ssod.compare(client_size, ssod.size) && + ssod.compare(server_size, ssod.size) ) + { + result = DETECTION_OPTION_MATCH; + } + break; + + default: + result = DETECTION_OPTION_NO_MATCH; + break; + } + PREPROC_PROFILE_END(streamSizePerfStats); + return result; +} + +//------------------------------------------------------------------------- +// stream_size module +//------------------------------------------------------------------------- + +static const Parameter size_params[] = +{ + { "*direction", Parameter::PT_ENUM, "either|client|server|both", nullptr, + "compare applies to the given direction(s)" }, + + { "*operator", Parameter::PT_ENUM, "= | != | < | > | <= | >=", nullptr, + "how to compare" }, + + { "*size", Parameter::PT_INT, nullptr, nullptr, + "size for comparison" }, + + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } +}; + +class SizeModule : public Module +{ +public: + SizeModule() : Module(IPS_SIZE, size_params) { }; + + bool begin(const char*, int, SnortConfig*); + bool set(const char*, Value&, SnortConfig*); + + ProfileStats* get_profile() const + { return &streamSizePerfStats; }; + + StreamSizeOptionData ssod; +}; + +bool SizeModule::begin(const char*, int, SnortConfig*) +{ + ssod.direction = 0; + ssod.opcode = SSOD_EQ; + ssod.size = 0; + return true; +} + +bool SizeModule::set(const char*, Value& v, SnortConfig*) +{ + if ( v.is("*direction") ) + ssod.direction = v.get_long(); + + else if ( v.is("*operator") ) + ssod.opcode = (SsodOp)(v.get_long() + 1); + + else if ( v.is("*size") ) + ssod.size = 0; + + else + return false; + + return true; +} + +//------------------------------------------------------------------------- +// stream_size api methods +//------------------------------------------------------------------------- + +static Module* size_mod_ctor() +{ + return new SizeModule; +} + +static void mod_dtor(Module* m) +{ + delete m; +} + +static IpsOption* size_ctor(Module* p, OptTreeNode*) +{ + SizeModule* m = (SizeModule*)p; + return new SizeOption(m->ssod); +} + +static void opt_dtor(IpsOption* p) +{ + delete p; +} + +static const IpsApi size_api = +{ + { + PT_IPS_OPTION, + IPS_SIZE, + IPSAPI_PLUGIN_V0, + 0, + size_mod_ctor, + mod_dtor + }, + OPT_TYPE_DETECTION, + 1, PROTO_BIT__TCP, + nullptr, + nullptr, + nullptr, + nullptr, + size_ctor, + opt_dtor, + nullptr +}; + +const BaseApi* ips_stream_size = &size_api.base; + diff --git a/src/stream/tcp/tcp_session.cc b/src/stream/tcp/tcp_session.cc index 3ffafa8e8..c5b78ddda 100644 --- a/src/stream/tcp/tcp_session.cc +++ b/src/stream/tcp/tcp_session.cc @@ -94,8 +94,6 @@ THREAD_LOCAL ProfileStats s5TcpPAFPerfStats; THREAD_LOCAL ProfileStats s5TcpFlushPerfStats; THREAD_LOCAL ProfileStats s5TcpBuildPacketPerfStats; THREAD_LOCAL ProfileStats s5TcpProcessRebuiltPerfStats; -THREAD_LOCAL ProfileStats streamSizePerfStats; -THREAD_LOCAL ProfileStats streamReassembleRuleOptionPerfStats; struct TcpStats { @@ -614,29 +612,6 @@ void Stream5UpdatePerfBaseState(SFBASE *sf_base, sf_base->stream5_mem_in_use = tcp_memcap->used(); } -#if 0 -static void Stream5TcpRegisterRuleOptions(SnortConfig*) -{ - // FIXIT implement preproc rule option as any other rule option - /* Register the 'stream_size' rule option */ - RegisterPreprocessorRuleOption(sc, "stream_size", &s5TcpStreamSizeInit, - &s5TcpStreamSizeEval, &s5TcpStreamSizeCleanup, - NULL, NULL, NULL, NULL); - - RegisterPreprocessorRuleOption(sc, "stream_reassemble", &s5TcpStreamReassembleRuleOptionInit, - &s5TcpStreamReassembleRuleOptionEval, &s5TcpStreamReassembleRuleOptionCleanup, - NULL, NULL, NULL, NULL); -#ifdef PERF_PROFILING - RegisterProfile( - "stream_size", &streamSizePerfStats, 4, &preprocRuleOptionPerfStats, - tcp_get_profile); - RegisterProfile( - "reassemble", &streamReassembleRuleOptionPerfStats, 4, - &preprocRuleOptionPerfStats, tcp_get_profile); -#endif -} -#endif - //------------------------------------------------------------------------- // policy translation //------------------------------------------------------------------------- @@ -6754,407 +6729,6 @@ char Stream5PacketsMissingTcp(Flow *lwssn, char dir) return 0; } -#define SSOD_LESS_THAN 1 -#define SSOD_GREATER_THAN 2 -#define SSOD_EQUALS 3 -#define SSOD_LESS_THAN_OR_EQUALS 4 -#define SSOD_GREATER_THAN_OR_EQUALS 5 -#define SSOD_NOT_EQUALS 6 - -#define SSOD_MATCH 1 -#define SSOD_NOMATCH 0 -typedef struct _StreamSizeOptionData -{ - char opcode; - uint32_t size; - char direction; -} StreamSizeOptionData; - -int s5TcpStreamSizeInit( - SnortConfig*, char *name, char *parameters, void **dataPtr) -{ - char **toks; - int num_toks; - char *endp; - StreamSizeOptionData *ssod; - toks = mSplit(parameters, ",", 4, &num_toks, 0); - - if (num_toks != 3) - { - ParseError("Invalid parameters for %s option", name); - } - - ssod = (StreamSizeOptionData*)SnortAlloc(sizeof(*ssod)); - - if (!ssod) - { - ParseError("Failed to allocate data for %s option", - name); - } - - /* Parse the direction. - * Can be: client, server, both, either - */ - if (!strcasecmp(toks[0], "client")) - { - ssod->direction = SSN_DIR_CLIENT; - } - else if (!strcasecmp(toks[0], "server")) - { - ssod->direction = SSN_DIR_SERVER; - } - else if (!strcasecmp(toks[0], "both")) - { - ssod->direction = SSN_DIR_BOTH; - } - else if (!strcasecmp(toks[0], "either")) - { - ssod->direction = SSN_DIR_NONE; - } - else - { - ParseError("Invalid direction: %s for option %s", - toks[0], name); - } - - /* Parse the opcode. - * Can be: =, <, > , !=, <=, >= - */ - if (!strcasecmp(toks[1], "=")) - { - ssod->opcode = SSOD_EQUALS; - } - else if (!strcasecmp(toks[1], "<")) - { - ssod->opcode = SSOD_LESS_THAN; - } - else if (!strcasecmp(toks[1], ">")) - { - ssod->opcode = SSOD_GREATER_THAN; - } - else if (!strcasecmp(toks[1], "!=")) - { - ssod->opcode = SSOD_NOT_EQUALS; - } - else if (!strcasecmp(toks[1], "<=")) - { - ssod->opcode = SSOD_LESS_THAN_OR_EQUALS; - } - else if (!strcasecmp(toks[1], ">=")) - { - ssod->opcode = SSOD_GREATER_THAN_OR_EQUALS; - } - else - { - ParseError("Invalid opcode: %s for option %s", - toks[1], name); - } - - ssod->size = SnortStrtoul(toks[2], &endp, 0); - if ((endp == toks[2]) || (errno == ERANGE)) - { - ParseError("Invalid size: %s for option %s", - toks[2], name); - } - - *dataPtr = ssod; - mSplitFree(&toks, num_toks); - - return 1; -} - -static inline int s5TcpStreamSizeCompare(uint32_t size1, uint32_t size2, char opcode) -{ - int retval = 0; - switch (opcode) - { - case SSOD_EQUALS: - if (size1 == size2) - retval = 1; - break; - case SSOD_LESS_THAN: - if (size1 < size2) - retval = 1; - break; - case SSOD_GREATER_THAN: - if (size1 > size2) - retval = 1; - break; - case SSOD_NOT_EQUALS: - if (size1 != size2) - retval = 1; - break; - case SSOD_LESS_THAN_OR_EQUALS: - if (size1 <= size2) - retval = 1; - break; - case SSOD_GREATER_THAN_OR_EQUALS: - if (size1 >= size2) - retval = 1; - break; - default: - break; - } - return retval; -} - -int s5TcpStreamSizeEval(Packet* pkt, const uint8_t**, void *dataPtr) -{ - Flow *lwssn = NULL; - TcpSession *tcpssn = NULL; - StreamSizeOptionData *ssod = (StreamSizeOptionData *)dataPtr; - uint32_t client_size; - uint32_t server_size; - PROFILE_VARS; - - if (!pkt || !pkt->flow || !ssod || !pkt->tcph) - return DETECTION_OPTION_NO_MATCH; - - lwssn = (Flow*)pkt->flow; - - PREPROC_PROFILE_START(streamSizePerfStats); - - tcpssn = (TcpSession *)lwssn->session; - - if (tcpssn->client.l_nxt_seq > tcpssn->client.isn) - { - /* the normal case... */ - client_size = tcpssn->client.l_nxt_seq - tcpssn->client.isn; - } - else - { - /* the seq num wrapping case... */ - client_size = tcpssn->client.isn - tcpssn->client.l_nxt_seq; - } - if (tcpssn->server.l_nxt_seq > tcpssn->server.isn) - { - /* the normal case... */ - server_size = tcpssn->server.l_nxt_seq - tcpssn->server.isn; - } - else - { - /* the seq num wrapping case... */ - server_size = tcpssn->server.isn - tcpssn->server.l_nxt_seq; - } - - switch (ssod->direction) - { - case SSN_DIR_CLIENT: - if (s5TcpStreamSizeCompare(client_size, ssod->size, ssod->opcode) - == SSOD_MATCH) - { - PREPROC_PROFILE_END(streamSizePerfStats); - return DETECTION_OPTION_MATCH; - } - break; - case SSN_DIR_SERVER: - if (s5TcpStreamSizeCompare(server_size, ssod->size, ssod->opcode) - == SSOD_MATCH) - { - PREPROC_PROFILE_END(streamSizePerfStats); - return DETECTION_OPTION_MATCH; - } - break; - case SSN_DIR_NONE: /* overloaded. really, its an 'either' */ - if ((s5TcpStreamSizeCompare(client_size, ssod->size, ssod->opcode) - == SSOD_MATCH) || - (s5TcpStreamSizeCompare(server_size, ssod->size, ssod->opcode) - == SSOD_MATCH)) - { - PREPROC_PROFILE_END(streamSizePerfStats); - return DETECTION_OPTION_MATCH; - } - break; - case SSN_DIR_BOTH: - if ((s5TcpStreamSizeCompare(client_size, ssod->size, ssod->opcode) - == SSOD_MATCH) && - (s5TcpStreamSizeCompare(server_size, ssod->size, ssod->opcode) - == SSOD_MATCH)) - { - PREPROC_PROFILE_END(streamSizePerfStats); - return DETECTION_OPTION_MATCH; - } - break; - default: - break; - } - PREPROC_PROFILE_END(streamSizePerfStats); - return DETECTION_OPTION_NO_MATCH; -} - -void s5TcpStreamSizeCleanup(void *dataPtr) -{ - StreamSizeOptionData *ssod = (StreamSizeOptionData*)dataPtr; - if (ssod) - { - free(ssod); - } -} - -typedef struct _StreamReassembleRuleOptionData -{ - char enable; - char alert; - char direction; - char fastpath; -} StreamReassembleRuleOptionData; - -int s5TcpStreamReassembleRuleOptionInit( - SnortConfig*, char *name, char *parameters, void **dataPtr) -{ - char **toks; - int num_toks; - StreamReassembleRuleOptionData *srod = NULL; - toks = mSplit(parameters, ",", 4, &num_toks, 0); - - if (num_toks < 2) - { - ParseError("Invalid parameters for %s option", name); - } - - srod = (StreamReassembleRuleOptionData*)SnortAlloc(sizeof(*srod)); - - if (!srod) - { - ParseError("Failed to allocate data for %s option", name); - } - - /* Parse the action. - * Can be: enable or disable - */ - if (!strcasecmp(toks[0], "enable")) - { - srod->enable = 1; - } - else if (!strcasecmp(toks[0], "disable")) - { - srod->enable = 0; - } - else - { - ParseError("Invalid action: %s for option %s. Valid " - "parameters are 'enable' or 'disable'", toks[0], name); - } - - /* Parse the direction. - * Can be: client, server, both - */ - /* Need to these around, so they match the ones specified via the stream_tcp ports - * option, ie, stream_tcp: ports client enables reassembly on client-sourced traffic. */ - if (!strcasecmp(toks[1], "client")) - { - srod->direction = SSN_DIR_SERVER; - } - else if (!strcasecmp(toks[1], "server")) - { - srod->direction = SSN_DIR_CLIENT; - } - else if (!strcasecmp(toks[1], "both")) - { - srod->direction = SSN_DIR_BOTH; - } - else - { - ParseError("Invalid direction: %s for option %s", toks[1], name); - } - - /* Parse the optional parameters: - * noalert flag, fastpath flag - */ - srod->alert = 1; - if (num_toks > 2) - { - int i = 2; - for (; i< num_toks; i++) - { - if (!strcasecmp(toks[i], "noalert")) - { - srod->alert = 0; - } - else if (!strcasecmp(toks[i], "fastpath")) - { - srod->fastpath = 1; - if (srod->enable) - { - ParseError("Using 'fastpath' with 'enable' is " - "not valid for %s", name); - } - } - else - { - ParseError("Invalid optional parameter: %s for option %s", - toks[i], name); - } - } - } - - *dataPtr = srod; - mSplitFree(&toks, num_toks); - - return 1; -} - -int s5TcpStreamReassembleRuleOptionEval( - Packet* pkt, const uint8_t**, void *dataPtr) -{ - Flow *lwssn = NULL; - StreamReassembleRuleOptionData *srod = (StreamReassembleRuleOptionData *)dataPtr; - PROFILE_VARS; - - if (!pkt || !pkt->flow || !srod || !pkt->tcph) - return 0; - - PREPROC_PROFILE_START(streamReassembleRuleOptionPerfStats); - lwssn = (Flow*)pkt->flow; - TcpSession* tcpssn = (TcpSession*)lwssn->session; - - if (!srod->enable) /* Turn it off */ - { - if ( srod->direction & SSN_DIR_SERVER ) - tcpssn->server.flush_policy = STREAM_FLPOLICY_IGNORE; - - if ( srod->direction & SSN_DIR_CLIENT ) - tcpssn->client.flush_policy = STREAM_FLPOLICY_IGNORE; - } - else - { - // FIXIT PAF need to instantiate atom splitter? - // FIXIT PAF need to check for ips / on-data - if ( srod->direction & SSN_DIR_SERVER ) - tcpssn->server.flush_policy = STREAM_FLPOLICY_ON_ACK; - - if ( srod->direction & SSN_DIR_CLIENT ) - tcpssn->client.flush_policy = STREAM_FLPOLICY_ON_ACK; - } - - if (srod->fastpath) - { - /* Turn off inspection */ - lwssn->s5_state.ignore_direction |= srod->direction; - DisableInspection(pkt); - - /* TBD: Set TF_FORCE_FLUSH ? */ - } - - if (srod->alert) - { - PREPROC_PROFILE_END(streamReassembleRuleOptionPerfStats); - return DETECTION_OPTION_MATCH; - } - - PREPROC_PROFILE_END(streamReassembleRuleOptionPerfStats); - return DETECTION_OPTION_NO_ALERT; -} - -void s5TcpStreamReassembleRuleOptionCleanup(void *dataPtr) -{ - StreamReassembleRuleOptionData *srod = (StreamReassembleRuleOptionData*)dataPtr; - if (srod) - { - free(srod); - } -} - void s5TcpSetSynSessionStatus( StreamTcpConfig* tcp_config, uint16_t status) { @@ -7396,10 +6970,6 @@ int TcpSession::process(Packet *p) void tcp_init() { -#if 0 - // FIXIT add inspector rule options - Stream5TcpRegisterRuleOptions(sc); -#endif } void tcp_reset() diff --git a/src/time/profiler.cc b/src/time/profiler.cc index 08630763c..45bc64197 100644 --- a/src/time/profiler.cc +++ b/src/time/profiler.cc @@ -655,11 +655,6 @@ void RegisterProfile( mpsePerfStats = &node->stats; } -void RegisterOtnProfile(const char *keyword, get_profile_func get) -{ - RegisterProfile(keyword, "rule tree eval", get); -} - void RegisterProfile(Module* m) { ProfileStats* ps = m->get_profile(); diff --git a/src/time/profiler.h b/src/time/profiler.h index c5a973fac..5163e749b 100644 --- a/src/time/profiler.h +++ b/src/time/profiler.h @@ -173,7 +173,6 @@ void RegisterProfile( const char* keyword, const char* parent, get_profile_func, class Module* owner = nullptr); -void RegisterOtnProfile(const char* keyword, get_profile_func); void RegisterProfile(class Module*); void ShowPreprocProfiles(void);