From: Russ Combs (rucombs) Date: Mon, 25 Mar 2019 16:55:42 +0000 (-0400) Subject: Merge pull request #1557 in SNORT/snort3 from ~RUCOMBS/snort3:various to master X-Git-Tag: 3.0.0-251~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9e685aeb006dba466d9e985d0a43772c387495a3;p=thirdparty%2Fsnort3.git Merge pull request #1557 in SNORT/snort3 from ~RUCOMBS/snort3:various to master Squashed commit of the following: commit b953cc05bab4496ade6f9db8a31cc9e25c965740 Author: russ Date: Sun Mar 24 12:09:49 2019 -0400 stream_tcp: fix up stream order flags -- use trivial fsm for proper flagging -- remove useless checks from smtp -- reorder tracker data members to save 48 bytes / flow commit 2a04335c17f174bb575e9179a91cb9dc81c20f4e Author: russ Date: Sat Mar 23 00:35:36 2019 -0400 stream_tcp: add track_only to disable reassembly commit bdfb917a0a350477b7d02a0acf073931e1926f81 Author: russ Date: Fri Mar 22 14:39:32 2019 -0400 conf: remove obscure and slow automatic iface var assignments; use Lua instead commit 9173b5a8862e22b2a8d2d3b86f09045d0d5a26de Author: russ Date: Thu Mar 21 20:23:06 2019 -0400 profiler: add quick exit if not configured to minimize overhead (rule times) commit 97804d99baafb7b60785f198758ba7e9d1c472cd Author: russ Date: Thu Mar 21 17:46:56 2019 -0400 appid: fixup profiling -- use generic DeepProfile instead of APPID_DEEP_PERF_PROFILING -- change tp_library to deep profile consistent with subprofiles --- diff --git a/src/flow/flow.cc b/src/flow/flow.cc index 34d01e379..a8adde24d 100644 --- a/src/flow/flow.cc +++ b/src/flow/flow.cc @@ -359,8 +359,6 @@ void Flow::markup_packet_flags(Packet* p) if ( p->packet_flags & PKT_STREAM_UNEST_UNI ) p->packet_flags ^= PKT_STREAM_UNEST_UNI; } - if ( ssn_state.session_flags & SSNFLAG_STREAM_ORDER_BAD ) - p->packet_flags |= PKT_STREAM_ORDER_BAD; } void Flow::set_direction(Packet* p) diff --git a/src/main/modules.cc b/src/main/modules.cc index b4cc46027..a0f11bfc8 100755 --- a/src/main/modules.cc +++ b/src/main/modules.cc @@ -513,6 +513,7 @@ bool ProfilerModule::set(const char* fqn, Value& v, SnortConfig* sc) bool ProfilerModule::end(const char*, int, SnortConfig* sc) { TimeProfilerStats::set_enabled(sc->profiler->time.show); + RuleContext::set_enabled(sc->profiler->rule.show); return true; } diff --git a/src/network_inspectors/appid/appid_http_session.cc b/src/network_inspectors/appid/appid_http_session.cc index 87496370c..a3c73539f 100644 --- a/src/network_inspectors/appid/appid_http_session.cc +++ b/src/network_inspectors/appid/appid_http_session.cc @@ -52,7 +52,6 @@ static const char* httpFieldName[ NUM_HTTP_FIELDS ] = // for use in debug messag "body", }; -#ifdef APPID_DEEP_PERF_PROFILING static THREAD_LOCAL snort::ProfileStats process_http_perf_stats; static ProfileStats* get_profile(const char*) { @@ -62,9 +61,6 @@ void appid_http_profiler_init() { Profiler::register_module("http_process", "appid", get_profile); } -#else -void appid_http_profiler_init() { return; } -#endif AppIdHttpSession::AppIdHttpSession(AppIdSession& asd) : asd(asd) @@ -389,9 +385,7 @@ void AppIdHttpSession::process_chp_buffers(AppidChangeBits& change_bits) int AppIdHttpSession::process_http_packet(AppidSessionDirection direction, AppidChangeBits& change_bits) { -#ifdef APPID_DEEP_PERF_PROFILING - snort::Profile profile(process_http_perf_stats); -#endif + DeepProfile profile(process_http_perf_stats); AppId service_id = APP_ID_NONE; AppId client_id = APP_ID_NONE; AppId payload_id = APP_ID_NONE; diff --git a/src/network_inspectors/appid/client_plugins/client_discovery.cc b/src/network_inspectors/appid/client_plugins/client_discovery.cc index 5f99e73d5..41272420b 100644 --- a/src/network_inspectors/appid/client_plugins/client_discovery.cc +++ b/src/network_inspectors/appid/client_plugins/client_discovery.cc @@ -52,13 +52,11 @@ using namespace snort; #define MAX_CANDIDATE_CLIENTS 10 -#ifdef APPID_DEEP_PERF_PROFILING static THREAD_LOCAL ProfileStats client_disco_perf_stats; static ProfileStats* get_profile(const char*) { return &client_disco_perf_stats; } -#endif ClientDiscovery* ClientDiscovery::discovery_manager = nullptr; THREAD_LOCAL ClientAppMatch* match_free_list = nullptr; @@ -128,9 +126,7 @@ void ClientDiscovery::initialize() for ( auto kv : udp_detectors ) kv.second->initialize(); -#ifdef APPID_DEEP_PERF_PROFILING Profiler::register_module("client_discovery", "appid", get_profile); -#endif } void ClientDiscovery::finalize_client_plugins() @@ -362,9 +358,7 @@ void ClientDiscovery::exec_client_detectors(AppIdSession& asd, Packet* p, bool ClientDiscovery::do_client_discovery(AppIdSession& asd, Packet* p, AppidSessionDirection direction, AppidChangeBits& change_bits) { -#ifdef APPID_DEEP_PERF_PROFILING - Profile profile(client_disco_perf_stats); -#endif + DeepProfile profile(client_disco_perf_stats); bool isTpAppidDiscoveryDone = false; AppInfoTableEntry* entry; uint32_t prevRnaClientState = asd.client_disco_state; diff --git a/src/network_inspectors/appid/ips_appid_option.cc b/src/network_inspectors/appid/ips_appid_option.cc index fb377a3a5..6b90aa3d5 100644 --- a/src/network_inspectors/appid/ips_appid_option.cc +++ b/src/network_inspectors/appid/ips_appid_option.cc @@ -122,11 +122,9 @@ IpsOption::EvalStatus AppIdIpsOption::eval(Cursor&, Packet* p) if ( !p->flow ) return NO_MATCH; -#ifdef APPID_DEEP_PERF_PROFILING - Profile profile(ips_appid_perf_stats); -#endif - + DeepProfile profile(ips_appid_perf_stats); AppIdSession* session = appid_api.get_appid_session(*(p->flow)); + if ( !session ) return NO_MATCH; diff --git a/src/network_inspectors/appid/lua_detector_api.cc b/src/network_inspectors/appid/lua_detector_api.cc index 1bdd445fd..181d88700 100644 --- a/src/network_inspectors/appid/lua_detector_api.cc +++ b/src/network_inspectors/appid/lua_detector_api.cc @@ -64,7 +64,6 @@ enum LuaLogLevels LUA_LOG_TRACE = 5, }; -#ifdef APPID_DEEP_PERF_PROFILING // FIXIT-L: Add separate perf stats for ODP detectors and custom // detectors if more granularity is desired static THREAD_LOCAL ProfileStats lua_validate_perf_stats; @@ -77,9 +76,6 @@ void lua_detector_profiler_init() { Profiler::register_module("lua_validate", "appid", get_profile); } -#else -void lua_detector_profiler_init() { return; } -#endif static std::unordered_map* CHP_glossary = nullptr; // tracks http multipatterns @@ -2640,9 +2636,7 @@ LuaServiceObject::LuaServiceObject(AppIdDiscovery* sdm, const std::string& detec int LuaServiceDetector::validate(AppIdDiscoveryArgs& args) { -#ifdef APPID_DEEP_PERF_PROFILING - Profile profile(lua_validate_perf_stats); -#endif + DeepProfile profile(lua_validate_perf_stats); //FIXIT-M: RELOAD - use lua references to get user data object from stack auto my_lua_state = lua_detector_mgr? lua_detector_mgr->L : nullptr; lua_settop(my_lua_state,0); @@ -2720,9 +2714,7 @@ LuaStateDescriptor* LuaObject::validate_lua_state(bool packet_context) int LuaClientDetector::validate(AppIdDiscoveryArgs& args) { -#ifdef APPID_DEEP_PERF_PROFILING - Profile profile(lua_validate_perf_stats); -#endif + DeepProfile profile(lua_validate_perf_stats); //FIXIT-M: RELOAD - use lua references to get user data object from stack auto my_lua_state = lua_detector_mgr? lua_detector_mgr->L : nullptr; std::string name = this->name + "_"; diff --git a/src/network_inspectors/appid/service_plugins/service_discovery.cc b/src/network_inspectors/appid/service_plugins/service_discovery.cc index a5f57839e..f35fcd473 100644 --- a/src/network_inspectors/appid/service_plugins/service_discovery.cc +++ b/src/network_inspectors/appid/service_plugins/service_discovery.cc @@ -86,13 +86,11 @@ using namespace snort; -#ifdef APPID_DEEP_PERF_PROFILING static THREAD_LOCAL ProfileStats service_disco_perf_stats; static ProfileStats* get_profile(const char*) { return &service_disco_perf_stats; } -#endif static ServiceDetector* ftp_service; ServiceDiscovery* ServiceDiscovery::discovery_manager = nullptr; @@ -182,9 +180,7 @@ void ServiceDiscovery::initialize() service_detector_list.emplace_back(kv.second); } -#ifdef APPID_DEEP_PERF_PROFILING Profiler::register_module("service_discovery", "appid", get_profile); -#endif } void ServiceDiscovery::finalize_service_patterns() @@ -595,9 +591,7 @@ int ServiceDiscovery::add_ftp_service_state(AppIdSession& asd) bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p, AppidSessionDirection direction, AppidChangeBits& change_bits) { -#ifdef APPID_DEEP_PERF_PROFILING - Profile profile(service_disco_perf_stats); -#endif + DeepProfile profile(service_disco_perf_stats); bool isTpAppidDiscoveryDone = false; uint32_t prevRnaServiceState = asd.service_disco_state; AppId tp_app_id = asd.get_tp_app_id(); diff --git a/src/network_inspectors/appid/tp_appid_utils.cc b/src/network_inspectors/appid/tp_appid_utils.cc index 34f1a3ce0..66a49af3a 100644 --- a/src/network_inspectors/appid/tp_appid_utils.cc +++ b/src/network_inspectors/appid/tp_appid_utils.cc @@ -54,8 +54,8 @@ using namespace snort; typedef AppIdHttpSession::pair_t pair_t; static THREAD_LOCAL ProfileStats tp_lib_perf_stats; -#ifdef APPID_DEEP_PERF_PROFILING static THREAD_LOCAL ProfileStats tp_disco_perf_stats; + static ProfileStats* get_profile(const char* key) { if ( !strcmp(key, "tp_discovery") ) @@ -64,21 +64,12 @@ static ProfileStats* get_profile(const char* key) return &tp_lib_perf_stats; return nullptr; } + void tp_appid_profiler_init() { Profiler::register_module("tp_discovery", "appid", get_profile); Profiler::register_module("tp_library", "tp_discovery", get_profile); } -#else -static ProfileStats* get_profile(const char*) -{ - return &tp_lib_perf_stats; -} -void tp_appid_profiler_init() -{ - Profiler::register_module("tp_library", "appid", get_profile); -} -#endif static inline bool contains(const vector& vec, const AppId val) { @@ -645,10 +636,7 @@ static inline void check_terminate_tp_module(AppIdSession& asd, uint16_t tpPktCo bool do_tp_discovery(AppIdSession& asd, IpProtocol protocol, Packet* p, AppidSessionDirection& direction, AppidChangeBits& change_bits) { -#ifdef APPID_DEEP_PERF_PROFILING - Profile tp_disco_profile(tp_disco_perf_stats); -#endif - + DeepProfile tp_disco_profile(tp_disco_perf_stats); AppId tp_app_id = asd.get_tp_app_id(); if (tp_app_id == APP_ID_SSH && asd.payload.get_id() != APP_ID_SFTP && @@ -685,10 +673,11 @@ bool do_tp_discovery(AppIdSession& asd, IpProtocol protocol, if (protocol != IpProtocol::TCP || (p->packet_flags & PKT_STREAM_ORDER_OK) || asd.config->mod_config->tp_allow_probes) { - Profile tp_lib_profile(tp_lib_perf_stats); + DeepProfile tp_lib_profile(tp_lib_perf_stats); int tp_confidence; ThirdPartyAppIDAttributeData tp_attribute_data; vector tp_proto_list; + if (!asd.tpsession) { const TPLibHandler* tph = TPLibHandler::get(); diff --git a/src/parser/parser.cc b/src/parser/parser.cc index a5b6f3473..11e28ddcf 100644 --- a/src/parser/parser.cc +++ b/src/parser/parser.cc @@ -201,98 +201,6 @@ static void OtnInit(SnortConfig* sc) ParseAbort("ParseRulesFile otn_map ghash_new failed."); } -#define IFACE_VARS_MAX 128 -typedef struct iface_var -{ - char name[128]; - uint32_t net; - uint32_t netmask; -} iface_var_t; - -/**************************************************************************** - * - * Function : DefineIfaceVar() - * Purpose : Assign network address and network mask to IFACE_ADDR_VARNAME - * variable. - * Arguments : interface name (string) netaddress and netmask (4 octets each) - * Returns : void function - * - ****************************************************************************/ -static void DefineIfaceVar(SnortConfig* sc, char* iname, const uint8_t* network, const uint8_t* netmask) -{ - char valbuf[32]; - char varbuf[BUFSIZ]; - - if ((network == nullptr) || (*network == 0)) - return; - - SnortSnprintf(varbuf, BUFSIZ, "%s_ADDRESS", iname); - - SnortSnprintf(valbuf, 32, "%d.%d.%d.%d/%d.%d.%d.%d", - network[0] & 0xff, network[1] & 0xff, network[2] & 0xff, - network[3] & 0xff, netmask[0] & 0xff, netmask[1] & 0xff, - netmask[2] & 0xff, netmask[3] & 0xff); - - VarDefine(sc, varbuf, valbuf); -} - -// Find all up interfaces and define iface_ADDRESS vars for them -static void DefineAllIfaceVars(SnortConfig* sc) -{ - // FIXIT-L don't come back here on reload unless we are going to find - // new ifaces. Cache retrieved devs so if user is running with dropped - // privs and does a reload, we can use previous values - static int num_vars = 0; - - // should be more than enough to cover the number of interfaces on a machine - static iface_var_t iface_vars[IFACE_VARS_MAX]; - - if (num_vars > 0) - { - int i; - - for (i = 0; i < num_vars; i++) - { - DefineIfaceVar(sc, iface_vars[i].name, - (uint8_t*)&iface_vars[i].net, - (uint8_t*)&iface_vars[i].netmask); - } - } - else - { - char errbuf[PCAP_ERRBUF_SIZE]; - pcap_if_t* alldevs; - pcap_if_t* dev; - bpf_u_int32 net, netmask; - - if (pcap_findalldevs(&alldevs, errbuf) == -1) - return; - - for (dev = alldevs; dev != nullptr; dev = dev->next) - { - if (pcap_lookupnet(dev->name, &net, &netmask, errbuf) == 0) - { - /* We've hit the maximum variables we can cache */ - if (num_vars >= IFACE_VARS_MAX) - break; - - SnortSnprintf(iface_vars[num_vars].name, - sizeof(iface_vars[num_vars].name), "%s", dev->name); - - DefineIfaceVar(sc, iface_vars[num_vars].name, - (uint8_t*)&net, - (uint8_t*)&netmask); - - iface_vars[num_vars].net = net; - iface_vars[num_vars].netmask = netmask; - num_vars++; - } - } - - pcap_freealldevs(alldevs); - } -} - static RuleListNode* addNodeToOrderedList(RuleListNode* ordered_list, RuleListNode* node, int evalIndex) { @@ -397,11 +305,6 @@ SnortConfig* ParseSnortConf(const SnortConfig* boot_conf, const char* fname, boo sc->rate_filter_config = RateFilter_ConfigNew(); sc->detection_filter_config = DetectionFilterConfigNew(); - /* If snort is not run with root privileges, no interfaces will be defined, - * so user beware if an iface_ADDRESS variable is used in snort.conf and - * snort is not run as root (even if just in read mode) */ - DefineAllIfaceVars(sc); - /* Add command line defined variables - duplicates will already * have been resolved */ while (tmp != nullptr) diff --git a/src/profiler/rule_profiler.cc b/src/profiler/rule_profiler.cc index e1a15eb6d..3fa0d078f 100644 --- a/src/profiler/rule_profiler.cc +++ b/src/profiler/rule_profiler.cc @@ -55,6 +55,8 @@ using namespace snort; #define s_rule_table_title "rule profile" +bool RuleContext::enabled = false; + static inline OtnState& operator+=(OtnState& lhs, const OtnState& rhs) { lhs.elapsed += rhs.elapsed; @@ -334,7 +336,7 @@ void reset_rule_profiler_stats() void RuleContext::stop(bool match) { - if ( finished ) + if ( !enabled or finished ) return; finished = true; @@ -682,6 +684,7 @@ TEST_CASE( "rule profiler sorting", "[profiler][rule_profiler]" ) TEST_CASE( "rule profiler time context", "[profiler][rule_profiler]" ) { dot_node_state_t stats; + RuleContext::set_enabled(true); stats.elapsed = 0_ticks; stats.checks = 0; @@ -740,12 +743,14 @@ TEST_CASE( "rule profiler time context", "[profiler][rule_profiler]" ) CHECK( stats.elapsed_match == save.elapsed_match ); CHECK( stats.checks == save.checks ); } + RuleContext::set_enabled(false); } TEST_CASE( "rule pause", "[profiler][rule_profiler]" ) { dot_node_state_t stats; RuleContext ctx(stats); + RuleContext::set_enabled(true); { RulePause pause(ctx); @@ -753,6 +758,7 @@ TEST_CASE( "rule pause", "[profiler][rule_profiler]" ) } CHECK( ctx.active() ); + RuleContext::set_enabled(false); } #endif diff --git a/src/profiler/rule_profiler_defs.h b/src/profiler/rule_profiler_defs.h index d168b47d0..c0a7988eb 100644 --- a/src/profiler/rule_profiler_defs.h +++ b/src/profiler/rule_profiler_defs.h @@ -55,20 +55,24 @@ public: { stop(); } void start() - { sw.start(); } + { if ( enabled ) sw.start(); } void pause() - { sw.stop(); } + { if ( enabled ) sw.stop(); } void stop(bool = false); bool active() const - { return sw.active(); } + { return enabled and sw.active(); } + + static void set_enabled(bool b) + { enabled = b; } private: dot_node_state_t& stats; Stopwatch sw; bool finished = false; + static bool enabled; }; class RulePause diff --git a/src/service_inspectors/smtp/smtp.cc b/src/service_inspectors/smtp/smtp.cc index 1ff7e1beb..1aaef0436 100644 --- a/src/service_inspectors/smtp/smtp.cc +++ b/src/service_inspectors/smtp/smtp.cc @@ -1050,14 +1050,7 @@ static void SMTP_ProcessServerPacket( else if ( !p->test_session_flags(SSNFLAG_MIDSTREAM) && !Stream::missed_packets(p->flow, SSN_DIR_BOTH)) { - /* Check to see if the raw packet is in order */ - if (p->packet_flags & PKT_STREAM_ORDER_OK) - { - /* revert back to command state - assume server didn't accept STARTTLS */ - smtp_ssn->state = STATE_COMMAND; - } - else - return; + smtp_ssn->state = STATE_COMMAND; } } @@ -1188,7 +1181,7 @@ static void snort_smtp(SMTP_PROTO_CONF* config, Packet* p) { smtp_ssn->state = STATE_TLS_SERVER_PEND; } - else if (p->packet_flags & PKT_STREAM_ORDER_OK) + else { /* reset state - server may have rejected STARTTLS command */ smtp_ssn->state = STATE_COMMAND; diff --git a/src/stream/libtcp/tcp_stream_tracker.cc b/src/stream/libtcp/tcp_stream_tracker.cc index 425796630..86eb7ece4 100644 --- a/src/stream/libtcp/tcp_stream_tracker.cc +++ b/src/stream/libtcp/tcp_stream_tracker.cc @@ -55,7 +55,7 @@ const char* tcp_event_names[] = { }; TcpStreamTracker::TcpStreamTracker(bool client) : - client_tracker(client), tcp_state(client ? TCP_STATE_NONE : TCP_LISTEN) + tcp_state(client ? TCP_STATE_NONE : TCP_LISTEN), client_tracker(client) { } TcpStreamTracker::~TcpStreamTracker() @@ -198,6 +198,7 @@ void TcpStreamTracker::init_tcp_state() fin_seq_status = TcpStreamTracker::FIN_NOT_SEEN; fin_seq_set = false; rst_pkt_sent = false; + order = 0; } //------------------------------------------------------------------------- diff --git a/src/stream/libtcp/tcp_stream_tracker.h b/src/stream/libtcp/tcp_stream_tracker.h index b2f0fd2d4..920ee7d50 100644 --- a/src/stream/libtcp/tcp_stream_tracker.h +++ b/src/stream/libtcp/tcp_stream_tracker.h @@ -51,7 +51,7 @@ class TcpSession; class TcpStreamTracker { public: - enum TcpState + enum TcpState : uint8_t { TCP_LISTEN, TCP_SYN_SENT, @@ -68,7 +68,7 @@ public: TCP_MAX_STATES }; - enum TcpEvent + enum TcpEvent : uint8_t { TCP_SYN_SENT_EVENT, TCP_SYN_RECV_EVENT, @@ -85,7 +85,7 @@ public: TCP_MAX_EVENTS }; - enum FinSeqNumStatus { FIN_NOT_SEEN, FIN_WITH_SEQ_SEEN, FIN_WITH_SEQ_ACKED }; + enum FinSeqNumStatus : uint8_t { FIN_NOT_SEEN, FIN_WITH_SEQ_SEEN, FIN_WITH_SEQ_ACKED }; TcpStreamTracker(bool client); virtual ~TcpStreamTracker(); @@ -277,63 +277,71 @@ public: virtual bool is_segment_seq_valid(TcpSegmentDescriptor&); virtual void flush_data_on_fin_recv(TcpSegmentDescriptor&); - bool client_tracker; - TcpState tcp_state; - TcpEvent tcp_event = TCP_MAX_EVENTS; - bool require_3whs = false; - +public: uint32_t snd_una = 0; // SND.UNA - send unacknowledged uint32_t snd_nxt = 0; // SND.NXT - send next uint32_t snd_wnd = 0; // SND.WND - send window - uint16_t snd_up = 0; // SND.UP - send urgent pointer uint32_t snd_wl1 = 0; // SND.WL1 - segment sequence number used for last window update uint32_t snd_wl2 = 0; // SND.WL2 - segment acknowledgment number used for last window update uint32_t iss = 0; // ISS - initial send sequence number uint32_t rcv_nxt = 0; // RCV.NXT - receive next uint32_t rcv_wnd = 0; // RCV.WND - receive window - uint16_t rcv_up = 0; // RCV.UP - receive urgent pointer uint32_t irs = 0; // IRS - initial receive sequence number + uint16_t snd_up = 0; // SND.UP - send urgent pointer + uint16_t rcv_up = 0; // RCV.UP - receive urgent pointer + + TcpState tcp_state; + TcpEvent tcp_event = TCP_MAX_EVENTS; + + bool client_tracker; + bool require_3whs = false; bool rst_pkt_sent = false; // FIXIT-L make these non-public public: - uint32_t r_win_base = 0; /* remote side window base sequence number - * (i.e. the last ack we got) */ - - TcpSession* session = nullptr; TcpNormalizerPolicy normalizer; TcpReassemblerPolicy reassembler; - snort::StreamSplitter* splitter = nullptr; - uint32_t small_seg_count = 0; - uint8_t alert_count = 0; StreamAlertInfo alerts[MAX_SESSION_ALERTS]; - FlushPolicy flush_policy = STREAM_FLPOLICY_IGNORE; + // this is intended to be private to paf but is included // directly to avoid the need for allocation; do not directly // manipulate within this module. PAF_State paf_state; // for tracking protocol aware flushing + TcpSession* session = nullptr; + snort::StreamSplitter* splitter = nullptr; + + FlushPolicy flush_policy = STREAM_FLPOLICY_IGNORE; + + uint32_t r_win_base = 0; // remote side window base sequence number (the last ack we got) + uint32_t small_seg_count = 0; + + uint16_t wscale = 0; /* window scale setting */ + uint16_t mss = 0; /* max segment size */ + + uint8_t alert_count = 0; + uint8_t order = 0; + + FinSeqNumStatus fin_seq_status = TcpStreamTracker::FIN_NOT_SEEN; + protected: // FIXIT-H reorganize per-flow structs to minimize padding uint32_t ts_last_packet = 0; uint32_t ts_last = 0; /* last timestamp (for PAWS) */ - uint16_t tf_flags = 0; - uint8_t mac_addr[6] = { }; - bool mac_addr_valid = false; uint32_t fin_final_seq = 0; uint32_t fin_seq_adjust = 0; - bool fin_seq_set = false; // FIXIT-M should be obviated by tcp state + + uint16_t tf_flags = 0; + + uint8_t mac_addr[6] = { }; uint8_t tcp_options_len = 0; - // FIXIT-L make this protected... -public: - uint16_t wscale = 0; /* window scale setting */ - uint16_t mss = 0; /* max segment size */ - FinSeqNumStatus fin_seq_status = TcpStreamTracker::FIN_NOT_SEEN; + bool mac_addr_valid = false; + bool fin_seq_set = false; // FIXIT-M should be obviated by tcp state }; // <--- note -- the 'state' parameter must be a reference diff --git a/src/stream/tcp/tcp_module.cc b/src/stream/tcp/tcp_module.cc index 6c6cf00ab..6698937fb 100644 --- a/src/stream/tcp/tcp_module.cc +++ b/src/stream/tcp/tcp_module.cc @@ -187,6 +187,9 @@ static const Parameter s_params[] = { "session_timeout", Parameter::PT_INT, "1:max31", "30", "session tracking timeout" }, + { "track_only", Parameter::PT_BOOL, nullptr, "false", + "disable reassembly if true" }, + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } }; @@ -331,6 +334,13 @@ bool StreamTcpModule::set(const char*, Value& v, SnortConfig*) else config->flags &= ~STREAM_CONFIG_SHOW_PACKETS; } + else if ( v.is("track_only") ) + { + if ( v.get_bool() ) + config->flags |= STREAM_CONFIG_NO_REASSEMBLY; + else + config->flags &= ~STREAM_CONFIG_NO_REASSEMBLY; + } else return false; diff --git a/src/stream/tcp/tcp_session.cc b/src/stream/tcp/tcp_session.cc index f5aa03aa9..6a0593de4 100644 --- a/src/stream/tcp/tcp_session.cc +++ b/src/stream/tcp/tcp_session.cc @@ -343,6 +343,30 @@ void TcpSession::process_tcp_stream(TcpSegmentDescriptor& tsd) } } +void TcpSession::update_stream_order(TcpSegmentDescriptor& tsd, bool aligned) +{ + switch ( listener->order ) + { + case 0: + if ( aligned ) + tsd.get_pkt()->packet_flags |= PKT_STREAM_ORDER_OK; + else + listener->order = 1; + break; + case 1: + if ( aligned ) + { + tsd.get_pkt()->packet_flags |= PKT_STREAM_ORDER_OK; + listener->order = 2; + } + break; + default: + if ( !(flow->get_session_flags() & SSNFLAG_STREAM_ORDER_BAD) ) + flow->set_session_flags(SSNFLAG_STREAM_ORDER_BAD); + tsd.get_pkt()->packet_flags |= PKT_STREAM_ORDER_BAD; + } +} + int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd) { DeepProfile profile(s5TcpDataPerfStats); @@ -378,12 +402,8 @@ int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd) if (tsd.get_seg_len() != 0) { - if (!( flow->get_session_flags() & SSNFLAG_STREAM_ORDER_BAD)) - tsd.get_pkt()->packet_flags |= PKT_STREAM_ORDER_OK; - + update_stream_order(tsd, true); process_tcp_stream(tsd); - /* set flags to session flags */ - return STREAM_ALIGNED; } } @@ -402,25 +422,9 @@ int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd) listener->normalizer.trim_win_payload(tsd); return STREAM_UNALIGNED; } - - if ((listener->get_tcp_state() == TcpStreamTracker::TCP_ESTABLISHED) - && (listener->flush_policy == STREAM_FLPOLICY_IGNORE)) - { - if (SEQ_GT(tsd.get_end_seq(), listener->rcv_nxt)) - { - // set next ack so we are within the window going forward on this side. - // FIXIT-L for ips, must move all the way to first hole or right end - listener->rcv_nxt = tsd.get_end_seq(); - } - } - if (tsd.get_seg_len() != 0) { - if (!( flow->get_session_flags() & SSNFLAG_STREAM_ORDER_BAD)) - { - if (!SEQ_LEQ((tsd.get_seg_seq() + tsd.get_seg_len()), listener->rcv_nxt)) - flow->set_session_flags(SSNFLAG_STREAM_ORDER_BAD); - } + update_stream_order(tsd, false); process_tcp_stream(tsd); } } @@ -967,12 +971,14 @@ bool TcpSession::do_packet_analysis_pre_checks(Packet* p, TcpSegmentDescriptor& if ( !splitter_init and tsd.get_seg_len() > 0 ) { - client.set_splitter(tsd.get_flow()); - server.set_splitter(tsd.get_flow()); - - client.init_flush_policy(); - server.init_flush_policy(); + if ( !(config->flags & STREAM_CONFIG_NO_REASSEMBLY) ) + { + client.set_splitter(tsd.get_flow()); + server.set_splitter(tsd.get_flow()); + client.init_flush_policy(); + server.init_flush_policy(); + } splitter_init = true; } diff --git a/src/stream/tcp/tcp_session.h b/src/stream/tcp/tcp_session.h index 7b9de1e5b..ba247867b 100644 --- a/src/stream/tcp/tcp_session.h +++ b/src/stream/tcp/tcp_session.h @@ -72,6 +72,7 @@ public: private: void set_os_policy() override; bool flow_exceeds_config_thresholds(TcpSegmentDescriptor&); + void update_stream_order(TcpSegmentDescriptor&, bool aligned); void process_tcp_stream(TcpSegmentDescriptor&); int process_tcp_data(TcpSegmentDescriptor&); void swap_trackers(); diff --git a/src/stream/tcp/tcp_stream_config.h b/src/stream/tcp/tcp_stream_config.h index f5c48b457..5bbf98196 100644 --- a/src/stream/tcp/tcp_stream_config.h +++ b/src/stream/tcp/tcp_stream_config.h @@ -28,6 +28,7 @@ #define STREAM_CONFIG_SHOW_PACKETS 0x00000001 #define STREAM_CONFIG_NO_ASYNC_REASSEMBLY 0x00000002 +#define STREAM_CONFIG_NO_REASSEMBLY 0x00000004 #define STREAM_DEFAULT_SSN_TIMEOUT 30