]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Detect files when they are transferred in segments in SMB2
authorhuica <huica@cisco.com>
Fri, 23 Sep 2016 16:21:00 +0000 (12:21 -0400)
committerhuica <huica@cisco.com>
Fri, 23 Sep 2016 16:21:00 +0000 (12:21 -0400)
254 files changed:
ChangeLog
cmake/configure_options.cmake
cmake/create_options.cmake
config.cmake.h.in
configure.ac
configure_cmake.sh
extra/src/inspectors/http_server/hi_main.cc
extra/src/inspectors/http_server/hi_main.h
extra/src/inspectors/http_server/hi_si.cc
extra/src/inspectors/http_server/hi_stream_splitter.cc
extra/src/inspectors/http_server/hi_stream_splitter.h
extra/src/inspectors/http_server/hi_util.h
extra/src/inspectors/http_server/http_inspect.cc
lua/snort.lua
src/CMakeLists.txt
src/Makefile.am
src/codecs/ip/cd_ipv4.cc
src/codecs/ip/cd_ipv6.cc
src/codecs/ip/cd_tcp.cc
src/connectors/tcp_connector/test/tcp_connector_test.cc
src/detection/detect.cc
src/detection/detection_options.cc
src/detection/fp_create.cc
src/detection/fp_detect.cc
src/detection/fp_detect.h
src/file_api/CMakeLists.txt
src/file_api/Makefile.am
src/file_api/circular_buffer.cc
src/file_api/circular_buffer.h
src/file_api/file_api.h
src/file_api/file_cache.cc [new file with mode: 0644]
src/file_api/file_cache.h [new file with mode: 0644]
src/file_api/file_config.cc
src/file_api/file_config.h
src/file_api/file_enforcer.cc
src/file_api/file_enforcer.h
src/file_api/file_flows.cc
src/file_api/file_flows.h
src/file_api/file_identifier.cc
src/file_api/file_identifier.h
src/file_api/file_lib.cc
src/file_api/file_lib.h
src/file_api/file_log.cc
src/file_api/file_module.cc
src/file_api/file_module.h
src/file_api/file_policy.cc
src/file_api/file_policy.h
src/file_api/file_segment.cc [new file with mode: 0644]
src/file_api/file_segment.h [new file with mode: 0644]
src/file_api/file_service.cc
src/file_api/file_service.h
src/file_api/file_stats.cc
src/file_api/file_stats.h
src/flow/expect_cache.cc
src/flow/flow.cc
src/flow/flow.h
src/flow/flow_cache.cc
src/flow/flow_cache.h
src/flow/flow_config.h
src/flow/flow_control.cc
src/flow/flow_control.h
src/flow/ha.cc
src/flow/session.h
src/flow/test/ha_test.cc
src/framework/ips_option.h
src/framework/range.cc
src/framework/range.h
src/host_tracker/host_tracker_module.cc
src/ips_options/ips_content.cc
src/ips_options/ips_file_type.cc
src/ips_options/ips_flow.cc
src/ips_options/ips_flowbits.cc
src/ips_options/ips_flowbits.h
src/ips_options/ips_regex.cc
src/ips_options/ips_sd_pattern.cc
src/ips_options/test/ips_regex_test.cc
src/latency/latency_module.cc
src/latency/latency_stats.h
src/latency/packet_latency.cc
src/latency/rule_latency.cc
src/loggers/log_pcap.cc
src/loggers/unified2.cc
src/main/build.h
src/main/modules.cc
src/main/snort.cc
src/memory/prune_handler.cc
src/network_inspectors/appid/appid_api.cc
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/detector_plugins/detector_imap.cc
src/network_inspectors/appid/detector_plugins/detector_kerberos.cc
src/network_inspectors/appid/detector_plugins/detector_pop3.cc
src/network_inspectors/appid/fw_appid.cc
src/network_inspectors/appid/ips_appid_option.cc
src/network_inspectors/appid/service_plugins/service_rpc.cc
src/network_inspectors/appid/test/external_apis.cc
src/network_inspectors/appid/test/external_apis.h
src/network_inspectors/appid/test/mpse.cc
src/network_inspectors/binder/CMakeLists.txt
src/network_inspectors/binder/Makefile.am
src/network_inspectors/binder/binder.cc
src/network_inspectors/binder/test/binder_test.cc
src/network_inspectors/normalize/norm.cc
src/network_inspectors/normalize/norm_module.cc
src/network_inspectors/port_scan/ps_detect.cc
src/network_inspectors/reputation/reputation_inspect.cc
src/network_inspectors/reputation/reputation_inspect.h
src/packet_io/active.cc
src/parser/parse_rule.cc
src/parser/parse_rule.h
src/profiler/memory_profiler.cc
src/profiler/profiler_stats_table.cc
src/profiler/rule_profiler.cc
src/profiler/rule_profiler_defs.h
src/profiler/time_profiler.cc
src/profiler/time_profiler_defs.h
src/protocols/packet_manager.cc
src/search_engines/hyperscan.cc
src/search_engines/test/hyperscan_test.cc
src/service_inspectors/dce_rpc/CMakeLists.txt
src/service_inspectors/dce_rpc/Makefile.am
src/service_inspectors/dce_rpc/dce_co.cc
src/service_inspectors/dce_rpc/dce_common.cc
src/service_inspectors/dce_rpc/dce_common.h
src/service_inspectors/dce_rpc/dce_smb.cc
src/service_inspectors/dce_rpc/dce_smb2.cc
src/service_inspectors/dce_rpc/dce_smb_module.cc
src/service_inspectors/dce_rpc/dce_smb_module.h
src/service_inspectors/dce_rpc/dce_smb_paf.h
src/service_inspectors/dce_rpc/dce_tcp.cc
src/service_inspectors/dce_rpc/dce_tcp_module.cc
src/service_inspectors/dce_rpc/dce_tcp_module.h
src/service_inspectors/dce_rpc/dce_tcp_paf.h
src/service_inspectors/dce_rpc/dce_udp.cc [new file with mode: 0644]
src/service_inspectors/dce_rpc/dce_udp.h [new file with mode: 0644]
src/service_inspectors/dce_rpc/dce_udp_module.cc [new file with mode: 0644]
src/service_inspectors/dce_rpc/dce_udp_module.h [new file with mode: 0644]
src/service_inspectors/dce_rpc/ips_dce_iface.cc
src/service_inspectors/dnp3/dnp3.cc
src/service_inspectors/dnp3/dnp3_paf.h
src/service_inspectors/dnp3/ips_dnp3_data.cc
src/service_inspectors/dnp3/ips_dnp3_func.cc
src/service_inspectors/dnp3/ips_dnp3_ind.cc
src/service_inspectors/dnp3/ips_dnp3_obj.cc
src/service_inspectors/dns/dns.cc
src/service_inspectors/dns/dns.h
src/service_inspectors/ftp_telnet/ftp.cc
src/service_inspectors/ftp_telnet/ftp_data.cc
src/service_inspectors/ftp_telnet/ftpp_si.cc
src/service_inspectors/ftp_telnet/ftpp_si.h
src/service_inspectors/ftp_telnet/pp_ftp.cc
src/service_inspectors/ftp_telnet/pp_telnet.cc
src/service_inspectors/ftp_telnet/telnet.cc
src/service_inspectors/gtp/gtp.cc
src/service_inspectors/gtp/ips_gtp_info.cc
src/service_inspectors/gtp/ips_gtp_type.cc
src/service_inspectors/gtp/ips_gtp_version.cc
src/service_inspectors/http_inspect/http_flow_data.h
src/service_inspectors/http_inspect/http_inspect.cc
src/service_inspectors/http_inspect/http_msg_section.h
src/service_inspectors/http_inspect/http_stream_splitter_reassemble.cc
src/service_inspectors/http_inspect/http_stream_splitter_scan.cc
src/service_inspectors/imap/imap.cc
src/service_inspectors/imap/imap.h
src/service_inspectors/imap/imap_paf.cc
src/service_inspectors/imap/imap_paf.h
src/service_inspectors/modbus/ips_modbus_func.cc
src/service_inspectors/modbus/ips_modbus_unit.cc
src/service_inspectors/modbus/modbus.cc
src/service_inspectors/modbus/modbus_decode.cc
src/service_inspectors/pop/pop.cc
src/service_inspectors/pop/pop.h
src/service_inspectors/pop/pop_paf.cc
src/service_inspectors/pop/pop_paf.h
src/service_inspectors/rpc_decode/rpc_decode.cc
src/service_inspectors/service_inspectors.cc
src/service_inspectors/sip/sip.cc
src/service_inspectors/sip/sip.h
src/service_inspectors/sip/sip_dialog.cc
src/service_inspectors/smtp/smtp.cc
src/service_inspectors/smtp/smtp.h
src/service_inspectors/smtp/smtp_paf.cc
src/service_inspectors/smtp/smtp_paf.h
src/service_inspectors/smtp/smtp_util.cc
src/service_inspectors/ssh/ssh.cc
src/service_inspectors/ssh/ssh.h
src/service_inspectors/ssl/ssl_inspector.cc
src/service_inspectors/ssl/ssl_inspector.h
src/stream/CMakeLists.txt
src/stream/Makefile.am
src/stream/base/stream_base.cc
src/stream/base/stream_ha.cc
src/stream/base/stream_module.cc
src/stream/base/stream_module.h
src/stream/file/file_module.cc
src/stream/file/file_module.h
src/stream/icmp/dev_notes.txt
src/stream/icmp/icmp_ha.cc
src/stream/icmp/icmp_module.cc
src/stream/icmp/icmp_module.h
src/stream/icmp/icmp_session.cc
src/stream/ip/dev_notes.txt
src/stream/ip/ip_ha.cc
src/stream/ip/ip_module.cc
src/stream/ip/ip_module.h
src/stream/ip/ip_session.cc
src/stream/ip/stream_ip.h
src/stream/libtcp/dev_notes.txt
src/stream/libtcp/tcp_stream_session.h
src/stream/libtcp/tcp_stream_tracker.cc
src/stream/libtcp/tcp_stream_tracker.h
src/stream/paf.cc
src/stream/paf.h
src/stream/stream.cc [moved from src/stream/stream_api.cc with 85% similarity]
src/stream/stream.h
src/stream/stream_api.h [deleted file]
src/stream/stream_splitter.cc
src/stream/stream_splitter.h
src/stream/tcp/dev_notes.txt
src/stream/tcp/ips_stream_reassemble.cc
src/stream/tcp/segment_overlap_editor.h
src/stream/tcp/stream_tcp.h
src/stream/tcp/tcp_defs.h
src/stream/tcp/tcp_ha.cc
src/stream/tcp/tcp_module.cc
src/stream/tcp/tcp_module.h
src/stream/tcp/tcp_reassembler.cc
src/stream/tcp/tcp_reassembler.h
src/stream/tcp/tcp_session.cc
src/stream/tcp/tcp_state_closed.cc
src/stream/tcp/tcp_state_none.cc
src/stream/tcp/tcp_state_syn_sent.cc
src/stream/tcp/tcp_stream_config.h
src/stream/tcp/tcp_tracker.cc
src/stream/tcp/tcp_tracker.h
src/stream/udp/dev_notes.txt
src/stream/udp/udp_ha.cc
src/stream/udp/udp_module.cc
src/stream/udp/udp_module.h
src/stream/udp/udp_session.cc
src/stream/user/user_module.cc
src/stream/user/user_session.cc
src/target_based/snort_protocols.cc
src/time/CMakeLists.txt
src/time/Makefile.am
src/time/clock_defs.h
src/time/cpuclock.h [deleted file]
src/time/stopwatch_test.cc
src/time/tsc_clock.cc [new file with mode: 0644]
src/time/tsc_clock.h [new file with mode: 0644]
src/utils/bitop.h
src/utils/bitop_test.cc
src/utils/util.cc
tools/snort2lua/config_states/config_one_int_option.cc
tools/snort2lua/config_states/config_one_string_option.cc

index 3dad43f22b634b545155564c3482af15bbfca52b..601cf8e5a98ba0a2ca1014559e89b3d1ff9e2ecc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+16/09/22 - build 211
+
+-- fix hyperscan detection with nocase
+-- fix shutdown sequence
+-- fix --dirty-pig
+-- fix FreeBSD build re appid / service_rpc
+
+16/09/20 - build 210
+
+-- started dce_udp porting
+-- added HA details to stream/* dev_notes
+-- added stream.ip_frag_only to avoid tracking unwanted flows
+-- updated default stream cache sizes to match 2.X
+-- fixed tcp_connector_test for OSX build
+-- fixed binder make files to include binder.h
+-- fixed double counting of ip and udp timeouts and prunes
+-- fixed clearing of SYN - RST flows
+
+16/09/14 - build 209
+
+-- add dce iface fast pattern for tcp
+-- add --enable-tsc-clock to build/use TSC register (on x86)
+-- update latency to use ticks during runtime
+-- tcp stream reassembly tweaks
+-- fix inverted detection_filter logic
+-- fix stream profile stats parents
+-- fix most bogus gap counts
+-- unit test fixes for high availability, hyperscan, and regex
+
 16/09/09 - build 208
 
 -- fixed for TCP high availability
index b4ec0b5c5890d1b960332749fbd2d979da23822c..d116576384c3e650cb266837ae471fa2fb3aa198 100644 (file)
@@ -12,6 +12,7 @@ if ( NOT ENABLE_COREFILES )
 endif ( NOT ENABLE_COREFILES )
 
 set ( _LARGEFILE_SOURCE ${ENABLE_LARGE_PCAP} )
+set ( USE_TSC_CLOCK ${ENABLE_TSC_CLOCK} )
 
 if ( ENABLE_LARGE_PCAP )
     set ( _FILE_OFFSET_BITS 64 )
index 24b4d6b1879f91ec927500c64a65628be6074861..a7438f46211b34f4a0298f88d1195f80ec349974 100644 (file)
@@ -22,6 +22,7 @@ option ( ENABLE_PIGLET "enable piglet test harness" OFF )
 option ( ENABLE_COREFILES "Prevent Snort from generating core files" ON )
 option ( ENABLE_INTEL_SOFT_CPM "Enable Intel Soft CPM support" OFF )
 option ( ENABLE_LARGE_PCAP "Enable support for pcaps larger than 2 GB" OFF )
+option ( ENABLE_TSC_CLOCK "Use timestamp counter register clock (x86 only)" OFF )
 
 # documentation
 option ( MAKE_HTML_DOC "Create the HTML documentation" ON )
index 6d912c481222c1a91ae8097752b73427ded19ff0..9649829e8e6e7de76eca713b5cdd8d5d90bf66db 100644 (file)
 #cmakedefine _LARGEFILE_SOURCE 1
 #cmakedefine _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@
 
+/* enable ha capable build */
+#cmakedefine USE_TSC_CLOCK 1
 
 
 /* platforms */
index 53eaef708138e6b17f0a028f1c44f111f179c330..c50576c7714a26fa5cc28b7ae0eca284dfedacf9 100644 (file)
@@ -377,6 +377,14 @@ if test "x$enable_shell" = "xyes"; then
     AC_DEFINE(SHELL, [1], [enable shell support])
 fi
 
+AC_ARG_ENABLE(tsc-clock,
+    AS_HELP_STRING([--enable-tsc-clock],[use timestamp counter register clock (x86 only)]),
+    enable_tsc_clock="$enableval", enable_tsc_clock="no")
+
+if test "x$enable_tsc_clock" = "xyes"; then
+    AC_DEFINE(USE_TSC_CLOCK, [1], [enable tsc clock])
+fi
+
 AC_ARG_ENABLE(large-pcap,
     AS_HELP_STRING([--enable-large-pcap],[enable support for pcaps larger than 2 GB]),
     enable_large_pcap="$enableval", enable_large_pcap="no")
index fabb5f307c949214cf87758645f07ff33608a0fa..bf47415bd40704c03631e6c43f2b2b918604c81d 100755 (executable)
@@ -40,6 +40,7 @@ Optional Features:
     --disable-static-codecs do not include codecs in binary
     --enable-shell          enable command line shell support
     --enable-large-pcap     enable support for pcaps larger than 2 GB
+    --enable-tsc-clock      use timestamp counter register clock (x86 only)
     --enable-debug-msgs     enable debug printing options (bugreports and
                             developers only)
     --enable-debug          enable debugging options (bugreports and developers
@@ -217,6 +218,9 @@ while [ $# -ne 0 ]; do
         --enable-large-pcap)
             append_cache_entry ENABLE_LARGE_PCAP        BOOL true
             ;;
+        --enable-tsc-clock)
+            append_cache_entry ENABLE_TSC_CLOCK         BOOL true
+            ;;
         --disable-large-pcap)
             append_cache_entry ENABLE_LARGE_PCAP        BOOL false
             ;;
index 742ffe2867a59b92d58229842e45aec3ff40799a..ad4e97f80dff8a7f7c12eb83200d9fcfd2f4d522 100644 (file)
@@ -71,7 +71,7 @@
 #include "protocols/packet.h"
 #include "protocols/tcp.h"
 #include "search_engines/search_tool.h"
-#include "stream/stream_api.h"
+#include "stream/stream.h"
 #include "utils/util.h"
 #include "utils/util_utf.h"
 #include "utils/sfsnprintfappend.h"
@@ -146,25 +146,23 @@ HttpFlowData::~HttpFlowData()
 HttpSessionData* SetNewHttpSessionData(Packet* p, void*)
 {
     HttpFlowData* fd = new HttpFlowData;
-    p->flow->set_application_data(fd);
+    p->flow->set_flow_data(fd);
     return &fd->session;
 }
 
 static HttpSessionData* get_session_data(Flow* flow)
 {
-    HttpFlowData* fd = (HttpFlowData*)flow->get_application_data(
-        HttpFlowData::flow_id);
-
+    HttpFlowData* fd = (HttpFlowData*)flow->get_flow_data(HttpFlowData::flow_id);
     return fd ? &fd->session : NULL;
 }
 
 void HttpInspectRegisterXtraDataFuncs()
 {
-    xtra_trueip_id = stream.reg_xtra_data_cb(GetHttpTrueIP);
-    xtra_uri_id = stream.reg_xtra_data_cb(GetHttpUriData);
-    xtra_hname_id = stream.reg_xtra_data_cb(GetHttpHostnameData);
-    xtra_gzip_id = stream.reg_xtra_data_cb(GetHttpGzipData);
-    xtra_jsnorm_id = stream.reg_xtra_data_cb(GetHttpJSNormData);
+    xtra_trueip_id = Stream::reg_xtra_data_cb(GetHttpTrueIP);
+    xtra_uri_id = Stream::reg_xtra_data_cb(GetHttpUriData);
+    xtra_hname_id = Stream::reg_xtra_data_cb(GetHttpHostnameData);
+    xtra_gzip_id = Stream::reg_xtra_data_cb(GetHttpGzipData);
+    xtra_jsnorm_id = Stream::reg_xtra_data_cb(GetHttpJSNormData);
 }
 
 static void PrintFileDecompOpt(HTTPINSPECT_CONF* ServerConf)
@@ -371,7 +369,7 @@ static inline int SetSiInput(HI_SI_INPUT* SiInput, Packet* p)
     /*
     **  We now set the packet direction
     */
-    if (p->flow && stream.is_midstream(p->flow))
+    if (p->flow && Stream::is_midstream(p->flow))
     {
         SiInput->pdir = HI_SI_NO_MODE;
     }
@@ -451,24 +449,24 @@ static inline void HttpLogFuncs(
 
     /* for pipelined HTTP requests */
     if ( !iCallDetect )
-        stream.clear_extra_data(p->flow, p, 0);
+        Stream::clear_extra_data(p->flow, p, 0);
 
     if (hsd->true_ip)
     {
         if (!(p->packet_flags & PKT_STREAM_INSERT) && !(p->packet_flags & PKT_REBUILT_STREAM))
             SetExtraData(p, xtra_trueip_id);
         else
-            stream.set_extra_data(p->flow, p, xtra_trueip_id);
+            Stream::set_extra_data(p->flow, p, xtra_trueip_id);
     }
 
     if (hsd->log_flags & HTTP_LOG_URI)
     {
-        stream.set_extra_data(p->flow, p, xtra_uri_id);
+        Stream::set_extra_data(p->flow, p, xtra_uri_id);
     }
 
     if (hsd->log_flags & HTTP_LOG_HOSTNAME)
     {
-        stream.set_extra_data(p->flow, p, xtra_hname_id);
+        Stream::set_extra_data(p->flow, p, xtra_hname_id);
     }
 
     if (hsd->log_flags & HTTP_LOG_JSNORM_DATA)
index 276833eda74289bcadf248511bcae3be6cfece44..25f1bc0ce1e8b90a525f7fb5a91c5bdb416367a5 100644 (file)
@@ -28,7 +28,6 @@
 
 #include "detection/detection_util.h"
 #include "protocols/packet.h"
-#include "stream/stream_api.h"
 #include "utils/util_jsnorm.h"
 #include "utils/util_utf.h"
 #include "hi_ui_config.h"
index 4f0ed3654e1b214c3c3873d2e618acd0e6c43205..826b442d4a9ea69c0585cd6a2653e797c1024410 100644 (file)
@@ -51,7 +51,6 @@
 #include "hi_ui_config.h"
 #include "hi_ad.h"
 #include "hi_main.h"
-#include "stream/stream_api.h"
 
 /*
 **  NAME
index 89625202c47cab5324a323e1484ab9eeae5abab7..e6d9f406ffbc7bd9812c37e08ae02a3180bf2856 100644 (file)
@@ -60,7 +60,7 @@
 #include "main/snort_debug.h"
 #include "events/event_queue.h"
 #include "protocols/packet.h"
-#include "stream/stream_api.h"
+#include "stream/stream.h"
 #include "utils/util.h"
 
 #ifdef DEBUG_MSGS
@@ -780,7 +780,7 @@ static inline Hi5State* get_state(Flow* flow, bool c2s)
     if ( !flow )
         return nullptr;
 
-    HttpSplitter* s = (HttpSplitter*)stream.get_splitter(flow, c2s);
+    HttpSplitter* s = (HttpSplitter*)Stream::get_splitter(flow, c2s);
     return s ? &s->state : nullptr;
 }
 
@@ -806,7 +806,7 @@ static void hi_pipe_push(Hi5State* s_req, Flow* ssn)
 
     if ( nreq == MAX_PIPELINE )
     {
-        if ( stream.is_paf_active(ssn, 0) )
+        if ( Stream::is_paf_active(ssn, 0) )
             hi_paf_event_pipe();
     }
     else if ( nreq < MAX_PIPELINE )
index 64e3938603551dd9ceabbf1ab22edd659a4e177e..b8199c945201c02a35898a4625207bb2248e2766 100644 (file)
@@ -28,7 +28,6 @@
 #define HI_STREAM_SPLITTER_H
 
 #include "main/snort_types.h"
-#include "stream/stream_api.h"
 #include "stream/stream_splitter.h"
 
 bool hi_paf_init(uint32_t cap);
index fe0f604c0fec34cef943f1e53fd4ef79a54d4aed..e9ba0da11d807a6aa20610579308e3ff13d8c5e5 100644 (file)
@@ -33,6 +33,7 @@
 #ifndef HI_UTIL_H
 #define HI_UTIL_H
 
+#include <strings.h>
 #include "hi_include.h"
 
 /*
index 11766ebea673e8521f79d9bbac0bb3838dce67f2..9f65a356fab689bda109dcb5e1f402c2f50f8b4c 100644 (file)
@@ -45,7 +45,6 @@
 #include "main/snort_debug.h"
 #include "decompress/file_decomp.h"
 #include "profiler/profiler.h"
-#include "stream/stream_api.h"
 #include "file_api/file_api.h"
 #include "file_api/file_service.h"
 #include "mime/decode_base.h"
index da5fde5280b1bb460eb540884d5496d8093e7071..2980ee45bbbf1c7d2378760e7ab3be2c83d03912 100644 (file)
@@ -69,6 +69,7 @@ back_orifice = { }
 dnp3 = { }
 dns = { }
 gtp_inspect = default_gtp
+http_inspect = { }
 imap = { }
 smtp = { }
 pop = { }
@@ -80,10 +81,6 @@ ssh = { }
 ssl = { }
 telnet = { }
 
--- use http_inspect or new_http_inspect (incomplete)
-http_inspect = { }
---new_http_inspect = { }
-
 ftp_server = default_ftp_server
 ftp_client = { }
 ftp_data = { }
index 769c5fe985ed39e9645560c2a9c780779ca247ef..fc78cf39e531f231976edc9a6af468744c877776 100644 (file)
@@ -133,9 +133,9 @@ target_link_libraries( snort
     detection
     framework
     file_api
-    time
     latency
     profiler
+    time
     ips_actions
     events
     hash
index a9227f301b9e978c84205fa9c7d75c1d0cfebeff..a2e3ca2af5aa9cdef5228e2e1de420ac01180292 100644 (file)
@@ -90,9 +90,9 @@ filters/libfilter.a \
 detection/libdetection.a \
 framework/libframework.a \
 file_api/libfile_api.a \
-time/libtime.a \
 latency/liblatency.a \
 profiler/libprofiler.a \
+time/libtime.a \
 actions/libips_actions.a \
 events/libevents.a \
 hash/libhash.a \
index f762a97f9f688c8c337ff90e6df0547f019c4780..4b7849e5d39c667cf1aa127294bbbb60cfe28d0a 100644 (file)
@@ -36,7 +36,6 @@
 #include "packet_io/active.h"
 #include "codecs/ip/checksum.h"
 #include "main/thread.h"
-#include "stream/stream_api.h"
 #include "codecs/codec_module.h"
 #include "protocols/ip.h"
 #include "protocols/ipv4_options.h"
index 8d8edf67046577cd0f203e51a2bf1704579d64a7..28e1a0306045a5b64c2abe778b4a07f2041bb4de 100644 (file)
@@ -28,7 +28,6 @@
 #include "protocols/ipv6.h"
 #include "codecs/codec_module.h"
 #include "framework/codec.h"
-#include "stream/stream_api.h"
 #include "main/snort_config.h"
 #include "packet_io/active.h"
 #include "protocols/protocol_ids.h"
index f3424ae98b6f14205919586b30096eac4ac17fda..3a36f210f233e74719bf6e3cbc63966eb429c875 100644 (file)
@@ -241,9 +241,8 @@ bool TcpCodec::decode(const RawData& raw, CodecData& codec, DecodeData& snort)
         }
 
         if ( sfvar_ip_in(SynToMulticastDstIp, snort.ip_api.get_dst()) )
-        {
             codec_event(codec, DECODE_SYN_TO_MULTICAST);
-        }
+
         if ( (tcph->th_flags & TH_RST) )
             codec_event(codec, DECODE_TCP_SYN_RST);
 
index 1e4a2270f7baf89a9eb73d9553946aa8eefe0b58..25148bbbd434ba9a2962e30200460fad27bb74cf 100644 (file)
 #include <CppUTest/CommandLineTestRunner.h>
 #include <CppUTest/TestHarness.h>
 
+#ifdef MACOS
+#define __THROW
+#define __SOCKADDR_ARG          struct sockaddr*
+#define __CONST_SOCKADDR_ARG    const struct sockaddr*
+#endif
+
 extern const BaseApi* tcp_connector;
 ConnectorApi* tcpc_api = nullptr;
 
@@ -89,7 +95,7 @@ int poll (struct pollfd* fds, nfds_t nfds, int)
 
     if ( s_poll_undesirable )
     {
-        fds[0].revents |= POLLRDHUP;
+        fds[0].revents |= POLLHUP;
         return 1;
     }
 
index 1ba081b0999ff2069f26a4d86cee179b0ad7b9cd..268340763d347194d34abf7f18415610fd0ac1c3 100644 (file)
@@ -46,6 +46,7 @@
 #include "ports/port_object.h"
 #include "profiler/profiler_defs.h"
 #include "sfip/sf_ipvar.h"
+#include "stream/stream.h"
 #include "utils/stats.h"
 
 #define CHECK_SRC_IP         0x01
@@ -71,7 +72,6 @@ void snort_inspect(Packet* p)
 {
     {
         PacketLatency::Context pkt_latency_ctx { p };
-
         bool inspected = false;
 
         // If the packet has errors, we won't analyze it.
@@ -108,8 +108,12 @@ void snort_inspect(Packet* p)
 
         check_tags_flag = 1;
 
-        /* Check for normally closed session */
-        stream.check_session_closed(p);
+        // clear closed sessions here after inspection since non-stream
+        // inspectors may depend on flow information
+        // FIXIT-H but this result in double clearing?  should normal
+        // clear_session() calls be deleted from stream?  this is a
+        // performance hit on short-lived flows
+        Stream::check_flow_closed(p);
 
         /*
         ** By checking tagging here, we make sure that we log the
index 9a027914c7cb9dc80655a405d5220fc7bd5a7cb8..dde3863b610314ca06ed999a683fff88155570fb 100644 (file)
@@ -310,13 +310,14 @@ void print_option_tree(detection_option_tree_node_t* node, int level)
 
     DEBUG_WRAP(
         DebugFormat(DEBUG_DETECT, "%d%*s%*d 0x%x\n",
-            level, indent - offset, option_type_str[node->option_type],
-            54 - indent, node->num_children, node->option_data);
+        level, indent - offset, option_type_str[node->option_type],
+        54 - indent, node->num_children, node->option_data);
 
         for (i=0; i<node->num_children; i++)
             print_option_tree(node->children[i], level+1);
         );
 }
+
 #endif
 
 void* add_detection_option_tree(
@@ -370,13 +371,13 @@ int detection_option_node_evaluate(
         auto last_check = state.last_check;
 
         if ( last_check.ts == p->pkth->ts &&
-             last_check.packet_number == cur_eval_pkt_count &&
-             last_check.rebuild_flag == (p->packet_flags & PKT_REBUILT_STREAM) &&
-             !(p->packet_flags & PKT_ALLOW_MULTIPLE_DETECT) )
+            last_check.packet_number == cur_eval_pkt_count &&
+            last_check.rebuild_flag == (p->packet_flags & PKT_REBUILT_STREAM) &&
+            !(p->packet_flags & PKT_ALLOW_MULTIPLE_DETECT) )
         {
             if ( !last_check.flowbit_failed &&
-                 !(p->packet_flags & PKT_IP_RULE_2ND) &&
-                 !(p->proto_bits & (PROTO_BIT__TEREDO|PROTO_BIT__GTP)) )
+                !(p->packet_flags & PKT_IP_RULE_2ND) &&
+                !(p->proto_bits & (PROTO_BIT__TEREDO|PROTO_BIT__GTP)) )
             {
                 return last_check.result;
             }
@@ -397,7 +398,7 @@ int detection_option_node_evaluate(
         IpsOption* opt = (IpsOption*)node->option_data;
         try_again = opt->retry();
 
-        PatternMatchData* pmd = opt->get_pattern();
+        PatternMatchData* pmd = opt->get_pattern(0, RULE_WO_DIR);
 
         if ( pmd and pmd->last_check )
             content_last = pmd->last_check + get_instance_id();
@@ -409,7 +410,7 @@ int detection_option_node_evaluate(
         switch ( node->option_type )
         {
         case RULE_OPTION_TYPE_LEAF_NODE:
-        // Add the match for this otn to the queue.
+            // Add the match for this otn to the queue.
         {
             OptTreeNode* otn = (OptTreeNode*)node->option_data;
             int16_t app_proto = p->get_application_protocol();
@@ -453,7 +454,7 @@ int detection_option_node_evaluate(
                 bool f_result = true;
 
                 if ( otn->detection_filter )
-                    f_result = detection_filter_test(otn->detection_filter,
+                    f_result = !detection_filter_test(otn->detection_filter,
                         p->ptrs.ip_api.get_src(), p->ptrs.ip_api.get_dst(),
                         p->pkth->ts.tv_sec);
 
@@ -486,8 +487,8 @@ int detection_option_node_evaluate(
                 if ( content_last )
                 {
                     if ( content_last->ts == p->pkth->ts &&
-                         content_last->packet_number == cur_eval_pkt_count &&
-                         content_last->rebuild_flag == (p->packet_flags & PKT_REBUILT_STREAM) )
+                        content_last->packet_number == cur_eval_pkt_count &&
+                        content_last->rebuild_flag == (p->packet_flags & PKT_REBUILT_STREAM) )
                     {
                         rval = DETECTION_OPTION_NO_MATCH;
                         break;
@@ -520,7 +521,6 @@ int detection_option_node_evaluate(
                 rval = node->evaluate(node->option_data, cursor, p);
 
             break;
-
         }
 
         if ( rval == DETECTION_OPTION_NO_MATCH )
@@ -528,7 +528,6 @@ int detection_option_node_evaluate(
             state.last_check.result = result;
             return result;
         }
-
         else if ( rval == DETECTION_OPTION_FAILED_BIT )
         {
             eval_data->flowbit_failed = 1;
@@ -537,7 +536,6 @@ int detection_option_node_evaluate(
             state.last_check.result = result;
             return 0;
         }
-
         else if ( rval == DETECTION_OPTION_NO_ALERT )
         {
             // Cache the current flowbit_noalert flag, and set it
@@ -590,14 +588,13 @@ int detection_option_node_evaluate(
                                     continue;
                                 }
                             }
-
                             else if ( child_node->option_type == RULE_OPTION_TYPE_CONTENT )
                             {
                                 // Check for an unbounded relative search.  If this
                                 // failed before, it's going to fail again so don't
                                 // go down this path again
                                 IpsOption* opt = (IpsOption*)node->option_data;
-                                PatternMatchData* pmd = opt->get_pattern();
+                                PatternMatchData* pmd = opt->get_pattern(0, RULE_WO_DIR);
 
                                 if ( pmd->unbounded() )
                                 {
@@ -610,7 +607,6 @@ int detection_option_node_evaluate(
                                 }
                             }
                         }
-
                         else if ( child_node->option_type == RULE_OPTION_TYPE_LEAF_NODE )
                             // Leaf node matched, don't eval again
                             continue;
@@ -665,12 +661,11 @@ int detection_option_node_evaluate(
         }
 
         if ( continue_loop &&
-             rval == DETECTION_OPTION_MATCH &&
-             node->relative_children )
+            rval == DETECTION_OPTION_MATCH &&
+            node->relative_children )
         {
             continue_loop = try_again;
         }
-
         else
             continue_loop = false;
 
@@ -747,7 +742,6 @@ static void detection_option_node_update_otn_stats(detection_option_tree_node_t*
         local_stats.latency_timeouts = timeouts;
         local_stats.latency_suspends = suspends;
     }
-
     else
     {
         local_stats.elapsed = node_stats.elapsed;
@@ -812,7 +806,6 @@ void detection_option_tree_update_otn_stats(SFXHASH* doth)
     }
 }
 
-
 detection_option_tree_root_t* new_root()
 {
     detection_option_tree_root_t* p = (detection_option_tree_root_t*)
index 04b2019f35a5db60c6a19a9a1c6535e1c7d98c41..819da873bddcb58e1a504bdc9cf2474c4a5b958f 100644 (file)
@@ -471,7 +471,14 @@ bool set_fp_content(OptTreeNode* otn)
             fp_only = !ofl->ips_opt->fp_research();
         }
 
-        PatternMatchData* tmp = get_pmd(ofl);
+        // Set rule direction
+        RuleDirection dir = RULE_WO_DIR;
+        if (OtnFlowFromServer(otn))
+            dir = RULE_FROM_SERVER;
+        else if (OtnFlowFromClient(otn))
+            dir = RULE_FROM_CLIENT;
+
+        PatternMatchData* tmp = get_pmd(ofl, otn->proto, dir);
 
         if ( !tmp )
             continue;
@@ -537,7 +544,7 @@ static PatternMatchData* get_fp_content(OptTreeNode* otn, OptFpList*& next)
         if ( !ofl->ips_opt )
             continue;
 
-        PatternMatchData* pmd = get_pmd(ofl);
+        PatternMatchData* pmd = get_pmd(ofl, 0, RULE_WO_DIR);
 
         if ( !pmd )
             continue;
@@ -585,8 +592,8 @@ static int fpFinishPortGroupRule(
         {
             static MpseAgent agent =
             {
-                  pmx_create_tree, add_patrn_to_neg_list,
-                  fpDeletePMX, free_detection_option_root, neg_list_free
+                pmx_create_tree, add_patrn_to_neg_list,
+                fpDeletePMX, free_detection_option_root, neg_list_free
             };
 
             pg->mpse[pmd->pm_type] = MpseManager::get_search_engine(
@@ -1924,7 +1931,6 @@ static void PrintFastPatternInfo(OptTreeNode* otn, PatternMatchData* pmd,
         snprintf(buf, sizeof(buf), "%2.02X ", (uint8_t)pattern[i]);
         hex += buf;
         txt += isprint(pattern[i]) ? pattern[i] : '.';
-
     }
     printf("fast pattern[%d] = x%s '%s'\n", pattern_length, hex.c_str(), txt.c_str());
 #else
index 8f66153a957e1f36112c4ed7d8383d82f13e6d62..d90f72698a5e92bd2319825643b768616584e149 100644 (file)
@@ -67,7 +67,6 @@
 #include "events/event_wrapper.h"
 #include "packet_io/active.h"
 #include "parser/parser.h"
-#include "stream/stream_api.h"
 #include "utils/sflsq.h"
 #include "utils/util.h"
 #include "profiler/profiler.h"
@@ -79,6 +78,7 @@
 #include "protocols/udp.h"
 #include "protocols/icmp4.h"
 #include "search_engines/pat_stats.h"
+#include "stream/stream.h"
 #include "utils/stats.h"
 
 THREAD_LOCAL ProfileStats rulePerfStats;
@@ -88,7 +88,7 @@ THREAD_LOCAL ProfileStats ruleNFPEvalPerfStats;
 
 THREAD_LOCAL uint64_t rule_eval_pkt_count = 0;
 
-THREAD_LOCAL OTNX_MATCH_DATA t_omd;
+static THREAD_LOCAL OTNX_MATCH_DATA t_omd;
 
 /* initialize the global OTNX_MATCH_DATA variable */
 void otnx_match_data_init(int num_rule_types)
@@ -111,14 +111,10 @@ void otnx_match_data_term()
 
 static inline void InitMatchInfo(OTNX_MATCH_DATA* o)
 {
-    int i = 0;
+    for ( int i = 0; i < o->iMatchInfoArraySize; i++ )
+        o->matchInfo[i].iMatchCount = 0;
 
-    for (i = 0; i < o->iMatchInfoArraySize; i++)
-    {
-        o->matchInfo[i].iMatchCount  = 0;
-        o->matchInfo[i].iMatchIndex  = 0;
-        o->matchInfo[i].iMatchMaxLen = 0;
-    }
+    o->have_match = false;
 }
 
 // called by fpLogEvent(), which does the filtering etc.
@@ -270,14 +266,10 @@ int fpLogEvent(const RuleTreeNode* rtn, const OptTreeNode* otn, Packet* p)
 **    int - 1 max_events variable hit, 0 successful.
 **
 */
-int fpAddMatch(OTNX_MATCH_DATA* omd_local, int pLen, const OptTreeNode* otn)
+int fpAddMatch(OTNX_MATCH_DATA* omd_local, int /*pLen*/, const OptTreeNode* otn)
 {
-    MATCH_INFO* pmi;
-    int evalIndex;
-    int i;
     RuleTreeNode* rtn = getRuntimeRtnFromOtn(otn);
-
-    evalIndex = rtn->listhead->ruleListNode->evalIndex;
+    int evalIndex = rtn->listhead->ruleListNode->evalIndex;
 
     /* bounds check index */
     if ( evalIndex >= omd_local->iMatchInfoArraySize )
@@ -285,7 +277,7 @@ int fpAddMatch(OTNX_MATCH_DATA* omd_local, int pLen, const OptTreeNode* otn)
         pc.match_limit++;
         return 1;
     }
-    pmi = &omd_local->matchInfo[evalIndex];
+    MATCH_INFO* pmi = &omd_local->matchInfo[evalIndex];
 
     /*
     **  If we hit the max number of unique events for any rule type alert,
@@ -298,43 +290,18 @@ int fpAddMatch(OTNX_MATCH_DATA* omd_local, int pLen, const OptTreeNode* otn)
         return 1;
     }
 
-    /* Check that we are not storing the same otn again */
-    for ( i=0; i< pmi->iMatchCount; i++ )
+    // don't store the same otn again
+    for ( int i=0; i< pmi->iMatchCount; i++ )
     {
         if ( pmi->MatchArray[ i  ] == otn )
-        {
-            //LogMessage("fpAddMatch: storing the same otn...\n");
             return 0;
-        }
     }
 
-    /*
-    **  Add the event to the appropriate list
-    */
+    //  add the event to the appropriate list
     pmi->MatchArray[ pmi->iMatchCount ] = otn;
 
-    /*
-    **  This means that we are adding a NC rule
-    **  and we only set the index to this rule
-    **  if there is no content rules in the
-    **  same array.
-    */
-    if (pLen > 0)
-    {
-        /*
-        **  Event Comparison Function
-        **  Here the largest content match is the
-        **  priority
-        */
-        if ( pmi->iMatchMaxLen < pLen )
-        {
-            pmi->iMatchMaxLen = pLen;
-            pmi->iMatchIndex  = pmi->iMatchCount;
-        }
-    }
-
     pmi->iMatchCount++;
-
+    omd_local->have_match = true;
     return 0;
 }
 
@@ -595,7 +562,7 @@ static inline int fpAddSessionAlert(Packet* p, const OptTreeNode* otn)
     if ( !otn )
         return 0;
 
-    return !stream.add_session_alert(
+    return !Stream::add_flow_alert(
         p->flow, p, otn->sigInfo.generator, otn->sigInfo.id);
 }
 
@@ -621,7 +588,7 @@ static inline int fpSessionAlerted(Packet* p, const OptTreeNode* otn)
 {
     const SigInfo* si = &otn->sigInfo;
 
-    if (!stream.check_session_alerted(p->flow, p, si->generator, si->id))
+    if (!Stream::check_flow_alerted(p->flow, p, si->generator, si->id))
         return 0;
     else
         return 1;
@@ -702,6 +669,9 @@ static inline int fpSessionAlerted(Packet* p, const OptTreeNode* otn)
 */
 static inline int fpFinalSelectEvent(OTNX_MATCH_DATA* o, Packet* p)
 {
+    if ( !o->have_match )
+        return 0;
+
     int i;
     int j;
     int k;
index 6efd95614804c5d65a8502a709942dcc5228bf6e..da9236f830f3b8822cb655b0975fec3900ca25df 100644 (file)
@@ -96,6 +96,7 @@ struct OTNX_MATCH_DATA
     unsigned size;
 
     int check_ports;
+    bool have_match;
 
     MATCH_INFO* matchInfo;
     int iMatchInfoArraySize;
index 665ad8410db203f8833105cdd63269f5ba5ce417..c6c1ab4a6c90a33291a035366032c30df7f3ddd1 100644 (file)
@@ -1,11 +1,13 @@
 
 set( FILE_API_INCLUDES
     file_api.h
-    file_config.h 
+    file_config.h
+    file_cache.h 
     file_flows.h
     file_identifier.h 
     file_lib.h 
     file_policy.h
+    file_segment.h
     file_service.h 
 )
 
@@ -15,6 +17,8 @@ add_library ( file_api STATIC
     circular_buffer.h
     file_capture.cc
     file_capture.h
+    file_cache.cc
+    file_cache.h
     file_config.cc 
     file_enforcer.cc 
     file_enforcer.h 
@@ -26,7 +30,9 @@ add_library ( file_api STATIC
     file_mempool.h
     file_module.cc
     file_module.h
-    file_policy.cc 
+    file_policy.cc
+    file_segment.cc
+    file_segment.h 
     file_service.cc 
     file_stats.cc 
     file_stats.h
index 9abfed86e1ef754e39ae084d3167038677d0dec4..d91c2f3f63755f66e718836c0f23ed0e9b022388 100644 (file)
@@ -10,11 +10,13 @@ file_flows.h \
 file_identifier.h \
 file_lib.h \
 file_policy.h \
+file_segment.h \
 file_service.h
 
 libfile_api_a_SOURCES = \
 circular_buffer.cc circular_buffer.h \
 file_capture.cc file_capture.h \
+file_cache.cc file_cache.h \
 file_config.cc \
 file_flows.cc \
 file_enforcer.cc file_enforcer.h \
@@ -24,6 +26,7 @@ file_lib.cc \
 file_mempool.cc file_mempool.h \
 file_module.cc file_module.h \
 file_policy.cc \
+file_segment.cc file_segment.h \
 file_service.cc \
 file_stats.cc file_stats.h
  
index 1f8fad726ab98743397d629e165351ca573d42ed..3189bf5635030887700c7cb83295c24f9a094b74 100644 (file)
@@ -44,11 +44,7 @@ struct _CircularBuffer
     uint64_t size;     /* maximum number of elements           */
     uint64_t start;    /* index of oldest element, reader update only */
     uint64_t end;      /* index to write new element, writer update only*/
-    uint64_t under_run;
-    uint64_t over_run;
     ElemType* elems;    /* vector of elements                   */
-    uint64_t total_write;
-    uint64_t total_read;
 };
 
 /* This approach adds one byte to end and start pointers */
@@ -110,12 +106,6 @@ uint64_t cbuffer_used(CircularBuffer* cb)
     }
 }
 
-/* Returns number of free elements*/
-uint64_t cbuffer_available(CircularBuffer* cb)
-{
-    return (cbuffer_size(cb) - cbuffer_used(cb));
-}
-
 /* Returns total number of elements*/
 uint64_t cbuffer_size(CircularBuffer* cb)
 {
@@ -138,7 +128,6 @@ int cbuffer_write(CircularBuffer* cb, const ElemType elem)
 
     if ( cbuffer_is_full (cb))  /* full, return error */
     {
-        cb->over_run++;
         return CB_FAIL;
     }
 
@@ -147,7 +136,6 @@ int cbuffer_write(CircularBuffer* cb, const ElemType elem)
         w = 0;
 
     cb->end = w;
-    cb->total_write++;
 
     return CB_SUCCESS;
 }
@@ -168,7 +156,6 @@ int cbuffer_read(CircularBuffer* cb, ElemType* elem)
 
     if (cbuffer_is_empty(cb)) /* Empty, return error */
     {
-        cb->under_run++;
         return CB_FAIL;
     }
 
@@ -177,52 +164,7 @@ int cbuffer_read(CircularBuffer* cb, ElemType* elem)
         r = 0;
 
     cb->start = r;
-    cb->total_read++;
-
-    return CB_SUCCESS;
-}
-
-/*
- * Read one element from the buffer and no change on buffer
- *
- * Args:
- *   CircularBuffer *: buffer
- *   ElemType *elem: the element pointer to be stored
- * Return:
- *   CB_FAIL
- *   CB_SUCCESS
- */
-int cbuffer_peek(CircularBuffer* cb, ElemType* elem)
-{
-    if (cbuffer_is_empty(cb)) /* Empty, return error */
-        return CB_FAIL;
-
-    *elem = cb->elems[cb->start];
 
     return CB_SUCCESS;
 }
 
-/* Returns total number of reads*/
-uint64_t cbuffer_num_reads(CircularBuffer* cb)
-{
-    return (cb->total_read);
-}
-
-/* Returns total number of writes*/
-uint64_t cbuffer_num_writes(CircularBuffer* cb)
-{
-    return (cb->total_write);
-}
-
-/* Returns total number of writer overruns*/
-uint64_t cbuffer_num_over_runs(CircularBuffer* cb)
-{
-    return (cb->over_run);
-}
-
-/* Returns total number of reader overruns*/
-uint64_t cbuffer_num_under_runs(CircularBuffer* cb)
-{
-    return (cb->under_run);
-}
-
index 66cbeb53fa480bd949b054ea015582f40ed0b8d0..bff7bb05f94ef6b764cf44378a2e2414ae983e83 100644 (file)
@@ -48,9 +48,6 @@ int cbuffer_is_empty(CircularBuffer* cb); // FIXIT-L use bool
 // Returns number of elements in use
 uint64_t cbuffer_used(CircularBuffer* cb);
 
-// Returns number of free elements
-uint64_t cbuffer_available(CircularBuffer* cb);
-
 // Returns total number of elements
 uint64_t cbuffer_size(CircularBuffer* cb);
 
@@ -61,19 +58,5 @@ int cbuffer_write(CircularBuffer* cb, const ElemType elem);
 // Returns CB_SUCCESS or CB_FAIL
 int cbuffer_read(CircularBuffer* cb, ElemType* elem);
 
-// Read one element from the buffer and no change on buffer
-// Returns CB_SUCCESS or CB_FAIL
-int cbuffer_peek(CircularBuffer* cb, ElemType* elem);
-
-uint64_t cbuffer_num_reads(CircularBuffer* cb);
-
-uint64_t cbuffer_num_writes(CircularBuffer* cb);
-
-/* Returns total number of writer overruns*/
-uint64_t cbuffer_num_over_runs(CircularBuffer* cb);
-
-/* Returns total number of reader overruns*/
-uint64_t cbuffer_num_under_runs(CircularBuffer* cb);
-
 #endif
 
index 31e8be73f841772777271d8ff8637d383351f46c..5cc4c5b2d527cd2c90965cede8d41b38a36856b1 100644 (file)
@@ -27,8 +27,8 @@
 // and configurations.
 
 #include <sys/types.h>
+#include <string>
 
-#include "stream/stream_api.h"
 #include "main/snort_types.h"
 
 #define     ENABLE_FILE_TYPE_IDENTIFICATION      0x1
@@ -90,7 +90,6 @@ enum FileProcessType
 
 enum FileDirection
 {
-   DIRECTION_UNKNOWN,
    FILE_DOWNLOAD,
    FILE_UPLOAD
 };
@@ -139,8 +138,8 @@ inline bool isFileEnd(FilePosition position)
     return ((position == SNORT_FILE_END) || (position == SNORT_FILE_FULL));
 }
 
-SO_PUBLIC uint64_t get_file_processed_size(Flow* flow);
-FilePosition get_file_position(Packet* pkt);
+SO_PUBLIC uint64_t get_file_processed_size(class Flow* flow);
+FilePosition get_file_position(struct Packet* pkt);
 
 #endif
 
diff --git a/src/file_api/file_cache.cc b/src/file_api/file_cache.cc
new file mode 100644 (file)
index 0000000..2ccd06f
--- /dev/null
@@ -0,0 +1,126 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2016 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.
+//--------------------------------------------------------------------------
+//  file_cache.cc author Hui Cao <huica@cisco.com>
+
+#include "file_cache.h"
+#include "file_service.h"
+
+#include "sfip/sfip_t.h"
+#include "sfip/sf_ip.h"
+#include "time/packet_time.h"
+#include "utils/util.h"
+#include "utils/snort_bounds.h"
+#include "main/snort_config.h"
+
+uint64_t FileCache::num_add_fails = 0;
+
+static int file_cache_free_func(void*, void* data)
+{
+    FileCache::FileNode* node = (FileCache::FileNode*)data;
+    if (node)
+    {
+        delete node->file;
+        node->file = nullptr;
+    }
+    return 0;
+}
+
+FileCache::FileCache()
+{
+    int max_files = snort_conf->file_config.max_files_cached;
+    fileHash = sfxhash_new(max_files, sizeof(FileHashKey), sizeof(FileNode),
+        0, 1, nullptr, file_cache_free_func, 1);
+    if (!fileHash)
+        FatalError("Failed to create the expected channel hash table.\n");
+    sfxhash_set_max_nodes(fileHash, max_files);
+}
+
+FileCache::~FileCache()
+{
+    if (fileHash)
+    {
+        sfxhash_delete(fileHash);
+    }
+}
+
+FileContext* FileCache::add(const FileHashKey& hashKey)
+{
+    FileNode new_node;
+    /*
+     * use the time that we keep files around
+     * since this info would effectively be invalid
+     * after that anyway because the file that
+     * caused this will be gone.
+     */
+    time_t now = packet_time();
+    new_node.expires = now + timeout;
+    new_node.file = new FileContext;
+
+    std::lock_guard<std::mutex> lock(cache_mutex);
+
+    if (sfxhash_add(fileHash, (void*)&hashKey, &new_node) != SFXHASH_OK)
+    {
+        /* Uh, shouldn't get here...
+         * There is already a node or couldn't alloc space
+         * for key.  This means bigger problems, but fail
+         * gracefully.
+         */
+        FileCache::num_add_fails++;
+        delete new_node.file;
+        return nullptr;
+    }
+
+    return new_node.file;
+}
+
+FileContext* FileCache::find(const FileHashKey& hashKey)
+{
+    std::lock_guard<std::mutex> lock(cache_mutex);
+
+    // No hash table, or its empty?  Get out of dodge.
+    if ((!fileHash) || (!sfxhash_count(fileHash)))
+    {
+        DebugMessage(DEBUG_FILE, "No expected sessions\n");
+        return nullptr;
+    }
+
+    SFXHASH_NODE* hash_node = sfxhash_find_node(fileHash, &hashKey);
+
+    if (!hash_node)
+        return nullptr;
+
+    FileNode* node = (FileNode*)hash_node->data;
+    if (!node)
+    {
+        sfxhash_free_node(fileHash, hash_node);
+        return nullptr;
+    }
+
+    DebugMessage(DEBUG_FILE, "Found resumed file\n");
+    time_t now = packet_time();
+    if (node->expires && now > node->expires)
+    {
+        DebugMessage(DEBUG_FILE, "File expired\n");
+        sfxhash_free_node(fileHash, hash_node);
+        return nullptr;
+    }
+
+    node->expires = now + timeout;
+    return node->file;
+}
+
diff --git a/src/file_api/file_cache.h b/src/file_api/file_cache.h
new file mode 100644 (file)
index 0000000..1a82b69
--- /dev/null
@@ -0,0 +1,68 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2016 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.
+//--------------------------------------------------------------------------
+
+// file_cache.h author Hui Cao <huica@cisco.com>
+
+#ifndef FILE_CACHE_H
+#define FILE_CACHE_H
+
+#include <mutex>
+
+#include "file_api.h"
+#include "file_lib.h"
+#include "file_config.h"
+
+#include "protocols/packet.h"
+#include "hash/sfxhash.h"
+#include "hash/hashes.h"
+
+class FileCache
+{
+public:
+
+    struct FileHashKey
+    {
+        sfip_t sip;
+        sfip_t dip;
+        uint64_t file_sig;
+    };
+
+    struct FileNode
+    {
+        time_t expires;
+        FileContext* file;
+    };
+
+    FileCache();
+    ~FileCache();
+    FileContext* add(const FileHashKey&);
+    FileContext* find(const FileHashKey&);
+
+    static uint64_t num_add_fails;
+
+private:
+
+    /* The hash table of expected files */
+    SFXHASH* fileHash = nullptr;
+    uint32_t timeout = DEFAULT_FILE_BLOCK_TIMEOUT;
+    std::mutex cache_mutex;
+
+};
+
+#endif
+
index 266ccd8c8661960a6f1879bed219c10e799db15f..33fd7d2436f8fb742babba046119c8f924776109 100644 (file)
@@ -36,7 +36,7 @@
 #include "main/snort_config.h"
 #include "main/snort_types.h"
 
-bool FileConfig::process_file_magic(FileMagicData &magic)
+bool FileConfig::process_file_magic(FileMagicDatamagic)
 {
     bool negated = false;
     std::string str = '"' + magic.content_str + '"';
@@ -57,22 +57,22 @@ uint32_t FileConfig::find_file_type_id(const uint8_t* buf, int len,
 }
 
 /*The main function for parsing rule option*/
-void FileConfig::process_file_rule(FileMagicRule &rule)
+void FileConfig::process_file_rule(FileMagicRulerule)
 {
     fileIdentifier.insert_file_rule(rule);
 }
 
-void FileConfig::process_file_policy_rule(FileRule &rule)
+void FileConfig::process_file_policy_rule(FileRulerule)
 {
     filePolicy.insert_file_rule(rule);
 }
 
-FileMagicRule*  FileConfig::get_rule_from_id(uint32_t id)
+FileMagicRule* FileConfig::get_rule_from_id(uint32_t id)
 {
     return fileIdentifier.get_rule_from_id(id);
 }
 
-std::string FileConfig::file_type_name( uint32_t id)
+std::string FileConfig::file_type_name(uint32_t id)
 {
     if (SNORT_FILE_TYPE_UNKNOWN == id)
         return "Unknown file type, done";
@@ -92,3 +92,4 @@ std::string file_type_name(uint32_t id)
 {
     return snort_conf->file_config.file_type_name(id);
 }
+
index dda9590e40fca2d70c78f81466bebabc49711d58..51bd2136db4ef7b8e55182f299a6ff29dbc45aea 100644 (file)
@@ -37,6 +37,8 @@
 #define DEFAULT_FILE_CAPTURE_MAX_SIZE       1048576     // 1 MiB
 #define DEFAULT_FILE_CAPTURE_MIN_SIZE       0           // 0
 #define DEFAULT_FILE_CAPTURE_BLOCK_SIZE     32768       // 32 KiB
+#define DEFAULT_MAX_FILES_CACHED            65536
+
 class FileConfig
 {
 public:
@@ -45,8 +47,8 @@ public:
     void process_file_policy_rule(FileRule&);
     bool process_file_magic(FileMagicData&);
     uint32_t find_file_type_id(const uint8_t* buf, int len, uint64_t file_offset, void** context);
-    FilePolicy& get_file_policy() {return filePolicy;}
-    std::string file_type_name( uint32_t id);
+    FilePolicy& get_file_policy() { return filePolicy; }
+    std::string file_type_name(uint32_t id);
 
     int64_t file_type_depth = DEFAULT_FILE_TYPE_DEPTH;
     int64_t file_signature_depth = DEFAULT_FILE_SIGNATURE_DEPTH;
@@ -58,6 +60,7 @@ public:
     int64_t capture_min_size = DEFAULT_FILE_CAPTURE_MIN_SIZE;
     int64_t capture_block_size = DEFAULT_FILE_CAPTURE_BLOCK_SIZE;
     int64_t file_depth =  0;
+    int64_t max_files_cached = DEFAULT_MAX_FILES_CACHED;
 
     static int64_t show_data_depth;
     static bool trace_type;
index 8bafc9a7a2230af38fd52471bca3e5b8ef7a7aae..787e26a0d68ba858c4b762cb5e676ca834d71f16 100644 (file)
@@ -181,7 +181,7 @@ bool FileEnforcer::apply_verdict(Flow* flow, FileInfo* file, FileVerdict verdict
     return false;
 }
 
-FileVerdict  FileEnforcer::cached_verdict_lookup(Flow* flow, FileInfo* file)
+FileVerdict FileEnforcer::cached_verdict_lookup(Flow* flow, FileInfo* file)
 {
     FileVerdict verdict = FILE_VERDICT_UNKNOWN;
     SFXHASH_NODE* hash_node;
index db1c4b9c977ad00c9a293cef052bf5dcf26f0b6a..e4d215bc65c6910ce72620605e38f57f97e22204 100644 (file)
@@ -38,13 +38,12 @@ class FileInfo;
 
 class FileEnforcer
 {
-
     struct FileHashKey
     {
         sfip_t sip;
         sfip_t dip;
         size_t file_sig;
-    } ;
+    };
 
     struct FileNode
     {
index 7fcd20850ff8973d86341a1138ce4e24398a3671..dc17f47a256410eab5d520e7d2e333ad148e8d79 100644 (file)
 #include "file_api.h"
 #include "file_stats.h"
 #include "file_capture.h"
+#include "file_cache.h"
 #include "file_enforcer.h"
 #include "file_policy.h"
 #include "file_lib.h"
 #include "file_config.h"
 
 #include "main/snort_types.h"
-#include "stream/stream_api.h"
 #include "packet_io/active.h"
+#include "sfip/sfip_t.h"
+#include "sfip/sf_ip.h"
 
 int64_t FileConfig::show_data_depth = DEFAULT_FILE_SHOW_DATA_DEPTH;
 bool FileConfig::trace_type = false;
@@ -55,7 +57,7 @@ unsigned FileFlows::flow_id = 0;
 
 FileFlows* FileFlows::get_file_flows(Flow* flow)
 {
-    FileFlows* fd = (FileFlows*) flow->get_application_data(FileFlows::flow_id);
+    FileFlows* fd = (FileFlows*)flow->get_flow_data(FileFlows::flow_id);
 
     if (fd)
         return fd;
@@ -63,7 +65,7 @@ FileFlows* FileFlows::get_file_flows(Flow* flow)
     if (FileService::is_file_service_enabled())
     {
         fd = new FileFlows(flow);
-        flow->set_application_data(fd);
+        flow->set_flow_data(fd);
     }
 
     return fd;
@@ -81,6 +83,15 @@ void FileFlows::set_current_file_context(FileContext* ctx)
     current_context = ctx;
 }
 
+FileContext* FileFlows::get_current_file_context()
+{
+    if (current_file_id)
+    {
+        return get_file_context(current_file_id, false);
+    }
+    return current_context;
+}
+
 uint32_t FileFlows::get_new_file_instance()
 {
     return max_file_id++;
@@ -97,13 +108,6 @@ FileFlows::~FileFlows()
     delete(main_context);
 }
 
-void FileFlows::init_file_context(FileDirection direction, FileContext* context)
-{
-    FilePolicy& inspect = FileService::get_inspect();
-    inspect.policy_check(flow, context);
-    context->set_file_direction(direction);
-}
-
 FileContext* FileFlows::find_main_file_context(FilePosition pos, FileDirection dir, size_t index)
 {
     /* Attempt to get a previously allocated context. */
@@ -111,123 +115,86 @@ FileContext* FileFlows::find_main_file_context(FilePosition pos, FileDirection d
 
     if (context)
     {
-        if ((pos == SNORT_FILE_MIDDLE) or (pos == SNORT_FILE_END))
+        if ((pos == SNORT_FILE_MIDDLE)or (pos == SNORT_FILE_END))
             return context;
         else
             delete context;
     }
 
     context = new FileContext;
-    file_stats.files_total++;
     main_context = context;
-    init_file_context(dir, context);
+    context->check_policy(flow, dir);
 
     if (!index)
-        context->set_file_id(max_file_id++);
+        context->set_file_id(get_new_file_instance());
     else
         context->set_file_id(index);
 
     return context;
 }
 
-void FileFlows::finish_signature_lookup(FileContext* context)
+FileContext* FileFlows::get_file_context(uint64_t file_id, bool to_create)
 {
-    if (context->get_file_sig_sha256())
-    {
-        //Check file type based on file policy
-        FilePolicy& inspect = FileService::get_inspect();
-        inspect.signature_lookup(flow, context);
-        log_file_event(context, flow);
-        context->config_file_signature(false);
-        file_stats.signatures_processed[context->get_file_type()][context->get_file_direction()]++;
-    }
+    // search for file based on id to support multiple files
+    FileCache* file_cache = FileService::get_file_cache();
+    assert(file_cache);
+
+    FileCache::FileHashKey key;
+    sfip_copy(key.dip, &(flow->client_ip));
+    sfip_copy(key.sip, &(flow->server_ip));
+    key.file_sig = file_id;
+
+    FileContext* context = file_cache->find(key);
+
+    if (!context && to_create)
+        context = file_cache->add(key);
+
+    current_file_id = file_id;
+    return context;
 }
 
-/*
+/* This function is used to process file that is sent in pieces
+ *
  * Return:
  *    true: continue processing/log/block this file
  *    false: ignore this file
  */
-bool FileFlows::file_process(FileContext* context, const uint8_t* file_data,
-    int data_size, FilePosition position)
+bool FileFlows::file_process(uint64_t file_id, const uint8_t* file_data,
+    int data_size, uint64_t offset, FileDirection dir)
 {
-    if ( FileConfig::trace_stream )
-    {
-        FileContext::print_file_data(stdout, file_data, data_size,
-            snort_conf->file_config.show_data_depth);
-    }
+    int ret = 0;
 
-    if (!context)
-        return false;
+    int64_t file_depth = FileService::get_max_file_depth();
 
-    set_current_file_context(context);
-    file_stats.file_data_total += data_size;
-
-    if ((!context->is_file_type_enabled()) and (!context->is_file_signature_enabled()))
+    if ((file_depth < 0)or (offset > (uint64_t)file_depth))
     {
-        context->update_file_size(data_size, position);
-        return false;
+        return 0;
     }
 
-    context->set_file_config(&(snort_conf->file_config));
-
-    if((FileService::get_file_enforcer()->cached_verdict_lookup(flow, context)
-        != FILE_VERDICT_UNKNOWN))
-        return true;
-
-    /*file type id*/
-    if (context->is_file_type_enabled())
-    {
-        context->process_file_type(file_data, data_size, position);
+    FileContext* context = get_file_context(file_id, true);
 
-        /*Don't care unknown file type*/
-        if (context->get_file_type()== SNORT_FILE_TYPE_UNKNOWN)
-        {
-            context->config_file_type(false);
-            context->config_file_signature(false);
-            context->update_file_size(data_size, position);
-            context->stop_file_capture();
-            return false;
-        }
+    if (!context)
+        return 0;
 
-        if (context->get_file_type() != SNORT_FILE_TYPE_CONTINUE)
-        {
-            context->config_file_type(false);
-            file_stats.files_processed[context->get_file_type()][context->get_file_direction()]++;
-            //Check file type based on file policy
-            FilePolicy& inspect = FileService::get_inspect();
-            inspect.type_lookup(flow, context);
-            log_file_event(context, flow);
-        }
-    }
+    context->check_policy(flow, dir);
+    context->set_file_id(file_id);
 
-    /* file signature calculation */
-    if (context->is_file_signature_enabled())
+    if (context->verdict != FILE_VERDICT_UNKNOWN)
     {
-        context->process_file_signature_sha256(file_data, data_size, position);
-
-        file_stats.data_processed[context->get_file_type()][context->get_file_direction()]
-                                                            += data_size;
+        /*A new file session, but policy might be different*/
+        context->check_policy(flow, dir);
 
-        context->update_file_size(data_size, position);
-
-        if ( FileConfig::trace_signature )
-            context->print_file_sha256(std::cout);
-
-        /*Fails to capture, when out of memory or size limit, need lookup*/
-        if (context->is_file_capture_enabled())
+        if ((context->get_file_sig_sha256())
+            || !context->is_file_signature_enabled())
         {
-            context->process_file_capture(file_data, data_size, position);
+            /* Just check file type and signature */
+            FilePosition position = SNORT_FILE_FULL;
+            ret = context->process(flow, file_data, data_size, position);
+            return ret;
         }
-
-        finish_signature_lookup(context);
-    }
-    else
-    {
-        context->update_file_size(data_size, position);
     }
 
-    return true;
+    return context->process(flow, file_data, data_size, offset);
 }
 
 /*
@@ -239,7 +206,7 @@ bool FileFlows::file_process(const uint8_t* file_data, int data_size,
     FilePosition position, bool upload, size_t file_index)
 {
     FileContext* context;
-    FileDirection direction = upload ? FILE_UPLOAD:FILE_DOWNLOAD;
+    FileDirection direction = upload ? FILE_UPLOAD : FILE_DOWNLOAD;
     /* if both disabled, return immediately*/
     if (!FileService::is_file_service_enabled())
         return false;
@@ -249,7 +216,9 @@ bool FileFlows::file_process(const uint8_t* file_data, int data_size,
 
     context = find_main_file_context(position, direction, file_index);
 
-    return file_process(context, file_data, data_size, position);
+    set_current_file_context(context);
+
+    return context->process(flow, file_data, data_size, position);
 }
 
 void FileFlows::set_file_name(const uint8_t* fname, uint32_t name_size)
@@ -258,42 +227,12 @@ void FileFlows::set_file_name(const uint8_t* fname, uint32_t name_size)
     if ( !context )
         return;
 
-    if ( !context->get_file_name().length() )
+    if ( !context->is_file_name_set() )
     {
         if (fname and name_size)
             context->set_file_name((const char*)fname, name_size);
-        else
-            context->set_file_name(".", 1);
-
-        log_file_event(context, flow);
-    }
-
-    if ( FileConfig::trace_type )
-        context->print(std::cout);
-}
 
-void FileFlows::log_file_event(FileContext* context, Flow* flow)
-{
-    if ( context->get_file_name().length() )
-    {
-        switch (context->verdict)
-        {
-        case FILE_VERDICT_LOG:
-            // Log file event through data bus
-            get_data_bus().publish("file_event", (const uint8_t*)"LOG", 3, flow);
-            break;
-
-        case FILE_VERDICT_BLOCK:
-            // can't block session inside a session
-            get_data_bus().publish( "file_event", (const uint8_t*)"BLOCK", 5, flow);
-            break;
-
-        case FILE_VERDICT_REJECT:
-            get_data_bus().publish( "file_event", (const uint8_t*)"RESET", 5, flow);
-            break;
-        default:
-            break;
-        }
+        context->log_file_event(flow);
     }
 }
 
@@ -314,4 +253,3 @@ FilePosition get_file_position(Packet* pkt)
     return position;
 }
 
-
index 9e740210ae042a3e94d89b1a66afa315ad393df1..0c74892b7e3b58ee698621c9e0acf77f203dcc04 100644 (file)
@@ -34,7 +34,7 @@ class SO_PUBLIC FileFlows : public FlowData
 {
 public:
 
-    FileFlows(Flow* f) : FlowData(flow_id), flow(f) {}
+    FileFlows(Flow* f) : FlowData(flow_id), flow(f) { }
     ~FileFlows();
     static void init()
     { flow_id = FlowData::get_flow_id(); }
@@ -42,9 +42,13 @@ public:
     // Factory method to get file flows
     static FileFlows* get_file_flows(Flow*);
 
-    FileContext* get_current_file_context() {return current_context; }
+    FileContext* get_current_file_context();
+
     void set_current_file_context(FileContext*);
 
+    // Get file context based on file id, create it if not existed
+    FileContext* get_file_context(uint64_t file_id, bool to_create);
+
     uint32_t get_new_file_instance();
 
     void set_file_name(const uint8_t* fname, uint32_t name_size);
@@ -54,21 +58,21 @@ public:
         bool upload, size_t file_index = 0);
 
     // This is used for each file context. Support multiple files per session
-    bool file_process(FileContext*, const uint8_t* file_data, int data_size, FilePosition);
+    bool file_process(uint64_t file_id, const uint8_t* file_data,
+        int data_size, uint64_t offset, FileDirection);
 
     //void handle_retransmit(Packet*) override;
     static unsigned flow_id;
 
 private:
     void save_to_pending_context();
-    void finish_signature_lookup(FileContext*);
     void init_file_context(FileDirection, FileContext*);
     FileContext* find_main_file_context(FilePosition, FileDirection, size_t id = 0);
-    void log_file_event(FileContext*, Flow*);
     FileContext* main_context = nullptr;
     FileContext* pending_context = nullptr;
     FileContext* current_context = nullptr;
     uint32_t max_file_id = 0;
+    uint64_t current_file_id = 0;
     Flow* flow = nullptr;
 };
 #endif
index cb59565da1bc07bdde3df8e2331506d4b48b8ddd..b8966ab08d8d85d5d1d33c08cf88485698cc02ac 100644 (file)
 #include "catch/catch.hpp"
 #endif
 
-typedef struct _IdentifierSharedNode
+struct MergeNode
 {
     IdentifierNode* shared_node;  /*the node that is shared*/
     IdentifierNode* append_node;  /*the node that is added*/
-} IdentifierSharedNode;
+} ;
 
 void FileMagicData::clear()
 {
@@ -68,8 +68,8 @@ void FileMagicRule::clear()
 
 void FileIdentifier::init_merge_hash()
 {
-    identifier_merge_hash = sfghash_new(1000, sizeof(IdentifierSharedNode), 0, NULL);
-    if (identifier_merge_hash == NULL)
+    identifier_merge_hash = sfghash_new(1000, sizeof(MergeNode), 0, nullptr);
+    if (identifier_merge_hash == nullptr)
     {
         FatalError("%s(%d) Could not create identifier merge hash.\n",
             __FILE__, __LINE__);
@@ -79,13 +79,12 @@ void FileIdentifier::init_merge_hash()
 FileIdentifier::~FileIdentifier()
 {
     /*Release memory used for identifiers*/
-    for (IDMemoryBlocks::iterator idMem = idMemoryBlocks.begin();
-            idMem != idMemoryBlocks.end(); idMem++)
+    for (auto mem_block:id_memory_blocks)
     {
-        snort_free(idMem->mem);
+        snort_free(mem_block);
     }
 
-    if (identifier_merge_hash != NULL)
+    if (identifier_merge_hash != nullptr)
     {
         sfghash_delete(identifier_merge_hash);
     }
@@ -93,13 +92,10 @@ FileIdentifier::~FileIdentifier()
 
 void* FileIdentifier::calloc_mem(size_t size)
 {
-    void* ret;
-    IDMemoryBlock memblock;
-    ret = snort_calloc(size);
+    void* ret = snort_calloc(size);
     memory_used += size;
     /*For memory management*/
-    memblock.mem = ret;
-    idMemoryBlocks.push_back(memblock);
+    id_memory_blocks.push_back(ret);
     return ret;
 }
 
@@ -116,10 +112,10 @@ void FileIdentifier::set_node_state_shared(IdentifierNode* start)
     if (start->state == ID_NODE_USED)
         start->state = ID_NODE_SHARED;
     else
-       start->state = ID_NODE_USED;
+        start->state = ID_NODE_USED;
 
     for (i = 0; i < MAX_BRANCH; i++)
-       set_node_state_shared(start->next[i]);
+        set_node_state_shared(start->next[i]);
 }
 
 /*Clone a trie*/
@@ -128,7 +124,7 @@ IdentifierNode* FileIdentifier::clone_node(IdentifierNode* start)
     int index;
     IdentifierNode* node;
     if (!start)
-        return NULL;
+        return nullptr;
 
     node = (IdentifierNode*)calloc_mem(sizeof(*node));
 
@@ -158,10 +154,10 @@ void FileIdentifier::verify_magic_offset(FileMagicData* parent, FileMagicData* c
 IdentifierNode* FileIdentifier::create_trie_from_magic(FileMagicRule& rule, uint32_t type_id)
 {
     IdentifierNode* current;
-    IdentifierNode* root = NULL;
+    IdentifierNode* root = nullptr;
 
     if (!rule.file_magics.size() || !type_id)
-        return NULL;
+        return nullptr;
 
     /* Content magics are sorted based on offset, this
      * will help compile the file magic trio
@@ -172,16 +168,15 @@ IdentifierNode* FileIdentifier::create_trie_from_magic(FileMagicRule& rule, uint
     current->state = ID_NODE_NEW;
     root = current;
 
-    for(FileMagics::iterator magic = rule.file_magics.begin();
-            magic !=rule.file_magics.end(); magic++)
+    for (auto magic:rule.file_magics)
     {
         unsigned int i;
-        current->offset = magic->offset;
-        for (i = 0; i < magic->content.size(); i++)
+        current->offset = magic.offset;
+        for (i = 0; i < magic.content.size(); i++)
         {
             IdentifierNode* node = (IdentifierNode*)calloc_mem(sizeof(*node));
-            uint8_t index = magic->content[i];
-            node->offset = magic->offset + i + 1;
+            uint8_t index = magic.content[i];
+            node->offset = magic.offset + i + 1;
             node->state = ID_NODE_NEW;
             current->next[index] = node;
             current = node;
@@ -199,14 +194,14 @@ bool FileIdentifier::update_next(IdentifierNode* start,IdentifierNode** next_ptr
     IdentifierNode* append)
 {
     IdentifierNode* next = (*next_ptr);
-    IdentifierSharedNode sharedIdentifier;
+    MergeNode merge_node;
     IdentifierNode* result;
 
     if (!append || (next == append))
         return false;
 
-    sharedIdentifier.append_node = append;
-    sharedIdentifier.shared_node = next;
+    merge_node.append_node = append;
+    merge_node.shared_node = next;
     if (!next)
     {
         /*reuse the append*/
@@ -214,7 +209,7 @@ bool FileIdentifier::update_next(IdentifierNode* start,IdentifierNode** next_ptr
         set_node_state_shared(append);
         return false;
     }
-    else if ((result = (IdentifierNode*)sfghash_find(identifier_merge_hash, &sharedIdentifier)))
+    else if ((result = (IdentifierNode*)sfghash_find(identifier_merge_hash, &merge_node)))
     {
         /*the same pointer has been processed, reuse it*/
         *next_ptr = result;
@@ -228,8 +223,8 @@ bool FileIdentifier::update_next(IdentifierNode* start,IdentifierNode** next_ptr
             /*offset could have gap when non 0 offset is allowed */
             int index;
             IdentifierNode* node = (IdentifierNode*)calloc_mem(sizeof(*node));
-            sharedIdentifier.shared_node = next;
-            sharedIdentifier.append_node = append;
+            merge_node.shared_node = next;
+            merge_node.append_node = append;
             node->offset = append->offset;
 
             for (index = 0; index < MAX_BRANCH; index++)
@@ -239,17 +234,17 @@ bool FileIdentifier::update_next(IdentifierNode* start,IdentifierNode** next_ptr
 
             set_node_state_shared(next);
             next = node;
-            sfghash_add(identifier_merge_hash, &sharedIdentifier, next);
+            sfghash_add(identifier_merge_hash, &merge_node, next);
         }
         else if (next->state == ID_NODE_SHARED)
         {
             /*shared, need to clone one*/
             IdentifierNode* current_next = next;
-            sharedIdentifier.shared_node = current_next;
-            sharedIdentifier.append_node = append;
+            merge_node.shared_node = current_next;
+            merge_node.append_node = append;
             next = clone_node(current_next);
             set_node_state_shared(next);
-            sfghash_add(identifier_merge_hash, &sharedIdentifier, next);
+            sfghash_add(identifier_merge_hash, &merge_node, next);
         }
 
         *next_ptr = next;
@@ -307,7 +302,7 @@ void FileIdentifier::insert_file_rule(FileMagicRule& rule)
 
     if (!identifier_root)
     {
-        identifier_root = (IdentifierNode *)calloc_mem(sizeof(*identifier_root));
+        identifier_root = (IdentifierNode*)calloc_mem(sizeof(*identifier_root));
         init_merge_hash();
     }
 
@@ -323,7 +318,6 @@ void FileIdentifier::insert_file_rule(FileMagicRule& rule)
         return;
     }
 
-
     file_magic_rules[rule.id] = rule;
 
     node = create_trie_from_magic(rule, rule.id);
@@ -375,7 +369,7 @@ uint32_t FileIdentifier::find_file_type_id(const uint8_t* buf, int len, uint64_t
     }
 
     /*Either end of magics or passed the current offset*/
-    *context = NULL;
+    *context = nullptr;
 
     if ( file_type_id == SNORT_FILE_TYPE_CONTINUE )
         file_type_id = SNORT_FILE_TYPE_UNKNOWN;
@@ -383,14 +377,14 @@ uint32_t FileIdentifier::find_file_type_id(const uint8_t* buf, int len, uint64_t
     return file_type_id;
 }
 
-FileMagicRule*  FileIdentifier::get_rule_from_id(uint32_t id)
+FileMagicRule* FileIdentifier::get_rule_from_id(uint32_t id)
 {
     if ((id < FILE_ID_MAX) && (file_magic_rules[id].id > 0))
     {
         return (&(file_magic_rules[id]));
     }
     else
-        return NULL;
+        return nullptr;
 }
 
 //--------------------------------------------------------------------------
@@ -424,10 +418,9 @@ TEST_CASE ("FileIdRulePDF", "[FileMagic]")
 
     const char* data = "PDF";
 
-    void *context = NULL;
-
-    CHECK(rc.find_file_type_id((const uint8_t *)data, strlen(data), 0, &context) == 1);
+    void* context = nullptr;
 
+    CHECK(rc.find_file_type_id((const uint8_t*)data, strlen(data), 0, &context) == 1);
 }
 
 TEST_CASE ("FileIdRuleUnknow", "[FileMagic]")
@@ -449,11 +442,10 @@ TEST_CASE ("FileIdRuleUnknow", "[FileMagic]")
 
     const char* data = "DDF";
 
-    void *context = NULL;
+    void* context = nullptr;
 
-    CHECK(rc.find_file_type_id((const uint8_t *)data, strlen(data), 0, &context) ==
+    CHECK(rc.find_file_type_id((const uint8_t*)data, strlen(data), 0, &context) ==
         SNORT_FILE_TYPE_UNKNOWN);
-
 }
 
 TEST_CASE ("FileIdRuleEXE", "[FileMagic]")
@@ -484,9 +476,9 @@ TEST_CASE ("FileIdRuleEXE", "[FileMagic]")
     rc.insert_file_rule(rule);
 
     const char* data = "PDFooo";
-    void *context = NULL;
+    void* context = nullptr;
 
-    CHECK(rc.find_file_type_id((const uint8_t *)data, strlen(data), 0, &context) == 1);
+    CHECK(rc.find_file_type_id((const uint8_t*)data, strlen(data), 0, &context) == 1);
 }
 
 TEST_CASE ("FileIdRulePDFEXE", "[FileMagic]")
@@ -517,10 +509,10 @@ TEST_CASE ("FileIdRulePDFEXE", "[FileMagic]")
     rc.insert_file_rule(rule);
 
     const char* data = "PDFEXE";
-    void *context = NULL;
+    void* context = nullptr;
 
     // Match the last one
-    CHECK(rc.find_file_type_id((const uint8_t *)data, strlen(data), 0, &context) == 3);
+    CHECK(rc.find_file_type_id((const uint8_t*)data, strlen(data), 0, &context) == 3);
 }
 
 TEST_CASE ("FileIdRuleFirst", "[FileMagic]")
@@ -551,8 +543,9 @@ TEST_CASE ("FileIdRuleFirst", "[FileMagic]")
     rc.insert_file_rule(rule);
 
     const char* data = "PDF";
-    void *context = NULL;
+    void* context = nullptr;
 
-    CHECK(rc.find_file_type_id((const uint8_t *)data, strlen(data), 0, &context) == 1);
+    CHECK(rc.find_file_type_id((const uint8_t*)data, strlen(data), 0, &context) == 1);
 }
 #endif
+
index 50f1ad2fca40ec4cf26cf3b852085de1ae1f82cd..6b32dcb1252a07a6e6274ed0c2a3b811c9934de4 100644 (file)
@@ -39,7 +39,7 @@ enum IdNodeState
     ID_NODE_NEW,
     ID_NODE_USED,
     ID_NODE_SHARED
-} ;
+};
 
 class FileMagicData
 {
@@ -48,7 +48,7 @@ public:
     std::string content_str;   /* magic content to match*/
     std::string content;       /* magic content raw values*/
     uint32_t offset;           /* pattern search start offset */
-    bool operator < (const FileMagicData& magic) const
+    bool operator <(const FileMagicData& magic) const
     {
         return (offset < magic.offset);
     }
@@ -69,29 +69,24 @@ public:
     FileMagics file_magics;
 };
 
-typedef struct _IdentifierNode
+struct IdentifierNode
 {
     uint32_t type_id;       /* magic content to match*/
     IdNodeState state;
     uint32_t offset;            /* offset from file start */
-    struct _IdentifierNode* next[MAX_BRANCH]; /* pointer to an array of 256 identifiers pointers*/
-} IdentifierNode;
-
-struct IDMemoryBlock
-{
-    void *mem;
+    struct IdentifierNode* next[MAX_BRANCH]; /* pointer to an array of 256 identifiers pointers*/
 };
 
-typedef std::list<IDMemoryBlock >  IDMemoryBlocks;
+typedef std::list<void* >  IDMemoryBlocks;
 
 class FileIdentifier
 {
-public:
-    ~FileIdentifier();
-    uint32_t memory_usage() {return memory_used;}
+public: ~FileIdentifier();
+    uint32_t memory_usage() { return memory_used; }
     void insert_file_rule(FileMagicRule& rule);
     uint32_t find_file_type_id(const uint8_t* buf, int len, uint64_t offset, void** context);
     FileMagicRule* get_rule_from_id(uint32_t);
+
 private:
     void init_merge_hash();
     void* calloc_mem(size_t size);
@@ -107,7 +102,7 @@ private:
     uint32_t memory_used = 0; /*Track memory usage*/
     SFGHASH* identifier_merge_hash = nullptr;
     FileMagicRule file_magic_rules[FILE_ID_MAX + 1];
-    IDMemoryBlocks idMemoryBlocks;
+    IDMemoryBlocks id_memory_blocks;
 };
 
 #endif
index 2426b699ec47379aafc829b683778b4149be9284..ecc3d3ac1cb9e76260562da73bc7a23b8ff481d5 100644 (file)
 #include <iostream>
 #include <iomanip>
 
-#include "file_identifier.h"
+#include "file_capture.h"
 #include "file_config.h"
+#include "file_enforcer.h"
+#include "file_identifier.h"
+#include "file_service.h"
+#include "file_segment.h"
+#include "file_stats.h"
+
 #include "hash/hashes.h"
 #include "utils/util.h"
-#include "file_api/file_capture.h"
+#include "main/snort_config.h"
+#include "framework/data_bus.h"
 
 FileInfo::~FileInfo ()
 {
-    if(sha256)
+    if (sha256)
         delete[] sha256;
 }
 
@@ -54,7 +61,7 @@ void FileInfo::copy(const FileInfo& other)
     if (other.sha256)
     {
         sha256 = new uint8_t[SHA256_HASH_SIZE];
-        memcpy( (char *)sha256, (const char *)other.sha256, SHA256_HASH_SIZE);
+        memcpy( (char*)sha256, (const char*)other.sha256, SHA256_HASH_SIZE);
     }
 
     file_size = other.file_size;
@@ -73,7 +80,7 @@ FileInfo::FileInfo(const FileInfo& other)
 FileInfo& FileInfo::operator=(const FileInfo& other)
 {
     // check for self-assignment
-    if(&other == this)
+    if (&other == this)
         return *this;
 
     copy(other);
@@ -82,12 +89,14 @@ FileInfo& FileInfo::operator=(const FileInfo& other)
 
 /*File properties*/
 
-void FileInfo::set_file_name (const char *name, uint32_t name_size)
+void FileInfo::set_file_name(const char* name, uint32_t name_size)
 {
     if (name and name_size)
     {
         file_name.assign(name, name_size);
     }
+
+    file_name_set = true;
 }
 
 std::string& FileInfo::get_file_name()
@@ -120,7 +129,6 @@ size_t FileInfo::get_file_id() const
     return file_id;
 }
 
-
 void FileInfo::set_file_direction(FileDirection dir)
 {
     direction = dir;
@@ -128,7 +136,7 @@ void FileInfo::set_file_direction(FileDirection dir)
 
 FileDirection FileInfo::get_file_direction() const
 {
-    return (direction);
+    return direction;
 }
 
 void FileInfo::set_file_sig_sha256(uint8_t* signature)
@@ -141,17 +149,17 @@ uint8_t* FileInfo::get_file_sig_sha256() const
     return (sha256);
 }
 
-std::string FileInfo::sha_to_string (const uint8_t *sha256)
+std::string FileInfo::sha_to_string(const uint8_t* sha256)
 {
     uint8_t conv[] = "0123456789ABCDEF";
-    const uint8_t *index;
-    const uint8_t *end;
+    const uint8_tindex;
+    const uint8_tend;
     std::string sha_out;
 
     index = sha256;
     end = index + SHA256_HASH_SIZE;
 
-    while(index < end)
+    while (index < end)
     {
         sha_out.push_back(conv[((*index & 0xFF)>>4)]);
         sha_out.push_back(conv[((*index & 0xFF)&0x0F)]);
@@ -165,16 +173,19 @@ FileContext::FileContext ()
 {
     file_type_context = nullptr;
     file_signature_context = nullptr;
-    file_config = nullptr;
+    file_config = &(snort_conf->file_config);
     file_capture = nullptr;
+    file_segments = nullptr;
 }
 
 FileContext::~FileContext ()
 {
     if (file_signature_context)
         snort_free(file_signature_context);
-    if(file_capture)
+    if (file_capture)
         stop_file_capture();
+    if (file_segments)
+        delete file_segments;
 }
 
 inline int FileContext::get_data_size_from_depth_limit(FileProcessType type, int
@@ -206,12 +217,152 @@ inline int FileContext::get_data_size_from_depth_limit(FileProcessType type, int
 }
 
 /* stop file type identification */
-inline void FileContext::finalize_file_type ()
+inline void FileContext::finalize_file_type()
 {
     if (SNORT_FILE_TYPE_CONTINUE ==  file_type_id)
         file_type_id = SNORT_FILE_TYPE_UNKNOWN;
     file_type_context = nullptr;
 }
+
+void FileContext::log_file_event(Flow* flow)
+{
+    // wait for file name is set to log file event
+    if ( is_file_name_set() )
+    {
+        switch (verdict)
+        {
+        case FILE_VERDICT_LOG:
+            // Log file event through data bus
+            get_data_bus().publish("file_event", (const uint8_t*)"LOG", 3, flow);
+            break;
+
+        case FILE_VERDICT_BLOCK:
+            // can't block session inside a session
+            get_data_bus().publish("file_event", (const uint8_t*)"BLOCK", 5, flow);
+            break;
+
+        case FILE_VERDICT_REJECT:
+            get_data_bus().publish("file_event", (const uint8_t*)"RESET", 5, flow);
+            break;
+        default:
+            break;
+        }
+        if ( FileConfig::trace_type )
+            print(std::cout);
+    }
+}
+
+void FileContext::finish_signature_lookup(Flow* flow)
+{
+    if (get_file_sig_sha256())
+    {
+        //Check file type based on file policy
+        FilePolicy& inspect = FileService::get_inspect();
+        inspect.signature_lookup(flow, this);
+        log_file_event(flow);
+        config_file_signature(false);
+        file_stats.signatures_processed[get_file_type()][get_file_direction()]++;
+    }
+}
+
+void FileContext::check_policy(Flow* flow, FileDirection dir)
+{
+    file_stats.files_total++;
+    set_file_direction(dir);
+    FilePolicy& inspect = FileService::get_inspect();
+    inspect.policy_check(flow, this);
+}
+
+/*
+ * Return:
+ *    true: continue processing/log/block this file
+ *    false: ignore this file
+ */
+bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size,
+    FilePosition position)
+{
+    if ( FileConfig::trace_stream )
+    {
+        FileContext::print_file_data(stdout, file_data, data_size,
+            snort_conf->file_config.show_data_depth);
+    }
+
+    //set_current_file_context(context);
+    file_stats.file_data_total += data_size;
+
+    if ((!is_file_type_enabled())and (!is_file_signature_enabled()))
+    {
+        update_file_size(data_size, position);
+        return false;
+    }
+
+    if ((FileService::get_file_enforcer()->cached_verdict_lookup(flow, this)
+            != FILE_VERDICT_UNKNOWN))
+        return true;
+
+    /*file type id*/
+    if (is_file_type_enabled())
+    {
+        process_file_type(file_data, data_size, position);
+
+        /*Don't care unknown file type*/
+        if (get_file_type()== SNORT_FILE_TYPE_UNKNOWN)
+        {
+            config_file_type(false);
+            config_file_signature(false);
+            update_file_size(data_size, position);
+            stop_file_capture();
+            return false;
+        }
+
+        if (get_file_type() != SNORT_FILE_TYPE_CONTINUE)
+        {
+            config_file_type(false);
+            file_stats.files_processed[get_file_type()][get_file_direction()]++;
+            //Check file type based on file policy
+            FilePolicy& inspect = FileService::get_inspect();
+            inspect.type_lookup(flow, this);
+            log_file_event(flow);
+        }
+    }
+
+    /* file signature calculation */
+    if (is_file_signature_enabled())
+    {
+        process_file_signature_sha256(file_data, data_size, position);
+
+        file_stats.data_processed[get_file_type()][get_file_direction()]
+            += data_size;
+
+        update_file_size(data_size, position);
+
+        if ( FileConfig::trace_signature )
+            print_file_sha256(std::cout);
+
+        /*Fails to capture, when out of memory or size limit, need lookup*/
+        if (is_file_capture_enabled())
+        {
+            process_file_capture(file_data, data_size, position);
+        }
+
+        finish_signature_lookup(flow);
+    }
+    else
+    {
+        update_file_size(data_size, position);
+    }
+
+    return true;
+}
+
+bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size,
+    uint64_t offset)
+{
+    if (!file_segments)
+        file_segments = new FileSegments(this);
+    return file_segments->process(flow, file_data, data_size, offset);
+}
+
 /*
  * Main File type processing function
  * We use file type context to decide file type across packets
@@ -384,17 +535,6 @@ uint64_t FileContext::get_processed_bytes()
     return processed_bytes;
 }
 
-
-void FileContext::set_file_config(FileConfig* config)
-{
-    file_config = config;
-}
-
-FileConfig*  FileContext::get_file_config()
-{
-    return file_config;
-}
-
 void FileContext::print_file_data(FILE* fp, const uint8_t* data, int len, int max_depth)
 {
     char str[18];
@@ -452,7 +592,6 @@ void FileContext::print_file_data(FILE* fp, const uint8_t* data, int len, int ma
  */
 void FileContext::print_file_sha256(std::ostream& log)
 {
-
     unsigned char* hash = sha256;
 
     if (!sha256)
@@ -472,7 +611,7 @@ void FileContext::print_file_sha256(std::ostream& log)
     log.flags(f);
 }
 
-void FileContext::print( std::ostream& log)
+void FileContext::print(std::ostream& log)
 {
     log << "File name: " << file_name << std::endl;
     log << "File type: " << file_config->file_type_name(file_type_id)
@@ -509,3 +648,4 @@ bool file_IDs_from_group(const void *conf, const char *group,
     return get_ids_from_group(conf, group, ids, count);
 }
  **/
+
index 4affa71960597c74bce14cfaf18c4e87c1215cd8..3fa7aab102cece297ab288d88ee62ef4021be8d4 100644 (file)
 
 class FileCapture;
 class FileConfig;
+class FileSegments;
+class Flow;
 
 class SO_PUBLIC FileInfo
 {
 public:
     virtual ~FileInfo();
-    FileInfo(){}
+    FileInfo() { }
     FileInfo(const FileInfo& other);
     FileInfo& operator=(const FileInfo& other);
     uint32_t get_file_type() const;
     void set_file_name(const char* file_name, uint32_t name_size);
     std::string& get_file_name();
+    // Whether file name has been set (could be empty file name)
+    bool is_file_name_set() const { return file_name_set; }
+
     void set_file_size(uint64_t size);
     uint64_t get_file_size() const;
     void set_file_direction(FileDirection dir);
     FileDirection get_file_direction() const;
     void set_file_sig_sha256(uint8_t* signature);
     uint8_t* get_file_sig_sha256() const;
-    std::string sha_to_string(const uint8_t *sha256);
+    std::string sha_to_string(const uint8_tsha256);
     void set_file_id(size_t index);
     size_t get_file_id() const;
     FileVerdict verdict = FILE_VERDICT_UNKNOWN;
 
 protected:
     std::string file_name;
+    bool file_name_set = false;
     uint64_t file_size = 0;
-    FileDirection direction = DIRECTION_UNKNOWN;
+    FileDirection direction = FILE_DOWNLOAD;
     uint32_t file_type_id = SNORT_FILE_TYPE_CONTINUE;
     uint8_t* sha256 = nullptr;
     size_t file_id = 0;
@@ -70,22 +76,32 @@ private:
     void copy(const FileInfo& other);
 };
 
-class SO_PUBLIC FileContext: public FileInfo
+class SO_PUBLIC FileContext : public FileInfo
 {
 public:
     FileContext();
     ~FileContext();
 
+    void check_policy(Flow*, FileDirection);
+
     // main processing functions
+
+    // Return:
+    //    true: continue processing/log/block this file
+    //    false: ignore this file
+    bool process(Flow*, const uint8_t* file_data, int data_size, FilePosition);
+    bool process(Flow*, const uint8_t* file_data, int data_size, uint64_t offset);
     void process_file_type(const uint8_t* file_data, int data_size, FilePosition position);
     void process_file_signature_sha256(const uint8_t* file_data, int data_size, FilePosition pos);
     void update_file_size(int data_size, FilePosition position);
     void stop_file_capture();
-    FileCaptureState process_file_capture(const uint8_t* file_data, int data_size, FilePosition pos);
+    FileCaptureState process_file_capture(const uint8_t* file_data, int data_size,
+        FilePosition pos);
+    void log_file_event(Flow*);
 
     // Preserve the file in memory until it is released
     // The file reserved will be returned and it will be detached from file context/session
-    FileCaptureState reserve_file(FileCapture* &dest);
+    FileCaptureState reserve_file(FileCapture*dest);
 
     // Configuration functions
     void config_file_type(bool enabled);
@@ -98,9 +114,6 @@ public:
     //File properties
     uint64_t get_processed_bytes();
 
-    void set_file_config(FileConfig* file_config);
-    FileConfig*  get_file_config();
-
     void print_file_sha256(std::ostream&);
     static void print_file_data(FILE* fp, const uint8_t* data, int len, int max_depth);
     void print(std::ostream&);
@@ -113,11 +126,13 @@ private:
     void* file_type_context;
     void* file_signature_context;
     FileConfig* file_config;
-    FileCapture *file_capture;
-    FileState file_state = {FILE_CAPTURE_SUCCESS, FILE_SIG_PROCESSING};
+    FileCapture* file_capture;
+    FileSegments* file_segments;
+    FileState file_state = { FILE_CAPTURE_SUCCESS, FILE_SIG_PROCESSING };
 
     inline int get_data_size_from_depth_limit(FileProcessType type, int data_size);
-    inline void finalize_file_type ();
+    inline void finalize_file_type();
+    inline void finish_signature_lookup(Flow*);
 };
 
 #endif
index 746b968be38da1d758f5db9fbbad4e60cdc17229..ced593347f9a5972bfe03911016bc78e612fbe0f 100644 (file)
@@ -121,12 +121,12 @@ void LogHandler::log_file_name(TextLog* log, FileContext* file)
 
     for (size_t i = start; i < name.length(); i++)
     {
-        if ( name[i] > 0x1F && name[i] < 0x7F)
-        {   /* printable */
+        if ( name[i] > 0x1F && name[i] < 0x7F) /* printable */
+        {
             TextLog_Putc(log, name[i]);
         }
-        else
-        {   /* not printable */
+        else /* not printable */
+        {
             TextLog_Putc(log, '.');
         }
     }
@@ -134,7 +134,7 @@ void LogHandler::log_file_name(TextLog* log, FileContext* file)
     TextLog_Puts(log, "\"] ");
 }
 
-void LogHandler::handle(DataEvent& , Flow* f)
+void LogHandler::handle(DataEvent&, Flow* f)
 {
     if (config.log_sys_time)
     {
@@ -216,8 +216,8 @@ private:
 void FileLog::show(SnortConfig*)
 {
     LogMessage("%s config:\n", s_name);
-    LogMessage("    Log system time: %s\n", config.log_sys_time? "true" : "false");
-    LogMessage("    Log packet time: %s\n", config.log_pkt_time? "true" : "false");
+    LogMessage("    Log system time: %s\n", config.log_sys_time ? "true" : "false");
+    LogMessage("    Log packet time: %s\n", config.log_pkt_time ? "true" : "false");
 }
 
 //-------------------------------------------------------------------------
@@ -279,7 +279,7 @@ static void mod_dtor(Module* m)
 
 static Inspector* fl_ctor(Module* m)
 {
-    FileLogModule* fl_module = (FileLogModule *)m;
+    FileLogModule* fl_module = (FileLogModule*)m;
     return new FileLog(fl_module->config);
 }
 
@@ -303,7 +303,7 @@ static const InspectApi fl_api
         mod_dtor
     },
     IT_PASSIVE,
-    (uint16_t)PktType::NONE,
+    (uint16_t) PktType::NONE,
     nullptr, // buffers
     nullptr, // service
     nullptr, // pinit
index f6db470e0ad5123b85398a36ec332af0d7953b69..8dbd36d3accb340159d6732c3adc4b8df8c58af4 100644 (file)
@@ -60,6 +60,9 @@ bool FileIdModule::set(const char*, Value& v, SnortConfig* sc)
     else if ( v.is("capture_block_size") )
         fc.capture_block_size = v.get_long();
 
+    else if ( v.is("max_files_cached") )
+        fc.max_files_cached = v.get_long();
+
     else if ( v.is("enable_type") )
     {
         if ( v.get_bool() )
@@ -200,3 +203,4 @@ bool FileIdModule::end(const char* fqn, int idx, SnortConfig* sc)
 
     return true;
 }
+
index 84973c11a07f44378448653778c2c124a5f87566..d0fbbdbcd7834fa8d5aad22ed9755034698e39a1 100644 (file)
@@ -137,6 +137,9 @@ static const Parameter file_id_params[] =
     { "capture_block_size", Parameter::PT_INT, "8:", "32768",
       "file capture block size in bytes" },
 
+    { "max_files_cached", Parameter::PT_INT, "8:", "65536",
+      "maximal number of files cached in memory" },
+
     { "enable_type", Parameter::PT_BOOL, nullptr, "false",
       "enable type ID" },
 
@@ -167,7 +170,6 @@ static const Parameter file_id_params[] =
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
 
-
 #define file_id_help \
     "configure file identification"
 
index 0e3ea16e556e08dd021a1baa9d816dea44b3aa0b..ed7846546f7cd5320ec0910fdbad54d1d126da06 100644 (file)
@@ -62,7 +62,7 @@ void FilePolicy::set_file_capture(bool enabled)
     capture_enabled = enabled;
 }
 
-void FilePolicy::insert_file_rule(FileRule &rule)
+void FilePolicy::insert_file_rule(FileRulerule)
 {
     file_rules.push_back(rule);
 
@@ -75,7 +75,7 @@ void FilePolicy::insert_file_rule(FileRule &rule)
 
         while (offset < hex.size())
         {
-            int buffer = std::stoi( hex.substr(offset, 2), nullptr, 16);
+            int buffer = std::stoi(hex.substr(offset, 2), nullptr, 16);
             bytes.push_back(static_cast<unsigned char>(buffer));
             offset += 2;
         }
@@ -109,18 +109,17 @@ void FilePolicy::load()
     emptyRule.use.type_enabled = type_enabled;
     emptyRule.use.signature_enabled = signature_enabled;
     emptyRule.use.capture_enabled = capture_enabled;
-
 }
 
 FileRule& FilePolicy::match_file_rule(Flow*, FileInfo* file)
 {
-    for(unsigned i = 0; i < file_rules.size(); i++)
+    for (unsigned i = 0; i < file_rules.size(); i++)
     {
         if (file_rules[i].when.sha256.size())
             continue;
         // No file type specified in rule or file type is matched
-        if ((file_rules[i].when.type_id == 0) or
-            (file_rules[i].when.type_id == file->get_file_type()))
+        if ((file_rules[i].when.type_id == 0)or
+                (file_rules[i].when.type_id == file->get_file_type()))
             return file_rules[i];
     }
 
@@ -132,11 +131,11 @@ FileVerdict FilePolicy::match_file_signature(Flow*, FileInfo* file)
     // No file type specified in rule or file type is matched
     if (file->get_file_sig_sha256())
     {
-        std::string sha((const char *)file->get_file_sig_sha256(), SHA256_HASH_SIZE);
-
-        std::map<std::string, FileVerdict>::iterator it;
+        std::string sha((const char*)file->get_file_sig_sha256(), SHA256_HASH_SIZE);
 
-        return file_shas[sha];
+        auto search = file_shas.find(sha);
+        if (search != file_shas.end())
+            return search->second;
     }
 
     return FILE_VERDICT_UNKNOWN;
@@ -161,7 +160,7 @@ FileVerdict FilePolicy::type_lookup(Flow* flow, FileInfo* file)
 
 FileVerdict FilePolicy::type_lookup(Flow* flow, FileContext* file)
 {
-    type_lookup(flow, (FileInfo *)file);
+    type_lookup(flow, (FileInfo*)file);
     FileRule rule = match_file_rule(nullptr, file);
     file->config_file_signature(rule.use.signature_enabled);
     file->config_file_capture(rule.use.capture_enabled);
@@ -179,20 +178,18 @@ FileVerdict FilePolicy::signature_lookup(Flow* flow, FileInfo* file)
     return verdict;
 }
 
-FileVerdict FilePolicy::signature_lookup(Flow* flow, FileContext* file )
+FileVerdict FilePolicy::signature_lookup(Flow* flow, FileContext* file)
 {
     FileRule& rule = match_file_rule(nullptr, file);
 
     if (rule.use.capture_enabled)
     {
-        FileCapture *captured = nullptr;
+        FileCapturecaptured = nullptr;
 
         if (file->reserve_file(captured) == FILE_CAPTURE_SUCCESS)
-        {
-           captured->store_file_async();
-        }
+            captured->store_file_async();
     }
 
-    return (signature_lookup(flow, (FileInfo *)file));
+    return (signature_lookup(flow, (FileInfo*)file));
 }
 
index 5c700d7ad86176a9c77d35bfcce98a6959246497..b9524aca8e39a69f0394f5c65b9d5779ff8d19a0 100644 (file)
 #ifndef FILE_POLICY_H
 #define FILE_POLICY_H
 
-#include "file_api.h"
 #include <map>
+#include <vector>
+
+#include "file_api.h"
 
 struct FileVerdictWhen
 {
@@ -44,7 +46,7 @@ public:
     FileVerdictUse use;
 
     FileRule();
-    ~FileRule() {}
+    ~FileRule() { }
     void clear();
 };
 
@@ -52,10 +54,9 @@ class FileInfo;
 
 class FilePolicy
 {
-
 public:
-    FilePolicy() {}
-    ~FilePolicy() {}
+    FilePolicy() { }
+    ~FilePolicy() { }
 
     // This is called when a new flow is queried for the first time
     // Check & update what file policy is enabled on this flow/file
@@ -73,13 +74,13 @@ public:
     // This is called after file signature is complete
     virtual FileVerdict signature_lookup(Flow* flow, FileInfo* file);
 
-    void insert_file_rule(FileRule &);
+    void insert_file_rule(FileRule&);
     void set_file_type(bool enabled);
     void set_file_signature(bool enabled);
     void set_file_capture(bool enabled);
-    bool is_type_id_enabled() {return type_enabled;}
-    bool is_signature_enabled() {return signature_enabled;}
-    bool is_capture_enabled() {return capture_enabled;}
+    bool is_type_id_enabled() { return type_enabled; }
+    bool is_signature_enabled() { return signature_enabled; }
+    bool is_capture_enabled() { return capture_enabled; }
     void load();
 
 private:
@@ -93,3 +94,4 @@ private:
 };
 
 #endif
+
diff --git a/src/file_api/file_segment.cc b/src/file_api/file_segment.cc
new file mode 100644 (file)
index 0000000..7ee021f
--- /dev/null
@@ -0,0 +1,220 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2015-2016 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.
+//--------------------------------------------------------------------------
+//  file_segment.cc author Hui Cao <huica@cisco.com>
+
+#include "file_segment.h"
+
+#include "log/messages.h"
+#include "file_flows.h"
+#include "file_service.h"
+
+FileSegment::~FileSegment ()
+{
+    if (data)
+        delete data;
+}
+
+FileSegments::FileSegments (FileContext* ctx)
+{
+    head = nullptr;
+    current_offset = 0;
+    context =  ctx;
+}
+
+FileSegments::~FileSegments ()
+{
+    clear();
+}
+
+void FileSegments::clear()
+{
+    FileSegment* current_segment = head;
+
+    while (current_segment)
+    {
+        FileSegment* previous_segment = current_segment;
+        current_segment = current_segment->next;
+        delete previous_segment;
+    }
+
+    head = nullptr;
+    current_offset = 0;
+}
+
+// Update the segment list based on new data
+void FileSegments::add(const uint8_t* file_data, uint64_t data_size, uint64_t offset)
+{
+    FileSegment* new_segment = new FileSegment();
+    new_segment->offset = offset;
+    new_segment->data = new std::string((const char*)file_data, data_size);
+
+    if (!head)
+    {
+        head = new_segment;
+        return;
+    }
+
+    FileSegment* current_segment = head;
+    uint64_t start = offset;
+    uint64_t end = offset + data_size;
+    // left points to segment that "next" pointer needs to be updated
+    FileSegment* left = nullptr;
+    FileSegment* previous = nullptr;
+    bool find_left = false;
+    bool is_overlap = false;
+
+    // Find left boundary, left points to segment that needs update
+    while (current_segment)
+    {
+        if (current_segment->offset > start)
+        {
+            find_left = true;
+            left = previous;
+            break;
+        }
+
+        previous = current_segment;
+        current_segment = current_segment->next;
+    }
+
+    // New segment should be at the end of link list
+    if (!find_left)
+    {
+        previous->next = new_segment;
+    }
+    // New segment should be at the start of link list
+    else if (!left)
+    {
+        if (end <= head->offset)
+        {
+            new_segment->next = head;
+            head = new_segment;
+        }
+        else
+        {
+            is_overlap = true;
+        }
+    }
+    else
+    {
+        if ((left->offset + left->data->size() > start) ||
+            (left->next->offset < end))
+        {
+            is_overlap = true;
+        }
+        else
+        {
+            new_segment->next = left->next;
+            left->next = new_segment;
+        }
+    }
+
+    // ignore overlap case
+    if (is_overlap)
+    {
+        delete new_segment;
+        return;
+    }
+}
+
+FilePosition FileSegments::get_file_position(uint64_t data_size, uint64_t file_size)
+{
+    if (current_offset == 0)
+    {
+        if (file_size == data_size)
+            return SNORT_FILE_FULL;
+        else
+            return SNORT_FILE_START;
+    }
+
+    if (file_size <= data_size + current_offset)
+        return SNORT_FILE_END;
+
+    return SNORT_FILE_MIDDLE;
+}
+
+int FileSegments::process_one(Flow* flow, const uint8_t* file_data, int data_size)
+{
+    FilePosition position = get_file_position(data_size, context->get_file_size());
+
+    return context->process(flow, file_data, data_size, position);
+}
+
+int FileSegments::process_all(Flow* flow)
+{
+    int ret = 1;
+
+    FileSegment* current_segment = head;
+    while (current_segment && (current_offset == current_segment->offset))
+    {
+        ret = process_one(flow, (uint8_t* )current_segment->data->data(),
+            current_segment->data->size());
+
+        if (!ret)
+        {
+            clear();
+            break;
+        }
+
+        current_offset += current_segment->data->size();
+        head = current_segment->next;
+        delete(current_segment);
+        current_segment = head;
+    }
+
+    return ret;
+}
+
+/*
+ * Process file segment, do file segment reassemble if the file segment is
+ * out of order.
+ * Return:
+ *    1: continue processing/log/block this file
+ *    0: ignore this file
+ */
+int FileSegments::process(Flow* flow, const uint8_t* file_data, uint64_t data_size,
+    uint64_t offset)
+{
+    int ret = 0;
+
+    if (offset == 0)
+    {
+        current_offset = 0;
+    }
+
+    // Walk through the segments that can be flushed
+    if (current_offset == offset)
+    {
+        ret =  process_one(flow, file_data, data_size);
+        current_offset += data_size;
+        if (!ret)
+        {
+            clear();
+            return 0;
+        }
+
+        ret = process_all(flow);
+    }
+    else if ((current_offset < context->get_file_size()) && (current_offset < offset))
+    {
+        add(file_data, data_size, offset);
+    }
+
+    return ret;
+}
+
diff --git a/src/file_api/file_segment.h b/src/file_api/file_segment.h
new file mode 100644 (file)
index 0000000..5a3a1bf
--- /dev/null
@@ -0,0 +1,67 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2015-2016 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.
+//--------------------------------------------------------------------------
+//  file_segment.h author Hui Cao <huica@cisco.com>
+
+#ifndef FILE_SEGMENT_H
+#define FILE_SEGMENT_H
+
+//Segmented file data reassemble and processing
+
+#include <sys/types.h>
+#include <string>
+
+#include "file_lib.h"
+#include "file_api.h"
+
+class FileSegment
+{
+public:
+    FileSegment() { }
+    ~FileSegment();
+
+    // Use single list for simplicity
+    FileSegment* next = nullptr;
+    uint32_t offset = 0;
+    std::string* data = nullptr;
+};
+
+class FileSegments
+{
+public:
+    FileSegments(FileContext*);
+    ~FileSegments();
+
+    void clear();
+
+    // Process file segments with current_offset specified. If file segment is out of order,
+    // it will be put into the file segments queue.
+    int process(Flow*, const uint8_t* file_data, uint64_t data_size, uint64_t offset);
+
+private:
+    FileSegment* head = nullptr;
+    uint64_t current_offset;
+    FileContext* context = nullptr;
+
+    void add(const uint8_t* file_data, uint64_t data_size, uint64_t offset);
+    FilePosition get_file_position(uint64_t data_size, uint64_t file_size);
+    int process_one(Flow*, const uint8_t* file_data, int data_size);
+    int process_all(Flow*);
+};
+
+#endif
+
index 346b66472ab6f31edf7f8a20283ec465ae8fe5d3..cce96dee35de3cc91212b4dd467305c73d67d8b2 100644 (file)
 #include <stdlib.h>
 
 #include "file_api.h"
-#include "file_stats.h"
 #include "file_capture.h"
+#include "file_cache.h"
+#include "file_config.h"
 #include "file_flows.h"
 #include "file_enforcer.h"
 #include "file_lib.h"
-#include "file_config.h"
+#include "file_stats.h"
 
 #include "mime/file_mime_config.h"
 #include "mime/file_mime_process.h"
 #include "main/snort_types.h"
 #include "managers/action_manager.h"
-#include "stream/stream_api.h"
 #include "detection/detect.h"
 #include "detection/detection_util.h"
 #include "packet_io/active.h"
@@ -56,6 +56,7 @@ bool FileService::file_signature_enabled = false;
 bool FileService::file_capture_enabled = false;
 bool FileService::file_processing_initiated = false;
 FileEnforcer* FileService::file_enforcer = nullptr;
+FileCache* FileService::file_cache = nullptr;
 
 void FileService::init()
 {
@@ -77,6 +78,8 @@ void FileService::close()
 {
     if (file_enforcer)
         delete file_enforcer;
+    if (file_cache)
+        delete file_cache;
 
     MimeSession::exit();
     FileCapture::exit();
@@ -87,6 +90,7 @@ void FileService::start_file_processing()
     if (!file_processing_initiated)
     {
         file_enforcer = new FileEnforcer;
+        file_cache = new FileCache;
         //RegisterProfileStats("file", print_file_stats);  FIXIT-M put in module
         file_processing_initiated = true;
     }
@@ -187,3 +191,4 @@ uint64_t get_file_processed_size(Flow* flow)
 
     return context->get_processed_bytes();
 }
+
index 3b3c7db9770a84493a0ea1c98374b9ed1f043c0c..544dd08ad00e5b41599b64eee7f0a528e3bbe348 100644 (file)
@@ -29,6 +29,7 @@
 #include "file_api/file_policy.h"
 
 class FileEnforcer;
+class FileCache;
 
 class SO_PUBLIC FileService
 {
@@ -43,16 +44,17 @@ public:
     static void close();
 
     static void enable_file_type();
-    static void enable_file_signature ();
+    static void enable_file_signature();
     static void enable_file_capture();
-    static bool is_file_type_id_enabled() {return file_type_id_enabled;}
-    static bool is_file_signature_enabled() {return file_signature_enabled;}
-    static bool is_file_capture_enabled() {return file_capture_enabled;}
+    static bool is_file_type_id_enabled() { return file_type_id_enabled; }
+    static bool is_file_signature_enabled() { return file_signature_enabled; }
+    static bool is_file_capture_enabled() { return file_capture_enabled; }
     static bool is_file_service_enabled();
     static int64_t get_max_file_depth();
 
     static FilePolicy& get_inspect();
-    static FileEnforcer* get_file_enforcer() {return file_enforcer;}
+    static FileEnforcer* get_file_enforcer() { return file_enforcer; }
+    static FileCache* get_file_cache() { return file_cache; }
 
 private:
     static void start_file_processing();
@@ -61,6 +63,7 @@ private:
     static bool file_capture_enabled;
     static bool file_processing_initiated;
     static FileEnforcer* file_enforcer;
+    static FileCache* file_cache;
 };
 
 extern const struct BaseApi* file_inspectors[];
index e8e0fd317aca83c100f94924129679a278bfaf5f..6077d760bd4c2a78011cf14ca19bc8dbf52a95b7 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "file_stats.h"
 #include "file_capture.h"
+#include "file_cache.h"
 #include "file_config.h"
 
 #include "main/snort_types.h"
@@ -148,7 +149,7 @@ void print_file_stats()
 #if 0
     LogLabel("file type verdicts");
 
-    uint64_t verdicts_total = 0;
+    uint64_t verdicts_total = 0;#include "file_capture.h"
     for (i = 0; i < FILE_VERDICT_MAX; i++)
     {
         verdicts_total+=file_stats.verdicts_type[i];
@@ -281,6 +282,7 @@ void print_file_stats()
     LogLabel("file stats summary");
     LogCount("Files processed",file_stats.files_total);
     LogCount("Files data processed", file_stats.file_data_total);
-
+    if(FileCache::num_add_fails)
+        LogCount("Fails to add to cache", FileCache::num_add_fails);
 }
 
index 4e61200e33d17904b6d577589c7a9dbd2c678b23..c4d3e9545ac3abb4dcf7fc694f0bf6663929db90 100644 (file)
@@ -36,7 +36,7 @@
 
 #define MAX_PROTOCOL_ORDINAL 8192  // FIXIT-L use std::vector and get_protocol_count()
 
-typedef struct _File_Stats
+struct FileStats
 {
     uint64_t files_total;
     uint64_t files_processed[FILE_ID_MAX + 1][2];
@@ -48,7 +48,7 @@ typedef struct _File_Stats
     uint64_t data_processed[FILE_ID_MAX + 1][2];
     uint64_t file_data_total;
     uint64_t files_sig_depth;
-} FileStats;
+};
 
 extern FileStats file_stats;
 
index 3246a37ff99fc35790f3c243ff3fc1fe536d13b9..af59cc876d2d28366b76110d004e1950cd9992cb 100644 (file)
@@ -22,8 +22,9 @@
 #include <assert.h>
 
 #include "time/packet_time.h"
-#include "stream/stream_api.h"  // FIXIT-M bad dependency
 #include "hash/zhash.h"
+#include "protocols/packet.h"
+#include "stream/stream.h"
 #include "sfip/sf_ip.h"
 
 /* Reasonably small, and prime */
@@ -432,7 +433,7 @@ char ExpectCache::process_expected(Packet* p, Flow* lws)
     while ((fd = head->data))
     {
         head->data = fd->next;
-        lws->set_application_data(fd);
+        lws->set_flow_data(fd);
         ++realized;
         fd->handle_expected(p);
     }
index 8c5dbcb6031c8c5818dc3a913b3dffef8e75d9d9..c2fdce289637485e29be6a834f9a8ebdd72c15cf 100644 (file)
 #include "flow/ha.h"
 #include "flow/session.h"
 #include "ips_options/ips_flowbits.h"
-#include "utils/bitop.h"
-#include "utils/util.h"
 #include "protocols/packet.h"
 #include "sfip/sf_ip.h"
+#include "utils/bitop.h"
+#include "utils/util.h"
 
 unsigned FlowData::flow_id = 0;
 
@@ -60,15 +60,15 @@ Flow::~Flow()
 void Flow::init(PktType type)
 {
     pkt_type = type;
-
-    // FIXIT-M getFlowbitSizeInBytes() should be attribute of ??? (or eliminate)
-    bitop = new BitOp(getFlowbitSizeInBytes());
+    bitop = nullptr;
 
     if ( HighAvailabilityManager::active() )
     {
         ha_state = new FlowHAState;
         previous_ssn_state = ssn_state;
     }
+    mpls_client.length = 0;
+    mpls_server.length = 0;
 }
 
 void Flow::term()
@@ -76,7 +76,16 @@ void Flow::term()
     if ( session )
         delete session;
 
-    free_application_data();
+    free_flow_data();
+
+    if ( mpls_client.length )
+        delete[] mpls_client.start;
+
+    if ( mpls_server.length )
+        delete[] mpls_server.start;
+
+    if ( bitop )
+        delete bitop;
 
     if ( ssn_client )
         ssn_client->rem_ref();
@@ -90,21 +99,26 @@ void Flow::term()
     if ( gadget )
         gadget->rem_ref();
 
-    if ( bitop )
-        delete bitop;
-
     if ( ha_state )
         delete ha_state;
+}
 
-    if ( clientMplsLyr.length )
+inline void Flow::clean()
+{
+    if ( mpls_client.length )
     {
-        delete[] clientMplsLyr.start;
-        clientMplsLyr.length = 0;
+        delete[] mpls_client.start;
+        mpls_client.length = 0;
     }
-    if ( serverMplsLyr.length )
+    if ( mpls_server.length )
     {
-        delete[] serverMplsLyr.start;
-        serverMplsLyr.length = 0;
+        delete[] mpls_server.start;
+        mpls_server.length = 0;
+    }
+    if ( bitop )
+    {
+        delete bitop;
+        bitop = nullptr;
     }
 }
 
@@ -119,18 +133,8 @@ void Flow::reset(bool do_cleanup)
             session->clear();
     }
 
-    free_application_data();
-
-    if ( clientMplsLyr.length )
-    {
-        delete[] clientMplsLyr.start;
-        clientMplsLyr.length = 0;
-    }
-    if ( serverMplsLyr.length )
-    {
-        delete[] serverMplsLyr.start;
-        serverMplsLyr.length = 0;
-    }
+    free_flow_data();
+    clean();
 
     // FIXIT-M cleanup() winds up calling clear()
     if ( ssn_client )
@@ -152,33 +156,20 @@ void Flow::reset(bool do_cleanup)
     if ( data )
         clear_data();
 
-    constexpr size_t offset = offsetof(Flow, appDataList);
-    // FIXIT-L need a struct to zero here to make future proof
-    memset((uint8_t*)this+offset, 0, sizeof(Flow)-offset);
-
-    bitop->reset();
-
     if ( ha_state )
         ha_state->reset();
+
+    constexpr size_t offset = offsetof(Flow, flow_data);
+    // FIXIT-L need a struct to zero here to make future proof
+    memset((uint8_t*)this+offset, 0, sizeof(Flow)-offset);
 }
 
-void Flow::restart(bool free_flow_data)
+void Flow::restart(bool dump_flow_data)
 {
-    if ( free_flow_data )
-        free_application_data();
+    if ( dump_flow_data )
+        free_flow_data();
 
-    if ( clientMplsLyr.length )
-    {
-        delete[] clientMplsLyr.start;
-        clientMplsLyr.length = 0;
-    }
-    if ( serverMplsLyr.length )
-    {
-        delete[] serverMplsLyr.start;
-        serverMplsLyr.length = 0;
-    }
-
-    bitop->reset();
+    clean();
 
     ssn_state.ignore_direction = 0;
     ssn_state.session_flags = SSNFLAG_NONE;
@@ -188,9 +179,9 @@ void Flow::restart(bool free_flow_data)
     previous_ssn_state = ssn_state;
 }
 
-void Flow::clear(bool free_flow_data)
+void Flow::clear(bool dump_flow_data)
 {
-    restart(free_flow_data);
+    restart(dump_flow_data);
     set_state(FlowState::SETUP);
 
     if ( ssn_client )
@@ -210,45 +201,45 @@ void Flow::clear(bool free_flow_data)
         clear_gadget();
 }
 
-int Flow::set_application_data(FlowData* fd)
+int Flow::set_flow_data(FlowData* fd)
 {
-    FlowData* appData = get_application_data(fd->get_id());
-    assert(appData != fd);
+    FlowData* old = get_flow_data(fd->get_id());
+    assert(old != fd);
 
-    if (appData)
-        free_application_data(appData);
+    if (old)
+        free_flow_data(old);
 
     fd->prev = nullptr;
-    fd->next = appDataList;
+    fd->next = flow_data;
 
-    if ( appDataList )
-        appDataList->prev = fd;
+    if ( flow_data )
+        flow_data->prev = fd;
 
-    appDataList = fd;
+    flow_data = fd;
     return 0;
 }
 
-FlowData* Flow::get_application_data(unsigned id)
+FlowData* Flow::get_flow_data(unsigned id)
 {
-    FlowData* appData = appDataList;
+    FlowData* fd = flow_data;
 
-    while (appData)
+    while (fd)
     {
-        if (appData->get_id() == id)
-            return appData;
+        if (fd->get_id() == id)
+            return fd;
 
-        appData = appData->next;
+        fd = fd->next;
     }
     return nullptr;
 }
 
-void Flow::free_application_data(FlowData* fd)
+void Flow::free_flow_data(FlowData* fd)
 {
-    if ( fd == appDataList )
+    if ( fd == flow_data )
     {
-        appDataList = fd->next;
-        if ( appDataList )
-            appDataList->prev = nullptr;
+        flow_data = fd->next;
+        if ( flow_data )
+            flow_data->prev = nullptr;
     }
     else if ( !fd->next )
     {
@@ -262,39 +253,39 @@ void Flow::free_application_data(FlowData* fd)
     delete fd;
 }
 
-void Flow::free_application_data(uint32_t proto)
+void Flow::free_flow_data(uint32_t proto)
 {
-    FlowData* fd = get_application_data(proto);
+    FlowData* fd = get_flow_data(proto);
 
     if ( fd )
-        free_application_data(fd);
+        free_flow_data(fd);
 }
 
-void Flow::free_application_data()
+void Flow::free_flow_data()
 {
-    FlowData* appData = appDataList;
+    FlowData* fd = flow_data;
 
-    while (appData)
+    while (fd)
     {
-        FlowData* tmp = appData;
-        appData = appData->next;
+        FlowData* tmp = fd;
+        fd = fd->next;
         delete tmp;
     }
-    appDataList = nullptr;
+    flow_data = nullptr;
 }
 
 void Flow::call_handlers(Packet* p, bool eof)
 {
-    FlowData* appData = appDataList;
+    FlowData* fd = flow_data;
 
-    while (appData)
+    while (fd)
     {
         if ( eof )
-            appData->handle_eof(p);
+            fd->handle_eof(p);
         else
-            appData->handle_retransmit(p);
+            fd->handle_retransmit(p);
 
-        appData = appData->next;
+        fd = fd->next;
     }
 }
 
@@ -375,27 +366,9 @@ void Flow::set_direction(Packet* p)
     }
 }
 
-static constexpr int TCP_HZ = 100;
-
-static inline uint64_t CalcJiffies(const Packet* p)
-{
-    uint64_t ret = 0;
-    uint64_t sec = (uint64_t)p->pkth->ts.tv_sec * TCP_HZ;
-    uint64_t usec = (p->pkth->ts.tv_usec / (1000000UL/TCP_HZ));
-
-    ret = sec + usec;
-
-    return ret;
-}
-
 void Flow::set_expire(const Packet* p, uint32_t timeout)
 {
-    expire_time = CalcJiffies(p) + (timeout * TCP_HZ);
-}
-
-int Flow::get_expire(const Packet* p)
-{
-    return ( CalcJiffies(p) > expire_time );
+    expire_time = (uint64_t)p->pkth->ts.tv_sec + timeout;
 }
 
 bool Flow::expired(const Packet* p)
@@ -403,9 +376,7 @@ bool Flow::expired(const Packet* p)
     if ( !expire_time )
         return false;
 
-    uint64_t pkttime = CalcJiffies(p);
-
-    if ( (int)(pkttime - expire_time) > 0 )
+    if ( (uint64_t)p->pkth->ts.tv_sec > expire_time )
         return true;
 
     return false;
@@ -472,22 +443,22 @@ void Flow::set_mpls_layer_per_dir(Packet* p)
 
     if ( p->packet_flags & PKT_FROM_CLIENT )
     {
-        if ( !clientMplsLyr.length )
+        if ( !mpls_client.length )
         {
-            clientMplsLyr.length = mpls_lyr->length;
-            clientMplsLyr.prot_id = mpls_lyr->prot_id;
-            clientMplsLyr.start = new uint8_t[mpls_lyr->length];
-            memcpy((void *)clientMplsLyr.start, mpls_lyr->start, mpls_lyr->length);
+            mpls_client.length = mpls_lyr->length;
+            mpls_client.prot_id = mpls_lyr->prot_id;
+            mpls_client.start = new uint8_t[mpls_lyr->length];
+            memcpy((void *)mpls_client.start, mpls_lyr->start, mpls_lyr->length);
         }
     }
     else
     {
-        if ( !serverMplsLyr.length )
+        if ( !mpls_server.length )
         {
-            serverMplsLyr.length = mpls_lyr->length;
-            serverMplsLyr.prot_id = mpls_lyr->prot_id;
-            serverMplsLyr.start = new uint8_t[mpls_lyr->length];
-            memcpy((void *)serverMplsLyr.start, mpls_lyr->start, mpls_lyr->length);
+            mpls_server.length = mpls_lyr->length;
+            mpls_server.prot_id = mpls_lyr->prot_id;
+            mpls_server.start = new uint8_t[mpls_lyr->length];
+            memcpy((void *)mpls_server.start, mpls_lyr->start, mpls_lyr->length);
         }
     }
 }
@@ -495,7 +466,7 @@ void Flow::set_mpls_layer_per_dir(Packet* p)
 Layer Flow::get_mpls_layer_per_dir(bool client)
 {
     if ( client )
-        return clientMplsLyr;
+        return mpls_client;
     else
-        return serverMplsLyr;
+        return mpls_server;
 }
index e3576ba620033f6d06ace83720f689c6f06de090..a0819b61c26ddeabadec1838b901b7490d96e329 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <assert.h>
 
-#include "utils/bitop.h"
 #include "sfip/sfip_t.h"
 #include "flow/flow_key.h"
 #include "framework/inspector.h"
@@ -156,23 +155,22 @@ public:
     void term();
 
     void reset(bool do_cleanup = true);
-    void restart(bool free_flow_data = true);
-    void clear(bool free_flow_data = true);
-
-    int set_application_data(FlowData*);
-    FlowData* get_application_data(uint32_t proto);
-    void free_application_data(uint32_t proto);
-    void free_application_data(FlowData*);
-    void free_application_data();
-    void set_application_ids(AppId serviceAppId, AppId clientAppId,
-            AppId payloadAppId, AppId miscAppId);
-    void get_application_ids(AppId& serviceAppId, AppId& clientAppId,
-            AppId& payloadAppId, AppId& miscAppId);
+    void restart(bool dump_flow_data = true);
+    void clear(bool dump_flow_data = true);
+
+    int set_flow_data(FlowData*);
+    FlowData* get_flow_data(uint32_t proto);
+    void free_flow_data(uint32_t proto);
+    void free_flow_data(FlowData*);
+    void free_flow_data();
+
+    void set_application_ids(AppId service, AppId client, AppId payload, AppId misc);
+    void get_application_ids(AppId& service, AppId& client, AppId& payload, AppId& misc);
+
     void call_handlers(Packet* p, bool eof = false);
     void markup_packet_flags(Packet*);
     void set_direction(Packet*);
     void set_expire(const Packet*, uint32_t timeout);
-    int get_expire(const Packet*);
     bool expired(const Packet*);
     void set_ttl(Packet*, bool client);
     void set_mpls_layer_per_dir(Packet*);
@@ -294,11 +292,15 @@ public:
     }
 
 public:  // FIXIT-M privatize if possible
+    // fields are organized by initialization and size to minimize
+    // void space and allow for memset of tail end of struct
+
     // these fields are const after initialization
     const FlowKey* key;
     class Session* session;
     class BitOp* bitop;
     class FlowHAState* ha_state;
+
     uint8_t ip_proto; // FIXIT-M do we need both of these?
     PktType pkt_type; // ^^
 
@@ -306,24 +308,30 @@ public:  // FIXIT-M privatize if possible
     Flow* prev, * next;
     Inspector* ssn_client;
     Inspector* ssn_server;
+
     long last_data_seen;
+    Layer mpls_client, mpls_server;
 
     // everything from here down is zeroed
-    FlowData* appDataList;
+    FlowData* flow_data;
     Inspector* clouseau;  // service identifier
     Inspector* gadget;    // service handler
     Inspector* data;
     const char* service;
-    Layer clientMplsLyr, serverMplsLyr;
 
-    unsigned policy_id;
-
-    FlowState flow_state;
+    uint64_t expire_time;
 
     sfip_t client_ip; // FIXIT-L family and bits should be changed to uint16_t
     sfip_t server_ip; // or uint8_t to reduce sizeof from 24 to 20
 
-    uint64_t expire_time;
+    LwState ssn_state;
+    LwState previous_ssn_state;
+
+    // FIXIT-L: if appid is only consumer of this move to appid
+    AppId application_ids[APP_PROTOID_MAX];
+
+    FlowState flow_state;
+    unsigned policy_id;
 
     int32_t iface_in;
     int32_t iface_out;
@@ -340,12 +348,8 @@ public:  // FIXIT-M privatize if possible
     uint8_t  response_count;
     bool disable_inspect;
 
-    // FIXIT-L: if appid is only consumer of this move to appid
-    AppId application_ids[APP_PROTOID_MAX];
-
-public:
-    LwState ssn_state;
-    LwState previous_ssn_state;
+private:
+    void clean();
 };
 
 #endif
index 95858cb0245252506f95f23d2c6149fa5dc1e696..ea7af7add8295c1da1c900d8e0a3503749a4d9f6 100644 (file)
@@ -31,6 +31,7 @@
 #include "main/snort_debug.h"
 #include "packet_io/active.h"
 #include "time/packet_time.h"
+#include "utils/stats.h"
 
 #define SESSION_CACHE_FLAG_PURGING  0x01
 
 
 FlowCache::FlowCache (const FlowConfig& cfg) : config(cfg)
 {
-    cleanup_flows = cfg.max_sessions * cfg.cleanup_pct / 100;
-    if ( cleanup_flows == 0 )
-        cleanup_flows = 1;
-
-    assert(cleanup_flows <= cfg.max_sessions);
-    assert(cleanup_flows > 0);
-
     hash_table = new ZHash(config.max_sessions, sizeof(FlowKey));
     hash_table->set_keyops(FlowKey::hash, FlowKey::compare);
 
@@ -307,7 +301,7 @@ unsigned FlowCache::timeout(unsigned num_flows, time_t thetime)
     if ( !flow )
         flow = static_cast<Flow*>(hash_table->first());
 
-    while ( flow and retired < num_flows )
+    while ( flow and (retired < num_flows) )
     {
         if ( flow->last_data_seen + config.nominal_timeout > thetime )
             break;
@@ -340,7 +334,6 @@ unsigned FlowCache::purge()
 
     while ( auto flow = static_cast<Flow*>(hash_table->first()) )
     {
-        flow->ssn_state.session_flags |= SSNFLAG_PRUNED;
         release(flow, PruneReason::PURGE);
         ++retired;
     }
index 3d6445cd7122839cd929b8cdbdc4a19af9eb5005..f62e69ae37c82b5ac3d7ffb51fab2c8008428bdb 100644 (file)
@@ -76,8 +76,8 @@ private:
     int remove(Flow*);
 
 private:
+    const unsigned cleanup_flows = 1;
     const FlowConfig& config;
-    unsigned cleanup_flows;
     unsigned uni_count;
     uint32_t flags;
 
index 453d3a3b5a0d59ad743ec8d0e9d3ec7b31df787a..3d8216e127bf95e24cb92f692820180cd022ade7 100644 (file)
@@ -28,7 +28,6 @@ struct FlowConfig
     unsigned max_sessions = 0;
     unsigned pruning_timeout = 0;
     unsigned nominal_timeout = 0;
-    unsigned cleanup_pct = 0;
 };
 
 #endif
index 2a2ea03bf3906cf4421ff3c7af11b6af94aecf68..8fbfda84775ea7997c793906e066e2e6129f51af 100644 (file)
@@ -34,6 +34,7 @@
 #include "protocols/udp.h"
 #include "protocols/vlan.h"
 #include "sfip/sf_ip.h"
+#include "stream/stream.h"
 
 #include "expect_cache.h"
 #include "flow_cache.h"
 #include "session.h"
 
 FlowControl::FlowControl()
-{
-    ip_cache = nullptr;
-    icmp_cache = nullptr;
-    tcp_cache = nullptr;
-    udp_cache = nullptr;
-    user_cache = nullptr;
-    file_cache = nullptr;
-    exp_cache = nullptr;
-
-    ip_mem = icmp_mem = nullptr;
-    tcp_mem = udp_mem = nullptr;
-    user_mem = file_mem = nullptr;
-
-    get_ip = get_icmp = nullptr;
-    get_tcp = get_udp = nullptr;
-    get_user = get_file = nullptr;
-
-    last_pkt_type = PktType::NONE;
-}
+{ }
 
 FlowControl::~FlowControl()
 {
@@ -90,16 +73,6 @@ static THREAD_LOCAL PegCount udp_count = 0;
 static THREAD_LOCAL PegCount user_count = 0;
 static THREAD_LOCAL PegCount file_count = 0;
 
-uint32_t FlowControl::max_flows(PktType type)
-{
-    FlowCache* cache = get_cache(type);
-
-    if ( cache )
-        return cache->get_max_flows();
-
-    return 0;
-}
-
 PegCount FlowControl::get_flows(PktType type)
 {
     switch ( type )
@@ -108,7 +81,7 @@ PegCount FlowControl::get_flows(PktType type)
     case PktType::ICMP: return icmp_count;
     case PktType::TCP:  return tcp_count;
     case PktType::UDP:  return udp_count;
-    case PktType::PDU: return user_count;
+    case PktType::PDU:  return user_count;
     case PktType::FILE: return file_count;
     default:            return 0;
     }
@@ -238,24 +211,6 @@ void FlowControl::purge_flows (PktType type)
         cache->purge();
 }
 
-void FlowControl::prune_flows(PktType type, const Packet* p)
-{
-    if ( !p )
-        return;
-
-    FlowCache* cache = get_cache(type);
-
-    if ( !cache )
-        return;
-
-    // smack the older timed out flows
-    if ( !cache->prune_stale(p->pkth->ts.tv_sec, p->flow) )
-    {
-        // if no luck, try the memcap
-        cache->prune_excess(p->flow);
-    }
-}
-
 // hole for memory manager/prune handler
 bool FlowControl::prune_one(PruneReason reason, bool do_cleanup)
 {
@@ -263,27 +218,19 @@ bool FlowControl::prune_one(PruneReason reason, bool do_cleanup)
     return cache ? cache->prune_one(reason, do_cleanup) : false;
 }
 
-void FlowControl::timeout_flows(uint32_t flowCount, time_t cur_time)
+void FlowControl::timeout_flows(time_t cur_time)
 {
-    Active::suspend();
-
-    if ( ip_cache )
-        ip_cache->timeout(flowCount, cur_time);
-
-    //if ( icmp_cache )
-    //icmp_cache does not need cleaning
-
-    if ( tcp_cache )
-        tcp_cache->timeout(flowCount, cur_time);
+    if ( !types.size() )
+        return;
 
-    if ( udp_cache )
-        udp_cache->timeout(flowCount, cur_time);
+    Active::suspend();
+    FlowCache* fc = get_cache(types[next]);
 
-    if ( user_cache )
-        user_cache->timeout(flowCount, cur_time);
+    if ( ++next >= types.size() )
+        next = 0;
 
-    if ( file_cache )
-        file_cache->timeout(flowCount, cur_time);
+    if ( fc )
+        fc->timeout(1, cur_time);
 
     Active::resume();
 }
@@ -500,7 +447,7 @@ unsigned FlowControl::process(Flow* flow, Packet* p)
 
     case Flow::FlowState::ALLOW:
         if ( news )
-            stream.stop_inspection(flow, p, SSN_DIR_BOTH, -1, 0);
+            Stream::stop_inspection(flow, p, SSN_DIR_BOTH, -1, 0);
         else
             DisableInspection();
 
@@ -509,7 +456,7 @@ unsigned FlowControl::process(Flow* flow, Packet* p)
 
     case Flow::FlowState::BLOCK:
         if ( news )
-            stream.drop_traffic(flow, SSN_DIR_BOTH);
+            Stream::drop_traffic(flow, SSN_DIR_BOTH);
         else
             Active::block_again();
 
@@ -518,11 +465,11 @@ unsigned FlowControl::process(Flow* flow, Packet* p)
 
     case Flow::FlowState::RESET:
         if ( news )
-            stream.drop_traffic(flow, SSN_DIR_BOTH);
+            Stream::drop_traffic(flow, SSN_DIR_BOTH);
         else
             Active::reset_again();
 
-        stream.blocked_session(flow, p);
+        Stream::blocked_flow(flow, p);
         DisableInspection();
         break;
     }
@@ -547,6 +494,7 @@ void FlowControl::init_ip(
         ip_cache->push(ip_mem + i);
 
     get_ip = get_ssn;
+    types.push_back(PktType::IP);
 }
 
 void FlowControl::process_ip(Packet* p)
@@ -590,6 +538,7 @@ void FlowControl::init_icmp(
         icmp_cache->push(icmp_mem + i);
 
     get_icmp = get_ssn;
+    types.push_back(PktType::ICMP);
 }
 
 void FlowControl::process_icmp(Packet* p)
@@ -636,6 +585,7 @@ void FlowControl::init_tcp(
         tcp_cache->push(tcp_mem + i);
 
     get_tcp = get_ssn;
+    types.push_back(PktType::TCP);
 }
 
 void FlowControl::process_tcp(Packet* p)
@@ -679,6 +629,7 @@ void FlowControl::init_udp(
         udp_cache->push(udp_mem + i);
 
     get_udp = get_ssn;
+    types.push_back(PktType::UDP);
 }
 
 void FlowControl::process_udp(Packet* p)
@@ -722,6 +673,7 @@ void FlowControl::init_user(
         user_cache->push(user_mem + i);
 
     get_user = get_ssn;
+    types.push_back(PktType::PDU);
 }
 
 void FlowControl::process_user(Packet* p)
@@ -765,6 +717,7 @@ void FlowControl::init_file(
         file_cache->push(file_mem + i);
 
     get_file = get_ssn;
+    types.push_back(PktType::FILE);
 }
 
 void FlowControl::process_file(Packet* p)
index 82f69519bf28654209fd02afe79635370c552e7b..6ea36bdefea7752fe5419061f0b20c63bc2beb17 100644 (file)
@@ -26,6 +26,7 @@
 // processed.  flows are pruned as needed to process new flows.
 
 #include <cstdint>
+#include <vector>
 
 #include "flow/flow_config.h"
 #include "framework/counts.h"
@@ -69,9 +70,9 @@ public:
     void delete_flow(const FlowKey*);
     void delete_flow(Flow*, PruneReason);
     void purge_flows(PktType);
-    void prune_flows(PktType, const Packet*);
     bool prune_one(PruneReason, bool do_cleanup);
-    void timeout_flows(uint32_t flowCount, time_t cur_time);
+
+    void timeout_flows(time_t cur_time);
 
     char expected_flow(Flow*, Packet*);
     bool is_expected(Packet*);
@@ -86,8 +87,6 @@ public:
         const sfip_t *dstIP, uint16_t dstPort,
         PktType, int16_t appId, FlowData*);
 
-    uint32_t max_flows(PktType);
-
     PegCount get_flows(PktType);
     PegCount get_total_prunes(PktType) const;
     PegCount get_prunes(PktType, PruneReason) const;
@@ -104,30 +103,33 @@ private:
     void preemptive_cleanup();
 
 private:
-    FlowCache* ip_cache;
-    FlowCache* icmp_cache;
-    FlowCache* tcp_cache;
-    FlowCache* udp_cache;
-    FlowCache* user_cache;
-    FlowCache* file_cache;
+    FlowCache* ip_cache = nullptr;
+    FlowCache* icmp_cache = nullptr;
+    FlowCache* tcp_cache = nullptr;
+    FlowCache* udp_cache = nullptr;
+    FlowCache* user_cache = nullptr;
+    FlowCache* file_cache = nullptr;
 
     // preallocated arrays
-    Flow* ip_mem;
-    Flow* icmp_mem;
-    Flow* tcp_mem;
-    Flow* udp_mem;
-    Flow* user_mem;
-    Flow* file_mem;
-
-    InspectSsnFunc get_ip;
-    InspectSsnFunc get_icmp;
-    InspectSsnFunc get_tcp;
-    InspectSsnFunc get_udp;
-    InspectSsnFunc get_user;
-    InspectSsnFunc get_file;
-
-    class ExpectCache* exp_cache;
-    PktType last_pkt_type;
+    Flow* ip_mem = nullptr;
+    Flow* icmp_mem = nullptr;
+    Flow* tcp_mem = nullptr;
+    Flow* udp_mem = nullptr;
+    Flow* user_mem = nullptr;
+    Flow* file_mem = nullptr;
+
+    InspectSsnFunc get_ip = nullptr;
+    InspectSsnFunc get_icmp = nullptr;
+    InspectSsnFunc get_tcp = nullptr;
+    InspectSsnFunc get_udp = nullptr;
+    InspectSsnFunc get_user = nullptr;
+    InspectSsnFunc get_file = nullptr;
+
+    class ExpectCache* exp_cache = nullptr;
+    PktType last_pkt_type = PktType::NONE;
+
+    std::vector<PktType> types;
+    unsigned next = 0;
 };
 
 #endif
index 24664c11ed1b68b43fa1553f8aaee07d0a8e1d85..cb4098067c9fbdc9aaa40f4b19001df86b69c4db 100644 (file)
@@ -31,7 +31,7 @@
 #include "packet_io/sfdaq.h"
 #include "profiler/profiler.h"
 #include "side_channel/side_channel.h"
-#include "stream/stream_api.h"
+#include "stream/stream.h"
 #include "time/packet_time.h"
 
 static const uint8_t HA_MESSAGE_VERSION = 3;
@@ -343,7 +343,7 @@ static void consume_receive_delete_message(HAMessage* msg)
 {
     FlowKey key;
     (void)read_flow_key(&key, msg);
-    stream.delete_session(&key);
+    Stream::delete_flow(&key);
 }
 
 static void consume_receive_update_message(HAMessage* msg)
@@ -351,7 +351,7 @@ static void consume_receive_update_message(HAMessage* msg)
     FlowKey key;
     (void)read_flow_key(&key, msg);
     // flow will be nullptr if/when the session does not exist in the caches
-    Flow* flow = stream.get_session(&key);
+    Flow* flow = Stream::get_flow(&key);
 
     assert(s_client_map);
 
index 2125fbb78146df6899b52a40a17fa474f1219203..745c3822675159903ace5d99747de0b37676ae21 100644 (file)
@@ -24,7 +24,7 @@
 // the subclasses do the actual work of tracking, reassembly, etc.
 
 #include "sfip/sfip_t.h"
-#include "stream/stream_api.h"
+#include "stream/stream.h"
 
 struct Packet;
 class Flow;
index 4eeab4a6d6a7b7e6254484621056911fac14039d..81ece5f41e1c23948e7043772db4a08b6e97cf9d 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "flow/flow.h"
 #include "main/snort_debug.h"
-#include "stream/stream_api.h"
+#include "stream/stream.h"
 
 #include <CppUTest/CommandLineTestRunner.h>
 #include <CppUTest/TestHarness.h>
@@ -132,14 +132,14 @@ public:
 private:
 };
 
-Flow*  Stream::get_session(const FlowKey* flowkey)
+Flow*  Stream::get_flow(const FlowKey* flowkey)
 {
     s_flowkey = *flowkey;
     s_get_session_called = true;
     return &s_flow;
 }
 
-void Stream::delete_session(const FlowKey* flowkey)
+void Stream::delete_flow(const FlowKey* flowkey)
 {
     s_flowkey = *flowkey;
     s_delete_session_called = true;
index c6a6669c1615ce388dd6574aaf9c293e5ac1a29d..b31cea5a30ac64a20336a0e4ab97c6198d3165b7 100644 (file)
@@ -51,6 +51,13 @@ enum CursorActionType
     CAT_SET_KEY,
 };
 
+enum RuleDirection
+{
+    RULE_FROM_CLIENT,
+    RULE_FROM_SERVER,
+    RULE_WO_DIR
+};
+
 class SO_PUBLIC IpsOption
 {
 public:
@@ -78,7 +85,7 @@ public:
     { return CAT_NONE; }
 
     // for fast-pattern options like content
-    virtual struct PatternMatchData* get_pattern()
+    virtual struct PatternMatchData* get_pattern(int /*proto*/, RuleDirection)
     { return nullptr; }
 
     static int eval(void* v, Cursor& c, Packet* p)
index 515b9bf04044aa256bea4dd5bd74ba415a6994c1..d0ad2ea3f153fac07bf5bb78c1d438cbc328d2f7 100644 (file)
@@ -177,7 +177,7 @@ void RangeCheck::init()
     min = max = 0;
 }
 
-bool RangeCheck::is_set()
+bool RangeCheck::is_set() const
 {
     return (op != MAX);
 }
@@ -222,7 +222,7 @@ bool RangeCheck::parse(const char* s)
     return true;
 }
 
-bool RangeCheck::eval(long c)
+bool RangeCheck::eval(long c) const
 {
     switch ( op )
     {
index 9d81a9d1ec63ee934ace0a8a75af4bb2f4a4f316..d7b330d13fce9591db90207729e3bec6b6e8b41e 100644 (file)
@@ -48,10 +48,10 @@ public:
     bool operator==(const RangeCheck&) const;
 
     void init();
-    bool is_set();
+    bool is_set() const;
     // FIXIT-L add ttl style syntax
     bool parse(const char* s);
-    bool eval(long);
+    bool eval(long) const;
 };
 
 #endif
index 05a24deae622a48104ecbdcaa00a1818f6d2d6af..8a7fd2f4cd4952f617a261f51e97a50b7351841c 100644 (file)
 
 // host_tracker_module.cc author Steve Chew <stechew@cisco.com>
 
-#include "host_tracker/host_tracker_module.h"
+#include "host_tracker_module.h"
 
-#include "host_tracker/host_cache.h"
-#include "stream/stream_api.h"
+#include "stream/stream.h"
 #include "target_based/snort_protocols.h"
+#include "host_cache.h"
 
 const PegInfo host_tracker_pegs[] =
 {
index 55c31ddb2ec9db4aa9e6a213af74e80851651977..f620c3064b2e113427e401f51af62cc08c995335 100644 (file)
@@ -143,7 +143,7 @@ public:
     int eval(Cursor& c, Packet*) override
     { return CheckANDPatternMatch(config, c); }
 
-    PatternMatchData* get_pattern() override
+    PatternMatchData* get_pattern(int, RuleDirection) override
     { return &config->pmd; }
 
 protected:
@@ -243,10 +243,11 @@ static bool same_buffers(
     }
     return true;
 }
+
 #endif
 
 // FIXIT-P fp, fp_only are set after hash table comparisons so this must
-// return false to avoid unnecessary reevaluation and false positives.
+// return this == &ips to avoid unnecessary reevaluation and false positives.
 // when this is fixed, add PatternMatchData::operator==().
 bool ContentOption::operator==(const IpsOption& ips) const
 {
@@ -286,10 +287,8 @@ bool ContentOption::operator==(const IpsOption& ips) const
     {
         return true;
     }
-#else
-    UNUSED(ips);
 #endif
-    return false;
+    return this == &ips;
 }
 
 //-------------------------------------------------------------------------
@@ -410,7 +409,6 @@ static int CheckANDPatternMatch(ContentData* idx, Cursor& c)
         DebugMessage(DEBUG_PATTERN_MATCH, "Pattern match found\n");
         return DETECTION_OPTION_MATCH;
     }
-
     else
     {
         DebugMessage(DEBUG_PATTERN_MATCH, "Pattern match failed\n");
index 738b7452cfbf7abca4cd13fa8a8a7b966cc7fc56..543bf6bc1c0c24d5283f944a71c5d0617ee29f33 100644 (file)
 
 #include <bitset>
 
-#include "profiler/profiler.h"
 #include "detection/detection_defines.h"
 #include "framework/ips_option.h"
 #include "framework/module.h"
 #include "file_api/file_identifier.h"
 #include "file_api/file_flows.h"
+#include "profiler/profiler.h"
+#include "protocols/packet.h"
 
 typedef std::bitset<FILE_ID_MAX> TypeBitSet;
 
index b7ead0f3bcc0c8b820d6ce03143835ead733fa04..988268b068f2e7dd2103aafdb0345a30477d1852 100644 (file)
@@ -36,7 +36,6 @@
 #include "parser/parser.h"
 #include "utils/util.h"
 #include "hash/sfhashfcn.h"
-#include "stream/stream_api.h"
 #include "profiler/profiler.h"
 #include "detection/detection_defines.h"
 #include "framework/ips_option.h"
index cc58cde571bcfe21fad0918184b66e68ecc3926e..1cbe2c285125c97d12798458b88ca859127c2571 100644 (file)
@@ -61,7 +61,6 @@ using namespace std;
 #include "utils/bitop.h"
 #include "hash/sfghash.h"
 #include "parser/mstring.h"
-#include "stream/stream_api.h"
 #include "profiler/profiler.h"
 #include "hash/sfhashfcn.h"
 #include "detection/detection_defines.h"
@@ -141,9 +140,15 @@ typedef struct _FLOWBITS_GRP
     BitOp* GrpBitOp;
 } FLOWBITS_GRP;
 
+static std::forward_list<const FLOWBITS_OP*> op_list;
+
+static SFGHASH* flowbits_hash = NULL;
 static SFGHASH* flowbits_grp_hash = NULL;
+static SF_QUEUE* flowbits_bit_queue = NULL;
 
-static std::forward_list<const FLOWBITS_OP*> op_list;
+static unsigned flowbits_count = 0;
+static unsigned flowbits_grp_count = 0;
+static int flowbits_toggle = 1;
 
 static int check_flowbits(
     uint8_t type, uint8_t evalType, uint16_t* ids, uint16_t num_ids,
@@ -269,6 +274,19 @@ int FlowBitsOption::eval(Cursor&, Packet* p)
 // helper methods
 //-------------------------------------------------------------------------
 
+static inline BitOp* get_flow_bitop(const Packet* p)
+{
+    Flow* flow = p->flow;
+
+    if (!flow)
+        return NULL;
+
+    if ( !flow->bitop )
+        flow->bitop = new BitOp(flowbits_count);
+
+    return flow->bitop;
+}
+
 static inline int clear_group_bit(BitOp* bitop, char* group)
 {
     if ( !group )
@@ -391,15 +409,15 @@ static int check_flowbits(
     uint8_t type, uint8_t evalType, uint16_t* ids, uint16_t num_ids, char* group, Packet* p)
 {
     int rval = DETECTION_OPTION_NO_MATCH;
-    BitOp* bitop;
     Flowbits_eval eval = (Flowbits_eval)evalType;
     int result = 0;
     int i;
 
-    bitop = stream.get_flow_bitop(p);
+    BitOp* bitop = get_flow_bitop(p);
+
     if (!bitop)
     {
-        DebugMessage(DEBUG_FLOWBITS, "No FLOWBITS_DATA");
+        assert(false);
         return rval;
     }
 
@@ -509,25 +527,6 @@ static int check_flowbits(
 // public methods
 //-------------------------------------------------------------------------
 
-static SFGHASH* flowbits_hash = NULL;
-static SF_QUEUE* flowbits_bit_queue = NULL;
-static uint16_t flowbits_count = 0;
-static uint16_t flowbits_grp_count = 0;
-static int flowbits_toggle = 1;
-
-// FIXIT-P consider allocating flowbits on session on demand instead of
-// preallocating.
-
-unsigned int getFlowbitSize()
-{
-    return flowbits_count;
-}
-
-unsigned int getFlowbitSizeInBytes()
-{
-    return flowbits_count ? (flowbits_count + 7) >> 3 : 1;
-}
-
 void FlowbitResetCounts()
 {
     SFGHASH_NODE* n;
@@ -605,7 +604,7 @@ static FLOWBITS_OBJECT* getFlowBitItem(char* flowbitName, FLOWBITS_OP* flowbits)
             if ( !flowbits_count )
             {
                 ParseError("The number of flowbit IDs in the current ruleset exceeds "
-                    "the maximum number of IDs that are allowed (65535).");
+                    "the maximum number of IDs that are allowed (%u).", flowbits_count-1);
             }
         }
 
@@ -981,14 +980,12 @@ static void init_groups()
     if ( !flowbits_hash or !flowbits_grp_hash )
         return;
 
-    unsigned size = getFlowbitSizeInBytes();
-
     for ( SFGHASH_NODE* n = sfghash_findfirst(flowbits_grp_hash);
         n != NULL;
         n= sfghash_findnext(flowbits_grp_hash) )
     {
         FLOWBITS_GRP* fbg = (FLOWBITS_GRP*)n->data;
-        fbg->GrpBitOp = new BitOp(size);
+        fbg->GrpBitOp = new BitOp(flowbits_count);
         fbg->GrpBitOp->reset();
     }
 
index b0dd766aff6087c2a9177749b1af578ca9c25d28..f5e52d8aa208441f4faf19e2a9360795b74c35cf 100644 (file)
@@ -23,9 +23,5 @@
 void FlowbitResetCounts();
 int FlowBits_SetOperation(void*);
 
-void setFlowbitSize(unsigned);
-unsigned int getFlowbitSize();
-unsigned int getFlowbitSizeInBytes();
-
 #endif
 
index 87f6f63b70732b5b2f2a0856672b6838319e5c89..c5f765a69e3b81a6b3054e0b51292423878ac6b9 100644 (file)
@@ -96,7 +96,7 @@ public:
 
     bool retry() override;
 
-    PatternMatchData* get_pattern() override
+    PatternMatchData* get_pattern(int, RuleDirection) override
     { return &config.pmd; }
 
     int eval(Cursor&, Packet*) override;
@@ -137,7 +137,7 @@ uint32_t RegexOption::hash() const
     return c;
 }
 
-// see ContentOption::operator==() for why this is always false
+// see ContentOption::operator==()
 bool RegexOption::operator==(const IpsOption& ips) const
 {
 #if 0
@@ -146,15 +146,12 @@ bool RegexOption::operator==(const IpsOption& ips) const
 
     RegexOption& rhs = (RegexOption&)ips;
 
-    if ( config.re == rhs.config.re and 
-         config.pmd.flags == rhs.config.pmd.flags and
-         config.pmd.relative == rhs.config.pmd.relative )
+    if ( config.re == rhs.config.re and
+        config.pmd.flags == rhs.config.pmd.flags and
+        config.pmd.relative == rhs.config.pmd.relative )
         return true;
-
-#else
-    UNUSED(ips);
 #endif
-    return false;
+    return this == &ips;
 }
 
 static int hs_match(
@@ -256,6 +253,7 @@ RegexModule::~RegexModule()
 bool RegexModule::begin(const char*, int, SnortConfig*)
 {
     config.reset();
+    config.pmd.flags |= HS_FLAG_SINGLEMATCH;
     return true;
 }
 
@@ -268,7 +266,6 @@ bool RegexModule::set(const char*, Value& v, SnortConfig*)
         config.re.erase(0, 1);
         config.re.erase(config.re.length()-1, 1);
     }
-
     else if ( v.is("nocase") )
     {
         config.pmd.flags |= HS_FLAG_CASELESS;
index c595faa8bd677f6ee898506aabb0946d3e249536..62be4b6e7efd8168a6dbd6b9e626da5d13f721ff 100644 (file)
@@ -81,7 +81,7 @@ struct SdPatternConfig
     std::string pii;
     unsigned threshold = 1;
     bool obfuscate_pii = false;
-    int (*validate)(const uint8_t* buf, unsigned long long buflen) = nullptr;
+    int (* validate)(const uint8_t* buf, unsigned long long buflen) = nullptr;
 
     inline bool operator==(const SdPatternConfig& rhs) const
     {
@@ -119,7 +119,7 @@ public:
     uint32_t hash() const override;
     bool operator==(const IpsOption&) const override;
 
-    PatternMatchData* get_pattern() override
+    PatternMatchData* get_pattern(int, RuleDirection) override
     { return &config.pmd; }
 
     int eval(Cursor&, Packet* p) override;
@@ -136,7 +136,7 @@ SdPatternOption::SdPatternOption(const SdPatternConfig& c) :
     {
         // FIXIT-L why is this failing but everything is working?
         ParseError("can't initialize sd_pattern for %s (%d) %p",
-                config.pii.c_str(), err, (void*)s_scratch);
+            config.pii.c_str(), err, (void*)s_scratch);
     }
 
     config.pmd.pattern_buf = config.pii.c_str();
@@ -146,7 +146,7 @@ SdPatternOption::SdPatternOption(const SdPatternConfig& c) :
 }
 
 SdPatternOption::~SdPatternOption()
-{ 
+{
     if ( config.db )
         hs_free_database(config.db);
 }
@@ -173,10 +173,10 @@ bool SdPatternOption::operator==(const IpsOption& ips) const
     return false;
 }
 
-struct hsContext 
+struct hsContext
 {
-    hsContext(const SdPatternConfig &c_, Packet* p_, const uint8_t* const start_)
-        : config(c_), packet(p_), start(start_) {}
+    hsContext(const SdPatternConfigc_, Packet* p_, const uint8_t* const start_)
+        : config(c_), packet(p_), start(start_) { }
 
     unsigned int count = 0;
 
@@ -209,7 +209,7 @@ static int hs_match(unsigned int /*id*/, unsigned long long from,
             ctx->packet->obfuscator = new Obfuscator();
 
         uint32_t off = ctx->buf - ctx->start;
-        // FIXIT-L Make configurable or don't show any PII partials (0 for user defined??) 
+        // FIXIT-L Make configurable or don't show any PII partials (0 for user defined??)
         len = len > 4 ? len - 4 : len;
         ctx->packet->obfuscator->push(off, len);
     }
@@ -323,13 +323,11 @@ bool SdPatternModule::set(const char*, Value& v, SnortConfig* sc)
         config.validate = SdLuhnAlgorithm;
         config.obfuscate_pii = sc->obfuscate_pii;
     }
-
     else if (config.pii == "us_social")
     {
         config.pii = SD_SOCIAL_PATTERN;
         config.obfuscate_pii = sc->obfuscate_pii;
     }
-
     else if (config.pii == "us_social_nodashes")
     {
         config.pii = SD_SOCIAL_NODASHES_PATTERN;
@@ -343,7 +341,8 @@ bool SdPatternModule::end(const char*, int, SnortConfig*)
 {
     hs_compile_error_t* err = nullptr;
 
-    if ( hs_compile(config.pii.c_str(), HS_FLAG_DOTALL|HS_FLAG_SOM_LEFTMOST, HS_MODE_BLOCK, nullptr, &config.db, &err)
+    if ( hs_compile(config.pii.c_str(), HS_FLAG_DOTALL|HS_FLAG_SOM_LEFTMOST, HS_MODE_BLOCK,
+        nullptr, &config.db, &err)
         or !config.db )
     {
         ParseError("can't compile regex '%s'", config.pii.c_str());
@@ -407,7 +406,7 @@ static IpsOption* sd_pattern_ctor(Module* m, OptTreeNode*)
 }
 
 static void sd_pattern_dtor(IpsOption* p)
-{ 
+{
     delete p;
 }
 
index d72b848ee65c3feecf4b3b0c6e4e98484175c34f..0fc3256b74c48ad7e50997b4520b782fa38ff7d6 100644 (file)
@@ -259,6 +259,8 @@ TEST_GROUP(ips_regex_option)
 
     void setup()
     {
+        // FIXIT-L cpputest hangs or crashes in the leak detector
+        MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
         opt = get_option(" foo ");
         regex_setup(snort_conf);
     }
@@ -268,6 +270,7 @@ TEST_GROUP(ips_regex_option)
         api->dtor(opt);
         regex_cleanup(snort_conf);
         api->pterm(snort_conf);
+        MemoryLeakWarningPlugin::turnOnNewDeleteOverloads();
     }
 };
 
@@ -330,6 +333,8 @@ TEST_GROUP(ips_regex_option_relative)
 
     void setup()
     {
+        // FIXIT-L cpputest hangs or crashes in the leak detector
+        MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
         opt = get_option("\\bfoo", true);
         regex_setup(snort_conf);
     }
@@ -338,6 +343,7 @@ TEST_GROUP(ips_regex_option_relative)
         IpsApi* api = (IpsApi*)ips_regex;
         api->dtor(opt);
         regex_cleanup(snort_conf);
+        MemoryLeakWarningPlugin::turnOnNewDeleteOverloads();
     }
 };
 
index 3b7092fd89bbae5ddc32c0501fd6bf2d5c26cdd6..0cc4fb3262a468cdcb93a16e28c561e751a524e5 100644 (file)
@@ -95,11 +95,13 @@ THREAD_LOCAL LatencyStats latency_stats;
 
 static const PegInfo latency_pegs[] =
 {
-    { "total_packets", "total packets monitored" },
-    { "packet_timeouts", "packets that timed out" },
-    { "total_rule_evals", "total rule evals monitored" },
-    { "rule_eval_timeouts", "rule evals that timed out" },
-    { "rule_tree_enables", "rule tree re-enables" },
+    { "total packets", "total packets monitored" },
+    { "total usecs", "total usecs elapsed" },
+    { "max usecs", "maximum usecs elapsed" },
+    { "packet timeouts", "packets that timed out" },
+    { "total rule evals", "total rule evals monitored" },
+    { "rule eval timeouts", "rule evals that timed out" },
+    { "rule tree enables", "rule tree re-enables" },
     { nullptr, nullptr }
 };
 
@@ -113,8 +115,10 @@ static inline bool latency_set(Value& v, PacketLatencyConfig& config)
     using std::chrono::microseconds;
 
     if ( v.is("max_time") )
-        config.max_time =
-            duration_cast<decltype(config.max_time)>(microseconds(v.get_long()));
+    {
+        long t = clock_ticks(v.get_long());
+        config.max_time = duration_cast<decltype(config.max_time)>(microseconds(t));
+    }
 
     else if ( v.is("fastpath") )
         config.fastpath = v.get_bool();
@@ -136,9 +140,10 @@ static inline bool latency_set(Value& v, RuleLatencyConfig& config)
     using std::chrono::milliseconds;
 
     if ( v.is("max_time") )
-        config.max_time =
-            duration_cast<decltype(config.max_time)>(microseconds(v.get_long()));
-
+    {
+        long t = clock_ticks(v.get_long());
+        config.max_time = duration_cast<decltype(config.max_time)>(microseconds(t));
+    }
     else if ( v.is("suspend") )
         config.suspend = v.get_bool();
 
@@ -146,9 +151,10 @@ static inline bool latency_set(Value& v, RuleLatencyConfig& config)
         config.suspend_threshold = v.get_long();
 
     else if ( v.is("max_suspend_time") )
-        config.max_suspend_time =
-            duration_cast<decltype(config.max_time)>(milliseconds(v.get_long()));
-
+    {
+        long t = clock_ticks(v.get_long());
+        config.max_suspend_time = duration_cast<decltype(config.max_time)>(milliseconds(t));
+    }
     else if ( v.is("action") )
         config.action =
             static_cast<decltype(config.action)>(v.get_long());
index 9b317e3165636bdfc2303e1bc8b9ca2c229ee9f7..4762b24bd055a31b4dd9f90cd0c61e8fb1830e02 100644 (file)
@@ -27,6 +27,8 @@
 struct LatencyStats
 {
     PegCount total_packets;
+    PegCount total_usecs;
+    PegCount max_usecs;
     PegCount packet_timeouts;
     PegCount total_rule_evals;
     PegCount rule_eval_timeouts;
index 2e7f4087ea0e0dcf4d99124ea5659aa91cb4819a..4c171bab4fe2161ecb4645886e6db32590afa57f 100644 (file)
@@ -29,6 +29,8 @@
 #include "protocols/packet.h"
 #include "sfip/sf_ip.h"
 #include "time/clock_defs.h"
+#include "utils/stats.h"
+
 #include "latency_config.h"
 #include "latency_timer.h"
 #include "latency_util.h"
 #include "catch/catch.hpp"
 #endif
 
+static THREAD_LOCAL uint64_t elapsed = 0;
+
 namespace packet_latency
 {
 // -----------------------------------------------------------------------------
 // helpers
 // -----------------------------------------------------------------------------
 
-using DefaultClock = hr_clock;
-
 struct Event
 {
     const Packet* packet;
     bool fastpathed;
-    typename DefaultClock::duration elapsed;
+    typename SnortClock::duration elapsed;
 };
 
 template<typename Clock>
@@ -85,13 +87,13 @@ static inline std::ostream& operator<<(std::ostream& os, const Event& e)
     using std::chrono::duration_cast;
     using std::chrono::microseconds;
 
-    os << "latency: packet timed out";
+    os << "latency: packet " << pc.total_from_daq << " timed out";
     if ( e.fastpathed )
         os << " (fastpathed)";
 
     os << ": ";
 
-    os << duration_cast<microseconds>(e.elapsed).count() << " usec, [";
+    os << clock_usecs(duration_cast<microseconds>(e.elapsed).count()) << " usec, [";
     os << e.packet->ptrs.ip_api.get_src() << " -> " <<
         e.packet->ptrs.ip_api.get_dst() << "]";
 
@@ -102,7 +104,7 @@ static inline std::ostream& operator<<(std::ostream& os, const Event& e)
 // implementation
 // -----------------------------------------------------------------------------
 
-template<typename Clock = DefaultClock>
+template<typename Clock = SnortClock>
 class Impl
 {
 public:
@@ -152,10 +154,15 @@ inline bool Impl<Clock>::pop(const Packet* p)
         if ( config->action & PacketLatencyConfig::LOG )
             log_handler.handle(e);
 
-        if ( timer.marked_as_fastpathed and (config->action & PacketLatencyConfig::ALERT) )
+        if ( config->action & PacketLatencyConfig::ALERT )
             event_handler.handle(e);
     }
 
+    // FIXIT-H this is fugly and inefficient
+    using std::chrono::duration_cast;
+    using std::chrono::microseconds;
+    elapsed = clock_usecs(duration_cast<microseconds>(timer.elapsed()).count());
+
     timers.pop_back();
     return timed_out;
 }
@@ -237,6 +244,12 @@ void PacketLatency::pop(const Packet* p)
     {
         if ( packet_latency::get_impl().pop(p) )
             ++latency_stats.packet_timeouts;
+
+        // FIXIT-L the timer is still running so this max is slightly larger than logged
+        if ( elapsed > latency_stats.max_usecs )
+            latency_stats.max_usecs = elapsed;
+
+        latency_stats.total_usecs += elapsed;
     }
 }
 
@@ -360,7 +373,7 @@ TEST_CASE ( "packet latency impl", "[latency]" )
             CHECK_FALSE( impl.fastpath() );
             CHECK( impl.pop(nullptr) );
 
-            CHECK( event_handler.count == 0 );
+            CHECK( event_handler.count == 1 );
             CHECK( log_handler.count == 1 );
         }
 
index 3cdc883c62dc9565c6ab820774fe4b7f38c0144c..a9a1aab4d8b8adb9ddabb8b6b23879397b4fabdd 100644 (file)
@@ -32,6 +32,7 @@
 #include "events/event_queue.h"
 #include "log/messages.h"
 #include "main/snort_config.h"
+
 #include "latency_config.h"
 #include "latency_rules.h"
 #include "latency_stats.h"
@@ -49,8 +50,6 @@ namespace rule_latency
 // helpers
 // -----------------------------------------------------------------------------
 
-using DefaultClock = hr_clock;
-
 struct Event
 {
     enum Type
@@ -61,7 +60,7 @@ struct Event
     };
 
     Type type;
-    typename DefaultClock::duration elapsed;
+    typename SnortClock::duration elapsed;
     detection_option_tree_root_t* root;
 };
 
@@ -96,7 +95,7 @@ static inline std::ostream& operator<<(std::ostream& os, const Event& e)
 
         os << ": ";
 
-        os << duration_cast<microseconds>(e.elapsed).count() << " usec, ";
+        os << clock_usecs(duration_cast<microseconds>(e.elapsed).count()) << " usec, ";
     }
 
     // FIXIT-L clean up rule latency logging; delete or make useful
@@ -175,7 +174,7 @@ struct DefaultRuleInterface
 // implementation
 // -----------------------------------------------------------------------------
 
-template<typename Clock = DefaultClock, typename RuleTree = DefaultRuleInterface>
+template<typename Clock = SnortClock, typename RuleTree = DefaultRuleInterface>
 class Impl
 {
 public:
index 3524e8f37c17fef67555e6467a4959bef6a56ff8..89aab1acc4ba357d3cebbf74098018686afba50b 100644 (file)
@@ -45,7 +45,6 @@ extern "C" {
 #include "events/event.h"
 #include "parser/parser.h"
 #include "packet_io/sfdaq.h"
-#include "stream/stream_api.h"
 #include "utils/util.h"
 #include "utils/stats.h"
 
index add0980ea7aca47c0924cbaae2ff6258151f23bc..680e70d09ae54788ea9d50d195af7b85b81e145b 100644 (file)
 #include "detection/detect.h"
 #include "parser/parser.h"
 #include "events/event.h"
-#include "utils/util.h"
+#include "log/obfuscator.h"
 #include "packet_io/active.h"
 #include "packet_io/sfdaq.h"
-#include "stream/stream_api.h"
 #include "protocols/layer.h"
 #include "protocols/vlan.h"
 #include "protocols/icmp4.h"
-#include "log/obfuscator.h"
+#include "stream/stream.h"
 #include "utils/safec.h"
+#include "utils/util.h"
 
 using namespace std;
 
@@ -878,7 +878,7 @@ void U2Logger::open()
 
     Unified2InitFile(&config);
 
-    stream.reg_xtra_data_log(AlertExtraData, &config);
+    Stream::reg_xtra_data_log(AlertExtraData, &config);
 }
 
 void U2Logger::close()
@@ -910,14 +910,14 @@ void U2Logger::alert(Packet* p, const char* msg, Event* event)
     }
 
     if ( p->flow )
-        stream.update_session_alert(
+        Stream::update_flow_alert(
             p->flow, p, event->sig_info->generator, event->sig_info->id,
             event->event_id, event->ref_time.tv_sec);
 
     if ( p->xtradata_mask )
     {
         LogFunction* log_funcs;
-        uint32_t max_count = stream.get_xtra_data_map(&log_funcs);
+        uint32_t max_count = Stream::get_xtra_data_map(&log_funcs);
 
         if ( max_count > 0 )
             AlertExtraData(
index 33801b0560189b184e4139acd9df31b21da64348..0bf8cfdcf2de694e704b20670a0ecc2a5d2f23f2 100644 (file)
@@ -10,7 +10,7 @@
 //                                               //
 //-----------------------------------------------//
 
-#define BUILD "208"
+#define BUILD "211"
 
 #endif
 
index a913477639bcf9628a32c5fe1dcf577f7b985c20..ed3c4f4c063268079438cb1917ddc98b6214ba81 100644 (file)
@@ -54,6 +54,7 @@
 #include "side_channel/side_channel_module.h"
 #include "sfip/sf_ip.h"
 #include "sfip/sf_ipvar.h"
+#include "stream/stream.h"
 #include "target_based/sftarget_data.h"
 #include "target_based/snort_protocols.h"
 
index 6f01719edb9ca569cba61e6ccd756e36f9397fc0..85910103dc4e791982b958214db6339bba723d21 100644 (file)
@@ -45,7 +45,6 @@
 #include "filters/detection_filter.h"
 #include "filters/rate_filter.h"
 #include "filters/sfthreshold.h"
-#include "flow/flow_control.h"
 #include "flow/ha.h"
 #include "framework/mpse.h"
 #include "helpers/process.h"
@@ -601,8 +600,7 @@ void Snort::capture_packet()
 
 void Snort::thread_idle()
 {
-    if ( flow_con )
-        flow_con->timeout_flows(16384, time(NULL));
+    Stream::timeout_flows(time(nullptr));
     perf_monitor_idle_process();
     aux_counts.idle++;
     HighAvailabilityManager::process_receive();
@@ -666,9 +664,11 @@ void Snort::thread_init_unprivileged()
 void Snort::thread_term()
 {
     HighAvailabilityManager::thread_term_beginning();
+
     if ( !snort_conf->dirty_pig )
-        InspectorManager::thread_stop(snort_conf);
+        Stream::purge_flows();
 
+    InspectorManager::thread_stop(snort_conf);
     ModuleManager::accumulate(snort_conf);
     InspectorManager::thread_term(snort_conf);
     ActionManager::thread_term(snort_conf);
@@ -850,12 +850,7 @@ DAQ_Verdict Snort::packet_callback(
 
     Active::reset();
     PacketManager::encode_reset();
-
-    if ( flow_con ) // FIXIT-M always instantiate
-    {
-        flow_con->timeout_flows(4, pkthdr->ts.tv_sec);
-    }
-
+    Stream::timeout_flows(pkthdr->ts.tv_sec);
     HighAvailabilityManager::process_receive();
 
     s_packet->pkth = nullptr;  // no longer avail upon sig segv
index 967b940d5cf8aad1321eaa1ded0db6699d6aba31..e19b4bb1d8beb123e1706d0e39de287c4311f2b5 100644 (file)
@@ -19,9 +19,6 @@
 // prune_handler.cc author Joel Cornett <jocornet@cisco.com>
 
 #include "prune_handler.h"
-
-#include "flow/flow_cache.h"
-#include "flow/flow_control.h"
 #include "stream/stream.h"
 
 namespace memory
@@ -29,9 +26,7 @@ namespace memory
 
 void prune_handler()
 {
-    // assert(flow_con);
-    if ( flow_con )
-        flow_con->prune_one(PruneReason::MEMCAP, false);
+    Stream::prune_flows();
 }
 
 } // namespace memory
index 87554efab269b7c82d0e6ce588a4abc522f8b8d0..c28ab3b2278fd64dbc13eece590272ad437618c5 100644 (file)
@@ -147,7 +147,7 @@ bool AppIdApi::is_ssl_session_decrypted(AppIdSession* session)
 
 AppIdSession* AppIdApi::get_appid_data(Flow* flow)
 {
-    AppIdSession* session = (AppIdSession*) flow->get_application_data(AppIdSession::flow_id);
+    AppIdSession* session = (AppIdSession*) flow->get_flow_data(AppIdSession::flow_id);
 
     return (session && session->common.fsf_type.flow_type == APPID_SESSION_TYPE_NORMAL) ?
            session : nullptr;
@@ -492,7 +492,7 @@ char* AppIdApi::get_netbios_name(AppIdSession* session)
 uint32_t AppIdApi::produce_ha_state(void* lwssn, uint8_t* buf)
 {
     AppIdSessionHA* appHA = (AppIdSessionHA*)buf;
-    AppIdSession* session = (AppIdSession*)(((Flow*)lwssn)->get_application_data(AppIdSession::flow_id));
+    AppIdSession* session = (AppIdSession*)(((Flow*)lwssn)->get_flow_data(AppIdSession::flow_id));
 
     // FIXIT - getFlowType should be a class member
     if (session && get_flow_type(session) != APPID_FLOW_TYPE_NORMAL)
@@ -529,13 +529,13 @@ uint32_t AppIdApi::consume_ha_state(void* lwssn, const uint8_t* buf, uint8_t, Ip
     AppIdSessionHA* appHA = (AppIdSessionHA*)buf;
     if (appHA->flags & APPID_HA_FLAGS_APP)
     {
-        AppIdSession* session = (AppIdSession*)(((Flow*)lwssn)->get_application_data(
+        AppIdSession* session = (AppIdSession*)(((Flow*)lwssn)->get_flow_data(
             AppIdSession::flow_id));
 
         if (!session)
         {
             session = new AppIdSession(proto, ip);
-            ((Flow*)lwssn)->set_application_data(session);
+            ((Flow*)lwssn)->set_flow_data(session);
             if (session->serviceAppId == APP_ID_FTP_CONTROL)
             {
                 session->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED |
index 7e5a87b2c14a2b58771ca590bd7f7c8d9fab7378..973b4ed0b7d95ea868f2bfa4bb8329fa38222eaa 100644 (file)
 
 // appid_flow_data.cc author Sourcefire Inc.
 
+#include "log/messages.h"
 #include "protocols/tcp.h"
 #include "profiler/profiler.h"
 #include "target_based/snort_protocols.h"
+#include "sfip/sf_ip.h"
+#include "stream/stream.h"
+#include "time/packet_time.h"
+#include "utils/util.h"
 
-#include "appid_session.h"
-#include "appid_module.h"
-#include "fw_appid.h"
-#include "appid_stats.h"
-#include "app_forecast.h"
-#include "host_port_app_cache.h"
-#include "lua_detector_module.h"
+#include "appid_utils/ip_funcs.h"
 #include "client_plugins/client_app_base.h"
 #include "detector_plugins/detector_http.h"
 #include "detector_plugins/detector_dns.h"
 #include "service_plugins/service_ssl.h"
 #include "service_plugins/service_util.h"
 
-#include "log/messages.h"
-#include "stream/stream_api.h"
-#include "sfip/sf_ip.h"
-#include "utils/util.h"
-#include "appid_utils/ip_funcs.h"
-#include "time/packet_time.h"
+#include "appid_session.h"
+#include "appid_module.h"
+#include "fw_appid.h"
+#include "appid_stats.h"
+#include "app_forecast.h"
+#include "host_port_app_cache.h"
+#include "lua_detector_module.h"
 
 ProfileStats tpPerfStats;
 ProfileStats tpLibPerfStats;
@@ -424,7 +424,7 @@ AppIdSession* AppIdSession::allocate_session(const Packet* p, IpProtocol proto,
     data->flow = p->flow;
     data->stats.firstPktsecond = p->pkth->ts.tv_sec;
 
-    p->flow->set_application_data(data);
+    p->flow->set_flow_data(data);
     return data;
 }
 
@@ -469,8 +469,8 @@ AppIdSession* AppIdSession::create_future_session(const Packet* /*ctrlPkt*/, con
 
     // FIXIT - 2.9.x set_application_protocol_id_expected has several new parameters, need to look
     // into what is required to support those here.
-    if (stream.set_application_protocol_id_expected(/*crtlPkt,*/ cliIp, cliPort, srvIp, srvPort,
-        protocol, app_id, session) )
+    if ( Stream::set_application_protocol_id_expected(
+        /*crtlPkt,*/ cliIp, cliPort, srvIp, srvPort, protocol, app_id, session) )
     {
         if (app_id_debug_session_flag)
             LogMessage("AppIdDbg %s failed to create a related flow for %s-%u -> %s-%u %u\n",
@@ -1256,7 +1256,8 @@ bool AppIdSession::do_third_party_discovery(IpProtocol protocol, const sfip_t* i
                 thirdparty_appid_module->disable_flags(tpsession,
                         TP_SESSION_FLAG_ATTRIBUTE | TP_SESSION_FLAG_TUNNELING | TP_SESSION_FLAG_FUTUREFLOW);
             }
-            if (tp_app_id == APP_ID_SSL && (stream.get_application_protocol_id(p->flow) == snortId_for_ftp_data))
+            if (tp_app_id == APP_ID_SSL &&
+                (Stream::get_application_protocol_id(p->flow) == snortId_for_ftp_data))
             {
                 //  If we see SSL on an FTP data channel set tpAppId back
                 //  to APP_ID_NONE so the FTP preprocessor picks up the flow.
@@ -1604,7 +1605,7 @@ void AppIdSession::do_application_discovery(Packet* p)
     if( is_packet_ignored(p) )
         return;
 
-    AppIdSession* session = (AppIdSession*) p->flow->get_application_data(AppIdSession::flow_id);
+    AppIdSession* session = (AppIdSession*) p->flow->get_flow_data(AppIdSession::flow_id);
     if (session)
     {
         if (session->common.fsf_type.flow_type == APPID_SESSION_TYPE_IGNORE)
@@ -1655,11 +1656,11 @@ void AppIdSession::do_application_discovery(Packet* p)
                 APPID_SESSION_BIDIRECTIONAL_CHECKED)
             {
                 // FIXIT-M: This _dpd call needs to be convert to correct snort++ call
-                // static THREAD_LOCAL APPID_SESSION_STRUCT_FLAG ignore_fsf {
-                // APPID_SESSION_TYPE_IGNORE };
+                // static THREAD_LOCAL APPID_SESSION_STRUCT_FLAG ignore_fsf
+                // { APPID_SESSION_TYPE_IGNORE };
+
+                // p->flow->set_flow_data(PP_APP_ID, &ignore_fsf, nullptr);
 
-                // _dpd.sessionAPI->set_application_data(p->flow, PP_APP_ID, &ignore_fsf,
-                //     nullptr);
                 if (app_id_debug_session_flag)
                     LogMessage("AppIdDbg %s not monitored\n", app_id_debug_session);
             }
@@ -1681,7 +1682,7 @@ void AppIdSession::do_application_discovery(Packet* p)
                 else
                     tmp_session->common.initiator_port = 0;
                 tmp_session->common.policyId = appIdPolicyId;
-                p->flow->set_application_data(tmp_session);
+                p->flow->set_flow_data(tmp_session);
                 if (app_id_debug_session_flag)
                     LogMessage("AppIdDbg %s unknown monitoring\n", app_id_debug_session);
             }
index 76d898275613b17106ee6a6539afd2077192cac8..d0869452dd618a702cf8c01a1727bd9964490791 100644 (file)
@@ -713,7 +713,7 @@ static CLIENT_APP_RETCODE validate(const uint8_t* data, uint16_t size, const int
         (SearchTool*)( ( AppIdConfig*)pConfig)->find_generic_config_element(client_app_mod.name);
 
 #ifdef APP_ID_USES_REASSEMBLED
-    stream.flush_response_flush(pkt);
+    Stream::flush_response_flush(pkt);
 #endif
 
     if (!size)
@@ -990,7 +990,7 @@ static int imap_validate(ServiceValidationArgs* args)
         goto inprocess;
 
 #ifdef APP_ID_USES_REASSEMBLED
-    stream.flush_response_flush(pkt);
+    Stream::flush_response_flush(pkt);
 #endif
 
     if (!size)
index 4326d483a1e0627ab09afc576fd7190f57a50dab..4879a0c385e310fb13de742f6326afe6f3479c3e 100644 (file)
@@ -973,7 +973,7 @@ static CLIENT_APP_RETCODE krb_client_validate(const uint8_t* data, uint16_t size
 #endif
 
 #ifdef APP_ID_USES_REASSEMBLED
-    stream.flush_response_flush(pkt);
+    Stream::flush_response_flush(pkt);
 #endif
 
     if (!size)
@@ -1046,7 +1046,7 @@ static int krb_server_validate(ServiceValidationArgs* args)
         goto inprocess;
 
 #ifdef APP_ID_USES_REASSEMBLED
-    stream.flush_response_flush(pkt);
+    Stream::flush_response_flush(pkt);
 #endif
 
     if (!size)
index 9b28db892081586cb2d409205ff9827b4a35cc2c..0baa1256994024dcac7535d53eab04fc3aa09e7b 100644 (file)
@@ -686,7 +686,7 @@ static CLIENT_APP_RETCODE pop3_ca_validate(const uint8_t* data, uint16_t size, c
         return CLIENT_APP_INPROCESS;
 
 #ifdef APP_ID_USES_REASSEMBLED
-    stream.flush_response_flush(pkt);
+    Stream::flush_response_flush(pkt);
 #endif
 
     dd = (POP3DetectorData*)pop3_detector_mod.api->data_get(flowp,
@@ -893,7 +893,7 @@ static int pop3_validate(ServiceValidationArgs* args)
         goto inprocess;
 
 #ifdef APP_ID_USES_REASSEMBLED
-    stream.flush_response_flush(pkt);
+    Stream::flush_response_flush(pkt);
 #endif
 
     if (dir != APP_ID_FROM_RESPONDER)
index 862aa4ac62a952369171778f3a72571a45e69269..52dd5d84b0eec992964680cc7b34d1572f3280e2 100644 (file)
@@ -44,7 +44,6 @@
 #include "appid_utils/network_set.h"
 #include "time/packet_time.h"
 #include "sfip/sf_ip.h"
-#include "stream/stream_api.h"
 
 #define HTTP_PATTERN_MAX_LEN    1024
 #define PORT_MAX 65535
index 41023158d495049cb2d9926374a9377ad2bd8265..dc6245d457069b092a3a88cd4e3ebee3e1bf82aa 100644 (file)
@@ -38,8 +38,8 @@
 #include "hash/sfhashfcn.h"
 #include "log/messages.h"
 #include "profiler/profiler.h"
+#include "stream/stream.h"
 #include "utils/util.h"
-#include "stream/stream_api.h"
 
 //-------------------------------------------------------------------------
 // appid option
index b0924902959ff8822309925d503fe55849e012a4..310bc0eca1fd4e7fc4eadb5cf075b553c6c7fac0 100644 (file)
 
 #include "service_rpc.h"
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <netdb.h>
 
 #if defined(FREEBSD) || defined(OPENBSD)
-#include "rpc/rpc.h"
+#include <rpc/rpc.h>
 #endif
 
 #include "service_api.h"
index 930d09719f1855dc6758334d7b5b43d7514b4b6d..e68cf3770980c7fb5e159e05fb7455dbdf178db1 100644 (file)
@@ -173,12 +173,12 @@ void enable_preproc_all_ports(struct _SnortConfig*, uint32_t, uint32_t)
 {
 }
 
-void* get_application_data(void*, uint32_t)
+void* get_flow_data(void*, uint32_t)
 {
     return pAppIdData;
 }
 
-int set_application_data(void*, uint32_t, AppIdSession* data, StreamAppDataFree)
+int set_flow_data(void*, uint32_t, AppIdSession* data, StreamAppDataFree)
 {
     pAppIdData = data;
 
index 923d1a49668866da2f6325bbf6f48e69fa7cb31a..7c2c540d2d9a648933b866e2f83f6e2b39fee02e 100644 (file)
@@ -53,8 +53,8 @@ int16_t findProtocolReference(const char* app);
 
 // Session APIs
 void enable_preproc_all_ports(SnortConfig*, uint32_t appId, uint32_t flags);
-void* get_application_data(void* stream_session, uint32_t protocol);
-int set_application_data(void* scbptr, uint32_t protocol, void* data, StreamAppDataFree);
+void* get_flow_data(void* stream_session, uint32_t protocol);
+int set_flow_data(void* scbptr, uint32_t protocol, void* data, StreamAppDataFree);
 uint32_t get_packet_direction(Packet*);
 uint32_t get_session_flags(void* ssnptr);
 sfaddr_t* get_session_ip_address(void* scbptr, uint32_t direction);
index ef86ec8b1ba2bff57748def8d1def2ff75166ba1..bd3db5b04dbfc8d7b2e0f35ab462e601178a9fbc 100644 (file)
@@ -34,7 +34,6 @@
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
-#include "bitop.h"
 #include "bnfa_search.h"
 #include "acsmx.h"
 #include "acsmx2.h"
@@ -464,17 +463,6 @@ int mpsePrepPatternsWithSnortConf(struct _SnortConfig* sc, void* pvoid,
     return retv;
 }
 
-void mpseSetRuleMask(void* pvoid, BITOP* rm)
-{
-    MPSE* p = (MPSE*)pvoid;
-
-    switch ( p->method )
-    {
-    default:
-        return;
-    }
-}
-
 int mpsePrintInfo(void* pvoid)
 {
     MPSE* p = (MPSE*)pvoid;
index c3a73bb545ca0c5662ac31060926ea98ec3f26bd..5eb80843d31ca8cd665a7f8b82fcc7c203bc016b 100644 (file)
@@ -1,6 +1,7 @@
 
 set(FILE_LIST
     binder.cc
+    binder.h
     binding.h
     bind_module.cc
     bind_module.h
index 67b53ac5135146a86926f85736b4d97b54c7c22d..484d64c7e2d22f6a65fe509bd6e8c748988126c2 100644 (file)
@@ -1,6 +1,7 @@
 
 file_list = \
 binder.cc \
+binder.h \
 binding.h \
 bind_module.cc \
 bind_module.h
index e49034e9c69a0f3227ca0aaebf2181b15e283a1e..06685b034cb041ad470759884b7cf461116fe8a3 100644 (file)
@@ -32,7 +32,6 @@ using namespace std;
 #include "protocols/packet.h"
 #include "protocols/vlan.h"
 #include "protocols/layer.h"
-#include "stream/stream_api.h"
 #include "stream/stream_splitter.h"
 #include "profiler/profiler.h"
 #include "utils/stats.h"
@@ -207,7 +206,7 @@ static void set_session(Flow* flow)
 
 static void set_service(Flow* flow, const HostAttributeEntry* host)
 {
-    stream.set_application_protocol_id_from_host_entry(flow, host, FROM_SERVER);
+    Stream::set_application_protocol_id(flow, host, FROM_SERVER);
 }
 
 static Inspector* get_gadget(Flow* flow)
@@ -472,13 +471,13 @@ int Binder::exec_handle_gadget( void* pv )
 
     if ( ins )
     {
-        stream.set_splitter(flow, true, ins->get_splitter(true));
-        stream.set_splitter(flow, false, ins->get_splitter(false));
+        Stream::set_splitter(flow, true, ins->get_splitter(true));
+        Stream::set_splitter(flow, false, ins->get_splitter(false));
     }
     else
     {
-        stream.set_splitter(flow, true, new AtomSplitter(true));
-        stream.set_splitter(flow, false, new AtomSplitter(false));
+        Stream::set_splitter(flow, true, new AtomSplitter(true));
+        Stream::set_splitter(flow, false, new AtomSplitter(false));
     }
 
     return 0;
index 2ed484df58d45b4b105db3ccb07cb674184264af..105fb2a84757c62b0319abe1fe91da22b76ff628 100644 (file)
@@ -30,7 +30,6 @@
 #include "managers/inspector_manager.h"
 #include "main/policy.h"
 #include "profiler/profiler.h"
-#include "stream/stream_api.h"
 #include "stream/stream_splitter.h"
 #include "utils/stats.h"
 
@@ -90,7 +89,7 @@ unsigned THREAD_LOCAL Inspector::slot = 0;
 void ParseError(const char*, ...) { }
 void LogMessage(const char*,...) { }
 
-void Stream::set_application_protocol_id_from_host_entry(Flow*, HostAttributeEntry const*, int) { }
+void Stream::set_application_protocol_id(Flow*, HostAttributeEntry const*, int) { }
 void Stream::set_splitter(Flow*, bool, class StreamSplitter*) { }
 const char* get_protocol_name(uint16_t) { return ""; }
 int16_t FindProtocolReference(const char*) { return 0; }
@@ -118,7 +117,7 @@ TEST(binder, exec)
     memset(conf,0,sizeof(SnortConfig));
     snort_conf = (SnortConfig*)conf;
     Flow* flow = new Flow;
-    constexpr size_t offset = offsetof(Flow, appDataList);
+    constexpr size_t offset = offsetof(Flow, flow_data);
     memset((uint8_t*)flow+offset, 0, sizeof(Flow)-offset);
 
     s_inspector = new MyInspector();
index 881fec962bf9e18bd7ccb2f90db398787a416866..7e268045795cc96fdf53ce9e9814607bd6254945 100644 (file)
@@ -33,7 +33,6 @@
 #include "protocols/tcp_options.h"
 #include "protocols/icmp4.h"
 #include "protocols/icmp6.h"
-#include "stream/stream.h"
 #include "stream/tcp/tcp_normalizer.h"
 #include "utils/stats.h"
 
index e03bd8a5364c92882f069b809901a2ad17dc7e1a..273ac05a8e3153e7dd3c45351dba278f3961a8cd 100644 (file)
@@ -24,7 +24,6 @@
 #include <sstream>
 #include <vector>
 
-#include "stream/stream.h"
 #include "stream/tcp/tcp_normalizer.h"
 
 using namespace std;
index ea88f18fcab90476362e2074404188974cd7b611..1f20ece735aa530aa3bbd242589516883e1a0cb7 100644 (file)
 #include "protocols/packet.h"
 #include "time/packet_time.h"
 #include "hash/sfxhash.h"
-#include "stream/stream_api.h"
-#include "sfip/sf_ip.h"
 #include "protocols/tcp.h"
 #include "protocols/udp.h"
 #include "protocols/icmp4.h"
 #include "protocols/icmp6.h"
 #include "protocols/eth.h"
+#include "sfip/sf_ip.h"
+#include "stream/stream.h"
 
 typedef struct s_PS_HASH_KEY
 {
@@ -343,7 +343,7 @@ int PortScan::ps_filter_ignore(PS_PKT* ps_pkt)
     }
     else if (p->ptrs.udph && p->flow)
     {
-        if (stream.get_packet_direction(p) & PKT_FROM_SERVER)
+        if (Stream::get_packet_direction(p) & PKT_FROM_SERVER)
             reverse_pkt = 1;
     }
 
@@ -996,7 +996,7 @@ int PortScan::ps_tracker_update_udp(PS_PKT* ps_pkt, PS_TRACKER* scanner,
     {
         if ( p->flow )
         {
-            uint32_t direction = stream.get_packet_direction(p);
+            uint32_t direction = Stream::get_packet_direction(p);
 
             if (direction == PKT_FROM_CLIENT)
             {
index 06eeaf4842b7d1c2f8d7aabe000a8bdefb997dd6..6214911437270091bb4f05151f3ec8a1fcf349d4 100644 (file)
@@ -39,7 +39,6 @@
 #include "main/snort_types.h"
 #include "main/snort_debug.h"
 #include "profiler/profiler.h"
-#include "stream/stream_api.h"
 #include "file_api/file_api.h"
 #include "parser/parser.h"
 #include "framework/inspector.h"
@@ -87,13 +86,13 @@ unsigned ReputationFlowData::flow_id = 0;
 static ReputationData* SetNewReputationData(Flow* flow)
 {
     ReputationFlowData* fd = new ReputationFlowData;
-    flow->set_application_data(fd);
+    flow->set_flow_data(fd);
     return &fd->session;
 }
 
 static ReputationData* get_session_data(Flow* flow)
 {
-    ReputationFlowData* fd = (ReputationFlowData*)flow->get_application_data(
+    ReputationFlowData* fd = (ReputationFlowData*)flow->get_flow_data(
         ReputationFlowData::flow_id);
 
     return fd ? &fd->session : nullptr;
index 42ec3a28da1db2691054c67c6fc9fcabec1f404e..ecadd3e58f4aa2240091a14925a14f2e18da393c 100644 (file)
@@ -20,7 +20,6 @@
 #define REPUTATION_INSPECT_H
 
 #include "protocols/packet.h"
-#include "stream/stream_api.h"
 
 // Per-session data block containing current state
 // of the Reputation preprocessor for the session.
index 1b8a75673f9b1fa20254cf507f9a8486243bda69..43011ee29f04c257ee8646f1a877687dd0297e7e 100644 (file)
@@ -28,6 +28,7 @@
 #include "managers/action_manager.h"
 #include "packet_io/sfdaq.h"
 #include "protocols/tcp.h"
+#include "stream/stream.h"
 #include "utils/dnet_header.h"
 
 #define MAX_ATTEMPTS 20
@@ -40,7 +41,7 @@ THREAD_LOCAL Active::ActiveAction Active::active_action = Active::ACT_PASS;
 THREAD_LOCAL Active::ActiveAction Active::delayed_active_action = Active::ACT_PASS;
 
 THREAD_LOCAL int Active::active_tunnel_bypass = 0;
-THREAD_LOCAL bool Active::active_suspend = 0;
+THREAD_LOCAL bool Active::active_suspend = false;
 
 THREAD_LOCAL uint8_t Active::s_attempts = 0;
 THREAD_LOCAL uint64_t Active::s_injects = 0;
@@ -415,7 +416,7 @@ void Active::block_session(const Packet* p, bool force)
     active_action = ACT_BLOCK;
 
     if ( force or SnortConfig::inline_mode() or SnortConfig::treat_drop_as_ignore() )
-        stream.drop_session(p);
+        Stream::drop_flow(p);
 }
 
 void Active::reset_session(const Packet* p, bool force)
@@ -424,7 +425,7 @@ void Active::reset_session(const Packet* p, bool force)
     active_action = ACT_RESET;
 
     if ( force or SnortConfig::inline_mode() or SnortConfig::treat_drop_as_ignore() )
-        stream.drop_session(p);
+        Stream::drop_flow(p);
 
     if ( s_enabled and snort_conf->max_responses )
     {
@@ -432,7 +433,7 @@ void Active::reset_session(const Packet* p, bool force)
 
         if ( p->flow )
         {
-            stream.init_active_response(p, p->flow);
+            Stream::init_active_response(p, p->flow);
             p->flow->set_state(Flow::FlowState::RESET);
         }
     }
index d0c45ea23417877c86cb2d9d96e64ee7662111e8..c93c5e00e9b70e5bf1ab48193b2f77dd30f3d8e5 100644 (file)
@@ -816,7 +816,7 @@ static void XferHeader(RuleTreeNode* test_node, RuleTreeNode* rtn)
  *
  ***************************************************************************/
 static void AddRuleFuncToList(
-    int (* rfunc) (Packet*, RuleTreeNode*, struct RuleFpList*, int),
+    int (* rfunc)(Packet*, RuleTreeNode*, struct RuleFpList*, int),
     RuleTreeNode* rtn)
 {
     RuleFpList* idx;
@@ -1143,17 +1143,17 @@ static int mergeDuplicateOtn(
     return 1;
 }
 
-PatternMatchData* get_pmd(OptFpList* ofl)
+PatternMatchData* get_pmd(OptFpList* ofl, int proto, RuleDirection direction)
 {
     if ( !ofl->ips_opt )
         return nullptr;
 
-    return ofl->ips_opt->get_pattern();
+    return ofl->ips_opt->get_pattern(proto, direction);
 }
 
 static void finalize_content(OptFpList* ofl)
 {
-    PatternMatchData* pmd = get_pmd(ofl);
+    PatternMatchData* pmd = get_pmd(ofl, 0, RULE_WO_DIR);
 
     if ( !pmd )
         return;
@@ -1165,7 +1165,7 @@ static void finalize_content(OptFpList* ofl)
 
 bool is_fast_pattern_only(OptFpList* ofl)
 {
-    PatternMatchData* pmd = get_pmd(ofl);
+    PatternMatchData* pmd = get_pmd(ofl, 0, RULE_WO_DIR);
 
     if ( !pmd )
         return false;
@@ -1175,7 +1175,7 @@ bool is_fast_pattern_only(OptFpList* ofl)
 
 static void clear_fast_pattern_only(OptFpList* ofl)
 {
-    PatternMatchData* pmd = get_pmd(ofl);
+    PatternMatchData* pmd = get_pmd(ofl, 0, RULE_WO_DIR);
 
     if ( pmd && pmd->fp_only > 0 )
         pmd->fp_only = 0;
@@ -1199,7 +1199,7 @@ static void ValidateFastPattern(OptTreeNode* otn)
         }
 
         // reset the check if one of these are present.
-        if ( fpl->ips_opt and !fpl->ips_opt->get_pattern()
+        if ( fpl->ips_opt and !fpl->ips_opt->get_pattern(0, RULE_WO_DIR))
         {
             if ( fpl->ips_opt->get_cursor_type() > CAT_NONE )
                 relative_is_bad_mkay = false;
@@ -1536,7 +1536,7 @@ const char* parse_rule_close(SnortConfig* sc, RuleTreeNode& rtn, OptTreeNode* ot
      * After otn processing we can finalize port object processing for this rule
      */
     if ( FinishPortListRule(
-            sc->port_tables, new_rtn, otn, rtn.proto, has_fp, sc->fast_pattern_config) )
+        sc->port_tables, new_rtn, otn, rtn.proto, has_fp, sc->fast_pattern_config) )
         ParseError("Failed to finish a port list rule.");
 
     return nullptr;
index dcd535fdabcdf0bace05691b2cc39ddd333313ed..20b23a05e614e48766968ea866e6bc6008041d09 100644 (file)
@@ -21,6 +21,7 @@
 #define PARSE_RULE_H
 
 #include "detection/rules.h"
+#include "framework/ips_option.h"
 
 struct OptFpList;
 struct OptTreeNode;
@@ -44,7 +45,7 @@ OptTreeNode* parse_rule_open(SnortConfig*, RuleTreeNode&, bool stub = false);
 const char* parse_rule_close(SnortConfig*, RuleTreeNode&, OptTreeNode*);
 
 bool is_fast_pattern_only(OptFpList*);
-struct PatternMatchData* get_pmd(OptFpList*);
+struct PatternMatchData* get_pmd(OptFpList*, int proto, RuleDirection);
 
 int get_rule_count();
 
index 82e950171b3797c5c1a8c07a569e3c8f611fc475..a8059d7c99e706c6550cb5c18af5109eeb571bdf 100644 (file)
@@ -40,7 +40,7 @@
 // show statistics
 // -----------------------------------------------------------------------------
 
-#define s_memory_table_title "Memory Profile Statistics"
+#define s_memory_table_title "memory profile"
 
 namespace memory_stats
 {
index e8020e4893a7afc24fb22e41be1086bca371e620..f1dff874f960f100113c794513ba5baf386b8e01 100644 (file)
@@ -32,7 +32,7 @@
 #include "catch/catch.hpp"
 #endif
 
-static constexpr unsigned WIDTH = 40;
+static constexpr unsigned WIDTH = 50;
 static constexpr char ENDL = '\n';
 
 const StatsTable::Header StatsTable::HEADER { '=' };
index cfd7279d146cbdd2c5770c4c6318b58c6f22c8e8..1d6eaf5149bc25a2ae1caf10d6d2da9ff6314e1d 100644 (file)
@@ -46,7 +46,7 @@
 #include "catch/catch.hpp"
 #endif
 
-#define s_rule_table_title "Rule Profile Statistics"
+#define s_rule_table_title "rule profile"
 
 static inline OtnState& operator+=(OtnState& lhs, const OtnState& rhs)
 {
@@ -228,17 +228,17 @@ static void print_single_entry(const View& v, unsigned n)
         table << n; // #
 
         table << v.sig_info.generator; // gid
-        table << v.sig_info.id; // sid
-        table << v.sig_info.rev; // rev
+        table << v.sig_info.id;        // sid
+        table << v.sig_info.rev;
 
-        table << v.checks(); // checks
-        table << v.matches(); // matches
-        table << v.alerts(); // alerts
+        table << v.checks();
+        table << v.matches();
+        table << v.alerts();
 
-        table << duration_cast<microseconds>(v.elapsed()).count(); // time
-        table << duration_cast<microseconds>(v.avg_check()).count(); // avg/check
-        table << duration_cast<microseconds>(v.avg_match()).count(); // avg/match
-        table << duration_cast<microseconds>(v.avg_no_match()).count(); // avg/non-match
+        table << clock_usecs(duration_cast<microseconds>(v.elapsed()).count());
+        table << clock_usecs(duration_cast<microseconds>(v.avg_check()).count());
+        table << clock_usecs(duration_cast<microseconds>(v.avg_match()).count());
+        table << clock_usecs(duration_cast<microseconds>(v.avg_no_match()).count());
 
         table << v.timeouts();
         table << v.suspends();
index d2aa9b469b718834a99a14eb1a56cd82b708d2d9..515dca8334ebda70461ca2bfdc86ad504410244d 100644 (file)
@@ -67,7 +67,7 @@ public:
 
 private:
     dot_node_state_t& stats;
-    Stopwatch<hr_clock> sw;
+    Stopwatch<SnortClock> sw;
     bool finished = false;
 };
 
index 77a5ff7bc8e4681636e3b3a9593f750b24eb00aa..b0e0f4ed72a6d57a8b164b24cc21c53852444258 100644 (file)
@@ -38,7 +38,7 @@
 #include "catch/catch.hpp"
 #endif
 
-#define s_time_table_title "Module Profile Statistics"
+#define s_time_table_title "module profile"
 
 namespace time_stats
 {
@@ -131,10 +131,10 @@ static void print_fn(StatsTable& t, const View& v)
     t << v.checks();
 
     // total time
-    t << duration_cast<microseconds>(v.elapsed()).count();
+    t << clock_usecs(duration_cast<microseconds>(v.elapsed()).count());
 
     // avg/check
-    t << duration_cast<microseconds>(v.avg_check()).count();
+    t << clock_usecs(duration_cast<microseconds>(v.avg_check()).count());
 }
 
 } // namespace time_stats
index 372a3d60709e748cd65125197c3fb5e0dbab4915..eaeaff7b2b5853e1398f3a9a20e2399f4096639a 100644 (file)
@@ -113,7 +113,7 @@ public:
 
 private:
     TimeProfilerStats& stats;
-    Stopwatch<hr_clock> sw;
+    Stopwatch<SnortClock> sw;
     bool stopped_once = false;
 };
 
index 01daf9277bd313958cc2e49a83f37431d027a3ec..bb562d40dbd0b566047730cbf9b4b587afe3ec2c 100644 (file)
@@ -46,9 +46,9 @@
 #include "utils/stats.h"
 #include "log/text_log.h"
 #include "main/snort_debug.h"
-#include "stream/stream_api.h"
 #include "packet_io/sfdaq.h"
 #include "packet_io/active.h"
+#include "stream/stream.h"
 
 THREAD_LOCAL ProfileStats decodePerfStats;
 
@@ -347,11 +347,11 @@ static inline uint8_t GetTTL(const Packet* const p, bool forward)
 
     // outermost ip is considered to be outer here,
     // even if it is the only ip layer ...
-    ttl = stream.get_session_ttl(p->flow, dir, outer);
+    ttl = Stream::get_flow_ttl(p->flow, dir, outer);
 
     // if we don't get outer, we use inner
     if ( 0 == ttl && outer )
-        ttl = stream.get_session_ttl(p->flow, dir, false);
+        ttl = Stream::get_flow_ttl(p->flow, dir, false);
 
     return ttl;
 }
index 724756f36e3f339ca97a0c05c481758d7d74d4fc..99b138d9e82d980e08828e10b66e0462d792e403 100644 (file)
@@ -62,6 +62,11 @@ Pattern::Pattern(
     flags = d.flags;
     user = u;
     user_tree = user_list = nullptr;
+
+    if ( no_case )
+        flags |= HS_FLAG_CASELESS;
+
+    flags |= HS_FLAG_SINGLEMATCH;
 }
 
 void Pattern::escape(const uint8_t* s, unsigned n, bool literal)
index 1f14bac0d5ad72aa570b4b0047fb8a8e1f81d071..30365279ac492a96158a41bb229f8e9f65b00505 100644 (file)
@@ -180,6 +180,8 @@ TEST_GROUP(mpse_hs_match)
 
     void setup()
     {
+        // FIXIT-L cpputest hangs or crashes in the leak detector
+        MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
         CHECK(se_hyperscan);
         hs = mpse_api->ctor(snort_conf, nullptr, false, &s_agent);
         CHECK(hs);
@@ -190,6 +192,7 @@ TEST_GROUP(mpse_hs_match)
     {
         mpse_api->dtor(hs);
         hyperscan_cleanup(snort_conf);
+        MemoryLeakWarningPlugin::turnOnNewDeleteOverloads();
     }
 };
 
@@ -219,21 +222,35 @@ TEST(mpse_hs_match, single)
     CHECK(hits == 1);
 }
 
+TEST(mpse_hs_match, nocase)
+{
+    Mpse::PatternDescriptor desc(true, true, false);
+
+    CHECK(hs->add_pattern(nullptr, (uint8_t*)"foo", 3, desc, s_user) == 0);
+    CHECK(hs->prep_patterns(snort_conf) == 0);
+    CHECK(hs->get_pattern_count() == 1);
+
+    hyperscan_setup(snort_conf);
+
+    int state = 0;
+    CHECK(hs->search((uint8_t*)"foo", 3, match, nullptr, &state) == 0);
+    CHECK(hs->search((uint8_t*)"fOo", 3, match, nullptr, &state) == 0);
+    CHECK(hits == 2);
+}
+
 TEST(mpse_hs_match, other)
 {
     Mpse::PatternDescriptor desc(false, true, false);
 
     CHECK(hs->add_pattern(nullptr, (uint8_t*)"foo", 3, desc, s_user) == 0);
-    CHECK(hs->add_pattern(nullptr, (uint8_t*)"\rbar\n", 3, desc, s_user) == 0);
-    CHECK(hs->add_pattern(nullptr, (uint8_t*)"\\(baz\\)", 3, desc, s_user) == 0);
-
     CHECK(hs->prep_patterns(snort_conf) == 0);
-    CHECK(hs->get_pattern_count() == 3);
+    CHECK(hs->get_pattern_count() == 1);
 
     hyperscan_setup(snort_conf);
 
     int state = 0;
     CHECK(hs->search((uint8_t*)"foo", 3, match, nullptr, &state) == 0);
+    CHECK(hs->search((uint8_t*)"fOo", 3, match, nullptr, &state) == 0);
     CHECK(hits == 1);
 }
 
@@ -304,6 +321,8 @@ TEST_GROUP(mpse_hs_multi)
 
     void setup()
     {
+        // FIXIT-L cpputest hangs or crashes in the leak detector
+        MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
         CHECK(se_hyperscan);
 
         hs1 = mpse_api->ctor(snort_conf, nullptr, false, &s_agent);
@@ -320,6 +339,7 @@ TEST_GROUP(mpse_hs_multi)
         mpse_api->dtor(hs1);
         mpse_api->dtor(hs2);
         hyperscan_cleanup(snort_conf);
+        MemoryLeakWarningPlugin::turnOnNewDeleteOverloads();
     }
 };
 
index 8b9afe9f04dd64307fa28587c61f2f89d519dc26..4f560a6b491bdc91d0dd7b0ada8bb9e054205328 100644 (file)
@@ -27,7 +27,11 @@ set( FILE_LIST
    dce_tcp_module.cc 
    dce_tcp_module.h 
    dce_tcp_paf.cc 
-   dce_tcp_paf.h 
+   dce_tcp_paf.h
+   dce_udp.cc
+   dce_udp.h 
+   dce_udp_module.cc 
+   dce_udp_module.h
    dce_utils.cc
    dce_utils.h
    ips_dce_iface.cc
index 867d0301b13bf267482da7191c667367fa30351a..5d563eeb7bc023825266241e4b87fcb448d8c6da 100644 (file)
@@ -27,6 +27,10 @@ dce_tcp_module.cc \
 dce_tcp_module.h \
 dce_tcp_paf.cc \
 dce_tcp_paf.h \
+dce_udp.cc\
+dce_udp.h \
+dce_udp_module.cc \
+dce_udp_module.h \
 dce_utils.cc \
 dce_utils.h \
 ips_dce_iface.cc \
index baf1591e944a91612d98f555d514af4c88131853..1bae2dd262c61d9d07f81f750c872b95133aa158 100644 (file)
@@ -318,12 +318,12 @@ static inline bool DCE2_GcReassembleEarly(DCE2_SsnData* sd)
     void* config = sd->config;
     if (sd->trans == DCE2_TRANS_TYPE__TCP)
     {
-        if (((dce2TcpProtoConf*)config)->co_reassemble_threshold > 0)
+        if (((dce2TcpProtoConf*)config)->common.co_reassemble_threshold > 0)
             return true;
     }
     else
     {
-        if (((dce2SmbProtoConf*)config)->co_reassemble_threshold > 0)
+        if (((dce2SmbProtoConf*)config)->common.co_reassemble_threshold > 0)
             return true;
     }
     return false;
@@ -336,11 +336,11 @@ static inline uint16_t DCE2_GcReassembleThreshold(DCE2_SsnData* sd)
     {
         if (sd->trans == DCE2_TRANS_TYPE__TCP)
         {
-            return ((dce2TcpProtoConf*)config)->co_reassemble_threshold;
+            return ((dce2TcpProtoConf*)config)->common.co_reassemble_threshold;
         }
         else
         {
-            return ((dce2SmbProtoConf*)config)->co_reassemble_threshold;
+            return ((dce2SmbProtoConf*)config)->common.co_reassemble_threshold;
         }
     }
     return UINT16_MAX;
index 994d0e5685419ca6dfae3cd8d97a267d7880f847..41a5b32b0965210c2937222503d5c8d332cfe3f0 100644 (file)
@@ -89,9 +89,19 @@ bool dce2_set_common_config(Value& v, dce2CommonProtoConf& common)
 
     else if ( v.is("max_frag_len") )
         common.max_frag_len = v.get_long();
+    else
+        return false;
+    return true;
+}
 
+bool dce2_set_co_config(Value& v, dce2CoProtoConf& co)
+{
+    if (dce2_set_common_config(v, co.common))
+        return true;
     else if ( v.is("policy") )
-        common.policy = (DCE2_Policy)v.get_long();
+        co.policy = (DCE2_Policy)v.get_long();
+    else if ( v.is("reassemble_threshold") )
+        co.co_reassemble_threshold = v.get_long();
     else
         return false;
     return true;
@@ -104,8 +114,16 @@ void print_dce2_common_config(dce2CommonProtoConf& common)
         "DISABLED" : "ENABLED");
     LogMessage("    Max Fragment length: %d\n",
         common.max_frag_len);
+}
+
+void print_dce2_co_config(dce2CoProtoConf& co)
+{
+    print_dce2_common_config(co.common);
+
     LogMessage("    Policy : %s\n",
-        dce2_get_policy_name(common.policy));
+        dce2_get_policy_name(co.policy));
+    LogMessage("    Reassemble Threshold : %d\n",
+        co.co_reassemble_threshold);
 }
 
 bool dce2_paf_abort(Flow* flow, DCE2_SsnData* sd)
@@ -553,6 +571,7 @@ SO_PUBLIC const BaseApi* snort_plugins[] =
 {
     &dce2_tcp_api.base,
     &dce2_smb_api.base,
+    &dce2_udp_api.base,
     ips_dce_iface,
     ips_dce_opnum,
     ips_dce_stub_data,
@@ -562,6 +581,7 @@ SO_PUBLIC const BaseApi* snort_plugins[] =
 
 const BaseApi* sin_dce_tcp = &dce2_tcp_api.base;
 const BaseApi* sin_dce_smb = &dce2_smb_api.base;
+const BaseApi* sin_dce_udp = &dce2_udp_api.base;
 
 #endif
 
index 0e6a56a85fad797fa85a840aadc85741f8143829..6ec2f94c9dc151f9f7069aba5b4107fa87edd024 100644 (file)
@@ -31,6 +31,7 @@
 
 extern const InspectApi dce2_smb_api;
 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;
@@ -103,7 +104,13 @@ struct dce2CommonProtoConf
 {
     bool disable_defrag;
     int max_frag_len;
+};
+
+struct dce2CoProtoConf
+{
+    dce2CommonProtoConf common;
     DCE2_Policy policy;
+    uint16_t co_reassemble_threshold;
 };
 
 #define DCE2_DEBUG__PAF_END_MSG    "=========================================================="
@@ -415,6 +422,8 @@ inline void dce_alert(uint32_t gid, uint32_t sid, dce2CommonStats* stats)
 
 bool dce2_set_common_config(Value&, dce2CommonProtoConf&);
 void print_dce2_common_config(dce2CommonProtoConf&);
+bool dce2_set_co_config(Value&, dce2CoProtoConf&);
+void print_dce2_co_config(dce2CoProtoConf&);
 bool dce2_paf_abort(Flow*, DCE2_SsnData*);
 void DCE2_Detect(DCE2_SsnData*);
 Packet* DCE2_GetRpkt(Packet*, DCE2_RpktType,
index a93fdb67fedd7ffff7d42665d522654c3fd1f47f..4c6f3127c598f9584e6e0f92941f9298873bd18b 100644 (file)
@@ -1660,18 +1660,15 @@ unsigned Dce2SmbFlowData::flow_id = 0;
 
 DCE2_SmbSsnData* get_dce2_smb_session_data(Flow* flow)
 {
-    Dce2SmbFlowData* fd = (Dce2SmbFlowData*)flow->get_application_data(
-        Dce2SmbFlowData::flow_id);
-
+    Dce2SmbFlowData* fd = (Dce2SmbFlowData*)flow->get_flow_data(Dce2SmbFlowData::flow_id);
     return fd ? &fd->dce2_smb_session : nullptr;
 }
 
 static DCE2_SmbSsnData* set_new_dce2_smb_session(Packet* p)
 {
     Dce2SmbFlowData* fd = new Dce2SmbFlowData;
-
     memset(&fd->dce2_smb_session,0,sizeof(DCE2_SmbSsnData));
-    p->flow->set_application_data(fd);
+    p->flow->set_flow_data(fd);
     return(&fd->dce2_smb_session);
 }
 
index 21f556f362020a1e998c0b227bd0affdf3bbd308..980d1324294364f09713ef1a709766907100f42d 100644 (file)
@@ -25,6 +25,7 @@
 #include "dce_smb_utils.h"
 #include "detection/detection_util.h"
 #include "main/snort_debug.h"
+#include "file_api/file_flows.h"
 
 #define   UNKNOWN_FILE_SIZE                  ~0
 
@@ -240,8 +241,16 @@ static inline void DCE2_Smb2ResetFileName(DCE2_SmbFileTracker* ftracker)
     ftracker->file_name_size = 0;
 }
 
+static inline FileContext* get_file_context(DCE2_SmbSsnData* ssd, uint64_t file_id)
+{
+    assert(ssd->sd.wire_pkt);
+    FileFlows* file_flows = FileFlows::get_file_flows((ssd->sd.wire_pkt)->flow);
+    assert(file_flows);
+    return file_flows->get_file_context(file_id, true);
+}
+
 static inline void DCE2_Smb2ProcessFileData(DCE2_SmbSsnData* ssd, const uint8_t* file_data,
-    uint32_t data_size, bool)
+    uint32_t data_size, FileDirection dir)
 {
     int64_t file_detection_depth = DCE2_ScSmbFileDepth((dce2SmbProtoConf*)ssd->sd.config);
     int64_t detection_size = 0;
@@ -264,13 +273,11 @@ static inline void DCE2_Smb2ProcessFileData(DCE2_SmbSsnData* ssd, const uint8_t*
         DCE2_FileDetect();
     }
 
-// FIXIT-L port file processing
-/*
-    _dpd.fileAPI->file_segment_process(fileCache, (void *)ssd->sd.wire_pkt,
-            ssd->ftracker.fid_v2, ssd->ftracker.tracker.file.file_size,
-            file_data, data_size, ssd->ftracker.tracker.file.file_offset,
-            upload);
-*/
+    assert(ssd->sd.wire_pkt);
+    FileFlows* file_flows = FileFlows::get_file_flows((ssd->sd.wire_pkt)->flow);
+
+    file_flows->file_process(ssd->ftracker.fid_v2, file_data, data_size,
+        ssd->ftracker.tracker.file.file_offset, dir);
 }
 
 /********************************************************************
@@ -378,11 +385,12 @@ static void DCE2_Smb2CreateResponse(DCE2_SmbSsnData* ssd, const Smb2Hdr*,
 
     if (ssd->ftracker.file_name && ssd->ftracker.file_name_size)
     {
-// FIXIT-L port file processing
-/*
-        _dpd.fileAPI->file_cache_update_entry(fileCache, (void *)ssd->sd.wire_pkt, ssd->ftracker.fid_v2,
-                (uint8_t *) ssd->ftracker.file_name,  ssd->ftracker.file_name_size, file_size);
-*/
+        FileContext* file = get_file_context(ssd, ssd->ftracker.fid_v2);
+        if (file)
+        {
+            file->set_file_size(file_size);
+            file->set_file_name(ssd->ftracker.file_name, ssd->ftracker.file_name_size);
+        }
     }
     DCE2_Smb2ResetFileName(&(ssd->ftracker));
 }
@@ -453,15 +461,16 @@ static void DCE2_Smb2CloseCmd(DCE2_SmbSsnData* ssd, const Smb2Hdr*,
         !ssd->ftracker.tracker.file.file_size
         && ssd->ftracker.tracker.file.file_offset)
     {
-        bool upload = DCE2_SsnFromClient(ssd->sd.wire_pkt) ? true : false;
+        FileDirection dir = DCE2_SsnFromClient(ssd->sd.wire_pkt) ? FILE_UPLOAD : FILE_DOWNLOAD;
         ssd->ftracker.tracker.file.file_size = ssd->ftracker.tracker.file.file_offset;
-// FIXIT-L port file processing
-/*
-        uint64_t fileId_persistent = alignedNtohq((const uint64_t *)(&(smb_close_hdr->fileId_persistent)));
-        _dpd.fileAPI->file_cache_update_entry(fileCache, (void *)ssd->sd.wire_pkt,
-                fileId_persistent, nullptr,  0, ssd->ftracker.tracker.file.file_size);
-*/
-        DCE2_Smb2ProcessFileData(ssd, nullptr, 0, upload);
+        uint64_t fileId_persistent = alignedNtohq(&(smb_close_hdr->fileId_persistent));
+        FileContext* file = get_file_context(ssd, fileId_persistent);
+        if (file)
+        {
+            file->set_file_size(ssd->ftracker.tracker.file.file_size);
+        }
+
+        DCE2_Smb2ProcessFileData(ssd, nullptr, 0, dir);
     }
 }
 
@@ -491,12 +500,12 @@ static void DCE2_Smb2SetInfo(DCE2_SmbSsnData* ssd, const Smb2Hdr*,
             uint64_t file_size = alignedNtohq((const uint64_t*)file_data);
             DebugFormat(DEBUG_DCE_SMB, "Get file size %lu!\n", file_size);
             ssd->ftracker.tracker.file.file_size = file_size;
-//FIXIT-L port file processing
-/*
-           uint64_t fileId_persistent = alignedNtohq((const uint64_t *)(&(smb_set_info_hdr->fileId_persistent)));
-            _dpd.fileAPI->file_cache_update_entry(fileCache, (void *)ssd->sd.wire_pkt,
-                    fileId_persistent, nullptr,  0, file_size);
-*/
+            uint64_t fileId_persistent = alignedNtohq(&(smb_set_info_hdr->fileId_persistent));
+            FileContext* file = get_file_context(ssd, fileId_persistent);
+            if (file)
+            {
+                file->set_file_size(ssd->ftracker.tracker.file.file_size);
+            }
         }
     }
 }
@@ -562,7 +571,7 @@ static void DCE2_Smb2ReadResponse(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
 
     DCE2_Smb2RemoveRequest(ssd, request);
 
-    DCE2_Smb2ProcessFileData(ssd, file_data, data_size, false);
+    DCE2_Smb2ProcessFileData(ssd, file_data, data_size, FILE_DOWNLOAD);
     ssd->ftracker.tracker.file.file_offset += data_size;
     total_data_length = alignedNtohl((const uint32_t*)&(smb_read_hdr->length));
     if (total_data_length > (uint32_t)data_size)
@@ -645,7 +654,7 @@ static void DCE2_Smb2WriteRequest(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
     ssd->ftracker.tracker.file.file_direction = DCE2_SMB_FILE_DIRECTION__UPLOAD;
     ssd->ftracker.tracker.file.file_offset = offset;
 
-    DCE2_Smb2ProcessFileData(ssd, file_data, data_size, true);
+    DCE2_Smb2ProcessFileData(ssd, file_data, data_size, FILE_UPLOAD);
     ssd->ftracker.tracker.file.file_offset += data_size;
     total_data_length = alignedNtohl((const uint32_t*)&(smb_write_hdr->length));
     if (total_data_length > (uint32_t)data_size)
@@ -797,8 +806,8 @@ void DCE2_Smb2Process(DCE2_SmbSsnData* ssd)
     else if (ssd->pdu_state == DCE2_SMB_PDU_STATE__RAW_DATA)
     {
         /*continue processing raw data*/
-        bool upload = DCE2_SsnFromClient(ssd->sd.wire_pkt) ? true : false;
-        DCE2_Smb2ProcessFileData(ssd, data_ptr, data_len, upload);
+        FileDirection dir = DCE2_SsnFromClient(ssd->sd.wire_pkt) ? FILE_UPLOAD : FILE_DOWNLOAD;
+        DCE2_Smb2ProcessFileData(ssd, data_ptr, data_len, dir);
         ssd->ftracker.tracker.file.file_offset += data_len;
     }
 }
index 0dea0d39d664c9821dcdc67feba0509357ef9492..848cb95bf6d5675bb51c351814915d3ce62c3dc3 100644 (file)
@@ -431,10 +431,8 @@ static bool set_smb_invalid_shares(dce2SmbProtoConf& config, Value& v)
 
 bool Dce2SmbModule::set(const char*, Value& v, SnortConfig*)
 {
-    if (dce2_set_common_config(v,config.common))
+    if (dce2_set_co_config(v,config.common))
         return true;
-    else if ( v.is("reassemble_threshold") )
-        config.co_reassemble_threshold = v.get_long();
     else if ( v.is("smb_fingerprint_policy") )
         config.smb_fingerprint_policy = (dce2SmbFingerprintPolicy)v.get_long();
     else if ( v.is("smb_max_chain") )
@@ -466,9 +464,7 @@ void print_dce2_smb_conf(dce2SmbProtoConf& config)
 {
     LogMessage("DCE SMB config: \n");
 
-    print_dce2_common_config(config.common);
-    LogMessage("    Reassemble Threshold : %d\n",
-        config.co_reassemble_threshold);
+    print_dce2_co_config(config.common);
     LogMessage("    SMB fingerprint policy : %s\n",
         dce2SmbFingerprintPolicyStrings[config.smb_fingerprint_policy]);
 
index ca7dfc9cbda043eb8415fad58e0a92fa4d7de45b..f9be762ac3597bc4c361e2cd4772daadca172f50 100644 (file)
@@ -55,8 +55,7 @@ struct dce2SmbShare
 
 struct dce2SmbProtoConf
 {
-    dce2CommonProtoConf common;
-    uint16_t co_reassemble_threshold;
+    dce2CoProtoConf common;
     dce2SmbFingerprintPolicy smb_fingerprint_policy;
     uint8_t smb_max_chain;
     uint8_t smb_max_compound;
index 0f783ad75d3a4c10c921f7337c7b420b0eaf6b12..ba5f16f7215e397d38f9f2720dfc66a2aae6aa09 100644 (file)
@@ -23,7 +23,6 @@
 #define DCE_SMB_PAF_H
 
 #include "main/snort_types.h"
-#include "stream/stream_api.h"
 #include "stream/stream_splitter.h"
 
 #define DCE2_SMB_PAF_SHIFT(x64, x8) { x64 <<= 8; x64 |= (uint64_t)x8; }
index 604d781796625234d97907716cbac137818994a3..45c7828d37c0af8e0e7568a9538982acd48a79c6 100644 (file)
@@ -61,9 +61,7 @@ unsigned Dce2TcpFlowData::flow_id = 0;
 
 DCE2_TcpSsnData* get_dce2_tcp_session_data(Flow* flow)
 {
-    Dce2TcpFlowData* fd = (Dce2TcpFlowData*)flow->get_application_data(
-        Dce2TcpFlowData::flow_id);
-
+    Dce2TcpFlowData* fd = (Dce2TcpFlowData*)flow->get_flow_data(Dce2TcpFlowData::flow_id);
     return fd ? &fd->dce2_tcp_session : nullptr;
 }
 
@@ -72,7 +70,7 @@ static DCE2_TcpSsnData* set_new_dce2_tcp_session(Packet* p)
     Dce2TcpFlowData* fd = new Dce2TcpFlowData;
 
     memset(&fd->dce2_tcp_session,0,sizeof(DCE2_TcpSsnData));
-    p->flow->set_application_data(fd);
+    p->flow->set_flow_data(fd);
     return(&fd->dce2_tcp_session);
 }
 
index 3ffbe5aa2863f125f609819d469b5cab56180a5e..30f82d57b2c92e285405cb040d9b8e2faffb0a8c 100644 (file)
@@ -178,13 +178,10 @@ ProfileStats* Dce2TcpModule::get_profile(
 
 bool Dce2TcpModule::set(const char*, Value& v, SnortConfig*)
 {
-    if (dce2_set_common_config(v,config.common))
+    if (dce2_set_co_config(v,config.common))
         return true;
-    else if ( v.is("reassemble_threshold") )
-        config.co_reassemble_threshold = v.get_long();
-    else
-        return false;
-    return true;
+    
+       return false;
 }
 
 void Dce2TcpModule::get_data(dce2TcpProtoConf& dce2_tcp_config)
@@ -195,9 +192,6 @@ void Dce2TcpModule::get_data(dce2TcpProtoConf& dce2_tcp_config)
 void print_dce2_tcp_conf(dce2TcpProtoConf& config)
 {
     LogMessage("DCE TCP config: \n");
-
-    print_dce2_common_config(config.common);
-    LogMessage("    Reassemble Threshold : %d\n",
-        config.co_reassemble_threshold);
+    print_dce2_co_config(config.common);
 }
 
index c7de6b9affad4941718639424f4d56906a42a9e1..f97d80abe673dbae142b3aca49e29e313bb40e1a 100644 (file)
@@ -28,8 +28,7 @@ struct SnortConfig;
 
 struct dce2TcpProtoConf
 {
-    dce2CommonProtoConf common;
-    uint16_t co_reassemble_threshold;
+    dce2CoProtoConf common;
 };
 
 class Dce2TcpModule : public Module
index 8a10bfe4cb7a15e592619d1b74042fc5321b7a39..9f6c775afbae241893004dc49c3a06af3403d802 100644 (file)
@@ -24,7 +24,6 @@
 
 #include "dce_common.h"
 #include "main/snort_types.h"
-#include "stream/stream_api.h"
 #include "stream/stream_splitter.h"
 
 #define DCE2_DEBUG__PAF_START_MSG_TCP  "DCE/RPC over TCP PAF ====================================="
diff --git a/src/service_inspectors/dce_rpc/dce_udp.cc b/src/service_inspectors/dce_rpc/dce_udp.cc
new file mode 100644 (file)
index 0000000..4e49971
--- /dev/null
@@ -0,0 +1,151 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2016 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_udp.cc author Maya Dagon <mdagon@cisco.com>
+// based on work by Todd Wease
+
+#include "dce_udp.h"
+#include "dce_udp_module.h"
+#include "main/snort_debug.h"
+#include "detection/detect.h"
+#include "log/messages.h"
+#include "protocols/packet_manager.h"
+#include "utils/util.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_session;
+THREAD_LOCAL ProfileStats dce2_udp_pstat_new_session;
+THREAD_LOCAL ProfileStats dce2_udp_pstat_detect;
+THREAD_LOCAL ProfileStats dce2_udp_pstat_log;
+THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_acts;
+THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_frag;
+THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_reass;
+
+//-------------------------------------------------------------------------
+// class stuff
+//-------------------------------------------------------------------------
+Dce2UdpFlowData::Dce2UdpFlowData() : FlowData(flow_id)
+{
+}
+
+Dce2UdpFlowData::~Dce2UdpFlowData()
+{
+    // FIXIT-M add cl_tracker cleanup
+}
+
+unsigned Dce2UdpFlowData::flow_id = 0;
+
+class Dce2Udp : public Inspector
+{
+public:
+    Dce2Udp(dce2UdpProtoConf&);
+    void show(SnortConfig*) override;
+    void eval(Packet*) override;
+
+private:
+    dce2UdpProtoConf config;
+};
+
+Dce2Udp::Dce2Udp(dce2UdpProtoConf& pc)
+{
+    config = pc;
+}
+
+void Dce2Udp::show(SnortConfig*)
+{
+    print_dce2_udp_conf(config);
+}
+
+void Dce2Udp::eval(Packet*)
+{
+}
+
+//-------------------------------------------------------------------------
+// api stuff
+//-------------------------------------------------------------------------
+
+static Module* mod_ctor()
+{
+    return new Dce2UdpModule;
+}
+
+static void mod_dtor(Module* m)
+{
+    delete m;
+}
+
+static Inspector* dce2_udp_ctor(Module* m)
+{
+    Dce2UdpModule* mod = (Dce2UdpModule*)m;
+    dce2UdpProtoConf config;
+    mod->get_data(config);
+    return new Dce2Udp(config);
+}
+
+static void dce2_udp_dtor(Inspector* p)
+{
+    delete p;
+}
+
+static void dce2_udp_init()
+{
+    Dce2UdpFlowData::init();
+}
+
+static void dce2_udp_thread_init()
+{
+    dce2_udp_inspector_instances++;
+}
+
+static void dce2_udp_thread_term()
+{
+    dce2_udp_inspector_instances--;
+}
+
+const InspectApi dce2_udp_api =
+{
+    {
+        PT_INSPECTOR,
+        sizeof(InspectApi),
+        INSAPI_VERSION,
+        0,
+        API_RESERVED,
+        API_OPTIONS,
+        DCE2_UDP_NAME,
+        DCE2_UDP_HELP,
+        mod_ctor,
+        mod_dtor
+    },
+    IT_SERVICE,
+    (uint16_t)PktType::UDP,
+    nullptr,  // buffers
+    "dce_udp",
+    dce2_udp_init,
+    nullptr, // pterm
+    dce2_udp_thread_init, // tinit
+    dce2_udp_thread_term, // tterm
+    dce2_udp_ctor,
+    dce2_udp_dtor,
+    nullptr, // ssn
+    nullptr  // reset
+};
+
diff --git a/src/service_inspectors/dce_rpc/dce_udp.h b/src/service_inspectors/dce_rpc/dce_udp.h
new file mode 100644 (file)
index 0000000..ccf38cd
--- /dev/null
@@ -0,0 +1,106 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2016 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_tcp.h author Maya Dagon <mdagon@cisco.com>
+// based on work by Todd Wease
+
+#ifndef DCE_UDP_H
+#define DCE_UDP_H
+
+#include "dce_common.h"
+#include "dce_list.h"
+#include "protocols/packet.h"
+#include "profiler/profiler.h"
+#include "framework/counts.h"
+
+#define DCE2_UDP_NAME "dce_udp"
+#define DCE2_UDP_HELP "dce over udp inspection"
+
+struct dce2UdpStats
+{
+    /* The common stats block has to be at the beginning followed
+       by the protocol specific stats */
+
+    /*common stats -defined in common.h*/
+    PegCount events;
+    PegCount sessions_aborted;
+    PegCount bad_autodetects;
+
+    /*DCE UDP specific*/
+    PegCount udp_sessions;
+    PegCount udp_pkts;
+    PegCount cl_pkts;
+    PegCount cl_request;
+    PegCount cl_ack;
+    PegCount cl_cancel;
+    PegCount cl_cli_fack;
+    PegCount cl_ping;
+    PegCount cl_response;
+    PegCount cl_reject;
+    PegCount cl_cancel_ack;
+    PegCount cl_srv_fack;
+    PegCount cl_fault;
+    PegCount cl_nocall;
+    PegCount cl_working;
+    PegCount cl_other_req;
+    PegCount cl_other_resp;
+    PegCount cl_fragments;
+    PegCount cl_max_frag_size;
+    PegCount cl_frag_reassembled;
+    PegCount cl_max_seqnum;
+};
+
+extern THREAD_LOCAL dce2UdpStats dce2_udp_stats;
+extern THREAD_LOCAL ProfileStats dce2_udp_pstat_main;
+extern THREAD_LOCAL ProfileStats dce2_udp_pstat_session;
+extern THREAD_LOCAL ProfileStats dce2_udp_pstat_new_session;
+extern THREAD_LOCAL ProfileStats dce2_udp_pstat_detect;
+extern THREAD_LOCAL ProfileStats dce2_udp_pstat_log;
+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;
+
+struct DCE2_ClTracker
+{
+    DCE2_List* act_trackers;  /* List of activity trackers */
+};
+
+struct DCE2_UdpSsnData
+{
+    DCE2_SsnData sd;  // This member must be first
+    DCE2_ClTracker cl_tracker;
+};
+
+class Dce2UdpFlowData : public FlowData
+{
+public:
+    Dce2UdpFlowData();
+    ~Dce2UdpFlowData();
+
+    static void init()
+    {
+        flow_id = FlowData::get_flow_id();
+    }
+
+public:
+    static unsigned flow_id;
+    DCE2_UdpSsnData dce2_udp_session;
+};
+
+#endif
+
diff --git a/src/service_inspectors/dce_rpc/dce_udp_module.cc b/src/service_inspectors/dce_rpc/dce_udp_module.cc
new file mode 100644 (file)
index 0000000..a21ad4a
--- /dev/null
@@ -0,0 +1,162 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2016 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_udp_module.cc author Maya Dagon <mdagon@cisco.com>
+
+#include "dce_udp_module.h"
+#include "dce_udp.h"
+#include "dce_common.h"
+#include "main/snort_config.h"
+
+using namespace std;
+
+static const Parameter s_params[] =
+{
+    { "disable_defrag", Parameter::PT_BOOL, nullptr, "false",
+      " Disable DCE/RPC defragmentation" },
+    { "max_frag_len", Parameter::PT_INT, "1514:65535", "65535",
+      " Maximum fragment size for defragmentation" },
+    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+static const RuleMap dce2_udp_rules[] =
+{
+    { DCE2_CL_BAD_MAJOR_VERSION, DCE2_CL_BAD_MAJOR_VERSION_STR },
+    { DCE2_CL_BAD_PDU_TYPE, DCE2_CL_BAD_PDU_TYPE_STR },
+    { DCE2_CL_DATA_LT_HDR, DCE2_CL_DATA_LT_HDR_STR },
+    { DCE2_CL_BAD_SEQ_NUM, DCE2_CL_BAD_SEQ_NUM_STR },
+    { 0, nullptr }
+};
+
+static const PegInfo dce2_udp_pegs[] =
+{
+    { "events", "total events" },
+    { "aborted sessions", "total aborted sessions" },
+    { "bad autodetects", "total bad autodetects" },
+    { "udp sessions", "total udp sessions" },
+    { "udp packets", "total udp packets" },
+    { "Requests", "total connection-less requests" },
+    { "Acks", "total connection-less acks" },
+    { "Cancels", "total connection-less cancels" },
+    { "Client facks", "total connection-less client facks" },
+    { "Ping", "total connection-less ping" },
+    { "Responses", "total connection-less responses" },
+    { "Rejects", "total connection-less rejects" },
+    { "Cancel acks", "total connection-less cancel acks" },
+    { "Server facks", "total connection-less server facks" },
+    { "Faults", "total connection-less faults" },
+    { "No calls", "total connection-less no calls" },
+    { "Working", "total connection-less working" },
+    { "Other requests", "total connection-less other requests" },
+    { "Other responses", "total connection-less other responses" },
+    { "Fragments", "total connection-less fragments" },
+    { "Max fragment size",
+      "connection-less maximum fragment size" },
+    { "Frags reassembled",
+      "total connection-less fragments reassembled" },
+    { "Max seqnum",
+      "max connection-less seqnum" },
+    { nullptr, nullptr }
+};
+
+Dce2UdpModule::Dce2UdpModule() : Module(DCE2_UDP_NAME, DCE2_UDP_HELP, s_params)
+{
+}
+
+const RuleMap* Dce2UdpModule::get_rules() const
+{
+    return dce2_udp_rules;
+}
+
+const PegInfo* Dce2UdpModule::get_pegs() const
+{
+    return dce2_udp_pegs;
+}
+
+PegCount* Dce2UdpModule::get_counts() const
+{
+    return (PegCount*)&dce2_udp_stats;
+}
+
+ProfileStats* Dce2UdpModule::get_profile(
+    unsigned index, const char*& name, const char*& parent) const
+{
+    switch ( index )
+    {
+    case 0:
+        name = "dce_udp_main";
+        parent = nullptr;
+        return &dce2_udp_pstat_main;
+
+    case 1:
+        name = "dce_udp_session";
+        parent = "dce_udp_main";
+        return &dce2_udp_pstat_session;
+
+    case 2:
+        name = "dce_udp_new_session";
+        parent = "dce_udp_session";
+        return &dce2_udp_pstat_new_session;
+
+    case 3:
+        name = "dce_udp_detect";
+        parent = "dce_udp_main";
+        return &dce2_udp_pstat_detect;
+
+    case 4:
+        name = "dce_udp_log";
+        parent = "dce_udp_main";
+        return &dce2_udp_pstat_log;
+
+    case 5:
+        name = "dce_udp_cl_acts";
+        parent = "dce_udp_main";
+        return &dce2_udp_pstat_cl_acts;
+
+    case 6:
+        name = "dce_udp_cl_frag";
+        parent = "dce_udp_main";
+        return &dce2_udp_pstat_cl_frag;
+
+    case 7:
+        name = "dce_udp_cl_reass";
+        parent = "dce_udp_main";
+        return &dce2_udp_pstat_cl_reass;
+    }
+    return nullptr;
+}
+
+bool Dce2UdpModule::set(const char*, Value& v, SnortConfig*)
+{
+    if (dce2_set_common_config(v,config.common))
+        return true;
+    else
+        return false;
+}
+
+void Dce2UdpModule::get_data(dce2UdpProtoConf& dce2_udp_config)
+{
+    dce2_udp_config = config;
+}
+
+void print_dce2_udp_conf(dce2UdpProtoConf& config)
+{
+    LogMessage("DCE UDP config: \n");
+    print_dce2_common_config(config.common);
+}
+
diff --git a/src/service_inspectors/dce_rpc/dce_udp_module.h b/src/service_inspectors/dce_rpc/dce_udp_module.h
new file mode 100644 (file)
index 0000000..5b15a44
--- /dev/null
@@ -0,0 +1,71 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2016 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_udp_module.h author Maya Dagon <mdagon@cisco.com>
+
+#ifndef DCE2_UDP_MODULE_H
+#define DCE2_UDP_MODULE_H
+
+#include "dce_common.h"
+#include "framework/module.h"
+
+#define DCE2_CL_BAD_MAJOR_VERSION           40
+#define DCE2_CL_BAD_PDU_TYPE                41
+#define DCE2_CL_DATA_LT_HDR                 42
+#define DCE2_CL_BAD_SEQ_NUM                 43
+
+#define DCE2_CL_BAD_MAJOR_VERSION_STR  "Connection-less DCE/RPC - Invalid major version."
+#define DCE2_CL_BAD_PDU_TYPE_STR  "Connection-less DCE/RPC - Invalid pdu type."
+#define DCE2_CL_DATA_LT_HDR_STR \
+    "Connection-less DCE/RPC - Data length less than header size."
+#define DCE2_CL_BAD_SEQ_NUM_STR \
+    "Connection-less DCE/RPC - Bad sequence number."
+
+struct SnortConfig;
+
+struct dce2UdpProtoConf
+{
+    dce2CommonProtoConf common;
+};
+
+class Dce2UdpModule : public Module
+{
+public:
+    Dce2UdpModule();
+
+    bool set(const char*, Value&, SnortConfig*) override;
+
+    unsigned get_gid() const override
+    {
+        return GID_DCE2;
+    }
+
+    const RuleMap* get_rules() const override;
+    const PegInfo* get_pegs() const override;
+    PegCount* get_counts() const override;
+    ProfileStats* get_profile(unsigned, const char*&, const char*&) const override;
+    void get_data(dce2UdpProtoConf&);
+
+private:
+    dce2UdpProtoConf config;
+};
+
+void print_dce2_udp_conf(dce2UdpProtoConf& config);
+
+#endif
+
index 765e661e4d111d9eef12429ed098cf6b382966ac..72aca4631c753579676e2adb0d12f272d1c647fe 100644 (file)
 #include "framework/range.h"
 #include "detection/detect.h"
 #include "detection/detection_defines.h"
+#include "detection/pattern_match_data.h"
 #include "hash/sfhashfcn.h"
 #include "profiler/profiler.h"
+#include "target_based/snort_protocols.h"
+#include "main/snort_debug.h"
 
 //-------------------------------------------------------------------------
 // dcerpc2 interface rule options
@@ -199,19 +202,72 @@ class Dce2IfaceOption : public IpsOption
 {
 public:
     Dce2IfaceOption(RangeCheck iface_version, bool iface_any_frag, Uuid iface_uuid) :
-        IpsOption(s_name)
-    { version = iface_version; any_frag = iface_any_frag; uuid = iface_uuid; }
+        IpsOption(s_name), version(iface_version), any_frag(iface_any_frag), uuid(iface_uuid)
+    {
+        memset(&pmd, 0, sizeof(pmd));
+    }
 
     uint32_t hash() const override;
     bool operator==(const IpsOption&) const override;
     int eval(Cursor&, Packet*) override;
+    PatternMatchData* get_pattern(int proto, RuleDirection direction) override;
+    ~Dce2IfaceOption();
 
 private:
-    RangeCheck version;
-    bool any_frag;
-    Uuid uuid;
+    const RangeCheck version;
+    const bool any_frag;
+    const Uuid uuid;
+    PatternMatchData pmd;
 };
 
+Dce2IfaceOption::~Dce2IfaceOption()
+{
+    if ( pmd.pattern_buf)
+    {
+        snort_free((char*)pmd.pattern_buf);
+    }
+}
+
+PatternMatchData* Dce2IfaceOption::get_pattern(int proto, RuleDirection direction)
+{
+    if (pmd.pattern_buf)
+    {
+        return &pmd;
+    }
+
+    if (proto == SNORT_PROTO_TCP)
+    {
+        const char client_fp[] = "\x05\x00\x00";
+        const char server_fp[] = "\x05\x00\x02";
+        const char no_dir_fp[] = "\x05\x00";
+
+        switch (direction)
+        {
+        case RULE_FROM_CLIENT:
+            pmd.pattern_size = 3;
+            pmd.pattern_buf = (char*)snort_alloc(pmd.pattern_size);
+            memcpy((void*)pmd.pattern_buf, client_fp, pmd.pattern_size);
+            break;
+
+        case RULE_FROM_SERVER:
+            pmd.pattern_size = 3;
+            pmd.pattern_buf = (char*)snort_alloc(pmd.pattern_size);
+            memcpy((void*)pmd.pattern_buf, server_fp, pmd.pattern_size);
+            break;
+
+        default:
+            pmd.pattern_size = 2;
+            pmd.pattern_buf = (char*)snort_alloc(pmd.pattern_size);
+            memcpy((void*)pmd.pattern_buf, no_dir_fp, pmd.pattern_size);
+            break;
+        }
+        return &pmd;
+    }
+    // FIXIT-L add udp fast pattern
+
+    return nullptr;
+}
+
 uint32_t Dce2IfaceOption::hash() const
 {
     uint32_t a, b, c;
@@ -244,19 +300,11 @@ uint32_t Dce2IfaceOption::hash() const
 
 bool Dce2IfaceOption::operator==(const IpsOption& ips) const
 {
-    if ( strcmp(get_name(), ips.get_name()) )
-        return false;
-
-    const Dce2IfaceOption& rhs = (Dce2IfaceOption&)ips;
-
-    if ((DCE2_UuidCompare(&uuid, &rhs.uuid) == 0) &&
-        (version == rhs.version) &&
-        (any_frag == rhs.any_frag))
-    {
-        return true;
-    }
-
-    return false;
+    // FIXIT-L
+    // Fast pattern is calculated only after the entire rule is parsed.
+    // The rule option can be mistaken as a duplicate because we don't take the fast pattern into
+    // account. Instead of comparing values, make sure it is the same object.
+    return this == &ips;
 }
 
 int Dce2IfaceOption::eval(Cursor&, Packet* p)
index fd0f27ae69490a99d478a820b0bf3ed7a6bb8b65..e8a5150760d52e87b4f063536efdda2d6d1225b1 100644 (file)
@@ -36,17 +36,14 @@ unsigned Dnp3FlowData::flow_id = 0;
 
 static dnp3_session_data_t* get_session_data(Flow* flow)
 {
-    Dnp3FlowData* fd = (Dnp3FlowData*)flow->get_application_data(
-        Dnp3FlowData::flow_id);
-
+    Dnp3FlowData* fd = (Dnp3FlowData*)flow->get_flow_data(Dnp3FlowData::flow_id);
     return fd ? &fd->dnp3_session : nullptr;
 }
 
 static dnp3_session_data_t* set_new_dnp3_session(Packet* p)
 {
     Dnp3FlowData* fd = new Dnp3FlowData;
-
-    p->flow->set_application_data(fd);
+    p->flow->set_flow_data(fd);
     return(&fd->dnp3_session);
 }
 
index 012ca885c3c6413e0c286445a532205d5378a127..6ef0533c1dcd5d2145d8debc5614bdd421b89b6b 100644 (file)
@@ -25,7 +25,6 @@
 // Protocol aware flushing for DNP3.
 
 #include "main/snort_types.h"
-#include "stream/stream_api.h"
 #include "stream/stream_splitter.h"
 
 enum dnp3_paf_state
index 677473a81d6b19b2d593639427b71c34c4e35533..277181deaad566fe2018ae184dbc7d9980f2a982 100644 (file)
@@ -72,8 +72,7 @@ int Dnp3DataOption::eval(Cursor& c, Packet* p)
     if ((p->has_tcp_data() && !p->is_full_pdu()) || !p->flow || !p->dsize)
         return DETECTION_OPTION_NO_MATCH;
 
-    Dnp3FlowData* fd = (Dnp3FlowData*)p->flow->get_application_data(
-        Dnp3FlowData::flow_id);
+    Dnp3FlowData* fd = (Dnp3FlowData*)p->flow->get_flow_data(Dnp3FlowData::flow_id);
 
     if (!fd)
         return DETECTION_OPTION_NO_MATCH;
index 2a571a52bab79ebd38a2febe16dafe5ac8365984..00fa7e247a64d295ba5ee6d909fa747a6ee08d13 100644 (file)
@@ -79,8 +79,7 @@ int Dnp3FuncOption::eval(Cursor&, Packet* p)
     if ((p->has_tcp_data() && !p->is_full_pdu()) || !p->flow || !p->dsize)
         return DETECTION_OPTION_NO_MATCH;
 
-    Dnp3FlowData* fd = (Dnp3FlowData*)p->flow->get_application_data(
-        Dnp3FlowData::flow_id);
+    Dnp3FlowData* fd = (Dnp3FlowData*)p->flow->get_flow_data(Dnp3FlowData::flow_id);
 
     if (!fd)
         return DETECTION_OPTION_NO_MATCH;
index 9f0585f6f1effa2bc02b5cb7625467a14b701ea0..276944f77cdd2fe5652fd561c0594a69438c7b6b 100644 (file)
@@ -80,8 +80,7 @@ int Dnp3IndOption::eval(Cursor&, Packet* p)
     if ((p->has_tcp_data() && !p->is_full_pdu()) || !p->flow || !p->dsize)
         return DETECTION_OPTION_NO_MATCH;
 
-    Dnp3FlowData* fd = (Dnp3FlowData*)p->flow->get_application_data(
-        Dnp3FlowData::flow_id);
+    Dnp3FlowData* fd = (Dnp3FlowData*)p->flow->get_flow_data(Dnp3FlowData::flow_id);
 
     if (!fd)
         return DETECTION_OPTION_NO_MATCH;
index e63d76e15e25f7a3284916c130ed1385b970295c..910315a7362e772f0176fb7d7e5aa5e56b690536 100644 (file)
@@ -112,8 +112,7 @@ int Dnp3ObjOption::eval(Cursor&, Packet* p)
     if ((p->has_tcp_data() && !p->is_full_pdu()) || !p->flow || !p->dsize)
         return DETECTION_OPTION_NO_MATCH;
 
-    Dnp3FlowData* fd = (Dnp3FlowData*)p->flow->get_application_data(
-        Dnp3FlowData::flow_id);
+    Dnp3FlowData* fd = (Dnp3FlowData*)p->flow->get_flow_data(Dnp3FlowData::flow_id);
 
     if (!fd)
         return DETECTION_OPTION_NO_MATCH;
index 2af9ca68b17297447f3dde6de70ce7b2d7502978..734eb396d9ac7083e40d944d267299f74b49bb03 100644 (file)
@@ -37,9 +37,9 @@
 #include "main/snort_types.h"
 #include "main/snort_debug.h"
 #include "profiler/profiler.h"
-#include "stream/stream_api.h"
 #include "parser/parser.h"
 #include "framework/inspector.h"
+#include "stream/stream.h"
 #include "utils/sfsnprintfappend.h"
 
 #include "dns_module.h"
@@ -79,7 +79,7 @@ static DNSData* SetNewDNSData(Packet* p)
 
     fd = new DnsFlowData;
 
-    p->flow->set_application_data(fd);
+    p->flow->set_flow_data(fd);
     return &fd->session;
 }
 
@@ -107,9 +107,7 @@ static DNSData* get_dns_session_data(Packet* p, bool from_server)
         return &udpSessionData;
     }
 
-    fd = (DnsFlowData*)((p->flow)->get_application_data(
-        DnsFlowData::flow_id));
-
+    fd = (DnsFlowData*)((p->flow)->get_flow_data(DnsFlowData::flow_id));
     return fd ? &fd->session : NULL;
 }
 
@@ -1036,7 +1034,7 @@ static void snort_dns(Packet* p)
             return;
         }
 
-        if ( !stream.is_stream_sequenced(p->flow, SSN_DIR_FROM_CLIENT) )
+        if ( !Stream::is_stream_sequenced(p->flow, SSN_DIR_FROM_CLIENT) )
         {
             return;
         }
index e9869a3521b4537aabe465dc0e2ef848392fb625..0eae5dcf6c7d96c980a4c18df2ebe4dbab369d94 100644 (file)
@@ -23,7 +23,6 @@
 #define DNS_H
 
 #include "protocols/packet.h"
-#include "stream/stream_api.h"
 
 // Implementation header with definitions, datatypes and flowdata class for
 // DNS service inspector.
index 25afbdc5bab243fd37c4b34d902b53d9702eb466..f6483565e5d522fa6ac85e0c10a9e1456062a3e6 100644 (file)
@@ -84,7 +84,7 @@ static int SnortFTP(
         // FIXIT-L breaks target-based non-standard ports
         //if ( !ScPafEnabled() )
         /* Force flush of client side of stream  */
-        stream.flush_response(p);
+        Stream::flush_response(p);
     }
     else
     {
@@ -138,7 +138,7 @@ static int snort_ftp(Packet* p)
 
     if (p->flow)
     {
-        FtpFlowData* fd = (FtpFlowData*)p->flow->get_application_data(FtpFlowData::flow_id);
+        FtpFlowData* fd = (FtpFlowData*)p->flow->get_flow_data(FtpFlowData::flow_id);
         ft_ssn = fd ? &fd->session.ft_ssn : nullptr;
 
         if (ft_ssn != NULL)
@@ -171,7 +171,7 @@ static int snort_ftp(Packet* p)
             {
                 /* XXX - Not FTP or Telnet */
                 assert(false);
-                p->flow->free_application_data(FtpFlowData::flow_id);
+                p->flow->free_flow_data(FtpFlowData::flow_id);
                 return 0;
             }
         }
index 59a884ce38bb0a522004748f8e0067f75dcc870a..024a9717abb97a00b9e021da4dbd92f6caf416b7 100644 (file)
@@ -82,7 +82,7 @@ static int SnortFTPData(Packet* p)
         return -1;
 
     FtpDataFlowData* fd = (FtpDataFlowData*)
-        p->flow->get_application_data(FtpFlowData::flow_id);
+        p->flow->get_flow_data(FtpFlowData::flow_id);
 
     FTP_DATA_SESSION* data_ssn = fd ? &fd->session : nullptr;
 
@@ -100,7 +100,7 @@ static int SnortFTPData(Packet* p)
         /* FTP-Data session is in limbo, we need to lookup the control session
          * to figure out what to do. */
 
-        FtpFlowData* fd = (FtpFlowData*)stream.get_application_data_from_key(
+        FtpFlowData* fd = (FtpFlowData*)Stream::get_flow_data(
             &data_ssn->ftp_key, FtpFlowData::flow_id);
 
         FTP_SESSION* ftp_ssn = fd ? &fd->session : NULL;
@@ -167,7 +167,7 @@ FtpDataFlowData::FtpDataFlowData(Packet* p) : FlowData(flow_id)
     memset(&session, 0, sizeof(session));
 
     session.ft_ssn.proto = FTPP_SI_PROTO_FTP_DATA;
-    stream.populate_session_key(p, &session.ftp_key);
+    Stream::populate_flow_key(p, &session.ftp_key);
 }
 
 FtpDataFlowData::~FtpDataFlowData()
@@ -186,7 +186,7 @@ void FtpDataFlowData::handle_eof(Packet* p)
     initFilePosition(&data_ssn->position, get_file_processed_size(p->flow));
     finalFilePosition(&data_ssn->position);
 
-    stream.flush_request(p);
+    Stream::flush_request(p);
 
     if (!(data_ssn->packet_flags & FTPDATA_FLG_STOP))
     {
index 9c182a90b8ca91d17cc173d6b9aa13409a843829..7c27934db60acfbd5bb3d23ee6c53526baf8701f 100644 (file)
@@ -48,6 +48,7 @@
 #include "ftpp_return_codes.h"
 
 #include "sfip/sf_ip.h"
+#include "stream/stream.h"
 #include "utils/util.h"
 
 unsigned FtpFlowData::flow_id = 0;
@@ -101,7 +102,7 @@ static int TelnetStatefulsessionInspection(Packet* p,
 
         SiInput->pproto = FTPP_SI_PROTO_TELNET;
 
-        p->flow->set_application_data(fd);
+        p->flow->set_flow_data(fd);
 
         *Telnetsession = Newsession;
         return FTPP_SUCCESS;
@@ -340,7 +341,7 @@ void FTPFreesession(FTP_SESSION* ssn)
 bool FTPDataDirection(Packet* p, FTP_DATA_SESSION* ftpdata)
 {
     uint32_t direction;
-    uint32_t pktdir = stream.get_packet_direction(p);
+    uint32_t pktdir = Stream::get_packet_direction(p);
 
     if (ftpdata->mode == FTPP_XFER_ACTIVE)
         direction = ftpdata->direction ?  PKT_FROM_SERVER : PKT_FROM_CLIENT;
@@ -421,7 +422,7 @@ static int FTPStatefulsessionInspection(
             Newsession->client_conf = ClientConf;
             Newsession->server_conf = ServerConf;
 
-            p->flow->set_application_data(fd);
+            p->flow->set_flow_data(fd);
 
             *Ftpsession = Newsession;
             SiInput->pproto = FTPP_SI_PROTO_FTP;
@@ -493,7 +494,7 @@ int SetSiInput(FTPP_SI_INPUT* SiInput, Packet* p)
     /*
      * We now set the packet direction
      */
-    if (p->flow && stream.is_midstream(p->flow))
+    if (p->flow && Stream::is_midstream(p->flow))
     {
         SiInput->pdir = FTPP_SI_NO_MODE;
     }
index b0b36639f85abaf7d548a4d7f738a5a332f249d4..c3c0d691a3a0b944f0c90644d22b5342349454c1 100644 (file)
@@ -43,8 +43,8 @@
 #include "ftp_server.h"
 #include "protocols/packet.h"
 #include "file_api/file_api.h"
-#include "stream/stream_api.h"
 #include "flow/flow.h"
+#include "stream/stream.h"
 
 /*
  * These are the defines for the different types of
index 988e1e2dc2997372a1f20881d633bfd818ff2ab6..33194a8b25cafbfb1f93c505e0a09d37a2da36a8 100644 (file)
@@ -1068,7 +1068,7 @@ static int do_stateful_checks(FTP_SESSION* session, Packet* p,
                                 ftpdata->data_chan = session->server_conf->data_chan;
 
                                 /* Call into Streams to mark data channel as ftp-data */
-                                result = stream.set_application_protocol_id_expected(
+                                result = Stream::set_application_protocol_id_expected(
                                     &session->clientIP, session->clientPort,
                                     &session->serverIP, session->serverPort,
                                     p->type(), ftp_data_app_id, fd);
@@ -1080,7 +1080,7 @@ static int do_stateful_checks(FTP_SESSION* session, Packet* p,
                             {
                                 /* Call into Streams to mark data channel as something
                                  * to ignore. */
-                                stream.ignore_session(
+                                Stream::ignore_flow(
                                     &session->clientIP, session->clientPort,
                                     &session->serverIP, session->serverPort,
                                     p->type(), SSN_DIR_BOTH,
@@ -1140,7 +1140,7 @@ static int do_stateful_checks(FTP_SESSION* session, Packet* p,
                             ftpdata->data_chan = session->server_conf->data_chan;
 
                             /* Call into Streams to mark data channel as ftp-data */
-                            result = stream.set_application_protocol_id_expected(
+                            result = Stream::set_application_protocol_id_expected(
                                 &session->clientIP, session->clientPort,
                                 &session->serverIP, session->serverPort,
                                 p->type(), ftp_data_app_id, fd);
@@ -1152,7 +1152,7 @@ static int do_stateful_checks(FTP_SESSION* session, Packet* p,
                         {
                             /* Call into Streams to mark data channel as something
                              * to ignore. */
-                            stream.ignore_session(
+                            Stream::ignore_flow(
                                 &session->clientIP, session->clientPort,
                                 &session->serverIP, session->serverPort,
                                 p->type(), SSN_DIR_BOTH,
@@ -1381,7 +1381,7 @@ int check_ftp(FTP_SESSION* ftpssn, Packet* p, int iMode)
                     if (!ftpssn->server_conf->check_encrypted_data)
                     {
                         /* Mark this session & packet as one to ignore */
-                        stream.stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
+                        Stream::stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
                     }
                     DebugMessage(DEBUG_FTPTELNET,
                         "FTP client stream is now encrypted\n");
@@ -1460,7 +1460,7 @@ int check_ftp(FTP_SESSION* ftpssn, Packet* p, int iMode)
                     if (!ftpssn->server_conf->check_encrypted_data)
                     {
                         /* Mark this session & packet as one to ignore */
-                        stream.stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
+                        Stream::stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
                     }
                     DebugMessage(DEBUG_FTPTELNET,
                         "FTP server stream is now encrypted\n");
index 9148190fe80dbf48e039c753952a880a425735a3..fa7aec791fd24f9704fc3da6cf3bea37783a2b35 100644 (file)
@@ -127,7 +127,7 @@ int normalize_telnet(
         else
         {
             /* Okay, it wasn't an IAC also its a midstream pickup */
-            if (*read_ptr > 0x7F && stream.is_midstream(p->flow))
+            if (*read_ptr > 0x7F && Stream::is_midstream(p->flow))
             {
                 consec_8bit_chars++;
                 if (consec_8bit_chars > CONSECUTIVE_8BIT_THRESHOLD)
@@ -145,7 +145,7 @@ int normalize_telnet(
                         if (!tnssn->telnet_conf->check_encrypted_data)
                         {
                             /* Mark this session & packet as one to ignore */
-                            stream.stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
+                            Stream::stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
                             /* No point to do further normalization */
                             return FTPP_ALERT;
                         }
@@ -342,7 +342,7 @@ int normalize_telnet(
                         if (!tnssn->telnet_conf->check_encrypted_data)
                         {
                             /* Mark this session & packet as one to ignore */
-                            stream.stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
+                            Stream::stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
                             /* No point to do further normalization */
                             return FTPP_ALERT;
                         }
index 1da8a91d8c5998a8d0735f0c445a32c5225f01ed..b3f6816e028402ae2e657638361e5e7b5b87af6b 100644 (file)
@@ -111,7 +111,7 @@ static int snort_telnet(TELNET_PROTO_CONF* GlobalConf, Packet* p)
     if (p->flow)
     {
         TelnetFlowData* fd = (TelnetFlowData*)
-            p->flow->get_application_data(FtpFlowData::flow_id);
+            p->flow->get_flow_data(FtpFlowData::flow_id);
 
         ft_ssn = fd ? &fd->session.ft_ssn : nullptr;
 
@@ -140,7 +140,7 @@ static int snort_telnet(TELNET_PROTO_CONF* GlobalConf, Packet* p)
             else
             {
                 assert(false);
-                p->flow->free_application_data(FtpFlowData::flow_id);
+                p->flow->free_flow_data(FtpFlowData::flow_id);
                 return 0;
             }
         }
index f2180e74c8a19529a39dba8c10cab35e6b7e9c3b..10fe59ca8a2eec0942a219180029d155cfdb5e2e 100644 (file)
@@ -87,7 +87,7 @@ static inline int GTP_Process(Packet* p, GTP_Roptions* pRopts)
 static GTP_Roptions* GTPGetNewSession(Packet* packetp)
 {
     GtpFlowData* gfd = new GtpFlowData;
-    packetp->flow->set_application_data(gfd);
+    packetp->flow->set_flow_data(gfd);
 
     GTP_Roptions* pRopts = &gfd->ropts;
     gtp_stats.sessions++;
@@ -99,7 +99,7 @@ static GTP_Roptions* GTPGetNewSession(Packet* packetp)
 void GTPmain(Packet* packetp)
 {
     /* Attempt to get a previously allocated GTP block. */
-    GtpFlowData* gfd = (GtpFlowData*)packetp->flow->get_application_data(GtpFlowData::flow_id);
+    GtpFlowData* gfd = (GtpFlowData*)packetp->flow->get_flow_data(GtpFlowData::flow_id);
     GTP_Roptions* pRopts = gfd ? &gfd->ropts : nullptr;
 
     if ( !pRopts )
index 8edfcfb8e3a8e71a799dc29ea4cfe00db7f9bf4f..fe78c5831281d0a78620cabb8f56794e72eef1b6 100644 (file)
@@ -105,7 +105,7 @@ int GtpInfoOption::eval(Cursor& c, Packet* p)
     if ( !p or !p->flow )
         return DETECTION_OPTION_NO_MATCH;
 
-    GtpFlowData* gfd = (GtpFlowData*)p->flow->get_application_data(GtpFlowData::flow_id);
+    GtpFlowData* gfd = (GtpFlowData*)p->flow->get_flow_data(GtpFlowData::flow_id);
 
     if ( !gfd or !gfd->ropts.gtp_infoElements )
         return DETECTION_OPTION_NO_MATCH;
index baf6a926cd915e95a13c816782b83243e91d299c..b02c9228efe7fec748ea37828c2b8b4eba9c58a7 100644 (file)
@@ -105,7 +105,7 @@ int GtpTypeOption::eval(Cursor&, Packet* p)
     if ( !p or !p->flow )
         return DETECTION_OPTION_NO_MATCH;
 
-    GtpFlowData* gfd = (GtpFlowData*)p->flow->get_application_data(GtpFlowData::flow_id);
+    GtpFlowData* gfd = (GtpFlowData*)p->flow->get_flow_data(GtpFlowData::flow_id);
 
     if ( !gfd )
         return DETECTION_OPTION_NO_MATCH;
index b2f53f304a9333509878af60199d6cb153e2248e..b4388cf7684a69947611dbee7730f76b1316d239 100644 (file)
@@ -84,7 +84,7 @@ int GtpVersionOption::eval(Cursor&, Packet* p)
     if ( !p or !p->flow )
         return DETECTION_OPTION_NO_MATCH;
 
-    GtpFlowData* gfd = (GtpFlowData*)p->flow->get_application_data(GtpFlowData::flow_id);
+    GtpFlowData* gfd = (GtpFlowData*)p->flow->get_flow_data(GtpFlowData::flow_id);
 
     if ( gfd and version == gfd->ropts.gtp_version )
         return DETECTION_OPTION_MATCH;
index 2a48d58ac66996cd696cba216eef3e6e03872671..86546db08e1c5884a65349ada91bc2412a64c27d 100644 (file)
@@ -23,7 +23,7 @@
 #include <stdio.h>
 #include <zlib.h>
 
-#include "stream/stream_api.h"
+#include "flow/flow.h"
 #include "mime/file_mime_process.h"
 #include "utils/util_utf.h"
 
index e653bdaf99b1ab4e49e5710a26a67f803dde6153..0112179f4d9a1bf98d1aa7b7dd28b8e7aa46bf54 100644 (file)
@@ -23,7 +23,6 @@
 #include <stdio.h>
 
 #include "main/snort_types.h"
-#include "stream/stream_api.h"
 
 #include "http_enum.h"
 #include "http_msg_request.h"
@@ -126,8 +125,7 @@ bool HttpInspect::get_fp_buf(InspectionBuffer::Type ibt, Packet*, InspectionBuff
 const Field& HttpInspect::process(const uint8_t* data, const uint16_t dsize, Flow* const flow,
     SourceId source_id, bool buf_owner) const
 {
-    HttpFlowData* session_data = (HttpFlowData*)flow->get_application_data(
-        HttpFlowData::http_flow_id);
+    HttpFlowData* session_data = (HttpFlowData*)flow->get_flow_data(HttpFlowData::http_flow_id);
     assert(session_data != nullptr);
 
     HttpModule::increment_peg_counts(PEG_INSPECT);
@@ -196,7 +194,7 @@ void HttpInspect::clear(Packet* p)
     latest_section = nullptr;
 
     HttpFlowData* session_data =
-        (HttpFlowData*)p->flow->get_application_data(HttpFlowData::http_flow_id);
+        (HttpFlowData*)p->flow->get_flow_data(HttpFlowData::http_flow_id);
 
     if (session_data == nullptr)
         return;
index bc42421a5c31c6dead175b8d4d4affbd007e712d..02c5e610e75d5c82b3a3b3b3fdc224a29af2cca6 100644 (file)
@@ -20,7 +20,6 @@
 #ifndef HTTP_MSG_SECTION_H
 #define HTTP_MSG_SECTION_H
 
-#include "stream/stream_api.h"
 #include "detection/detection_util.h"
 
 #include "http_field.h"
index 6240488d885c4f58beea825e7b59eeddb41bd31a..4b14f0ae24ae1e30df24a2d379853c030fc19dd8 100644 (file)
@@ -207,8 +207,7 @@ const StreamBuffer* HttpStreamSplitter::reassemble(Flow* flow, unsigned total, u
 
     assert(total <= MAX_OCTETS);
 
-    HttpFlowData* session_data = (HttpFlowData*)flow->get_application_data(
-        HttpFlowData::http_flow_id);
+    HttpFlowData* session_data = (HttpFlowData*)flow->get_flow_data(HttpFlowData::http_flow_id);
     assert(session_data != nullptr);
 
 #ifdef REG_TEST
index c5acc658c3fe0e8965536e288a3bb85e238764f2..5f795fb60e4e4bda11132789f8393abde4aea5ff 100644 (file)
@@ -85,11 +85,11 @@ StreamSplitter::Status HttpStreamSplitter::scan(Flow* flow, const uint8_t* data,
     // This is the session state information we share with HttpInspect and store with stream. A
     // session is defined by a TCP connection. Since scan() is the first to see a new TCP
     // connection the new flow data object is created here.
-    HttpFlowData* session_data = (HttpFlowData*)flow->get_application_data(
-        HttpFlowData::http_flow_id);
+    HttpFlowData* session_data = (HttpFlowData*)flow->get_flow_data(HttpFlowData::http_flow_id);
+
     if (session_data == nullptr)
     {
-        flow->set_application_data(session_data = new HttpFlowData);
+        flow->set_flow_data(session_data = new HttpFlowData);
         HttpModule::increment_peg_counts(PEG_FLOW);
     }
 
@@ -205,9 +205,7 @@ StreamSplitter::Status HttpStreamSplitter::scan(Flow* flow, const uint8_t* data,
 
 bool HttpStreamSplitter::finish(Flow* flow)
 {
-    HttpFlowData* session_data = (HttpFlowData*)flow->get_application_data(
-        HttpFlowData::http_flow_id);
-
+    HttpFlowData* session_data = (HttpFlowData*)flow->get_flow_data(HttpFlowData::http_flow_id);
     assert(session_data != nullptr);
 
 #ifdef REG_TEST
index f992c8c9a292ad3af3dc03eff18d10202cc8313b..4085a3fe5d292db031e1c672aa6fbbe46ea4b48d 100644 (file)
@@ -34,7 +34,6 @@
 #include "main/snort_types.h"
 #include "main/snort_debug.h"
 #include "profiler/profiler.h"
-#include "stream/stream_api.h"
 #include "file_api/file_api.h"
 #include "parser/parser.h"
 #include "framework/inspector.h"
@@ -44,6 +43,7 @@
 #include "utils/util.h"
 #include "protocols/ssl.h"
 #include "mime/file_mime_process.h"
+#include "stream/stream.h"
 
 #include "imap_paf.h"
 #include "imap_module.h"
@@ -159,9 +159,7 @@ ImapFlowData::~ImapFlowData()
 unsigned ImapFlowData::flow_id = 0;
 static IMAPData* get_session_data(Flow* flow)
 {
-    ImapFlowData* fd = (ImapFlowData*)flow->get_application_data(
-        ImapFlowData::flow_id);
-
+    ImapFlowData* fd = (ImapFlowData*)flow->get_flow_data(ImapFlowData::flow_id);
     return fd ? &fd->session : NULL;
 }
 
@@ -170,7 +168,7 @@ static IMAPData* SetNewIMAPData(IMAP_PROTO_CONF* config, Packet* p)
     IMAPData* imap_ssn;
     ImapFlowData* fd = new ImapFlowData;
 
-    p->flow->set_application_data(fd);
+    p->flow->set_flow_data(fd);
     imap_ssn = &fd->session;
 
     imapstats.sessions++;
@@ -300,7 +298,7 @@ static int IMAP_Setup(Packet* p, IMAPData* ssn)
         (p->packet_flags & PKT_REBUILT_STREAM))
     {
         int missing_in_rebuilt =
-            stream.missing_in_reassembled(p->flow, SSN_DIR_FROM_CLIENT);
+            Stream::missing_in_reassembled(p->flow, SSN_DIR_FROM_CLIENT);
 
         if (ssn->session_flags & IMAP_FLAG_NEXT_STATE_UNKNOWN)
         {
@@ -647,7 +645,7 @@ static void snort_imap(IMAP_PROTO_CONF* config, Packet* p)
                 imap_ssn->state = STATE_TLS_DATA;
             }
             else if (!(p->flow->get_session_flags() & SSNFLAG_MIDSTREAM)
-                && !stream.missed_packets(p->flow, SSN_DIR_BOTH))
+                && !Stream::missed_packets(p->flow, SSN_DIR_BOTH))
             {
                 /* revert back to command state - assume server didn't accept STARTTLS */
                 imap_ssn->state = STATE_UNKNOWN;
index f4e08314d7d6c93ac68d82683a84df1152b38cea..0fddd3bead89e77808936b3404e880869a9d0499 100644 (file)
@@ -25,7 +25,7 @@
 // IMAP service inspector.
 
 #include "protocols/packet.h"
-#include "stream/stream_api.h"
+#include "stream/stream.h"
 #include "imap_config.h"
 
 // Direction packet is coming from, if we can figure it out
index d5b21b0f94a7932c82164b26a09ffd6e502bc7b6..69cfa76790516d74a1095e6b634bf11590c95238 100644 (file)
@@ -31,7 +31,7 @@ static inline ImapPafData* get_state(Flow* flow, bool c2s)
     if ( !flow )
         return nullptr;
 
-    ImapSplitter* s = (ImapSplitter*)stream.get_splitter(flow, c2s);
+    ImapSplitter* s = (ImapSplitter*)Stream::get_splitter(flow, c2s);
     return s ? &s->state : nullptr;
 }
 
index 88bffd2ab3f4fbdbda6fcb2ac6dc0025ba57be54..6f34e73bd62ad249ef545deb0a4d93f6dfc658bb 100644 (file)
@@ -25,7 +25,6 @@
 // Protocol aware flushing for IMAP
 
 #include "main/snort_types.h"
-#include "stream/stream_api.h"
 #include "stream/stream_splitter.h"
 #include "mime/file_mime_paf.h"
 
index db48c5f8cfa34ff1748923143ac7e28118eab2d8..0d9c9272454fda45f9f6d49d53483640669605ab 100644 (file)
@@ -131,7 +131,7 @@ int ModbusFuncOption::eval(Cursor&, Packet* p)
         return DETECTION_OPTION_NO_MATCH;
 
     ModbusFlowData* mfd =
-        (ModbusFlowData*)p->flow->get_application_data(ModbusFlowData::flow_id);
+        (ModbusFlowData*)p->flow->get_flow_data(ModbusFlowData::flow_id);
 
     if ( mfd and func == mfd->ssn_data.func )
         return DETECTION_OPTION_MATCH;
index e128b354d03dae6e53218b4dd8177357126b686a..a521015a3f2044eb17b5ec8ecbc2dac2a3e6008b 100644 (file)
@@ -83,7 +83,7 @@ int ModbusUnitOption::eval(Cursor&, Packet* p)
         return DETECTION_OPTION_NO_MATCH;
 
     ModbusFlowData* mfd =
-        (ModbusFlowData*)p->flow->get_application_data(ModbusFlowData::flow_id);
+        (ModbusFlowData*)p->flow->get_flow_data(ModbusFlowData::flow_id);
 
     if ( mfd and unit == mfd->ssn_data.unit )
         return DETECTION_OPTION_MATCH;
index 83af926cd917122a2af4ccffc675572c857f8e25..e7b0faf317e088b0d9134138742ea2c10391433a 100644 (file)
@@ -75,7 +75,7 @@ void Modbus::eval(Packet* p)
     assert(p->has_tcp_data());
 
     ModbusFlowData* mfd =
-        (ModbusFlowData*)p->flow->get_application_data(ModbusFlowData::flow_id);
+        (ModbusFlowData*)p->flow->get_flow_data(ModbusFlowData::flow_id);
 
     if ( !p->is_full_pdu() )
     {
@@ -93,7 +93,7 @@ void Modbus::eval(Packet* p)
     if ( !mfd )
     {
         mfd = new ModbusFlowData;
-        p->flow->set_application_data(mfd);
+        p->flow->set_flow_data(mfd);
         modbus_stats.sessions++;
     }
 
index 4dbe62e5cbf5ac0c6889eed1f147fada9196feee..444d58ad98d4be337eb60bd9c523fe0e2b8bcd63 100644 (file)
@@ -24,7 +24,6 @@
 #include "modbus.h"
 #include "modbus_module.h"
 #include "protocols/packet.h"
-#include "stream/stream_api.h"
 #include "events/event_queue.h"
 
 // FIXIT-L convert this stuff to a table and make configurable
@@ -406,7 +405,7 @@ bool ModbusDecode(Packet* p)
         return false;
 
     ModbusFlowData* mfd =
-        (ModbusFlowData*)p->flow->get_application_data(ModbusFlowData::flow_id);
+        (ModbusFlowData*)p->flow->get_flow_data(ModbusFlowData::flow_id);
 
     /* Lay the header struct over the payload */
     header = (modbus_header_t*)p->data;
index 6ad2721658b9df48b3cc8731fc2b8590102ab564..78db7a5dfb163092b0951e8ed6d86953e0173e12 100644 (file)
@@ -34,7 +34,6 @@
 #include "main/snort_types.h"
 #include "main/snort_debug.h"
 #include "profiler/profiler.h"
-#include "stream/stream_api.h"
 #include "parser/parser.h"
 #include "framework/inspector.h"
 #include "target_based/snort_protocols.h"
@@ -118,9 +117,7 @@ PopFlowData::~PopFlowData()
 unsigned PopFlowData::flow_id = 0;
 static POPData* get_session_data(Flow* flow)
 {
-    PopFlowData* fd = (PopFlowData*)flow->get_application_data(
-        PopFlowData::flow_id);
-
+    PopFlowData* fd = (PopFlowData*)flow->get_flow_data(PopFlowData::flow_id);
     return fd ? &fd->session : NULL;
 }
 
@@ -129,7 +126,7 @@ static POPData* SetNewPOPData(POP_PROTO_CONF* config, Packet* p)
     POPData* pop_ssn;
     PopFlowData* fd = new PopFlowData;
 
-    p->flow->set_application_data(fd);
+    p->flow->set_flow_data(fd);
     pop_ssn = &fd->session;
 
     popstats.sessions++;
@@ -257,7 +254,7 @@ static int POP_Setup(Packet* p, POPData* ssn)
         (p->packet_flags & PKT_REBUILT_STREAM))
     {
         int missing_in_rebuilt =
-            stream.missing_in_reassembled(p->flow, SSN_DIR_FROM_CLIENT);
+            Stream::missing_in_reassembled(p->flow, SSN_DIR_FROM_CLIENT);
 
         if (ssn->session_flags & POP_FLAG_NEXT_STATE_UNKNOWN)
         {
@@ -585,7 +582,7 @@ static void snort_pop(POP_PROTO_CONF* config, Packet* p)
                 pop_ssn->state = STATE_TLS_DATA;
             }
             else if (!(p->flow->get_session_flags() & SSNFLAG_MIDSTREAM)
-                && !stream.missed_packets(p->flow, SSN_DIR_BOTH))
+                && !Stream::missed_packets(p->flow, SSN_DIR_BOTH))
             {
                 /* revert back to command state - assume server didn't accept STARTTLS */
                 pop_ssn->state = STATE_UNKNOWN;
index 602a84d621ff5800929a144a0e58162abb9f55d1..ee91f18fad37d50223b67edc7ed789ee06192961 100644 (file)
@@ -25,7 +25,7 @@
 // POP service inspector.
 
 #include "protocols/packet.h"
-#include "stream/stream_api.h"
+#include "stream/stream.h"
 #include "pop_config.h"
 
 // Direction packet is coming from, if we can figure it out
index 2211c3d4776576cae91a4634c8188994a4097b45..650f35e3bb96fd5898ae971c2b250942d269140d 100644 (file)
@@ -32,7 +32,7 @@ static inline PopPafData* get_state(Flow* flow, bool c2s)
     if ( !flow )
         return nullptr;
 
-    PopSplitter* s = (PopSplitter*)stream.get_splitter(flow, c2s);
+    PopSplitter* s = (PopSplitter*)Stream::get_splitter(flow, c2s);
     return s ? &s->state : nullptr;
 }
 
index f7cc3f76d6cb8f4acb6194f8183264abadb69351..b611e6d24b073dd6d086d42b3a8086f59159fa06 100644 (file)
@@ -25,7 +25,6 @@
 // Protocol aware flushing for POP.
 
 #include "main/snort_types.h"
-#include "stream/stream_api.h"
 #include "stream/stream_splitter.h"
 #include "mime/file_mime_paf.h"
 
index aa7fe7815dd8c5310f6eeafe97965e3a58047dd4..110c7daf7c48e6bc9cc651a6b8ca073fdbd580e3 100644 (file)
 #include "profiler/profiler.h"
 #include "utils/util.h"
 #include "detection/detection_util.h"
-#include "stream/stream_api.h"
 #include "stream/stream_splitter.h"
 #include "target_based/snort_protocols.h"
 #include "protocols/tcp.h"
 #include "protocols/packet.h"
 #include "framework/data_bus.h"
 #include "framework/inspector.h"
+#include "stream/stream.h"
 #include "utils/safec.h"
 
 #include "rpc_module.h"
@@ -656,7 +656,7 @@ static RpcSsnData* RpcSsnDataNew(Packet* p)
     RpcSsnData* rsdata = &fd->session;
     rsdata->active = 1;
 
-    p->flow->set_application_data(fd);
+    p->flow->set_flow_data(fd);
 
     DebugFormat(DEBUG_RPC, "STATEFUL: Created new session: " "%p\n", (void*) rsdata);
     return rsdata;
@@ -985,8 +985,7 @@ void RpcDecode::eval(Packet* p)
 
     if ( p->flow )
     {
-        RpcFlowData* fd = (RpcFlowData*)p->flow->get_application_data(
-            RpcFlowData::flow_id);
+        RpcFlowData* fd = (RpcFlowData*)p->flow->get_flow_data(RpcFlowData::flow_id);
 
         if ( fd )
             rsdata = &fd->session;
@@ -994,7 +993,7 @@ void RpcDecode::eval(Packet* p)
 
     ++rdstats.total_packets;
 
-    if ( !rsdata && p->flow && !stream.is_midstream(p->flow) )
+    if ( !rsdata && p->flow && !Stream::is_midstream(p->flow) )
         rsdata = RpcSsnDataNew(p);
 
     if ( RpcSsnIsActive(rsdata) and (p->packet_flags & PKT_REBUILT_STREAM) )
index 719ebfc98fa08b11b6caf96beeee5ae22077b15b..d3a14a0044ce341121b2613842bcdb68bb1ebc47 100644 (file)
@@ -72,6 +72,7 @@ extern const BaseApi* ips_http_raw_status;
 extern const BaseApi* sin_bo;
 extern const BaseApi* sin_dce_smb;
 extern const BaseApi* sin_dce_tcp;
+extern const BaseApi* sin_dce_udp;
 extern const BaseApi* sin_dnp3;
 extern const BaseApi* sin_dns;
 extern const BaseApi* sin_ftp_client;
@@ -135,6 +136,7 @@ const BaseApi* service_inspectors[] =
     sin_bo,
     sin_dce_smb,
     sin_dce_tcp,
+    sin_dce_udp,
     sin_dnp3,
     sin_dns,
     sin_ftp_client,
index 9a740ecbb6a30ab45bdd9f86bc25b0558a915def..f181b6c9003e86c5730eeb53fc938b82e7fc6e6a 100644 (file)
@@ -32,7 +32,6 @@
 #include "main/snort_debug.h"
 #include "main/snort_config.h"
 #include "profiler/profiler.h"
-#include "stream/stream_api.h"
 #include "file_api/file_api.h"
 #include "parser/parser.h"
 #include "framework/inspector.h"
@@ -74,16 +73,14 @@ static SIPData* SetNewSIPData(Packet* p, SIP_PROTO_CONF* config)
         MaxSessionsAlerted = 0;
     }
     SipFlowData* fd = new SipFlowData;
-    p->flow->set_application_data(fd);
+    p->flow->set_flow_data(fd);
     numSessions++;
     return &fd->session;
 }
 
 SIPData* get_sip_session_data(Flow* flow)
 {
-    SipFlowData* fd = (SipFlowData*)flow->get_application_data(
-        SipFlowData::flow_id);
-
+    SipFlowData* fd = (SipFlowData*)flow->get_flow_data(SipFlowData::flow_id);
     return fd ? &fd->session : NULL;
 }
 
index 881ca9c9babac50585c58b90a687dbf11ad8659d..91374e3a5f3617656de6199aae7feedd8a829629 100644 (file)
@@ -22,7 +22,6 @@
 // Implementation header with definitions, datatypes and flowdata class for SIP service inspector.
 
 #include "protocols/packet.h"
-#include "stream/stream_api.h"
 #include "sip_config.h"
 #include "sip_dialog.h"
 #include "sip_parser.h"
index 47122c8fdb8d66a7650d45ff1866336fded90d7b..63c82be625b7b3e9f6fcab178b79a261546167eb 100644 (file)
 
 #include <assert.h>
 
+#include "framework/data_bus.h"
 #include "main/snort_types.h"
 #include "main/snort_debug.h"
 #include "main/snort_config.h"
+#include "stream/stream.h"
 #include "sfip/sf_ip.h"
-#include "stream/stream_api.h"
-#include "framework/data_bus.h"
 
 #include "sip_module.h"
 #include "sip.h"
@@ -408,7 +408,7 @@ static int SIP_ignoreChannels(SIP_DialogData* dialog, Packet* p, SIP_PROTO_CONF*
             sfip_to_str(&mdataB->maddress), mdataB->mport);
 
         /* Call into Streams to mark data channel as something to ignore. */
-        FlowData* fd = stream.get_application_data_from_ip_port(
+        FlowData* fd = Stream::get_flow_data(
             PktType::UDP, IpProtocol::UDP, &mdataA->maddress,mdataA->mport,
             &mdataB->maddress, mdataB->mport, 0, 0, p->pkth->address_space_id,
             SipFlowData::flow_id);
@@ -418,7 +418,7 @@ static int SIP_ignoreChannels(SIP_DialogData* dialog, Packet* p, SIP_PROTO_CONF*
         }
         else
         {
-            stream.ignore_session(&mdataA->maddress, mdataA->mport, &mdataB->maddress,
+            Stream::ignore_flow(&mdataA->maddress, mdataA->mport, &mdataB->maddress,
                 mdataB->mport, p->type(), SSN_DIR_BOTH, SipFlowData::flow_id);
         }
         sip_stats.ignoreChannels++;
@@ -694,7 +694,7 @@ static void sip_update_appid(const Packet* p, const SIPMsg* sipMsg, const SIP_Di
 
     sipEventData.packet = p;
 
-    if (stream.service_event_publish(PP_SIP, p->flow, SIP_EVENT_TYPE_SIP_DIALOG, &sipEventData)
+    if (Stream::service_event_publish(PP_SIP, p->flow, SIP_EVENT_TYPE_SIP_DIALOG, &sipEventData)
      == false)
      ErrorMessage("failed to publish to SIP_DIALOG\n");
 }
index 0d2ce75966e242d7349967bb04df6ae7079720e4..f0d132480693cc500482764c84fec1c21a34f829 100644 (file)
@@ -29,7 +29,6 @@
 #include "main/snort_types.h"
 #include "main/snort_debug.h"
 #include "profiler/profiler.h"
-#include "stream/stream_api.h"
 #include "file_api/file_api.h"
 #include "mime/file_mime_process.h"
 #include "parser/parser.h"
@@ -200,9 +199,7 @@ SmtpFlowData::~SmtpFlowData()
 unsigned SmtpFlowData::flow_id = 0;
 static SMTPData* get_session_data(Flow* flow)
 {
-    SmtpFlowData* fd = (SmtpFlowData*)flow->get_application_data(
-        SmtpFlowData::flow_id);
-
+    SmtpFlowData* fd = (SmtpFlowData*)flow->get_flow_data(SmtpFlowData::flow_id);
     return fd ? &fd->session : NULL;
 }
 
@@ -211,7 +208,7 @@ static SMTPData* SetNewSMTPData(SMTP_PROTO_CONF* config, Packet* p)
     SMTPData* smtp_ssn;
     SmtpFlowData* fd = new SmtpFlowData;
 
-    p->flow->set_application_data(fd);
+    p->flow->set_flow_data(fd);
     smtp_ssn = &fd->session;
 
     smtpstats.sessions++;
@@ -223,7 +220,7 @@ static SMTPData* SetNewSMTPData(SMTP_PROTO_CONF* config, Packet* p)
     smtp_ssn->mime_ssn->config = config;
     smtp_ssn->mime_ssn->set_mime_stats(&(smtpstats.mime_stats));
 
-    if(stream.is_midstream(p->flow))
+    if(Stream::is_midstream(p->flow))
     {
         DebugMessage(DEBUG_SMTP, "Got midstream packet - "
             "setting state to unknown\n");
@@ -548,7 +545,7 @@ static int SMTP_Setup(Packet* p, SMTPData* ssn)
         (p->packet_flags & PKT_REBUILT_STREAM))
     {
         int missing_in_rebuilt =
-            stream.missing_in_reassembled(p->flow, SSN_DIR_FROM_CLIENT);
+            Stream::missing_in_reassembled(p->flow, SSN_DIR_FROM_CLIENT);
 
         if (ssn->session_flags & SMTP_FLAG_NEXT_STATE_UNKNOWN)
         {
@@ -1097,7 +1094,7 @@ static void SMTP_ProcessServerPacket(SMTP_PROTO_CONF* config, Packet* p, SMTPDat
             smtp_ssn->state = STATE_TLS_DATA;
         }
         else if (!(p->flow->get_session_flags() & SSNFLAG_MIDSTREAM)
-            && !stream.missed_packets(p->flow, SSN_DIR_BOTH))
+            && !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)
@@ -1287,7 +1284,7 @@ static void snort_smtp(SMTP_PROTO_CONF* config, Packet* p)
             /* if we're ignoring tls data, set a zero length alt buffer */
             if (config->ignore_tls_data)
             {
-                stream.stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
+                Stream::stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
                 return;
             }
         }
@@ -1392,10 +1389,10 @@ static int SMTP_GetEmailHdrs(Flow* flow, uint8_t** buf, uint32_t* len, uint32_t*
 
 static void SMTP_RegXtraDataFuncs(SMTP_PROTO_CONF* config)
 {
-    config->xtra_filename_id = stream.reg_xtra_data_cb(SMTP_GetFilename);
-    config->xtra_mfrom_id = stream.reg_xtra_data_cb(SMTP_GetMailFrom);
-    config->xtra_rcptto_id = stream.reg_xtra_data_cb(SMTP_GetRcptTo);
-    config->xtra_ehdrs_id = stream.reg_xtra_data_cb(SMTP_GetEmailHdrs);
+    config->xtra_filename_id = Stream::reg_xtra_data_cb(SMTP_GetFilename);
+    config->xtra_mfrom_id = Stream::reg_xtra_data_cb(SMTP_GetMailFrom);
+    config->xtra_rcptto_id = Stream::reg_xtra_data_cb(SMTP_GetRcptTo);
+    config->xtra_ehdrs_id = Stream::reg_xtra_data_cb(SMTP_GetEmailHdrs);
 }
 
 int SmtpMime::handle_header_line(const uint8_t* ptr, const uint8_t* eol,
index 46275851b2a37dd03652edac3972dec3443b6522..5cb6c0cf132afcb316db6df65105d2f607107c18 100644 (file)
@@ -24,9 +24,9 @@
 // Implementation header with definitions, datatypes and flowdata class for
 // SMTP service inspector.
 
-#include "protocols/packet.h"
-#include "stream/stream_api.h"
 #include "main/thread.h"
+#include "protocols/packet.h"
+#include "stream/stream.h"
 #include "smtp_config.h"
 
 // Direction packet is coming from, if we can figure it out
index 7d1902b61cb995bbefa57702c05608858976fedf..729c9afaf3f4f0fa2821f16beae28a84831313c1 100644 (file)
@@ -66,7 +66,7 @@ static inline SmtpPafData* get_state(Flow* flow, bool c2s)
     if ( !flow )
         return nullptr;
 
-    SmtpSplitter* s = (SmtpSplitter*)stream.get_splitter(flow, c2s);
+    SmtpSplitter* s = (SmtpSplitter*)Stream::get_splitter(flow, c2s);
     return s ? &s->state : nullptr;
 }
 
index 5ec6dc58f1451e65e0a0238e066288fcf79d95b9..53aad5abda3e377b9b5753ec9c9b185d11b77b97 100644 (file)
@@ -24,7 +24,6 @@
 // Protocol aware flushing for SMTP
 
 #include "main/snort_types.h"
-#include "stream/stream_api.h"
 #include "stream/stream_splitter.h"
 #include "mime/file_mime_paf.h"
 
index 15d181798b02e00ff88c31ee4c73bb82eb89ad8e..9bb4536c7b6b28182a0c10c51974c7e7c2fc79a7 100644 (file)
@@ -31,7 +31,6 @@
 
 #include "smtp.h"
 #include "smtp_config.h"
-#include "stream/stream_api.h"
 #include "detection/detection_util.h"
 #include "utils/safec.h"
 
@@ -129,22 +128,22 @@ void SMTP_LogFuncs(SMTP_PROTO_CONF* config, Packet* p, MimeSession* mime_ssn)
 
     if (log->is_file_name_present())
     {
-        stream.set_extra_data(p->flow, p, config->xtra_filename_id);
+        Stream::set_extra_data(p->flow, p, config->xtra_filename_id);
     }
 
     if (log->is_email_from_present())
     {
-        stream.set_extra_data(p->flow, p, config->xtra_mfrom_id);
+        Stream::set_extra_data(p->flow, p, config->xtra_mfrom_id);
     }
 
     if (log->is_email_to_present())
     {
-        stream.set_extra_data(p->flow, p, config->xtra_rcptto_id);
+        Stream::set_extra_data(p->flow, p, config->xtra_rcptto_id);
     }
 
     if (log->is_email_hdrs_present())
     {
-        stream.set_extra_data(p->flow, p, config->xtra_ehdrs_id);
+        Stream::set_extra_data(p->flow, p, config->xtra_ehdrs_id);
     }
 }
 
index 8d722e32eaf6496678a44000407d2c5c7a12e3f5..2bd8fdfe7102cf8724aa2079e750fb25f09abf89 100644 (file)
 #include <sys/types.h>
 
 #include "events/event_queue.h"
+#include "file_api/file_api.h"
+#include "framework/inspector.h"
 #include "log/messages.h"
 #include "main/snort_types.h"
 #include "main/snort_debug.h"
-#include "profiler/profiler.h"
-#include "stream/stream_api.h"
-#include "file_api/file_api.h"
 #include "parser/parser.h"
-#include "framework/inspector.h"
+#include "profiler/profiler.h"
 #include "utils/sfsnprintfappend.h"
 #include "target_based/snort_protocols.h"
 
@@ -64,15 +63,13 @@ unsigned SshFlowData::flow_id = 0;
 static SSHData* SetNewSSHData(Packet* p)
 {
     SshFlowData* fd = new SshFlowData;
-    p->flow->set_application_data(fd);
+    p->flow->set_flow_data(fd);
     return &fd->session;
 }
 
 static SSHData* get_session_data(Flow* flow)
 {
-    SshFlowData* fd = (SshFlowData*)flow->get_application_data(
-        SshFlowData::flow_id);
-
+    SshFlowData* fd = (SshFlowData*)flow->get_flow_data(SshFlowData::flow_id);
     return fd ? &fd->session : NULL;
 }
 
@@ -175,7 +172,7 @@ static void snort_ssh(SSH_PROTO_CONF* config, Packet* p)
     // means we've already missed packets) set missed packets flag and make
     // sure we don't do any more reassembly on this session
     if ((p->flow->get_session_flags() & SSNFLAG_MIDSTREAM)
-        || stream.missed_packets(p->flow, SSN_DIR_BOTH))
+        || Stream::missed_packets(p->flow, SSN_DIR_BOTH))
     {
         // Order only matters if the packets are not encrypted
         if ( !(sessp->state_flags & SSH_FLG_SESS_ENCRYPTED ))
@@ -272,7 +269,7 @@ static void snort_ssh(SSH_PROTO_CONF* config, Packet* p)
                     else
                         SnortEventqAdd(GID_SSH, SSH_EVENT_RESPOVERFLOW);
 
-                    stream.stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
+                    Stream::stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
                 }
             }
 
@@ -292,7 +289,7 @@ static void snort_ssh(SSH_PROTO_CONF* config, Packet* p)
             // and therefore cannot be used late in an
             // encrypted session. For performance purposes,
             // stop examining this session.
-            stream.stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
+            Stream::stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0);
         }
     }
 }
index 464e763e53bff868e31a38d36e7ea11fc8e28543..c6e41433aafa1e226d12d8f720f211d3800c1646 100644 (file)
@@ -31,7 +31,7 @@
 // packets appear malformed/spoofed.
 
 #include "protocols/packet.h"
-#include "stream/stream_api.h"
+#include "stream/stream.h"
 #include "ssh_config.h"
 
 // Per-session data block containing current state
index 94993d3fdd2cbd969cc8ee02e8631a15467b4d82..61bfa0063c51abef44c22c5607f87d78da4f21ae 100644 (file)
 #include "main/snort_types.h"
 #include "main/snort_debug.h"
 #include "profiler/profiler.h"
-#include "stream/stream_api.h"
 #include "parser/parser.h"
 #include "framework/inspector.h"
 #include "utils/sfsnprintfappend.h"
 #include "target_based/snort_protocols.h"
 #include "detection/detect.h"
 #include "protocols/ssl.h"
+#include "stream/stream.h"
 
 #include "ssl_module.h"
 
@@ -85,15 +85,13 @@ const PegInfo ssl_peg_names[] =
 static SSLData* SetNewSSLData(Packet* p)
 {
     SslFlowData* fd = new SslFlowData;
-    p->flow->set_application_data(fd);
+    p->flow->set_flow_data(fd);
     return &fd->session;
 }
 
 SSLData* get_ssl_session_data(Flow* flow)
 {
-    SslFlowData* fd = (SslFlowData*)flow->get_application_data(
-        SslFlowData::flow_id);
-
+    SslFlowData* fd = (SslFlowData*)flow->get_flow_data(SslFlowData::flow_id);
     return fd ? &fd->session : NULL;
 }
 
@@ -165,7 +163,7 @@ static inline bool SSLPP_is_encrypted(SSL_PROTO_CONF* config, uint32_t ssl_flags
         /* Check if we're either midstream or if packets were missed after the
          *          * connection was established */
         else if ((packet->flow->get_session_flags() & SSNFLAG_MIDSTREAM) ||
-            (stream.missed_packets(packet->flow, SSN_DIR_BOTH)))
+            (Stream::missed_packets(packet->flow, SSN_DIR_BOTH)))
         {
             if ((ssl_flags & (SSL_CAPP_FLAG | SSL_SAPP_FLAG)) == (SSL_CAPP_FLAG | SSL_SAPP_FLAG))
             {
@@ -238,7 +236,7 @@ static inline uint32_t SSLPP_process_app(SSL_PROTO_CONF* config, uint32_t ssn_fl
         if (!config->max_heartbeat_len)
         {
             DebugMessage(DEBUG_SSL, "STOPPING INSPECTION (process_app)\n");
-            stream.stop_inspection(packet->flow, packet, SSN_DIR_BOTH, -1, 0);
+            Stream::stop_inspection(packet->flow, packet, SSN_DIR_BOTH, -1, 0);
             sslstats.stopped++;
         }
         else if (!(new_flags & SSL_HEARTBEAT_SEEN))
@@ -266,7 +264,7 @@ static inline void SSLPP_process_other(SSL_PROTO_CONF* config, SSLData* sd, uint
         if (!config->max_heartbeat_len)
         {
             DebugMessage(DEBUG_SSL, "STOPPING INSPECTION (process_other)\n");
-            stream.stop_inspection(packet->flow, packet, SSN_DIR_BOTH, -1, 0);
+            Stream::stop_inspection(packet->flow, packet, SSN_DIR_BOTH, -1, 0);
         }
         else if (!(new_flags & SSL_HEARTBEAT_SEEN))
         {
@@ -376,7 +374,7 @@ static void snort_ssl(SSL_PROTO_CONF* config, Packet* p)
     {
         if ( (SSL_IS_SHELLO(new_flags) && !SSL_IS_CHELLO(sd->ssn_flags) ))
         {
-            if (!(stream.missed_packets(p->flow, SSN_DIR_FROM_CLIENT)))
+            if (!(Stream::missed_packets(p->flow, SSN_DIR_FROM_CLIENT)))
                 SnortEventqAdd(GID_SSL, SSL_INVALID_SERVER_HELLO);
         }
     }
index 95b6af4f2d5d7b644d5448abc20750c737dfe0a3..eabbe4bb87e72407415099f94ee91319faa28a24 100644 (file)
@@ -22,7 +22,6 @@
 // Implementation header with definitions, datatypes and flowdata class for SSL service inspector.
 
 #include "protocols/packet.h"
-#include "stream/stream_api.h"
 #include "ssl_config.h"
 
 #define SSLPP_ENCRYPTED_FLAGS \
index 5e08120e2453ab6a3947856526dc40e56d401a2e..d702f362b01479690b2b1eb08d1db32d7d0f1e09 100644 (file)
@@ -10,13 +10,12 @@ add_subdirectory(file)
 
 set (STREAM_INCLUDES
     paf.h
-    stream_api.h
+    stream.h
     stream_splitter.h
 )
 
 add_library( stream STATIC
-    stream.h
-    stream_api.cc
+    stream.cc
     stream_inspectors.cc
     stream_inspectors.h
     stream_splitter.cc
index 72bda49cc51082fe744a3237a666455996c2feb6..684abd27199b16a0361e8f41b3ee554b811382f0 100644 (file)
@@ -7,12 +7,11 @@ x_includedir = $(pkgincludedir)/stream
 
 x_include_HEADERS = \
 paf.h \
-stream_api.h \
+stream.h \
 stream_splitter.h
 
 libstream_a_SOURCES = \
-stream.h \
-stream_api.cc \
+stream.cc \
 stream_inspectors.cc \
 stream_inspectors.h \
 stream_splitter.cc
index de1b41dfbb26b125aa88a3a337f3c48055a8290f..a4e9b4f47724b96d34da84dd2bf52b466d725ae4 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-#include "stream/stream.h"
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include <assert.h>
 
-#include "stream_module.h"
-#include "stream_ha.h"
-#include "main/snort_debug.h"
-#include "managers/inspector_manager.h"
 #include "flow/flow_control.h"
 #include "flow/prune_stats.h"
-#include "stream/stream_api.h"
+#include "main/snort_debug.h"
+#include "managers/inspector_manager.h"
 #include "profiler/profiler.h"
+
 #include "stream/tcp/tcp_session.h"
+#include "stream_module.h"
+#include "stream_ha.h"
 
 //-------------------------------------------------------------------------
 // stats
@@ -203,13 +201,6 @@ void StreamBase::tinit()
 
 void StreamBase::tterm()
 {
-    flow_con->purge_flows(PktType::IP);
-    flow_con->purge_flows(PktType::ICMP);
-    flow_con->purge_flows(PktType::TCP);
-    flow_con->purge_flows(PktType::UDP);
-    flow_con->purge_flows(PktType::PDU);
-    flow_con->purge_flows(PktType::FILE);
-
     StreamHAManager::tterm();
 }
 
@@ -229,7 +220,8 @@ void StreamBase::eval(Packet* p)
     switch ( p->type() )
     {
     case PktType::IP:
-        if ( p->has_ip() )
+        if ( p->has_ip() and
+            ((p->ptrs.decode_flags & DECODE_FRAG) or !config->ip_frags_only) )
             flow_con->process_ip(p);
         break;
 
index 1f681ed99061ca1943c353185afa104f1450540b..22fc140f5278e7b8a85d091f8b3ccf2dfaef3124 100644 (file)
@@ -25,8 +25,8 @@
 #include "binder/binder.h"
 #include "main/snort_debug.h"
 #include "managers/inspector_manager.h"
+#include "stream/stream.h"
 #include "sfip/sf_ip.h"
-#include "stream/stream_api.h"
 
 // HA Session flags helper macros
 #define HA_IGNORED_SESSION_FLAGS \
index d874347a43f75776470d7063dd7e63baeb65d331..295380b499bd0bf3803f567bbfa3b45de6473d1a 100644 (file)
@@ -20,8 +20,6 @@
 
 #include "stream_module.h"
 
-#include "stream/stream.h"
-
 #include <string>
 
 using namespace std;
@@ -42,16 +40,13 @@ static const Parameter name[] = \
     { "idle_timeout", Parameter::PT_INT, "1:", idle, \
       "maximum inactive time before retiring session tracker" }, \
  \
-    { "cleanup_pct", Parameter::PT_INT, "1:100", cleanup, \
-      "percent of cache to clean when max_sessions is reached" }, \
-\
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } \
 }
 
 CACHE_PARAMS(ip_params,    "16384",  "30", "180", "5");
-CACHE_PARAMS(icmp_params,  "32768",  "30", "180", "5");
-CACHE_PARAMS(tcp_params,  "131072",  "30", "180", "5");
-CACHE_PARAMS(udp_params,   "65536",  "30", "180", "5");
+CACHE_PARAMS(icmp_params,  "65536",  "30", "180", "5");
+CACHE_PARAMS(tcp_params,  "262144",  "30", "180", "5");
+CACHE_PARAMS(udp_params,  "131072",  "30", "180", "5");
 CACHE_PARAMS(user_params,   "1024",  "30", "180", "5");
 CACHE_PARAMS(file_params,    "128",  "30", "180", "5");
 
@@ -61,6 +56,9 @@ CACHE_PARAMS(file_params,    "128",  "30", "180", "5");
 
 static const Parameter s_params[] =
 {
+    { "ip_frags_only", Parameter::PT_BOOL, nullptr, "false",
+      "don't process non-frag flows" },
+
     CACHE_TABLE("ip_cache",   "ip",   ip_params),
     CACHE_TABLE("icmp_cache", "icmp", icmp_params),
     CACHE_TABLE("tcp_cache",  "tcp",  tcp_params),
@@ -93,7 +91,12 @@ bool StreamModule::set(const char* fqn, Value& v, SnortConfig*)
 {
     FlowConfig* fc = nullptr;
 
-    if ( strstr(fqn, "ip_cache") )
+    if ( v.is("ip_frags_only") )
+    {
+        config.ip_frags_only = v.get_bool();
+        return true;
+    }
+    else if ( strstr(fqn, "ip_cache") )
         fc = &config.ip_cfg;
 
     else if ( strstr(fqn, "icmp_cache") )
@@ -123,9 +126,6 @@ bool StreamModule::set(const char* fqn, Value& v, SnortConfig*)
     else if ( v.is("idle_timeout") )
         fc->nominal_timeout = v.get_long();
 
-    else if ( v.is("cleanup_pct") )
-        fc->cleanup_pct = v.get_long();
-
     else
         return false;
 
index 30be7656a8f600a531992880ad8806145d5c93e2..4e4d28f0f1b62ff5e25e5b785fc2dfe6940a9b1a 100644 (file)
@@ -55,6 +55,8 @@ struct BaseStats
     PROTO_FIELDS(file);
 };
 
+extern const PegInfo base_pegs[];
+
 extern THREAD_LOCAL BaseStats stream_base_stats;
 
 struct StreamModuleConfig
@@ -65,6 +67,7 @@ struct StreamModuleConfig
     FlowConfig udp_cfg;
     FlowConfig user_cfg;
     FlowConfig file_cfg;
+    bool ip_frags_only;
 };
 
 class StreamModule : public Module
index 99509ef6f4263b035885f7fb5b39907829a1eef8..f55b240614559ce95762f6bd35415b5859c164a4 100644 (file)
@@ -24,7 +24,6 @@ using namespace std;
 
 #include "stream_file.h"
 #include "main/snort_config.h"
-#include "stream/stream.h"
 
 //-------------------------------------------------------------------------
 // stream_file module
index 39014a897f34017ef6869c06fc96b3208efdc2e0..81e9f4f5dc239384872127650c6329c08a4331aa 100644 (file)
@@ -23,7 +23,6 @@
 #include "main/snort_types.h"
 #include "main/thread.h"
 #include "framework/module.h"
-#include "stream/stream.h"
 
 struct SnortConfig;
 
index fb6857069810e72d510da1bbb97334bfce423674..f5a0a0123c27878ad40825dce1142dccf54fa81f 100644 (file)
@@ -11,3 +11,17 @@ packets directly to the ICMP session packet processing method.
 Currently only the ICMP Unreachable message is handled by the ICMP session
 module.
 
+The module icmp_ha.cc (and icmp_ha.h) implements the per-protocol hooks into
+the stream logic for HA.  IcmpHAManager is a static class that interfaces
+to a per-packet thread instance of the class IcmpHA.  IcmpHA is sub-class
+of ProtocolHA, declared in the stream/base area.  Thus each protocol
+within 'stream' can have specific HA logic and interfaces.
+
+IcmpHAManager::process_deletion() is called when an ICMP stream is being 
+destroyed and indicates to the stream & flow HA logic that a flow
+deletion HA message needs to be emitted for the flow in question.
+Icmp streams are closed due to timeout or puning actions which lead
+to the invocation of process_deletion().
+
+IcmpHA::create_session() is called from the stream & flow HA logic and
+handles the creation of new flow upon receiving an HA update message.
index a8864f6d2e69ca93f716c96c879758a154d0f342..61271c06d7e3321a03ee1c3be0367ee7670032da 100644 (file)
 
 Flow* IcmpHA::create_session(FlowKey* key)
 {
-    DebugMessage(DEBUG_HA,"IcmpHA::create_session\n");
-
-    assert ( key );
-
-    Flow* flow = flow_con->new_flow(key);
+    assert(key);
+    Flow* flow = Stream::new_flow(key);
 
     if ( (flow != nullptr ) && (flow->session == nullptr) )
     {
index 33cbaefe0f9f72a7d06ffe7e4e15940e9a0a1c75..9d9205e0b5df8479f2bdb4639455606c30d3f045 100644 (file)
@@ -43,8 +43,16 @@ StreamIcmpModule::StreamIcmpModule() :
     config = nullptr;
 }
 
-ProfileStats* StreamIcmpModule::get_profile() const
-{ return &icmp_perf_stats; }
+ProfileStats* StreamIcmpModule::get_profile(
+    unsigned index, const char*& name, const char*& parent) const
+{
+    if ( index )
+        return nullptr;
+
+    name = MOD_NAME;
+    parent = "stream";
+    return &icmp_perf_stats;
+}
 
 StreamIcmpConfig* StreamIcmpModule::get_data()
 {
index 447bdf51f7ecbc8a28f388bb2508859d15bc2e5e..eb664c0e65648f48bc4983c12aa76cb1b7ae9e6a 100644 (file)
@@ -23,8 +23,8 @@
 
 #include "main/snort_types.h"
 #include "main/thread.h"
+#include "flow/session.h"
 #include "framework/module.h"
-#include "stream/stream.h"
 
 extern const PegInfo icmp_pegs[];
 extern THREAD_LOCAL struct IcmpStats icmpStats;
@@ -54,7 +54,7 @@ public:
     bool begin(const char*, int, SnortConfig*) override;
     bool end(const char*, int, SnortConfig*) override;
 
-    ProfileStats* get_profile() const override;
+    ProfileStats* get_profile(unsigned, const char*&, const char*&) const override;
     const PegInfo* get_pegs() const override;
     PegCount* get_counts() const override;
 
index 2e5a8d42ac611f01f6e41db6e3df5cd67be51349..718eb3d32e9e3ad23bb5c46fb4e7ddf90bece58c 100644 (file)
@@ -62,6 +62,7 @@ static void IcmpSessionCleanup(Flow* ssn)
 {
     if (ssn->ssn_state.session_flags & SSNFLAG_PRUNED)
         icmpStats.prunes++;
+
     else if (ssn->ssn_state.session_flags & SSNFLAG_TIMEDOUT)
         icmpStats.timeouts++;
 
@@ -157,15 +158,15 @@ static int ProcessIcmpUnreach(Packet* p)
     {
     case PktType::TCP:
         /* Lookup a TCP session */
-        ssn = Stream::get_session(&skey);
+        ssn = Stream::get_flow(&skey);
         break;
     case PktType::UDP:
         /* Lookup a UDP session */
-        ssn = Stream::get_session(&skey);
+        ssn = Stream::get_flow(&skey);
         break;
     case PktType::ICMP:
         /* Lookup a ICMP session */
-        ssn = Stream::get_session(&skey);
+        ssn = Stream::get_flow(&skey);
         break;
     default:
         break;
index b909f1aaf56bb160c46c9a26c27e45be1647d9d1..54047342fa1c495b224349245077a6541a90e93b 100644 (file)
@@ -8,3 +8,17 @@ functions for loading stream IP configuration and packet evaluation.  The
 packet eval method is not used as the base Stream Inspector delegates
 packets directly to the IP session packet processing method.
 
+The module ip_ha.cc (and ip_ha.h) implements the per-protocol hooks into
+the stream logic for HA.  IpHAManager is a static class that interfaces
+to a per-packet thread instance of the class IpHA.  IpHA is sub-class
+of ProtocolHA, declared in the stream/base area.  Thus each protocol
+within 'stream' can have specific HA logic and interfaces.
+
+IpHAManager::process_deletion() is called when an IP stream is being 
+destroyed and indicates to the stream & flow HA logic that a flow
+deletion HA message needs to be emitted for the flow in question.
+Ip streams are closed due to timeout or puning actions which lead
+to the invocation of process_deletion().
+
+IpHA::create_session() is called from the stream & flow HA logic and
+handles the creation of new flow upon receiving an HA update message.
index c88d26374b4bcfc6a22bede99bcdd6afa1b5d202..d2d3cbe3351b7a04ce154080a52b951aac5108e3 100644 (file)
 
 #include "ip_ha.h"
 
-#include "flow/flow_control.h"
 #include "main/snort_debug.h"
-#include "stream/ip/ip_session.h"
+#include "stream/stream.h"
+#include "ip_session.h"
 
 Flow* IpHA::create_session(FlowKey* key)
 {
-    DebugMessage(DEBUG_HA,"IpHA::create_session\n");
+    assert(key);
 
-    assert ( key );
-
-    Flow* flow = flow_con->new_flow(key);
+    Flow* flow = Stream::new_flow(key);
 
     if ( (flow != nullptr ) && (flow->session == nullptr) )
     {
index 13dbb4dd2cb5c79b079046ba1db7ddfd5bb57fcf..352d63abd5b86af77796b3d98a68fc9ffede0a1e 100644 (file)
@@ -140,7 +140,7 @@ ProfileStats* StreamIpModule::get_profile(
     {
     case 0:
         name = "stream_ip";
-        parent = nullptr;
+        parent = "stream";
         return &ip_perf_stats;
 
     case 1:
index 14b3e720681f202c62bffd0f1af1e2a563e189fa..1aa5215f95ce5b2e18833667b9745a250009ffec 100644 (file)
@@ -23,8 +23,8 @@
 
 #include "main/snort_types.h"
 #include "main/thread.h"
+#include "flow/session.h"
 #include "framework/module.h"
-#include "stream/stream.h"
 
 struct SnortConfig;
 
index 34390a12b7db1f3552d5bf84b351980ee8ef9648..abcb85e94a2b13d9bb93add66bef48925f0ea18d 100644 (file)
@@ -28,7 +28,6 @@
 #include "ip_defrag.h"
 #include "ip_ha.h"
 #include "stream/stream.h"
-#include "flow/flow_control.h"
 #include "sfip/sf_ip.h"
 #include "profiler/profiler.h"
 
@@ -74,11 +73,7 @@ static void IpSessionCleanup(Flow* lws, FragTracker* tracker)
 
     if ( lws->ssn_state.session_flags & SSNFLAG_TIMEDOUT )
         ip_stats.timeouts++;
-    else if ( lws->ssn_state.session_flags & SSNFLAG_PRUNED )
-        ip_stats.prunes++;
 
-    if ( lws->ssn_state.session_flags & SSNFLAG_TIMEDOUT )
-        ip_stats.timeouts++;
     else if ( lws->ssn_state.session_flags & SSNFLAG_PRUNED )
         ip_stats.prunes++;
 
@@ -156,7 +151,7 @@ bool IpSession::setup(Packet*)
     ip_stats.current++;
 
 #ifdef ENABLE_EXPECTED_IP
-    if ( flow_con->expected_session(flow, p))
+    if ( Stream::expected_flow(flow, p) )
     {
         ip_stats.sessions--; // Incremented in SESSION_STATS_ADD
         MODULE_PROFILE_END(ip_perf_stats);
@@ -169,18 +164,18 @@ int IpSession::process(Packet* p)
 {
     Profile profile(ip_perf_stats);
 
-    if ( stream.expired_session(flow, p) )
+    if ( Stream::expired_flow(flow, p) )
     {
         IpSessionCleanup(flow, &tracker);
 
 #ifdef ENABLE_EXPECTED_IP
-        if ( flow_con->expected_session(flow, p))
+        if ( Stream::expected_flow(flow, p) )
             return 0;
 #endif
         IpHAManager::process_deletion(flow);
     }
 
-    if ( stream.blocked_session(flow, p) || stream.ignored_session(flow, p) )
+    if ( Stream::blocked_flow(flow, p) || Stream::ignored_flow(flow, p) )
         return 0;
 
     if ( p->ptrs.decode_flags & DECODE_FRAG )
index 502002b7df474248272f32e1057c6cefc8e11dfb..80ed54548be7d0b8ee1faa81815f711afe78a7fa 100644 (file)
@@ -25,7 +25,7 @@
 #include "flow/flow.h"
 
 /* engine-based defragmentation policy enums */
-// must update stream_api.h::IP_POLICIES if this changes
+// must update stream.h::IP_POLICIES if this changes
 enum
 {
     FRAG_POLICY_FIRST = 1,
index 12a79d004520d936a1c71274594ef381e54fc9f7..0a6ebc9509834c39be330366abc95f7f20af3654 100644 (file)
@@ -16,3 +16,12 @@ This TCP library module provides the following functions:
 * TCP State Machine - this class is the engine that dispatches processing to the correct
   event handling method of the handler for the current TCP state of the flow.
 
+Most of the TCP HA processing is contained in the ../tcp area and one needed to refer
+to ../tcp/dev_notes.txt for a description.
+
+One HA state transition is implemented within this TCP library.  In
+TcpStreamSession::clear(), TcpHAManager::process_deletion() is invoked to
+cause HA to generate a Deletion message for the target flow.  This handles
+the case where a TCP session is being removed from from the flow cache due
+to a timeout or pruning function.  Other normal TCP stream closure actions
+are handled in the ../tcp/tcp_session.cc module.
index 4428d90ceb0f3754bd6f799fb675420e30420271..84b4dd94add62bfef96a27a02b871fb597067762 100644 (file)
@@ -72,7 +72,8 @@ public:
     void SwapPacketHeaderFoo();
 
     virtual void update_perf_base_state(char) { }
-    virtual void clear_session(bool free_flow_data, bool flush_segments, bool restart, Packet* p = nullptr) = 0;
+    virtual void clear_session(
+        bool free_flow_data, bool flush_segments, bool restart, Packet* p = nullptr) = 0;
 
     // FIXIT-L these 2 function names convey no meaning afaict... figure out
     // why are they called and name appropriately...
@@ -94,8 +95,12 @@ public:
 
     virtual void flush() { }
 
-    virtual TcpStreamTracker::TcpState get_talker_state() { return TcpStreamTracker::TCP_MAX_STATES; }
-    virtual TcpStreamTracker::TcpState get_listener_state() { return TcpStreamTracker::TCP_MAX_STATES; }
+    virtual TcpStreamTracker::TcpState get_talker_state()
+    { return TcpStreamTracker::TCP_MAX_STATES; }
+
+    virtual TcpStreamTracker::TcpState get_listener_state()
+    { return TcpStreamTracker::TCP_MAX_STATES; }
+
     virtual void init_new_tcp_session(TcpSegmentDescriptor&);
     virtual void update_timestamp_tracking(TcpSegmentDescriptor&) { }
     virtual void update_session_on_syn_ack();
@@ -117,9 +122,7 @@ public:
     }
 
     void set_pkt_action_flag(uint32_t flag)
-    {
-        pkt_action_mask |= flag;
-    }
+    { pkt_action_mask |= flag; }
 
     virtual void update_paws_timestamps(TcpSegmentDescriptor&) { }
     virtual void check_for_repeated_syn(TcpSegmentDescriptor&) { }
index ac0348f0ff75a3e3716c5509c2f1ee4375ac847c..866fdae4e90094dc4eca50f3ccea0d6791338e92 100644 (file)
 // tcp_stream_tracker.cpp author davis mcpherson <davmcphe@@cisco.com>
 // Created on: Jun 24, 2015
 
-#include "protocols/tcp_options.h"
-#include "protocols/tcp.h"
-#include "protocols/eth.h"
-#include "profiler/profiler.h"
+#include "tcp_stream_tracker.h"
 
+#include "profiler/profiler.h"
+#include "protocols/eth.h"
+#include "protocols/tcp.h"
+#include "protocols/tcp_options.h"
 #include "stream/stream.h"
-#include "tcp_stream_tracker.h"
 
 const char* tcp_state_names[] =
-{ "TCP_LISTEN", "TCP_SYN_SENT", "TCP_SYN_RECV", "TCP_ESTABLISHED","TCP_FIN_WAIT1",
-  "TCP_FIN_WAIT2", "TCP_CLOSE_WAIT", "TCP_CLOSING", "TCP_LAST_ACK",
-  "TCP_TIME_WAIT", "TCP_CLOSED", "TCP_STATE_NONE",};
-
-const char* tcp_event_names[] = { "TCP_SYN_SENT_EVENT", "TCP_SYN_RECV_EVENT",
-                                  "TCP_SYN_ACK_SENT_EVENT", "TCP_SYN_ACK_RECV_EVENT",
-                                  "TCP_ACK_SENT_EVENT",
-                                  "TCP_ACK_RECV_EVENT", "TCP_DATA_SEG_SENT_EVENT",
-                                  "TCP_DATA_SEG_RECV_EVENT",
-                                  "TCP_FIN_SENT_EVENT", "TCP_FIN_RECV_EVENT", "TCP_RST_SENT_EVENT",
-                                  "TCP_RST_RECV_EVENT" };
+{
+    "TCP_LISTEN", "TCP_SYN_SENT", "TCP_SYN_RECV",
+    "TCP_ESTABLISHED",
+    "TCP_FIN_WAIT1", "TCP_FIN_WAIT2", "TCP_CLOSE_WAIT", "TCP_CLOSING",
+    "TCP_LAST_ACK", "TCP_TIME_WAIT", "TCP_CLOSED",
+    "TCP_STATE_NONE"
+};
+
+const char* tcp_event_names[] = {
+    "TCP_SYN_SENT_EVENT", "TCP_SYN_RECV_EVENT",
+    "TCP_SYN_ACK_SENT_EVENT", "TCP_SYN_ACK_RECV_EVENT",
+    "TCP_ACK_SENT_EVENT", "TCP_ACK_RECV_EVENT",
+    "TCP_DATA_SEG_SENT_EVENT", "TCP_DATA_SEG_RECV_EVENT",
+    "TCP_FIN_SENT_EVENT", "TCP_FIN_RECV_EVENT",
+    "TCP_RST_SENT_EVENT", "TCP_RST_RECV_EVENT"
+};
 
 TcpStreamTracker::TcpStreamTracker(bool client) :
     client_tracker(client), tcp_state(client ? TCP_STATE_NONE : TCP_LISTEN)
index 8e033af3ea7a1eba0b0a1418e9b83a1cb6aec213..90f879e3081c99871c0ecec90685b364d840c225 100644 (file)
@@ -240,6 +240,10 @@ public:
         this->fin_final_seq = fin_final_seq;
     }
 
+    // FIXIT-M fin_final_seq can be zero so need to use current state
+    // or other flag to know when it is actually set
+    bool fin_set() { return fin_final_seq != 0; }
+
     uint32_t get_ts_last_packet() const
     {
         return ts_last_packet;
index 93da110123b79564f1f122e0d5a6881e5eddeeef..d49911dbcbacbab999c23c2addfb9fa827253dca 100644 (file)
@@ -34,8 +34,7 @@
 
 #include "main/snort_types.h"
 #include "main/snort_debug.h"
-#include "stream/stream.h"
-#include "stream/stream_api.h"
+#include "protocols/packet.h"
 
 //--------------------------------------------------------------------
 // private state
index 4192f544e4162d18836284808c101bc4b5be77cd..799638bd9cbdca87020c972ddde289d0f719d0c8 100644 (file)
@@ -28,7 +28,6 @@
 #include <stdint.h>
 
 #include "main/snort_types.h"
-#include "stream/stream_api.h"
 #include "stream/stream_splitter.h"
 
 struct SnortConfig;
similarity index 85%
rename from src/stream/stream_api.cc
rename to src/stream/stream.cc
index e50dc80d00b38c55f80d611aee883903b36f0266..94b029c282ba26d58eca69e105e8836a7ce2eb45 100644 (file)
@@ -17,7 +17,7 @@
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-#include "stream_api.h"
+#include "stream.h"
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #include "main/snort_config.h"
 #include "main/snort_debug.h"
 #include "main/snort_debug.h"
-#include "utils/util.h"
 #include "flow/flow_control.h"
 #include "flow/flow_cache.h"
 #include "flow/ha.h"
+#include "flow/prune_stats.h"
 #include "flow/session.h"
 #include "stream/stream.h"
 #include "stream/paf.h"
 #include "protocols/vlan.h"
 #include "target_based/snort_protocols.h"
 #include "target_based/sftarget_hostentry.h"
+#include "utils/bitop.h"
+#include "utils/util.h"
 
 #ifdef UNIT_TEST
 #include "catch/catch.hpp"
 #include "stream/libtcp/stream_tcp_unit_test.h"
 #endif
 
-Stream stream;  // FIXIT-L global for SnortContext
+// this should not be publicly accessible
+extern THREAD_LOCAL class FlowControl* flow_con;
 
-Stream::Stream()
+struct StreamImpl
 {
-    xtradata_func_count = 0;
-    extra_data_log = NULL;
-    extra_data_config = NULL;
-}
+public:
+    uint32_t xtradata_func_count = 0;
+    LogFunction xtradata_map[MAX_LOG_FN];
+    LogExtraData extra_data_log = nullptr;
+    void* extra_data_config = nullptr;
+};
 
-Stream::~Stream() { }
+static StreamImpl stream;
 
 //-------------------------------------------------------------------------
 // session foo
 //-------------------------------------------------------------------------
 
-Flow* Stream::get_session(const FlowKey* key)
+Flow* Stream::get_flow(const FlowKey* key)
 { return flow_con->find_flow(key); }
 
-Flow* Stream::new_session(const FlowKey* key)
+Flow* Stream::new_flow(const FlowKey* key)
 { return flow_con->new_flow(key); }
 
-void Stream::delete_session(const FlowKey* key)
+Flow* Stream::new_flow(FlowKey* key)
+{
+    return flow_con ? flow_con->new_flow(key) : nullptr;
+}
+
+void Stream::delete_flow(const FlowKey* key)
 { flow_con->delete_flow(key); }
 
 //-------------------------------------------------------------------------
 // key foo
 //-------------------------------------------------------------------------
 
-Flow* Stream::get_session_ptr_from_ip_port(
+Flow* Stream::get_flow(
     PktType type, IpProtocol proto,
     const sfip_t* srcIP, uint16_t srcPort,
     const sfip_t* dstIP, uint16_t dstPort,
     uint16_t vlan, uint32_t mplsId, uint16_t addressSpaceId)
 {
     FlowKey key;
-
     key.init(type, proto, srcIP, srcPort, dstIP, dstPort, vlan, mplsId, addressSpaceId);
-
-    return get_session(&key);
+    return get_flow(&key);
 }
 
-void Stream::populate_session_key(Packet* p, FlowKey* key)
+void Stream::populate_flow_key(Packet* p, FlowKey* key)
 {
     if (!key || !p)
         return;
@@ -114,10 +122,10 @@ void Stream::populate_session_key(Packet* p, FlowKey* key)
         p->pkth->address_space_id);
 }
 
-FlowKey* Stream::get_session_key(Packet* p)
+FlowKey* Stream::get_flow_key(Packet* p)
 {
     FlowKey* key = (FlowKey*)snort_calloc(sizeof(*key));
-    populate_session_key(p, key);
+    populate_flow_key(p, key);
     return key;
 }
 
@@ -125,23 +133,21 @@ FlowKey* Stream::get_session_key(Packet* p)
 // app data foo
 //-------------------------------------------------------------------------
 
-FlowData* Stream::get_application_data_from_key(
+FlowData* Stream::get_flow_data(
     const FlowKey* key, unsigned flow_id)
 {
-    Flow* flow = get_session(key);
-    return flow->get_application_data(flow_id);
+    Flow* flow = get_flow(key);
+    return flow->get_flow_data(flow_id);
 }
 
-FlowData* Stream::get_application_data_from_ip_port(
+FlowData* Stream::get_flow_data(
     PktType type, IpProtocol proto,
     const sfip_t* srcIP, uint16_t srcPort,
     const sfip_t* dstIP, uint16_t dstPort,
     uint16_t vlan, uint32_t mplsId,
     uint16_t addressSpaceID, unsigned flow_id)
 {
-    Flow* flow;
-
-    flow = get_session_ptr_from_ip_port(
+    Flow* flow = get_flow(
         type, proto,
         srcIP, srcPort, dstIP, dstPort,
         vlan, mplsId, addressSpaceID);
@@ -149,18 +155,18 @@ FlowData* Stream::get_application_data_from_ip_port(
     if (!flow)
         return NULL;
 
-    return flow->get_application_data(flow_id);
+    return flow->get_flow_data(flow_id);
 }
 
 //-------------------------------------------------------------------------
 // session status
 //-------------------------------------------------------------------------
 
-void Stream::check_session_closed(Packet* p)
+void Stream::check_flow_closed(Packet* p)
 {
     Flow* flow = p->flow;
 
-    if (!p || !flow)
+    if ( !flow )
         return;
 
     if (flow->session_state & STREAM_STATE_CLOSED)
@@ -172,18 +178,15 @@ void Stream::check_session_closed(Packet* p)
     }
 }
 
-int Stream::ignore_session(
+int Stream::ignore_flow(
     const sfip_t* srcIP, uint16_t srcPort,
     const sfip_t* dstIP, uint16_t dstPort,
     PktType protocol, char direction,
     uint32_t flow_id)
 {
     assert(flow_con);
-
     FlowData* fd = new FlowData(flow_id);
-
-    return flow_con->add_expected(
-        srcIP, srcPort, dstIP, dstPort, protocol, direction, fd);
+    return flow_con->add_expected(srcIP, srcPort, dstIP, dstPort, protocol, direction, fd);
 }
 
 void Stream::proxy_started(Flow* flow, unsigned dir)
@@ -195,10 +198,10 @@ void Stream::proxy_started(Flow* flow, unsigned dir)
     tcpssn->flush();
 
     if ( dir & SSN_DIR_FROM_SERVER )
-        stream.set_splitter(flow, true, new LogSplitter(true));
+        set_splitter(flow, true, new LogSplitter(true));
 
     if ( dir & SSN_DIR_FROM_CLIENT )
-        stream.set_splitter(flow, false, new LogSplitter(false));
+        set_splitter(flow, false, new LogSplitter(false));
 
     tcpssn->start_proxy();
     flow->set_proxied();
@@ -295,7 +298,7 @@ void Stream::drop_traffic(Flow* flow, char dir)
     }
 }
 
-void Stream::drop_session(const Packet* p)
+void Stream::drop_flow(const Packet* p)
 {
     Flow* flow = p->flow;
 
@@ -305,7 +308,7 @@ void Stream::drop_session(const Packet* p)
     flow->session->clear();
     flow->set_state(Flow::FlowState::BLOCK);
 
-    if (!(p->packet_flags & PKT_STATELESS))
+    if ( !(p->packet_flags & PKT_STATELESS) )
         drop_traffic(flow, SSN_DIR_BOTH);
 }
 
@@ -313,16 +316,6 @@ void Stream::drop_session(const Packet* p)
 // misc support
 //-------------------------------------------------------------------------
 
-BitOp* Stream::get_flow_bitop(const Packet* p)
-{
-    Flow* flow = p->flow;
-
-    if (!flow)
-        return NULL;
-
-    return flow->bitop;
-}
-
 void Stream::init_active_response(const Packet* p, Flow* flow)
 {
     if ( !flow )
@@ -334,6 +327,37 @@ void Stream::init_active_response(const Packet* p, Flow* flow)
         flow->set_expire(p, snort_conf->min_interval);
 }
 
+void Stream::purge_flows()
+{
+    if ( !flow_con )
+        return;
+
+    flow_con->purge_flows(PktType::IP);
+    flow_con->purge_flows(PktType::ICMP);
+    flow_con->purge_flows(PktType::TCP);
+    flow_con->purge_flows(PktType::UDP);
+    flow_con->purge_flows(PktType::PDU);
+    flow_con->purge_flows(PktType::FILE);
+}
+
+void Stream::timeout_flows(time_t cur_time)
+{
+    if ( flow_con )
+        // FIXIT-M batch here or loop vs looping over idle?
+        flow_con->timeout_flows(cur_time);
+}
+
+void Stream::prune_flows()
+{
+    if ( flow_con )
+        flow_con->prune_one(PruneReason::MEMCAP, false);
+}
+
+bool Stream::expected_flow(Flow* f, Packet* p)
+{
+    return flow_con->expected_flow(f, p) != SSN_DIR_NONE;
+}
+
 //-------------------------------------------------------------------------
 // app proto id foo
 //-------------------------------------------------------------------------
@@ -349,7 +373,7 @@ int Stream::set_application_protocol_id_expected(
         srcIP, srcPort, dstIP, dstPort, protocol, appId, fd);
 }
 
-void Stream::set_application_protocol_id_from_host_entry(
+void Stream::set_application_protocol_id(
     Flow* flow, const HostAttributeEntry* host_entry, int /*direction*/)
 {
     int16_t application_protocol;
@@ -391,7 +415,6 @@ int16_t Stream::get_application_protocol_id(Flow* flow)
     /* Not caching the source and dest host_entry in the session so we can
      * swap the table out after processing this packet if we need
      * to.  */
-    HostAttributeEntry* host_entry = NULL;
     int16_t protocol = 0;
 
     if (!flow)
@@ -408,30 +431,23 @@ int16_t Stream::get_application_protocol_id(Flow* flow)
         set_ip_protocol(flow);
     }
 
-    host_entry = SFAT_LookupHostEntryByIP(&flow->server_ip);
-    if (host_entry)
+    if ( HostAttributeEntry* host_entry = SFAT_LookupHostEntryByIP(&flow->server_ip) )
     {
-        set_application_protocol_id_from_host_entry(flow, host_entry, FROM_SERVER);
+        set_application_protocol_id(flow, host_entry, FROM_SERVER);
 
         if (flow->ssn_state.application_protocol != 0)
-        {
             return flow->ssn_state.application_protocol;
-        }
     }
 
-    host_entry = SFAT_LookupHostEntryByIP(&flow->client_ip);
-    if (host_entry)
+    if ( HostAttributeEntry* host_entry = SFAT_LookupHostEntryByIP(&flow->client_ip) )
     {
-        set_application_protocol_id_from_host_entry(flow, host_entry, FROM_CLIENT);
+        set_application_protocol_id(flow, host_entry, FROM_CLIENT);
 
         if (flow->ssn_state.application_protocol != 0)
-        {
             return flow->ssn_state.application_protocol;
-        }
     }
 
     flow->ssn_state.application_protocol = -1;
-
     return 0;
 }
 
@@ -488,52 +504,50 @@ bool Stream::is_paf_active(Flow* flow, bool to_server)
 void Stream::log_extra_data(
     Flow* flow, uint32_t mask, uint32_t id, uint32_t sec)
 {
-    if ( mask && extra_data_log )
+    if ( mask && stream.extra_data_log )
     {
-        extra_data_log(
-            flow, extra_data_config, xtradata_map,
-            xtradata_func_count, mask, id, sec);
+        stream.extra_data_log(
+            flow, stream.extra_data_config, stream.xtradata_map,
+            stream.xtradata_func_count, mask, id, sec);
     }
 }
 
 uint32_t Stream::reg_xtra_data_cb(LogFunction f)
 {
     uint32_t i = 0;
-    while (i < xtradata_func_count)
+    while (i < stream.xtradata_func_count)
     {
-        if (xtradata_map[i++] == f)
-        {
+        if (stream.xtradata_map[i++] == f)
             return i;
-        }
     }
-    if ( xtradata_func_count == MAX_LOG_FN)
+    if ( stream.xtradata_func_count == MAX_LOG_FN)
         return 0;
-    xtradata_map[xtradata_func_count++] = f;
-    return xtradata_func_count;
+
+    stream.xtradata_map[stream.xtradata_func_count++] = f;
+    return stream.xtradata_func_count;
 }
 
 uint32_t Stream::get_xtra_data_map(LogFunction** f)
 {
     if (f)
     {
-        *f = xtradata_map;
-        return xtradata_func_count;
+        *f = stream.xtradata_map;
+        return stream.xtradata_func_count;
     }
-    else
-        return 0;
+    return 0;
 }
 
 void Stream::reg_xtra_data_log(LogExtraData f, void* config)
 {
-    extra_data_log = f;
-    extra_data_config = config;
+    stream.extra_data_log = f;
+    stream.extra_data_config = config;
 }
 
 //-------------------------------------------------------------------------
 // other foo
 //-------------------------------------------------------------------------
 
-uint8_t Stream::get_session_ttl(Flow* flow, char dir, bool outer)
+uint8_t Stream::get_flow_ttl(Flow* flow, char dir, bool outer)
 {
     if ( !flow )
         return 0;
@@ -560,7 +574,7 @@ static void active_response(Packet* p, Flow* lwssn)
     else
         lwssn->session_state |= STREAM_STATE_DROP_SERVER;
 
-    if ( (lwssn->response_count < max) && lwssn->get_expire(p) )
+    if ( (lwssn->response_count < max) && lwssn->expired(p) )
     {
         uint32_t delay = snort_conf->min_interval;
         EncodeFlags flags =
@@ -576,7 +590,7 @@ static void active_response(Packet* p, Flow* lwssn)
     }
 }
 
-bool Stream::blocked_session(Flow* flow, Packet* p)
+bool Stream::blocked_flow(Flow* flow, Packet* p)
 {
     if ( !(flow->ssn_state.session_flags & (SSNFLAG_DROP_CLIENT|SSNFLAG_DROP_SERVER)) )
         return false;
@@ -600,7 +614,7 @@ bool Stream::blocked_session(Flow* flow, Packet* p)
     return false;
 }
 
-bool Stream::ignored_session(Flow* flow, Packet* p)
+bool Stream::ignored_flow(Flow* flow, Packet* p)
 {
     if (((p->is_from_server()) &&
         (flow->ssn_state.ignore_direction & SSN_DIR_FROM_CLIENT)) ||
@@ -618,8 +632,11 @@ bool Stream::ignored_session(Flow* flow, Packet* p)
     return false;
 }
 
-static int StreamExpireSession(Flow* lwssn)
+static int StreamExpire(Packet* p, Flow* lwssn)
 {
+    if ( !lwssn->expired(p) )
+        return 0;
+
     if ( HighAvailabilityManager::in_standby(lwssn) )
         return 1;
 
@@ -629,18 +646,7 @@ static int StreamExpireSession(Flow* lwssn)
     return 1;
 }
 
-static int StreamExpire(Packet* p, Flow* lwssn)
-{
-    if ( lwssn->expired(p) )
-    {
-        /* Expiration time has passed. */
-        return StreamExpireSession(lwssn);
-    }
-
-    return 0;
-}
-
-bool Stream::expired_session(Flow* flow, Packet* p)
+bool Stream::expired_flow(Flow* flow, Packet* p)
 {
     if ( (flow->session_state & STREAM_STATE_TIMEDOUT)
         || StreamExpire(p, flow) )
@@ -714,7 +720,7 @@ void Stream::flush_response(Packet* p)
 }
 
 // return true if added
-bool Stream::add_session_alert(
+bool Stream::add_flow_alert(
     Flow* flow, Packet* p, uint32_t gid, uint32_t sid)
 {
     if ( !flow )
@@ -724,7 +730,7 @@ bool Stream::add_session_alert(
 }
 
 // return true if gid/sid have already been seen
-bool Stream::check_session_alerted(
+bool Stream::check_flow_alerted(
     Flow* flow, Packet* p, uint32_t gid, uint32_t sid)
 {
     if ( !flow )
@@ -733,7 +739,7 @@ bool Stream::check_session_alerted(
     return flow->session->check_alerted(p, gid, sid);
 }
 
-int Stream::update_session_alert(
+int Stream::update_flow_alert(
     Flow* flow, Packet* p,
     uint32_t gid, uint32_t sid,
     uint32_t event_id, uint32_t event_second)
@@ -783,8 +789,6 @@ bool Stream::missed_packets(Flow* flow, uint8_t dir)
 
 #ifdef UNIT_TEST
 
-#include "framework/cursor.h"
-
 TEST_CASE("Stream API", "[stream_api][stream]")
 {
     // initialization code here
@@ -839,7 +843,7 @@ TEST_CASE("Stream API", "[stream_api][stream]")
         pkt->flow->session = new TcpSession(flow);
 
         Stream::stop_inspection(flow, pkt, SSN_DIR_FROM_SERVER, 0, 0);
-        bool ignored = Stream::ignored_session(flow, pkt);
+        bool ignored = Stream::ignored_flow(flow, pkt);
         CHECK(ignored);
 
         delete pkt->flow->session;
@@ -852,7 +856,7 @@ TEST_CASE("Stream API", "[stream_api][stream]")
         pkt->flow->session = new TcpSession(flow);
 
         Stream::stop_inspection(flow, pkt, SSN_DIR_FROM_SERVER, 0, 0);
-        bool ignored = Stream::ignored_session(flow, pkt);
+        bool ignored = Stream::ignored_flow(flow, pkt);
         CHECK(!ignored);
         delete pkt->flow->session;
         delete pkt;
@@ -864,7 +868,7 @@ TEST_CASE("Stream API", "[stream_api][stream]")
         pkt->flow->session = new TcpSession(flow);
 
         Stream::stop_inspection(flow, pkt, SSN_DIR_FROM_CLIENT, 0, 0);
-        bool ignored = Stream::ignored_session(flow, pkt);
+        bool ignored = Stream::ignored_flow(flow, pkt);
         CHECK(!ignored);
 
         delete pkt->flow->session;
@@ -877,7 +881,7 @@ TEST_CASE("Stream API", "[stream_api][stream]")
         pkt->flow->session = new TcpSession(flow);
 
         Stream::stop_inspection(flow, pkt, SSN_DIR_FROM_CLIENT, 0, 0);
-        bool ignored = Stream::ignored_session(flow, pkt);
+        bool ignored = Stream::ignored_flow(flow, pkt);
         CHECK(ignored);
         delete pkt->flow->session;
         delete pkt;
@@ -889,7 +893,7 @@ TEST_CASE("Stream API", "[stream_api][stream]")
         pkt->flow->session = new TcpSession(flow);
 
         Stream::stop_inspection(flow, pkt, SSN_DIR_BOTH, 0, 0);
-        bool ignored = Stream::ignored_session(flow, pkt);
+        bool ignored = Stream::ignored_flow(flow, pkt);
         CHECK(ignored);
 
         delete pkt->flow->session;
@@ -902,7 +906,7 @@ TEST_CASE("Stream API", "[stream_api][stream]")
         pkt->flow->session = new TcpSession(flow);
 
         Stream::stop_inspection(flow, pkt, SSN_DIR_BOTH, 0, 0);
-        bool ignored = Stream::ignored_session(flow, pkt);
+        bool ignored = Stream::ignored_flow(flow, pkt);
         CHECK(ignored);
         delete pkt->flow->session;
         delete pkt;
index d615938d0b7eda65530e7dfc23e4a46bf65ce09d..a55085c54d5a73150ce8d4de18c0b18d322525f0 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
+// stream.h author Steven Sturges
+
 #ifndef STREAM_H
 #define STREAM_H
 
+// provides a common flow management interface
+
 #include <sys/types.h>
-#include <netinet/in.h>
 
+#include "sfip/sfip_t.h"
+#include "protocols/packet.h"
+#include "flow/flow.h"
 #include "main/snort_types.h"
-#include "stream/stream_api.h"
-#include "network_inspectors/normalize/norm.h"
-#include "flow/session.h"
-
-#define STREAM_DEFAULT_SSN_TIMEOUT  30        /* seconds to timeout a session */
-#define STREAM_MAX_SSN_TIMEOUT      3600*24   /* max timeout (approx 1 day) */
-#define STREAM_MIN_SSN_TIMEOUT      1         /* min timeout (1 second) */
-
-#define STREAM_TRACK_YES            1
-#define STREAM_TRACK_NO             0
-
-// FIXIT-L move to proto specific where possible
-#define STREAM_CONFIG_STATEFUL_INSPECTION      0x00000001
-#define STREAM_CONFIG_LOG_STREAMS              0x00000004
-#define STREAM_CONFIG_REASS_CLIENT             0x00000008
-#define STREAM_CONFIG_REASS_SERVER             0x00000010
-#define STREAM_CONFIG_ASYNC                    0x00000020
-#define STREAM_CONFIG_SHOW_PACKETS             0x00000040
-#define STREAM_CONFIG_MIDSTREAM_DROP_NOALERT   0x00000080
-#define STREAM_CONFIG_IGNORE_ANY               0x00000100
-#define STREAM_CONFIG_STATIC_FLUSHPOINTS       0x00000200
-#define STREAM_CONFIG_IPS                      0x00000400
-#define STREAM_CONFIG_NO_ASYNC_REASSEMBLY      0x00000800
-
-// shared stream state
-extern THREAD_LOCAL class FlowControl* flow_con;
-extern const PegInfo base_pegs[];
-
-const PegInfo* Stream_GetNormPegs();
-NormPegs Stream_GetNormCounts(unsigned&);
+
+/* traffic direction identification */
+#define FROM_SERVER     0
+#define FROM_CLIENT     1
+
+#define SSN_MISSING_NONE   0x00
+#define SSN_MISSING_BEFORE 0x01
+#define SSN_MISSING_AFTER  0x02
+#define SSN_MISSING_BOTH   (SSN_MISSING_BEFORE | SSN_MISSING_AFTER)
+
+#define SSN_DIR_NONE           0x00
+#define SSN_DIR_FROM_CLIENT    0x01
+#define SSN_DIR_FROM_SERVER    0x02
+#define SSN_DIR_BOTH           0x03
+
+// sequence must match FRAG_POLICY_* enum in stream_ip.h (1-based)
+#define IP_POLICIES  \
+     "first | linux | bsd | bsd_right | last | windows | solaris"
+
+// sequence must match STREAM_POLICY_* defines in tcp_session.cc (1-based)
+#define TCP_POLICIES \
+    "first | last | linux | old_linux | bsd | macos | solaris | irix | " \
+    "hpux11 | hpux10 | windows | win_2003 | vista | proxy"
+
+class Flow;
+
+typedef int (* LogFunction)(Flow*, uint8_t** buf, uint32_t* len, uint32_t* type);
+typedef void (* LogExtraData)(Flow*, void* config, LogFunction* funcs,
+    uint32_t max_count, uint32_t xtradata_mask, uint32_t id, uint32_t sec);
+
+#define MAX_LOG_FN 32
+
+//-------------------------------------------------------------------------
+
+class SO_PUBLIC Stream
+{
+public:
+    // for shutdown only
+    static void purge_flows();
+
+    static void timeout_flows(time_t cur_time);
+    static void prune_flows();
+    static bool expected_flow(Flow*, Packet*);
+    static Flow* new_flow(FlowKey*);
+
+    // Looks in the flow cache for flow session with specified key and returns
+    // pointer to flow session oject if found, otherwise null.
+    static Flow* get_flow(const FlowKey*);
+
+    // Allocates a flow session object from the flow cache table for the protocol
+    // type of the specified key.  If no cache exists for that protocol type null is
+    // returned.  If a flow already exists for the key a pointer to that session
+    // object is returned.
+    // If a new session object can not be allocated the program is terminated.
+    static Flow* new_flow(const FlowKey*);
+
+    // Removes the flow session object from the flow cache table and returns
+    // the resources allocated to that flow to the free list.
+    static void delete_flow(const FlowKey*);
+
+    // Examines the source and destination ip addresses and ports to determine if the
+    // packet is from the client or server side of the flow and sets bits in the
+    // packet_flags field of the Packet struct to indicate the direction determined.
+    static uint32_t get_packet_direction(Packet*);
+
+    // Sets the stream session into proxy mode.
+    static void proxy_started(Flow*, unsigned dir);  // FIXIT-L method name is misleading
+
+    // Stop inspection on a flow for up to count bytes (-1 to ignore for life or until resume).
+    // If response flag is set, automatically resume inspection up to count bytes when a data
+    // packet in the other direction is seen.  Also marks the packet to be ignored
+    // FIXIT-L stop_inspection() does not currently support the bytes/response parameters
+    static void stop_inspection(Flow*, Packet*, char dir, int32_t bytes, int rspFlag);
+
+    // Adds entry to the expected session cache with a flow key generated from the network
+    // n-tuple parameters specified.  Inspection will be turned off for this expected session
+    // when it arrives.
+    static int ignore_flow(
+        const sfip_t *addr1, uint16_t p1, const sfip_t *addr2, uint16_t p2,
+        PktType, char dir, uint32_t ppId);
+
+    // Resume inspection for flow.
+    // FIXIT-L does resume work only for a flow that has been stopped by call to stop_inspection?
+    static void resume_inspection(Flow*, char dir);
+
+    // Set Active status to force drop the current packet and set flow state to drop
+    // subsequent packets arriving from the direction specified.
+    static void drop_traffic(Flow*, char dir);
+
+    // Mark a flow as dropped, release allocated resources, and set flow state such that any
+    // subsequent packets received on this flow are dropped.
+    static void drop_flow(const Packet*);
+
+    // FIXIT-L flush_request() / flush_response() are misnomers in ips mode and may cause errors
+
+    // Flush queued data on the listener side of a stream flow.  The listener is the side of the
+    // connection the packet is destined, so if the Packet is from the client, then the
+    // server side tracker is flushed.
+    static void flush_request(Packet*);  // flush listener
+
+    // Flush queued data on the talker side of a stream flow.  The talker is the side of the
+    // connection the packet originated from, so if the Packet is from the client, then the
+    // client side tracker is flushed.
+     static void flush_response(Packet*);  // flush talker
+
+    // Add session alert - true if added
+    static bool add_flow_alert(Flow*, Packet*, uint32_t gid, uint32_t sid);
+
+    // Check session alert - true if previously alerted
+    static bool check_flow_alerted(Flow*, Packet* p, uint32_t gid, uint32_t sid);
+
+    // Set Extra Data Logging
+    static int update_flow_alert(
+        Flow*, Packet* p, uint32_t gid, uint32_t sid,
+        uint32_t eventId, uint32_t eventSecond);
+
+    // Get reassembly direction for given session
+    static char get_reassembly_direction(Flow*);
+
+    // Returns true if stream data for the flow is in sequence, otherwise return false.
+    static bool is_stream_sequenced(Flow*, uint8_t dir);
+
+    // Get state of missing packets for the flow.
+    //      SSN_MISSING_BOTH if missing before and after
+    //      SSN_MISSING_BEFORE if missing before
+    //      SSN_MISSING_AFTER if missing after
+    //      SSN_MISSING_NONE if none missing
+    static int missing_in_reassembled(Flow*, uint8_t dir);
+
+    // Returns true if packets were missed on the stream, otherwise returns false.
+    static bool missed_packets(Flow*, uint8_t dir);
+
+    // Get the protocol identifier from a stream
+    static int16_t get_application_protocol_id(Flow*);
+
+    // Set the protocol identifier for a stream
+    static int16_t set_application_protocol_id(Flow*, int16_t appId);
+
+    // initialize response count and expiration time
+    static void init_active_response(const Packet*, Flow*);
+
+    static void set_splitter(Flow*, bool toServer, class StreamSplitter* = nullptr);
+    static StreamSplitter* get_splitter(Flow*, bool toServer);
+    static bool is_paf_active(Flow*, bool toServer);
+
+    // Turn off inspection for potential session. Adds session identifiers to a hash table.
+    // TCP only.
+    static int set_application_protocol_id_expected(
+        const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2, PktType,
+        int16_t appId, FlowData*);
+
+    // Get pointer to application data for a flow based on the lookup tuples for cases where
+    // Snort does not have an active packet that is relevant.
+    static FlowData* get_flow_data(
+        PktType type, IpProtocol proto,
+        const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2,
+        uint16_t vlanId, uint32_t mplsId, uint16_t addrSpaceId, unsigned flow_id);
+
+    // Get pointer to application data for a flow using the FlowKey as the lookup criteria
+    static FlowData* get_flow_data(const FlowKey*, unsigned flow_id);
+
+    // Get pointer to a session flow instance for a flow based on the lookup tuples for
+    // cases where Snort does not have an active packet that is relevant.
+    static Flow* get_flow(
+        PktType type, IpProtocol proto,
+        const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2,
+        uint16_t vlanId, uint32_t mplsId, uint16_t addrSpaceId);
+
+    // Delete the session if it is in the closed session state.
+    static void check_flow_closed(Packet*);
+
+    //  Create a session key from the Packet
+    static FlowKey* get_flow_key(Packet*);
+
+    //  Populate a session key from the Packet
+    static void populate_flow_key(Packet*, FlowKey*);
+
+    static void update_direction(Flow*, char dir, const sfip_t* ip, uint16_t port);
+
+    static void set_application_protocol_id(
+        Flow*, const struct HostAttributeEntry*, int direction);
+
+    static bool is_midstream(Flow* flow)
+    { return flow->ssn_state.session_flags & SSNFLAG_MIDSTREAM; }
+
+    // Get the TTL value used at session setup
+    // Set outer=false to get inner ip ttl for ip in ip; else outer=true
+    static uint8_t get_flow_ttl(Flow*, char dir, bool outer);
+
+    static bool expired_flow(Flow*, Packet*);
+    static bool ignored_flow(Flow*, Packet*);
+    static bool blocked_flow(Flow*, Packet*);
+
+    // extra data methods
+    static void set_extra_data(Flow*, Packet*, uint32_t);
+    static void clear_extra_data(Flow*, Packet*, uint32_t);
+    static void log_extra_data(Flow*, uint32_t mask, uint32_t id, uint32_t sec);
+
+    static uint32_t reg_xtra_data_cb(LogFunction);
+    static void reg_xtra_data_log(LogExtraData, void*);
+    static uint32_t get_xtra_data_map(LogFunction**);
+
+private:
+    static void set_ip_protocol(Flow*);
+};
 
 #endif
 
diff --git a/src/stream/stream_api.h b/src/stream/stream_api.h
deleted file mode 100644 (file)
index cd4817c..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2016 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2005-2013 Sourcefire, Inc.
-//
-// 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.
-//--------------------------------------------------------------------------
-
-// stream_api.h author Steven Sturges
-
-#ifndef STREAM_API_H
-#define STREAM_API_H
-
-/*
- * Purpose: Definition of the StreamAPI.  To be used as a common interface
- *          for TCP (and later UDP & ICMP) Stream access for other
- *          preprocessors and detection plugins.
- */
-
-#include <sys/types.h>
-
-#include "sfip/sfip_t.h"
-#include "protocols/packet.h"
-#include "flow/flow.h"
-#include "main/snort_types.h"
-
-/* traffic direction identification */
-#define FROM_SERVER     0
-#define FROM_CLIENT     1
-
-#define SSN_MISSING_NONE   0x00
-#define SSN_MISSING_BEFORE 0x01
-#define SSN_MISSING_AFTER  0x02
-#define SSN_MISSING_BOTH   (SSN_MISSING_BEFORE | SSN_MISSING_AFTER)
-
-#define SSN_DIR_NONE           0x00
-#define SSN_DIR_FROM_CLIENT    0x01
-#define SSN_DIR_FROM_SERVER    0x02
-#define SSN_DIR_BOTH           0x03
-
-// sequence must match FRAG_POLICY_* enum in stream_ip.h (1-based)
-#define IP_POLICIES  \
-     "first | linux | bsd | bsd_right | last | windows | solaris"
-
-// sequence must match STREAM_POLICY_* defines in tcp_session.cc (1-based)
-#define TCP_POLICIES \
-    "first | last | linux | old_linux | bsd | macos | solaris | irix | " \
-    "hpux11 | hpux10 | windows | win_2003 | vista | proxy"
-
-class Flow;
-
-typedef int (* LogFunction)(Flow*, uint8_t** buf, uint32_t* len, uint32_t* type);
-typedef void (* LogExtraData)(Flow*, void* config, LogFunction* funcs,
-    uint32_t max_count, uint32_t xtradata_mask, uint32_t id, uint32_t sec);
-
-typedef int (* PacketIterator)
-(
-    DAQ_PktHdr_t*,
-    uint8_t*,    /* pkt pointer */
-    void*        /* user-defined data pointer */
-);
-
-typedef int (* StreamSegmentIterator)
-(
-    DAQ_PktHdr_t*,
-    uint8_t*,    /* pkt pointer */
-    uint8_t*,    /* payload pointer */
-    uint32_t,    /* sequence number */
-    void*        /* user-defined data pointer */
-);
-
-#define MAX_LOG_FN 32
-
-//-------------------------------------------------------------------------
-// public methods other than ctor / dtor must all be declared SO_PUBLIC
-//-------------------------------------------------------------------------
-
-class SO_PUBLIC Stream
-{
-public:
-    SO_PRIVATE Stream();
-    SO_PRIVATE ~Stream();
-
-    // Looks in the flow cache for flow session with specified key and returns
-    // pointer to flow session oject if found, otherwise null.
-    static Flow* get_session(const FlowKey*);
-
-    // Allocates a flow session object from the flow cache table for the protocol
-    // type of the specified key.  If no cache exists for that protocol type null is
-    // returned.  If a flow already exists for the key a pointer to that session
-    // object is returned.
-    // If a new session object can not be allocated the program is terminated.
-    static Flow* new_session(const FlowKey*);
-
-    // Removes the flow session object from the flow cache table and returns
-    // the resources allocated to that flow to the free list.
-    static void delete_session(const FlowKey*);
-
-    // Examines the source and destination ip addresses and ports to determine if the
-    // packet is from the client or server side of the flow and sets bits in the
-    // packet_flags field of the Packet struct to indicate the direction determined.
-    static uint32_t get_packet_direction(Packet*);
-
-    // Sets the stream session into proxy mode.
-    static void proxy_started(Flow*, unsigned dir);  // FIXIT-L method name is misleading
-
-    // Stop inspection on a flow for up to count bytes (-1 to ignore for life or until resume).
-    // If response flag is set, automatically resume inspection up to count bytes when a data
-    // packet in the other direction is seen.  Also marks the packet to be ignored
-    // FIXIT-L stop_inspection() does not currently support the bytes/response parameters
-    static void stop_inspection(Flow*, Packet*, char dir, int32_t bytes, int rspFlag);
-
-    // Adds entry to the expected session cache with a flow key generated from the network
-    // n-tuple parameters specified.  Inspection will be turned off for this expected session
-    // when it arrives.
-    int ignore_session( const sfip_t *addr1, uint16_t p1, const sfip_t *addr2, uint16_t p2,
-        PktType, char dir, uint32_t ppId);
-
-    // Resume inspection for flow.
-    // FIXIT-L does resume work only for a flow that has been stopped by call to stop_inspection?
-    static void resume_inspection(Flow*, char dir);
-
-    // Set Active status to force drop the current packet and set flow state to drop
-    // subsequent packets arriving from the direction specified.
-    static void drop_traffic(Flow*, char dir);
-
-    // Mark a flow as dropped, release allocated resources, and set flow state such that any
-    // subsequent packets received on this flow are dropped.
-    static void drop_session(const Packet*);
-
-    // FIXIT-L flush_request() / flush_response() are misnomers in ips mode and may cause errors
-
-    // Flush queued data on the listener side of a stream flow.  The listener is the side of the
-    // connection the packet is destined, so if the Packet is from the client, then the
-    // server side tracker is flushed.
-    static void flush_request(Packet*);  // flush listener
-
-    // Flush queued data on the talker side of a stream flow.  The talker is the side of the
-    // connection the packet originated from, so if the Packet is from the client, then the
-    // client side tracker is flushed.
-     static void flush_response(Packet*);  // flush talker
-
-    // Add session alert - true if added
-    static bool add_session_alert(Flow*, Packet*, uint32_t gid, uint32_t sid);
-
-    // Check session alert - true if previously alerted
-    static bool check_session_alerted(Flow*, Packet* p, uint32_t gid, uint32_t sid);
-
-    // Set Extra Data Logging
-    static int update_session_alert(
-        Flow*, Packet* p, uint32_t gid, uint32_t sid,
-        uint32_t eventId, uint32_t eventSecond);
-
-    // Get pointer to Flowbits data
-    static BitOp* get_flow_bitop(const Packet*);
-
-    // Get reassembly direction for given session
-    static char get_reassembly_direction(Flow*);
-
-    // Returns true if stream data for the flow is in sequence, otherwise return false.
-    static bool is_stream_sequenced(Flow*, uint8_t dir);
-
-    // Get state of missing packets for the flow.
-    //      SSN_MISSING_BOTH if missing before and after
-    //      SSN_MISSING_BEFORE if missing before
-    //      SSN_MISSING_AFTER if missing after
-    //      SSN_MISSING_NONE if none missing
-    static int missing_in_reassembled(Flow*, uint8_t dir);
-
-    // Returns true if packets were missed on the stream, otherwise returns false.
-    static bool missed_packets(Flow*, uint8_t dir);
-
-    // Get the protocol identifier from a stream
-    static int16_t get_application_protocol_id(Flow*);
-
-    // Set the protocol identifier for a stream
-    static int16_t set_application_protocol_id(Flow*, int16_t appId);
-
-    // initialize response count and expiration time
-    static void init_active_response(const Packet*, Flow*);
-
-    static void set_splitter(Flow*, bool toServer, class StreamSplitter* = nullptr);
-    static StreamSplitter* get_splitter(Flow*, bool toServer);
-    static bool is_paf_active(Flow*, bool toServer);
-
-    // Turn off inspection for potential session. Adds session identifiers to a hash table.
-    // TCP only.
-    int set_application_protocol_id_expected(
-        const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2, PktType,
-        int16_t appId, FlowData*);
-
-    // Get pointer to application data for a flow based on the lookup tuples for cases where
-    // Snort does not have an active packet that is relevant.
-    static FlowData* get_application_data_from_ip_port(
-        PktType type, IpProtocol proto,
-        const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2,
-        uint16_t vlanId, uint32_t mplsId, uint16_t addrSpaceId, unsigned flow_id);
-
-    // Get pointer to application data for a flow using the FlowKey as the lookup criteria
-     static FlowData* get_application_data_from_key(const FlowKey*, unsigned flow_id);
-
-    // -- extra data methods
-    uint32_t reg_xtra_data_cb(LogFunction);
-    void reg_xtra_data_log(LogExtraData, void*);
-    uint32_t get_xtra_data_map(LogFunction**);
-
-    static void set_extra_data(Flow*, Packet*, uint32_t);
-    static void clear_extra_data(Flow*, Packet*, uint32_t);
-    void log_extra_data(Flow*, uint32_t mask, uint32_t id, uint32_t sec);
-
-    // Get pointer to a session flow instance for a flow based on the lookup tuples for
-    // cases where Snort does not have an active packet that is relevant.
-     static Flow* get_session_ptr_from_ip_port(
-        PktType type, IpProtocol proto,
-        const sfip_t *a1, uint16_t p1, const sfip_t *a2, uint16_t p2,
-        uint16_t vlanId, uint32_t mplsId, uint16_t addrSpaceId);
-
-    // Delete the session if it is in the closed session state.
-    void check_session_closed(Packet*);
-
-    //  Create a session key from the Packet
-    static FlowKey* get_session_key(Packet*);
-
-    //  Populate a session key from the Packet
-    static void populate_session_key(Packet*, FlowKey*);
-
-    void update_direction(Flow*, char dir, const sfip_t* ip, uint16_t port);
-
-    static void set_application_protocol_id_from_host_entry(
-        Flow*, const struct HostAttributeEntry*, int direction);
-
-    static bool is_midstream(Flow* flow)
-    { return flow->ssn_state.session_flags & SSNFLAG_MIDSTREAM; }
-
-    // Get the TTL value used at session setup
-    // Set outer=false to get inner ip ttl for ip in ip; else outer=true
-    static uint8_t get_session_ttl(Flow*, char dir, bool outer);
-
-    static bool expired_session(Flow*, Packet*);
-    static bool ignored_session(Flow*, Packet*);
-    static bool blocked_session(Flow*, Packet*);
-
-private:
-    static void set_ip_protocol(Flow*);
-
-private:
-    uint32_t xtradata_func_count = 0;
-    LogFunction xtradata_map[MAX_LOG_FN];
-    LogExtraData extra_data_log = NULL;
-    void* extra_data_config = NULL;
-};
-
-SO_PUBLIC extern Stream stream;
-
-#endif
-
index 584693a709e47c37e7c7644668c4c1a3dcc15a31..eb8240a1eb7fa73ebc14449a7c681d4ab18f9f60 100644 (file)
@@ -25,7 +25,7 @@
 #include "flush_bucket.h"
 #include "protocols/packet.h"
 
-static THREAD_LOCAL uint8_t pdu_buf[65536];
+static THREAD_LOCAL uint8_t pdu_buf[StreamSplitter::max_buf];
 static THREAD_LOCAL StreamBuffer str_buf;
 
 unsigned StreamSplitter::max_pdu = 16384;
index 2be13751231e39449f4af7951603c34983520c74..e45a57095c7b1eb3082f4e3927278bbfddf8943c 100644 (file)
@@ -84,6 +84,9 @@ public:
     // paf_max; the HI splitter should pull from there
     static void set_max(unsigned);
 
+    // FIXIT-L max_pdu should suffice
+    static const unsigned max_buf = 65536;
+
     virtual void reset() { }
     virtual void update() { }
 
index d3cc981cb16921430e519bdec41a405fec059b3a..b4bc8bcadce18547683cb511981835d41327bad4 100644 (file)
@@ -42,4 +42,23 @@ State information includes:
 An instance of this data structure is allocated and managed for each end of
 the connection.
 
-
+The module tcp_ha.cc (and tcp_ha.h) implements the per-protocol hooks into
+the stream logic for HA.  TcpHAManager is a static class that interfaces
+to a per-packet thread instance of the class TcpHA.  TcpHA is sub-class
+of ProtocolHA, declared in the stream/base area.  Thus each protocol
+within 'stream' can have specific HA logic and interfaces.
+
+TcpHAManager::process_deletion() is called when an TCP stream is being 
+destroyed and indicates to the stream & flow HA logic that a flow
+deletion HA message needs to be emitted for the flow in question.
+Tcp streams are both closed internally (e.g. FIN) and externally due
+to cache timeout or pruning.  The calls to TcpHAManager::process_deletion()
+in tcp/tcp_session.cc indicate a normal closure of a stream/flow.  
+
+TcpHA::create_session() is called from the stream & flow HA logic and
+handles the creation of new flow upon receiving an HA update message.
+
+TcpHA::deactivate_session() is called from the stream & flow HA logic to 
+place a session into standby mode.  Upon receiving an HA Update message, 
+the flow is first created if necessary, and is then placed into Standby
+state.  deactivate_session() sets the TCP specific state for Standy mode.
index f026e64b0a3f1afbfd020e8431d33515882858fe..ef0eced4c262c01b46aae9e1314b178ab03e9e3e 100644 (file)
@@ -124,13 +124,13 @@ int ReassembleOption::eval(Cursor&, Packet* pkt)
             if ( srod.direction & SSN_DIR_FROM_SERVER )
             {
                 tcpssn->server->flush_policy = STREAM_FLPOLICY_IGNORE;
-                stream.set_splitter(lwssn, true);
+                Stream::set_splitter(lwssn, true);
             }
 
             if ( srod.direction & SSN_DIR_FROM_CLIENT )
             {
                 tcpssn->client->flush_policy = STREAM_FLPOLICY_IGNORE;
-                stream.set_splitter(lwssn, false);
+                Stream::set_splitter(lwssn, false);
             }
         }
         else
@@ -140,13 +140,13 @@ int ReassembleOption::eval(Cursor&, Packet* pkt)
             if ( srod.direction & SSN_DIR_FROM_SERVER )
             {
                 tcpssn->server->flush_policy = STREAM_FLPOLICY_ON_ACK;
-                stream.set_splitter(lwssn, true, new AtomSplitter(true));
+                Stream::set_splitter(lwssn, true, new AtomSplitter(true));
             }
 
             if ( srod.direction & SSN_DIR_FROM_CLIENT )
             {
                 tcpssn->client->flush_policy = STREAM_FLPOLICY_ON_ACK;
-                stream.set_splitter(lwssn, false, new AtomSplitter(false));
+                Stream::set_splitter(lwssn, false, new AtomSplitter(false));
             }
         }
 
@@ -316,7 +316,7 @@ TEST_CASE("IPS Stream Reassemble", "[ips_stream_reassemble][stream_tcp]")
         IpsOption* ropt = reassemble_api.ctor(reassembler, nullptr);
         int rc = ropt->eval(cursor, pkt);
         CHECK( ( rc == DETECTION_OPTION_MATCH ) );
-        StreamSplitter* ss = stream.get_splitter(flow, true);
+        StreamSplitter* ss = Stream::get_splitter(flow, true);
         CHECK( ( ss != nullptr ) );
         CHECK( ( !ss->is_paf() ) );
         CHECK( ( ( ( TcpSession* )pkt->flow->session)->server.flush_policy
index e9ef45653805127dab27171cfb715de7f3b9b90f..5c557b915ee78655379131f4dfd4951f7f7bf8ee 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef SEGMENT_OVERLAP_EDITOR_H
 #define SEGMENT_OVERLAP_EDITOR_H
 
+#include "normalize/normalize.h"
 #include "tcp_defs.h"
 #include "tcp_segment_node.h"
 #include "tcp_session.h"
index 30b208cb00bee14cc245d694f811f13669bafdaa..25ad3c8e7f084e92d953587aa54945a1d170b883 100644 (file)
@@ -20,7 +20,6 @@
 #define STREAM_TCP_H
 
 #include "flow/flow.h"
-#include "stream/stream_api.h"
 #include "protocols/packet.h"
 
 #include "tcp_defs.h"
index 8bdac94ee6b970c32e54a6cb5bbabc91a94fd1dd..23233f0fb9fcb8b7a1dd3b200e0f28eb79aef149 100644 (file)
@@ -73,7 +73,7 @@
 
 #define SLAM_MAX 4
 
-// target-based policy types - changes to this enum require changes to stream_api.h::TCP_POLICIES
+// target-based policy types - changes to this enum require changes to stream.h::TCP_POLICIES
 enum class StreamPolicy
 {
     OS_INVALID = 0,
index 85b9ac2313c77bac1b02685b66d76af5203a266b..6952c16990dd988eaf113472b5dd372ee0469579 100644 (file)
 
 #include "tcp_ha.h"
 
-#include "flow/flow_control.h"
 #include "main/snort_debug.h"
-#include "stream/tcp/tcp_session.h"
+#include "stream/stream.h"
+#include "tcp_session.h"
 
 Flow* TcpHA::create_session(FlowKey* key)
 {
-    DebugMessage(DEBUG_HA,"TcpHA::create_session)\n");
+    assert(key);
 
-    assert ( key );
-
-    Flow* flow = flow_con->new_flow(key);
+    Flow* flow = Stream::new_flow(key);
 
     if ( (flow != nullptr ) && (flow->session == nullptr) )
     {
index 39250f92a4dc175d36038f1d3c924f026ac3a9ea..670f86e68befddda2de0ab5396b1321ce64fae7b 100644 (file)
@@ -23,8 +23,8 @@
 #include <string>
 
 #include "profiler/profiler.h"
-#include "stream_tcp.h"
 #include "stream/stream.h"
+#include "stream_tcp.h"
 
 using namespace std;
 
@@ -228,8 +228,8 @@ ProfileStats* StreamTcpModule::get_profile(
     switch ( index )
     {
     case 0:
-        name = "stream_tcp";
-        parent = nullptr;
+        name = MOD_NAME;
+        parent = "stream";
         return &s5TcpPerfStats;
 
     case 1:
index b5654697521f2ecb9dc76b6ec0f550c21ff2d9bb..1dd5b18624c8114b298e859c7d46fa30cf6e638e 100644 (file)
@@ -26,8 +26,8 @@
 
 #include "main/snort_types.h"
 #include "main/thread.h"
+#include "flow/session.h"
 #include "framework/module.h"
-#include "stream/stream.h"
 #include "tcp_stream_config.h"
 
 #define GID_STREAM_TCP  129
index c3581023d8824e18f2ce819bfa2e6651aae9015a..256e32097edfa0e35d880aadd0dda0fc9bec057c 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "main/snort.h"
 #include "protocols/packet.h"
-#include "stream/stream.h"
+#include "protocols/packet_manager.h"
 #include "profiler/profiler.h"
 #include "flow/flow_control.h"
 
@@ -305,7 +305,7 @@ int TcpReassembler::purge_alerts(uint32_t /*flush_seq*/,  Flow* flow)
 
         //if (SEQ_LT(ai->seq, flush_seq) )
         {
-            stream.log_extra_data(flow, xtradata_mask, ai->event_id, ai->event_second);
+            Stream::log_extra_data(flow, xtradata_mask, ai->event_id, ai->event_second);
             memset(ai, 0, sizeof(*ai));
         }
 #if 0
@@ -457,14 +457,12 @@ void TcpReassembler::show_rebuilt_packet(Packet* pkt)
     }
 }
 
-uint32_t TcpReassembler::get_flush_data_len(TcpSegmentNode* tsn, uint32_t to_seq,
-    uint32_t flushBufSize)
+uint32_t TcpReassembler::get_flush_data_len(TcpSegmentNode* tsn, uint32_t to_seq, unsigned max)
 {
     unsigned int flushSize = tsn->payload_size;
 
-    // copy only till flush buffer gets full
-    if ( flushSize > flushBufSize )
-        flushSize = flushBufSize;
+    if ( flushSize > max )
+        flushSize = max;
 
     // copy only to flush point
     if ( paf_active(&tracker->paf_state) && SEQ_GT(tsn->seq + flushSize, to_seq) )
@@ -474,10 +472,9 @@ uint32_t TcpReassembler::get_flush_data_len(TcpSegmentNode* tsn, uint32_t to_seq
 }
 
 // flush the client seglist up to the most recently acked segment
-int TcpReassembler::flush_data_segments(Packet* p, uint32_t toSeq, uint8_t* flushbuf,
-    const uint8_t* flushbuf_end)
+int TcpReassembler::flush_data_segments(Packet* p, uint32_t toSeq)
 {
-    uint16_t bytes_flushed = 0;
+    uint32_t bytes_flushed = 0;
     uint32_t segs = 0;
     uint32_t flags = PKT_PDU_HEAD;
     DEBUG_WRAP(uint32_t bytes_queued = seg_bytes_logical; );
@@ -489,8 +486,7 @@ int TcpReassembler::flush_data_segments(Packet* p, uint32_t toSeq, uint8_t* flus
     while ( SEQ_LT(seglist.next->seq, toSeq) )
     {
         TcpSegmentNode* tsn = seglist.next, * sr = nullptr;
-        unsigned flushbuf_size = flushbuf_end - flushbuf;
-        unsigned bytes_to_copy = get_flush_data_len(tsn, toSeq, flushbuf_size);
+        unsigned bytes_to_copy = get_flush_data_len(tsn, toSeq, tracker->splitter->max(p->flow));
         unsigned bytes_copied = 0;
         assert(bytes_to_copy);
 
@@ -500,25 +496,20 @@ int TcpReassembler::flush_data_segments(Packet* p, uint32_t toSeq, uint8_t* flus
             || SEQ_EQ(tsn->seq +  bytes_to_copy, toSeq) )
             flags |= PKT_PDU_TAIL;
 
-        const StreamBuffer* sb = tracker->splitter->reassemble(p->flow, total, bytes_flushed,
-            tsn->payload,
-            bytes_to_copy, flags, bytes_copied);
+        const StreamBuffer* sb = tracker->splitter->reassemble(
+            p->flow, total, bytes_flushed, tsn->payload, bytes_to_copy, flags, bytes_copied);
+
         flags = 0;
+
         if ( sb )
         {
             s5_pkt->data = sb->data;
             s5_pkt->dsize = sb->length;
             assert(sb->length <= s5_pkt->max_dsize);
 
-            // FIXIT-M flushbuf should be eliminated from this function
-            // since we are actually using the stream splitter buffer
-            flushbuf = ( uint8_t* )s5_pkt->data;
-            // ensure we stop here
             bytes_to_copy = bytes_copied;
         }
         assert(bytes_to_copy == bytes_copied);
-
-        flushbuf += bytes_to_copy;
         bytes_flushed += bytes_to_copy;
 
         if ( bytes_to_copy < tsn->payload_size
@@ -533,9 +524,6 @@ int TcpReassembler::flush_data_segments(Packet* p, uint32_t toSeq, uint8_t* flus
         flush_count++;
         segs++;
 
-        if ( flushbuf >= flushbuf_end )
-            break;
-
         if ( SEQ_EQ(tsn->seq + bytes_to_copy, toSeq) )
             break;
 
@@ -550,13 +538,19 @@ int TcpReassembler::flush_data_segments(Packet* p, uint32_t toSeq, uint8_t* flus
             if ( tsn->next )
                 seglist.next = tsn->next;
 
-            tracker->set_tf_flags(TF_MISSING_PKT);
+            // FIXIT-L this is suboptimal - better to exclude fin from toSeq
+            if ( !tracker->fin_set() or SEQ_LT(toSeq, tracker->fin_final_seq) )
+                tracker->set_tf_flags(TF_MISSING_PKT);
+
             break;
         }
         seglist.next = tsn->next;
 
         if ( sb || !seglist.next )
             break;
+
+        if ( bytes_flushed + seglist.next->payload_size >= StreamSplitter::max_buf )
+            break;
     }
 
     DEBUG_WRAP(bytes_queued -= bytes_flushed; );
@@ -634,10 +628,6 @@ int TcpReassembler::_flush_to_seq(uint32_t bytes, Packet* p, uint32_t pkt_flags)
 
     prep_s5_pkt(session->flow, p, pkt_flags);
 
-    // if not specified, set bytes to flush to what was acked
-    if (!bytes && SEQ_GT(tracker->r_win_base, seglist_base_seq))
-        bytes = tracker->r_win_base - seglist_base_seq;
-
     // FIXIT-L this should not be necessary here
     seglist_base_seq = seglist.next->seq;
     stop_seq = seglist_base_seq + bytes;
@@ -676,9 +666,8 @@ int TcpReassembler::_flush_to_seq(uint32_t bytes, Packet* p, uint32_t pkt_flags)
 
         /* setup the pseudopacket payload */
         s5_pkt->dsize = 0;
-        s5_pkt->data = s5_pkt->pkt;
-        const uint8_t* s5_pkt_end = s5_pkt->data + s5_pkt->max_dsize;
-        flushed_bytes = flush_data_segments(p, stop_seq, (uint8_t*)s5_pkt->data, s5_pkt_end);
+        s5_pkt->data = nullptr;
+        flushed_bytes = flush_data_segments(p, stop_seq);
 
         if ( flushed_bytes == 0 )
             break; /* No more data... bail */
@@ -783,28 +772,26 @@ int TcpReassembler::flush_to_seq(uint32_t bytes, Packet* p, uint32_t pkt_flags)
     return _flush_to_seq(bytes, p, pkt_flags);
 }
 
-// FIXIT-H the seq number math in the following 2 funcs does not handle
-// wrapping get the footprint for the current seglist, the difference
+// get the footprint for the current seglist, the difference
 // between our base sequence and the last ack'd sequence we received
 
 uint32_t TcpReassembler::get_q_footprint()
 {
-    int32_t fp;
-
-    if ( tracker == nullptr )
-        return 0;
-
-    fp = tracker->r_win_base - seglist_base_seq;
-    if ( fp <= 0 )
+    if ( !tracker )
         return 0;
 
     seglist.next = seglist.head;
+    uint32_t fp = tracker->r_win_base - seglist_base_seq;
+
+    // FIXIT-M ideally would exclude fin here
+
     return fp;
 }
 
 // FIXIT-P get_q_sequenced() performance could possibly be
 // boosted by tracking sequenced bytes as seglist is updated
 // to avoid the while loop, etc. below.
+
 uint32_t TcpReassembler::get_q_sequenced()
 {
     int32_t len;
index 9e23578ffe06d42bd5d7ab2d4ebeae7afc483099..951aa86b14e66666c8a933c4dbe4f1a6e577df60 100644 (file)
@@ -25,7 +25,6 @@
 #include "framework/counts.h"
 #include "detection/detect.h"
 #include "normalize/normalize.h"
-#include "stream/stream_api.h"
 
 #include "segment_overlap_editor.h"
 #include "tcp_defs.h"
@@ -146,9 +145,8 @@ protected:
     bool is_segment_fasttrack(TcpSegmentNode* tail, TcpSegmentDescriptor&);
     int purge_alerts(uint32_t /*flush_seq*/,  Flow* flow);
     void show_rebuilt_packet(Packet* pkt);
-    uint32_t get_flush_data_len(TcpSegmentNode* ss, uint32_t to_seq, uint32_t flushBufSize);
-    int flush_data_segments(Packet* p, uint32_t toSeq,  uint8_t* flushbuf,
-            const  uint8_t* flushbuf_end);
+    uint32_t get_flush_data_len(TcpSegmentNode* ss, uint32_t to_seq, unsigned max);
+    int flush_data_segments(Packet* p, uint32_t toSeq);
     void prep_s5_pkt(Flow* flow, Packet* p, uint32_t pkt_flags);
     int _flush_to_seq(uint32_t bytes, Packet* p, uint32_t pkt_flags);
     int flush_to_seq(uint32_t bytes, Packet* p, uint32_t pkt_flags);
index b77d971fa6f488ba1a58e3da20018b4407558c11..8d95c2ef376d53f8536aa8d0970682561c412bc2 100644 (file)
 #include "log/log_text.h"
 #include "stream/stream.h"
 #include "stream/stream_splitter.h"
-#include "flow/flow_control.h"
 #include "flow/session.h"
 #include "profiler/profiler.h"
 #include "file_api/file_api.h"
-#include "normalize/normalize.h"
 #include "perf_monitor/flow_tracker.h"
 #include "filters/sfrf.h"
 
@@ -160,14 +158,14 @@ void TcpSession::clear_session(bool free_flow_data, bool flush_segments, bool re
 {
     if ( client->reassembler )
     {
-        if( flush_segments )
+        if ( flush_segments )
             client->reassembler->flush_queued_segments(flow, true, p);
         client->reassembler->purge_segment_list();
     }
 
     if ( server->reassembler )
     {
-        if( flush_segments )
+        if ( flush_segments )
             server->reassembler->flush_queued_segments(flow, true, p);
         server->reassembler->purge_segment_list();
     }
@@ -179,14 +177,15 @@ void TcpSession::clear_session(bool free_flow_data, bool flush_segments, bool re
     else
         return;
 
-    if (flow->get_session_flags() & SSNFLAG_PRUNED)
+    if ( flow->get_session_flags() & SSNFLAG_PRUNED )
         tcpStats.prunes++;
-    else if (flow->get_session_flags() & SSNFLAG_TIMEDOUT)
+
+    else if ( flow->get_session_flags() & SSNFLAG_TIMEDOUT )
         tcpStats.timeouts++;
 
     update_perf_base_state(TcpStreamTracker::TCP_CLOSED);
 
-    if( restart )
+    if ( restart )
     {
         flow->restart(free_flow_data);
         paf_reset(&client->paf_state);
@@ -234,8 +233,9 @@ void TcpSession::update_perf_base_state(char newState)
             if ( ( session_flags & SSNFLAG_COUNTED_INITIALIZE )
                 && !( session_flags & SSNFLAG_COUNTED_CLOSING ) )
             {
-                assert(tcpStats.sessions_initializing);
-                tcpStats.sessions_initializing--;
+                //assert(tcpStats.sessions_initializing);
+                if ( tcpStats.sessions_initializing )  // FIXIT-L eliminate / fix underflow
+                    tcpStats.sessions_initializing--;
             }
         }
         break;
@@ -248,7 +248,7 @@ void TcpSession::update_perf_base_state(char newState)
 
             if ( session_flags & SSNFLAG_COUNTED_ESTABLISH )
             {
-                assert(tcpStats.sessions_established);
+                //assert(tcpStats.sessions_established);
                 tcpStats.sessions_established--;
 
                 if (perfmon_config  && (perfmon_config->perf_flags & PERF_FLOWIP))
@@ -257,8 +257,9 @@ void TcpSession::update_perf_base_state(char newState)
             }
             else if ( session_flags & SSNFLAG_COUNTED_INITIALIZE )
             {
-                assert(tcpStats.sessions_initializing);
-                tcpStats.sessions_initializing--;
+                //assert(tcpStats.sessions_initializing);
+                if ( tcpStats.sessions_initializing )  // FIXIT-L eliminate / fix underflow
+                    tcpStats.sessions_initializing--;
             }
         }
         break;
@@ -266,13 +267,14 @@ void TcpSession::update_perf_base_state(char newState)
     case TcpStreamTracker::TCP_CLOSED:
         if ( session_flags & SSNFLAG_COUNTED_CLOSING )
         {
-            assert(tcpStats.sessions_closing);
+            //assert(tcpStats.sessions_closing);
             tcpStats.sessions_closing--;
         }
         else if ( session_flags & SSNFLAG_COUNTED_ESTABLISH )
         {
-            assert(tcpStats.sessions_established);
-            tcpStats.sessions_established--;
+            //assert(tcpStats.sessions_established);
+            if ( tcpStats.sessions_established )  // FIXIT-L eliminate / fix underflow
+                tcpStats.sessions_established--;
 
             if ( perfmon_config && ( perfmon_config->perf_flags & PERF_FLOWIP ) )
                 perf_flow_ip->update_state(&flow->client_ip,
@@ -280,8 +282,9 @@ void TcpSession::update_perf_base_state(char newState)
         }
         else if ( session_flags & SSNFLAG_COUNTED_INITIALIZE )
         {
-            assert(tcpStats.sessions_initializing);
-            tcpStats.sessions_initializing--;
+            //assert(tcpStats.sessions_initializing);
+            if ( tcpStats.sessions_initializing )  // FIXIT-L eliminate / fix underflow
+                tcpStats.sessions_initializing--;
         }
         break;
 
@@ -601,7 +604,7 @@ void TcpSession::update_ignored_session(TcpSegmentDescriptor& tsd)
 {
     // FIXIT-L why flush here instead of just purge?
     // s5_ignored_session() may be disabling detection too soon if we really want to flush
-    if (stream.ignored_session(flow, tsd.get_pkt()))
+    if (Stream::ignored_flow(flow, tsd.get_pkt()))
     {
         if ( talker && ( talker->get_tf_flags() & TF_FORCE_FLUSH ) )
         {
@@ -649,7 +652,7 @@ void TcpSession::update_session_on_rst(TcpSegmentDescriptor& tsd, bool flush)
         flush_talker(tsd.get_pkt());
         set_splitter(true, nullptr);
         set_splitter(false, nullptr);
-        flow->free_application_data();
+        flow->free_flow_data();
     }
 
     talker->update_on_rst_sent( );
@@ -831,12 +834,17 @@ TcpStreamTracker::TcpState TcpSession::get_listener_state()
 void TcpSession::check_for_repeated_syn(TcpSegmentDescriptor& tsd)
 {
     uint32_t action = ACTION_NOTHING;
-    if (!SEQ_EQ(tsd.get_seg_seq(), talker->get_iss())
-        && listener->normalizer->packet_dropper(tsd, NORM_TCP_BLOCK))
+
+    if ( !SEQ_EQ(tsd.get_seg_seq(), talker->get_iss()) and
+        listener->normalizer->packet_dropper(tsd, NORM_TCP_BLOCK) )
+    {
         action = ACTION_BAD_PKT;
-    else if (talker->get_tcp_state() >= TcpStreamTracker::TCP_ESTABLISHED)
+    }
+    else if ( talker->get_tcp_state() >= TcpStreamTracker::TCP_ESTABLISHED and
+        talker->get_tcp_state() < TcpStreamTracker::TCP_CLOSED )
+    {
         action = listener->normalizer->handle_repeated_syn(tsd);
-
+    }
     if (action != ACTION_NOTHING)
     {
         /* got a bad SYN on the session, alert! */
@@ -1014,13 +1022,13 @@ bool TcpSession::is_flow_handling_packets(Packet* p)
         flow_ready = false;
     }
 
-    if (stream.blocked_session(flow, p) || (flow->session_state & STREAM_STATE_IGNORE))
+    if (Stream::blocked_flow(flow, p) || (flow->session_state & STREAM_STATE_IGNORE))
         flow_ready = false;
 
-    // FIXIT-L expected flow should be checked by flow_con before we get here
+    // FIXIT-L expected flow should be checked by Stream before we get here
     // harmonize this with that and the checks above
-    char ignore = flow_con->expected_flow(flow, p);
-    if (ignore)
+
+    if ( Stream::expected_flow(flow, p) )
     {
         server->flush_policy = STREAM_FLPOLICY_IGNORE;
         client->flush_policy = STREAM_FLPOLICY_IGNORE;
@@ -1034,7 +1042,7 @@ void TcpSession::cleanup_session_if_expired(Packet* p)
 {
     // Check if the session is expired. Should be done before we do something with
     // the packet...Insert a packet, or handle state change SYN, FIN, RST, etc.
-    if (stream.expired_session(flow, p))
+    if (Stream::expired_flow(flow, p))
     {
         /* Session is timed out, if also reset then restart, otherwise clear */
         if (flow->get_session_flags() & SSNFLAG_RESET)
index 0f6052488c65b667274b659b7c5b5486075dc841..69dc5b648b6e55cfc9dfff20bf82b99b91d0895a 100644 (file)
 // tcp_state_closed.cc author davis mcpherson <davmcphe@@cisco.com>
 // Created on: Jul 30, 2015
 
-#include "stream/stream.h"
+#include "tcp_state_closed.h"
 
 #include "tcp_module.h"
 #include "tcp_tracker.h"
 #include "tcp_session.h"
 #include "tcp_normalizer.h"
-#include "tcp_state_closed.h"
 
 #ifdef UNIT_TEST
 #include "catch/catch.hpp"
index 684ee1642872986eecdc50fedb433753af9d0aa5..b35acb546d13e82f1b5947b572c37eb7059df4cf 100644 (file)
 // tcp_state_none.cc author davis mcpherson <davmcphe@@cisco.com>
 // Created on: Jul 30, 2015
 
-#include "stream/stream.h"
+#include "tcp_state_none.h"
 
 #include "tcp_module.h"
 #include "tcp_tracker.h"
 #include "tcp_session.h"
 #include "tcp_normalizer.h"
-#include "tcp_state_none.h"
 
 #ifdef UNIT_TEST
 #include "catch/catch.hpp"
index 708d67b138beef6787dad546a4f68988b458f20d..7e1c754123342a679cceb8c88681261320bec6b2 100644 (file)
@@ -145,8 +145,10 @@ bool TcpStateSynSent::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
     if ( trk.update_on_rst_recv(tsd) )
     {
         trk.session->update_session_on_rst(tsd, false);
-        trk.session->update_perf_base_state(TcpStreamTracker::TCP_CLOSING);
+        trk.set_tcp_state(TcpStreamTracker::TCP_CLOSED);
+        trk.session->update_perf_base_state(TcpStreamTracker::TCP_CLOSED);
         trk.session->set_pkt_action_flag(ACTION_RST);
+        tsd.get_pkt()->flow->session_state |= STREAM_STATE_CLOSED;
     }
     else
     {
index a8eaab555252aee6631a62d5cb5cd0410108fe09..3727251ea1cddcea6249e1bc1e3a7e9a05cdb5ab 100644 (file)
 #define TCP_STREAM_CONFIG_H
 
 #include "time/packet_time.h"
-#include "stream/stream.h"
-
 #include "tcp_defs.h"
 
+#define STREAM_CONFIG_STATEFUL_INSPECTION      0x00000001
+#define STREAM_CONFIG_LOG_STREAMS              0x00000004
+#define STREAM_CONFIG_REASS_CLIENT             0x00000008
+#define STREAM_CONFIG_REASS_SERVER             0x00000010
+#define STREAM_CONFIG_ASYNC                    0x00000020
+#define STREAM_CONFIG_SHOW_PACKETS             0x00000040
+#define STREAM_CONFIG_MIDSTREAM_DROP_NOALERT   0x00000080
+#define STREAM_CONFIG_IGNORE_ANY               0x00000100
+#define STREAM_CONFIG_STATIC_FLUSHPOINTS       0x00000200
+#define STREAM_CONFIG_IPS                      0x00000400
+#define STREAM_CONFIG_NO_ASYNC_REASSEMBLY      0x00000800
+
+#define STREAM_DEFAULT_SSN_TIMEOUT  30
+
 class TcpStreamConfig
 {
 public:
index 8334709aa9784c27d6a19d348a5eddba74be8355..66d1b4aa92d063091ce9f663004e70439c0b89cf 100644 (file)
@@ -490,7 +490,7 @@ bool TcpTracker::update_on_fin_recv(TcpSegmentDescriptor& tsd)
     r_nxt_ack++;
 
     // set final seq # any packet rx'ed with seq > is bad
-    if ( fin_final_seq == 0 )
+    if ( !fin_set() )
         fin_final_seq = tsd.get_end_seq() + 1;
 
     return true;
index 79bd6cd8fef3351df8e8b64f63d44a75d795b286..81b4ba790e135475b5e5a7a099b50cc7abf5866a 100644 (file)
@@ -87,7 +87,6 @@ public:
     void flush_data_on_fin_recv(TcpSegmentDescriptor& tsd) override;
 
     void init_toolbox() override;
-
 };
 
 #endif
index 7ac0a9fc03c0b8eb0ab99c642768c1a7a7360706..12d5719ef045c180f5a94b1db2ac3793344dea25 100644 (file)
@@ -8,3 +8,17 @@ functions for loading stream UDP configuration and packet evaluation.  The
 packet eval method is not used as the base Stream Inspector delegates
 packets directly to the UDP session packet processing method.
 
+The module udp_ha.cc (and udp_ha.h) implements the per-protocol hooks into
+the stream logic for HA.  UdpHAManager is a static class that interfaces
+to a per-packet thread instance of the class UdpHA.  UdpHA is sub-class
+of ProtocolHA, declared in the stream/base area.  Thus each protocol
+within 'stream' can have specific HA logic and interfaces.
+
+UdpHAManager::process_deletion() is called when an UDP stream is being 
+destroyed and indicates to the stream & flow HA logic that a flow
+deletion HA message needs to be emitted for the flow in question.
+Udp streams are closed due to timeout or puning actions which lead
+to the invocation of process_deletion().
+
+UdpHA::create_session() is called from the stream & flow HA logic and
+handles the creation of new flow upon receiving an HA update message.
index d2df14eb0c6309d8482fb60adf962c60e1ca41af..815278a38fdd9a140bb8112e885ca6ba24647ee1 100644 (file)
 
 #include "udp_ha.h"
 
-#include "flow/flow_control.h"
 #include "main/snort_debug.h"
-#include "stream/udp/udp_session.h"
-
-extern THREAD_LOCAL class FlowControl* flow_con;
+#include "stream/stream.h"
+#include "udp_session.h"
 
 Flow* UdpHA::create_session(FlowKey* key)
 {
-    DebugMessage(DEBUG_HA,"UdpHA::create_session\n");
-
-    assert ( key );
+    assert(key);
 
-    Flow* flow = flow_con->new_flow(key);
+    Flow* flow = Stream::new_flow(key);
 
     if ( (flow != nullptr ) && (flow->session == nullptr) )
     {
index 952817e7a116b51f0ae0dfae62a11041fa653072..f8062ad71cc8f4df6dd397ad3f68fe9ab7ed30a6 100644 (file)
@@ -46,8 +46,14 @@ StreamUdpModule::StreamUdpModule() :
     config = nullptr;
 }
 
-ProfileStats* StreamUdpModule::get_profile() const
+ProfileStats* StreamUdpModule::get_profile(
+    unsigned index, const char*& name, const char*& parent) const
 {
+    if ( index )
+        return nullptr;
+
+    name = MOD_NAME;
+    parent = "stream";
     return &udp_perf_stats;
 }
 
index 8f4c96566a596f7afebe773047649696c7b45072..9d52f303d6ffdbc7d58ca86235d80c86fb74eb60 100644 (file)
@@ -26,8 +26,8 @@
 
 #include "main/snort_types.h"
 #include "main/thread.h"
+#include "flow/session.h"
 #include "framework/module.h"
-#include "stream/stream.h"
 
 struct SnortConfig;
 
@@ -57,7 +57,7 @@ public:
     bool begin(const char*, int, SnortConfig*) override;
     bool end(const char*, int, SnortConfig*) override;
 
-    ProfileStats* get_profile() const override;
+    ProfileStats* get_profile(unsigned, const char*&, const char*&) const override;
     const PegInfo* get_pegs() const override;
     PegCount* get_counts() const override;
     StreamUdpConfig* get_data();
index 87d6fd39623c4034c9f770eb6b7784a8da859c77..cac2649a5d4e107570e776bf803136182e81a2a4 100644 (file)
 #include "config.h"
 #endif
 
-#include "stream_udp.h"
-#include "udp_module.h"
-#include "udp_ha.h"
-
 #include "stream/stream.h"
 #include "main/snort_types.h"
 #include "main/snort_debug.h"
 #include "hash/sfxhash.h"
 #include "utils/util.h"
 #include "protocols/packet.h"
-#include "flow/flow_control.h"
 #include "flow/session.h"
 #include "packet_io/active.h"
+#include "perf_monitor/flow_ip_tracker.h"
 #include "profiler/profiler.h"
 #include "sfip/sf_ip.h"
-#include "perf_monitor/flow_ip_tracker.h"
+#include "stream/stream.h"
+
+#include "stream_udp.h"
+#include "udp_module.h"
+#include "udp_ha.h"
 
 // NOTE:  sender is assumed to be client
 //        responder is assumed to be server
@@ -61,6 +61,7 @@ static void UdpSessionCleanup(Flow* lwssn)
 {
     if (lwssn->ssn_state.session_flags & SSNFLAG_PRUNED)
         udpStats.prunes++;
+
     else if (lwssn->ssn_state.session_flags & SSNFLAG_TIMEDOUT)
         udpStats.timeouts++;
 
@@ -73,10 +74,10 @@ static int ProcessUdp(
 {
     assert(lwssn->pkt_type == PktType::UDP);
 
-    if ( stream.blocked_session(lwssn, p) )
+    if ( Stream::blocked_flow(lwssn, p) )
         return 0;
 
-    if ( stream.ignored_session(lwssn, p) )
+    if ( Stream::ignored_flow(lwssn, p) )
         return 0;
 
     /* if both seen, mark established */
@@ -138,7 +139,7 @@ bool UdpSession::setup(Packet* p)
             &flow->server_ip, SFS_STATE_UDP_CREATED);
     }
 
-    if ( flow_con->expected_flow(flow, p) )
+    if ( Stream::expected_flow(flow, p) )
     {
         udpStats.sessions--; // incremented in SESSIONS_STATS_ADD
         return false;
@@ -193,13 +194,12 @@ int UdpSession::process(Packet* p)
     StreamUdpConfig* pc = get_udp_cfg(flow->ssn_server);
     // Check if the session is expired.
     // Should be done before we do something with the packet...
-    if ( stream.expired_session(flow, p) )
+    if ( Stream::expired_flow(flow, p) )
     {
         UdpSessionCleanup(flow);
         flow->restart();
         flow->ssn_state.session_flags |= SSNFLAG_SEEN_SENDER;
-        udpStats.created++; // FIXIT-M is this correct? will mess with calc of current sessions
-        udpStats.timeouts++;
+        udpStats.created++;
         UdpHAManager::process_deletion(flow);
     }
 
index e3fe16c2023b2f01c615247d635bb9f61bba853d..a2afce61d8b50d9213352cbdeb20ef75c20413ee 100644 (file)
@@ -24,7 +24,6 @@ using namespace std;
 
 #include "stream_user.h"
 #include "main/snort_config.h"
-#include "stream/stream.h"
 
 //-------------------------------------------------------------------------
 // stream_user module
index 0d464f33615e2015839abfee05140997c3f79505..6d305d5ad7490598d31a7ce506b978c1be90adb9 100644 (file)
 #include "config.h"
 #endif
 
-#include "stream_user.h"
-#include "user_module.h"
-
-#include "stream/stream.h"
-#include "stream/stream_splitter.h"
-#include "stream/paf.h"
-
-#include "flow/flow_control.h"
 #include "main/snort.h"
 #include "perf_monitor/perf_monitor.h"
 #include "profiler/profiler.h"
 #include "sfip/sf_ip.h"
 #include "utils/util.h"
 
+#include "stream/stream.h"
+#include "stream/stream_splitter.h"
+#include "stream/paf.h"
+
+#include "stream_user.h"
+#include "user_module.h"
+
 THREAD_LOCAL ProfileStats user_perf_stats;
 
 // we always get exactly one copy of user data in order
@@ -427,7 +426,7 @@ bool UserSession::setup(Packet*)
     server.init();
 
 #ifdef ENABLE_EXPECTED_USER
-    if ( flow_con->expected_session(flow, p))
+    if ( Stream::expected_flow(flow, p) )
         return false;
 #endif
     return true;
@@ -463,20 +462,20 @@ int UserSession::process(Packet* p)
 {
     Profile profile(user_perf_stats);
 
-    if ( stream.expired_session(flow, p) )
+    if ( Stream::expired_flow(flow, p) )
     {
         flow->restart();
         // FIXIT-M count user session timeouts here
 
 #ifdef ENABLE_EXPECTED_USER
-        if ( flow_con->expected_session(flow, p))
+        if ( Stream::expected_flow(flow, p))
             return 0;
 #endif
     }
 
     flow->set_direction(p);
 
-    if ( stream.blocked_session(flow, p) || stream.ignored_session(flow, p) )
+    if ( Stream::blocked_flow(flow, p) || Stream::ignored_flow(flow, p) )
         return 0;
 
     update(p, flow);
index af593a60e66752bc34d8322c6f557fed1aaf3438..9bdde5a6bc0650fc04dac2eddddd5891cad7693b 100644 (file)
 #include <vector>
 using namespace std;
 
+#include "hash/sfghash.h"
+#include "main/snort_debug.h"
+#include "utils/util.h"
+#include "stream/stream.h"
+
 #include "sftarget_reader.h"
 #include "sftarget_hostentry.h"
 #include "sftarget_data.h"
 
-#include "hash/sfghash.h"
-#include "utils/util.h"
-#include "main/snort_debug.h"
-#include "stream/stream_api.h"
-
 struct SFTargetProtocolReference
 {
     char name[SFAT_BUFSZ];
@@ -177,7 +177,7 @@ int16_t GetProtocolReference(Packet* p)
         if ( p->flow )
         {
             /* Use session information via Stream API */
-            protocol = stream.get_application_protocol_id(p->flow);
+            protocol = Stream::get_application_protocol_id(p->flow);
 
             if ( protocol )
                 break;
index ec5dd24a5a5e74cab702aaa5eb3d177ecf2cda0c..db8e2e06e73cc964d02d9d354ab999e25be94c93 100644 (file)
@@ -4,6 +4,7 @@ set ( TIME_INTERNAL_SOURCES
     periodic.cc
     periodic.h
     timersub.h
+    tsc_clock.cc
     )
 
 if ( ENABLE_UNIT_TESTS )
@@ -11,9 +12,9 @@ if ( ENABLE_UNIT_TESTS )
 endif ( ENABLE_UNIT_TESTS )
 
 set ( TIME_INCLUDES
-    cpuclock.h
     clock_defs.h
     stopwatch.h
+    tsc_clock.h
     )
 
 add_library ( time STATIC
index b2f89a36451e6bd2eca467feb04c9735b8a7c8f8..b32475d0761df10e871e644422325cdeb587422d 100644 (file)
@@ -3,18 +3,19 @@ noinst_LIBRARIES = libtime.a
 x_includedir = $(pkgincludedir)/time
 
 x_include_HEADERS = \
-cpuclock.h \
 clock_defs.h \
-stopwatch.h
+stopwatch.h \
+tsc_clock.h
 
 libtime_a_SOURCES = \
+clock_defs.h \
 packet_time.cc \
 packet_time.h \
 periodic.cc \
 periodic.h \
-timersub.h \
-clock_defs.h \
-stopwatch.h
+stopwatch.h \
+timersub.h  \
+tsc_clock.cc
 
 if ENABLE_UNIT_TESTS
 libtime_a_SOURCES += stopwatch_test.cc
index f0f17f5f8eea78663f4024f38d891d0f0f09de8b..23b1e60de33e1d8ac0d3c6794833851055c4c41f 100644 (file)
 #ifndef CLOCK_DEFS_H
 #define CLOCK_DEFS_H
 
-#include <chrono>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef USE_TSC_CLOCK
+#include "time/tsc_clock.h"
+using SnortClock = TscClock;
 
+#else
+#include <chrono>
 using hr_clock = std::chrono::high_resolution_clock;
-using hr_duration = hr_clock::duration;
-using hr_time = hr_clock::time_point;
+using SnortClock = hr_clock;
+inline long clock_scale() { return 1.0; }
+#endif
+
+using hr_duration = SnortClock::duration;
+using hr_time = SnortClock::time_point;
 
 inline constexpr hr_duration operator "" _ticks (unsigned long long int v)
 { return hr_duration(v); }
@@ -39,4 +51,11 @@ struct ClockTraits
     using time_point = TimePoint;
     using rep = Rep;
 };
+
+inline long clock_usecs(long ticks)
+{ return ticks / clock_scale(); }
+
+inline long clock_ticks(long usecs)
+{ return usecs * clock_scale(); }
+
 #endif
diff --git a/src/time/cpuclock.h b/src/time/cpuclock.h
deleted file mode 100644 (file)
index 91e3609..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2016 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2006-2013 Sourcefire, Inc.
-//
-// 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.
-//--------------------------------------------------------------------------
-
-#ifndef CPUCLOCK_H
-#define CPUCLOCK_H
-
-// Assembly to find clock ticks
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <unistd.h>
-
-// INTEL LINUX/BSD/..
-#if (defined(__i386) || defined(__amd64) || defined(__x86_64__))
-#define get_clockticks(val) \
-{ \
-    uint32_t a, d; \
-    __asm__ __volatile__ ("rdtsc" : "=a" (a), "=d" (d));  \
-    val = ((uint64_t)a) | (((uint64_t)d) << 32);  \
-}
-#else
-#if (defined(__ia64) && defined(__GNUC__) )
-#define get_clockticks(val) \
-{ \
-    __asm__ __volatile__ ("mov %0=ar.itc" : "=r" (val)); \
-}
-#else
-#if (defined(__ia64) && defined(__hpux))
-#include <machine/sys/inline.h>
-#define get_clockticks(val) \
-{ \
-    val = _Asm_mov_from_ar (_AREG_ITC); \
-}
-#else
-// POWER PC
-#if (defined(__GNUC__) && (defined(__powerpc__) || (defined(__ppc__))))
-#define get_clockticks(val) \
-{ \
-    uint32_t tbu0, tbu1, tbl; \
-    do \
-    { \
-        __asm__ __volatile__ ("mftbu %0" : "=r" (tbu0)); \
-        __asm__ __volatile__ ("mftb  %0" : "=r" (tbl)); \
-        __asm__ __volatile__ ("mftbu %0" : "=r" (tbu1)); \
-    } while (tbu0 != tbu1); \
-    val = ((uint64_t)tbl) | (((uint64_t)tbu0) << 32);  \
-}
-#else
-// SPARC
-#ifdef SPARCV9
-#ifdef _LP64
-#define get_clockticks(val) \
-{ \
-    __asm__ __volatile__ ("rd %%tick, %0" : "=r" (val)); \
-}
-#else
-#define get_clockticks(val) \
-{ \
-    uint32_t a, b; \
-    __asm__ __volatile__ ("rd %%tick, %0\n" \
-        "srlx %0, 32, %1" \
-        : "=r" (a), "=r" (b)); \
-    val = ((uint64_t)a) | (((uint64_t)b) << 32); \
-}
-#endif // _LP64
-#else
-#define get_clockticks(val)
-#endif // SPARCV9
-#endif // __GNUC__ && __powerpc__ || __ppc__
-#endif // __ia64 && __hpux
-#endif // __ia64 && __GNUC__
-#endif // __i386 || __amd64 || __x86_64__
-
-inline double get_ticks_per_usec()
-{
-    uint64_t start = 0, end = 0;
-    get_clockticks(start);
-
-    sleep(1);
-    get_clockticks(end);
-
-    return (double)(end-start)/1e6;
-}
-
-#endif
-
index b986ec0fa1fe3f486c2326511ec4874bde5e975c..cad2c27e6bf9b61181bef958ce44bb5b22e055b2 100644 (file)
@@ -25,7 +25,7 @@
 namespace t_stopwatch
 {
 
-struct Clock : public ClockTraits<hr_clock>
+struct Clock : public ClockTraits<SnortClock>
 {
     static time_point now()
     { return time; }
diff --git a/src/time/tsc_clock.cc b/src/time/tsc_clock.cc
new file mode 100644 (file)
index 0000000..9fcad20
--- /dev/null
@@ -0,0 +1,37 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2016 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.
+//--------------------------------------------------------------------------
+// tsc_clock.cc author Russ Combs <rucombs@cisco.com>
+
+#include "tsc_clock.h"
+#include <time.h>
+
+long clock_scale()
+{
+    static long tpus = 0;  // ticks / usec
+
+    if ( !tpus )
+    {
+        struct timespec one_sec = { 1, 0 };
+        uint64_t start = TscClock::counter();
+        nanosleep(&one_sec, nullptr);
+        uint64_t end = TscClock::counter();
+        tpus = (long)((end - start)/1e6);
+    }
+    return tpus;
+}
+
diff --git a/src/time/tsc_clock.h b/src/time/tsc_clock.h
new file mode 100644 (file)
index 0000000..848649f
--- /dev/null
@@ -0,0 +1,65 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2016 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.
+//--------------------------------------------------------------------------
+// tsc_clock.h author Russ Combs <rucombs@cisco.com>
+
+#ifndef TSC_CLOCK_H
+#define TSC_CLOCK_H
+
+// the STL chrono clocks are kinda heavy so we use the time stamp counter
+// where available (x86 with rdtsc support).  this wasn't always a good
+// choice on multi-core systems but most now have rdtscp, constant_tsc,
+// tsc_reliable, and nonstop_tsc.  note that we don't worry about exact
+// instruction sequencing.
+//
+// references:
+// http://stackoverflow.com/questions/275004/timer-function-to-provide-time-in-nano-seconds-using-c
+// http://stackoverflow.com/questions/7935518/is-clock-gettime-adequate-for-submicrosecond-timing
+//
+// this clock stores ticks, not actual time values.  use ticks during runtime
+// convert from/to usecs at startup/shutdown.  see clock_defs.h.
+
+#include <chrono>
+
+struct TscClock
+{
+    // this has to be const so we use a nice round number and scale it later
+    typedef std::ratio<1, 1000000> period;
+
+    typedef uint64_t rep;
+    typedef std::chrono::duration<rep, period> duration;
+    typedef std::chrono::time_point<TscClock> time_point;
+
+    static const bool is_steady = true;
+
+    static uint64_t counter()
+    {
+        uint32_t lo, hi;
+        asm volatile("rdtsc" : "=a" (lo), "=d" (hi));
+        return ((uint64_t)hi << 32) | lo;
+    }
+
+    static time_point now() noexcept
+    {
+        return time_point(duration(counter()));
+    }
+};
+
+long clock_scale();
+
+#endif
+
index 53125263bbad831008cf4ca9e604e1e5c23daa1c..db5d05246f60821910aee76e686d555b601b0400 100644 (file)
@@ -59,8 +59,10 @@ private:
 // -----------------------------------------------------------------------------
 
 inline BitOp::BitOp(size_t len) :
-    bit_buf(new uint8_t[len]()), buf_size(len)
-{ }
+    buf_size(len ? (len + 7) >> 3 : 1)
+{
+    bit_buf = new uint8_t[len]();
+}
 
 inline BitOp::~BitOp()
 { delete[] bit_buf; }
@@ -68,7 +70,6 @@ inline BitOp::~BitOp()
 inline uint8_t BitOp::mask(size_t bit) const
 { return (uint8_t)(0x80 >> (bit & 7)); }
 
-// FIXIT-L ops that don't need to be inlined can probably be put into a .cc file
 // Reset the bit buffer so that it can be reused
 inline void BitOp::reset()
 { memset(bit_buf, 0, buf_size); }
index 63af4275cded5783c84b304f372a5b2b7fe11629..dd92281cdf9198dace2d5d40bd17c364abb249be 100644 (file)
@@ -12,7 +12,7 @@ static bool t_bitop_buffer_zero(BitOp& bitop)
 
 TEST_CASE( "bitop", "[bitop]" )
 {
-    BitOp bitop(3);
+    BitOp bitop(24);
 
     SECTION( "zero-initialized" )
     {
index 4c6adf21e3255b11758b8ca1eb6b3a4bcd142f22..9f09a00af76ac89fee382389e0912b036ea70fda 100644 (file)
@@ -69,7 +69,6 @@
 #include "ips_options/ips_pcre.h"
 #include "time/packet_time.h"
 #include "time/timersub.h"
-#include "stream/stream.h"
 
 #ifdef PATH_MAX
 #define PATH_MAX_UTIL PATH_MAX
index 14de579414c7294f4af3e15d8af754e87b065bae..8e70dba2414bfea44a635c232f0f60f0bec33bf0 100644 (file)
@@ -68,8 +68,7 @@ public:
         if ((lua_option != nullptr) && snort_option->compare(*lua_option))
         {
             retval = parse_int_option(*lua_option, stream, false);
-            table_api.add_diff_option_comment("config " + *snort_option +
-                ":", *lua_option);
+            table_api.add_diff_option_comment("config " + *snort_option + ":", *lua_option);
         }
         else
         {
@@ -92,10 +91,7 @@ const std::string* lua_table,
 const std::string* lua_option = nullptr>
 static ConversionState* config_int_ctor(Converter& c)
 {
-    return new ConfigIntOption(c,
-        snort_option,
-        lua_table,
-        lua_option);
+    return new ConfigIntOption(c, snort_option, lua_table, lua_option);
 }
 } // namespace
 
index 571ad10cda78db6b6f9d3f0210f8253e96ad6dfd..6f42df40546f1fbb2fe32711da08fc6fc3f82a14 100644 (file)
@@ -111,11 +111,7 @@ const std::string* lua_option = nullptr,
 bool use_string_array = false>
 static ConversionState* config_string_ctor(Converter& c)
 {
-    return new ConfigStringOption(c,
-        snort_option,
-        lua_table,
-        lua_option,
-        use_string_array);
+    return new ConfigStringOption(c, snort_option, lua_table, lua_option, use_string_array);
 }
 } // namespace