]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #3373: ips_bag2
authorRuss Combs (rucombs) <rucombs@cisco.com>
Thu, 21 Apr 2022 12:27:01 +0000 (12:27 +0000)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Thu, 21 Apr 2022 12:27:01 +0000 (12:27 +0000)
Merge in SNORT/snort3 from ~RUCOMBS/snort3:ips_bag2 to master

Squashed commit of the following:

commit faebae4e783ceb1e110663326756a87ba83510fe
Author: russ <rucombs@cisco.com>
Date:   Thu Apr 14 11:26:01 2022 -0400

    mms_data: make a fast pattern buffer

    Also some minor refactoring of related framework code.

commit aca6b04e9c610ecff216e28c549176a1f5962aa4
Author: russ <rucombs@cisco.com>
Date:   Tue Apr 12 13:31:08 2022 -0400

    ips_options: eliminate obsolete RULE_OPTION_TYPE_BUFFER_*

commit 75469d9cb9528a1952390d961a32199653678a3e
Author: russ <rucombs@cisco.com>
Date:   Mon Apr 11 16:26:00 2022 -0400

    conf: add cip and s7commplus to the default snort.lua

commit ed2856e6e08ef74187dda09c095177f8fd5fcd18
Author: russ <rucombs@cisco.com>
Date:   Sun Apr 10 16:03:51 2022 -0400

    raw_data: only search pkt_data if no alt buffer or raw_data rules included in group

commit f3d69b64eba4a520d2d782f2b4507ddb4f42d7f3
Author: russ <rucombs@cisco.com>
Date:   Sat Apr 9 22:13:44 2022 -0400

    detection: remove now obsolete get buf support

    The only remaining inspection buffer provided by multiple inspectors
    is vba_data. pkt_data and file_data are pushed to the detection engine.
    alt_data is pushed as well but is used where pkt_data is used. All other
    buffers are provided by solely by individual inspector ips options.
    (http2 just internally uses http_* buffers.)

commit f79e200c64a8de929764cded5dc10f8022fd429b
Author: russ <rucombs@cisco.com>
Date:   Fri Apr 8 18:27:40 2022 -0400

    ips: eliminate direct dependence on get_fp_buf of all ibt (by using rule options)

commit e54fa287fd110a6d7634ed22d9fcd43297b6490c
Author: russ <rucombs@cisco.com>
Date:   Fri Apr 8 06:08:01 2022 -0400

    service inspectors: update fast pattern access

commit 9d6477ebb015e2ddfdcf80aece115da3d21867b0
Author: russ <rucombs@cisco.com>
Date:   Fri Apr 8 02:59:57 2022 -0400

    detection: rearrange startup rule counts

commit d22ea5aeda36790a229a24226e9a5a5c509fc057
Author: russ <rucombs@cisco.com>
Date:   Thu Apr 7 15:49:47 2022 -0400

    ips: eliminate PM_TYPE_* to make fast pattern buffers generic

commit a49cd8f04e54c86228e45e3316c2f06769782fe2
Author: russ <rucombs@cisco.com>
Date:   Wed Apr 6 16:52:20 2022 -0400

    detection: add missing fast pattern buffer translations

commit 1ba179ea66d4050f3c57bd1d3fcc884106b08409
Author: russ <rucombs@cisco.com>
Date:   Tue Apr 5 17:53:12 2022 -0400

    inspectors: add / update api buffer lists

commit 127236881855c6230d413acdbae95320fbacf80c
Author: russ <rucombs@cisco.com>
Date:   Tue Apr 5 17:52:12 2022 -0400

    bufferlen: add missing relative override

commit 774a078e38b90fa610d70a3663383a260d8361f9
Author: russ <rucombs@cisco.com>
Date:   Mon Apr 4 10:09:04 2022 -0400

    ips_options: fix cursor action type overrides

commit 07fbe66bba3a81f4f8dbe3e8dcb4a351b22344b1
Author: russ <rucombs@cisco.com>
Date:   Mon Apr 4 08:41:42 2022 -0400

    detection: make CursorActionType generic

commit c7063241d67718633e5c533ea49ab9defd736f1e
Author: russ <rucombs@cisco.com>
Date:   Mon Apr 4 07:18:46 2022 -0400

    detection: map buffers to services

commit 0837fc34448a36c6a817491c916cda319e335112
Author: russ <rucombs@cisco.com>
Date:   Sun Apr 3 07:13:10 2022 -0400

    ips: further limit port group rules

    Rules with buffers that imply services go only in service groups.

commit eba1ff1bad596d1222b1dc934235ad29c929445a
Author: russ <rucombs@cisco.com>
Date:   Sun Apr 3 07:10:30 2022 -0400

    content: auto no-case non-alpha patterns

94 files changed:
lua/snort.lua
src/detection/detect_trace.cc
src/detection/detection_options.cc
src/detection/fp_create.cc
src/detection/fp_create.h
src/detection/fp_detect.cc
src/detection/fp_utils.cc
src/detection/fp_utils.h
src/detection/ips_context.cc
src/detection/pattern_match_data.h
src/detection/rule_option_types.h
src/detection/treenodes.h
src/flow/flow.cc
src/flow/flow_cache.cc
src/framework/cursor.cc
src/framework/inspector.h
src/framework/ips_option.cc
src/framework/ips_option.h
src/framework/mpse_batch.h
src/ips_options/ips_asn1.cc
src/ips_options/ips_base64.cc
src/ips_options/ips_ber_data.cc
src/ips_options/ips_ber_skip.cc
src/ips_options/ips_bufferlen.cc
src/ips_options/ips_byte_extract.cc
src/ips_options/ips_byte_jump.cc
src/ips_options/ips_byte_math.cc
src/ips_options/ips_byte_test.cc
src/ips_options/ips_content.cc
src/ips_options/ips_file_data.cc
src/ips_options/ips_file_type.cc
src/ips_options/ips_flowbits.cc
src/ips_options/ips_flowbits.h
src/ips_options/ips_hash.cc
src/ips_options/ips_luajit.cc
src/ips_options/ips_pkt_data.cc
src/ips_options/ips_raw_data.cc
src/ips_options/ips_regex.cc
src/ips_options/ips_sd_pattern.cc
src/ips_options/ips_vba_data.cc
src/ips_options/ips_vba_data.h
src/ips_options/test/ips_regex_test.cc
src/main/snort_config.cc
src/managers/inspector_manager.cc
src/managers/ips_manager.cc
src/managers/test/get_inspector_stubs.h
src/network_inspectors/appid/test/appid_discovery_test.cc
src/parser/parse_conf.cc
src/parser/parse_rule.cc
src/parser/parse_rule.h
src/parser/parser.cc
src/parser/parser.h
src/payload_injector/test/payload_injector_test.cc
src/ports/port_group.cc
src/ports/port_group.h
src/protocols/packet.h
src/service_inspectors/dce_rpc/dce_smb_inspector.cc
src/service_inspectors/dce_rpc/dce_tcp.cc
src/service_inspectors/dce_rpc/dce_udp.cc
src/service_inspectors/dce_rpc/ips_dce_iface.cc
src/service_inspectors/dce_rpc/ips_dce_stub_data.cc
src/service_inspectors/dnp3/dnp3.cc
src/service_inspectors/dnp3/ips_dnp3_data.cc
src/service_inspectors/ftp_telnet/ftp_data.cc
src/service_inspectors/ftp_telnet/telnet.cc
src/service_inspectors/gtp/gtp_inspect.cc
src/service_inspectors/gtp/ips_gtp_info.cc
src/service_inspectors/gtp/ips_gtp_type.cc
src/service_inspectors/http2_inspect/ips_http2.h
src/service_inspectors/http_inspect/ips_http.cc
src/service_inspectors/http_inspect/ips_http.h
src/service_inspectors/http_inspect/ips_http_buffer.cc
src/service_inspectors/http_inspect/ips_http_buffer.h
src/service_inspectors/http_inspect/ips_http_num_hdrs.cc
src/service_inspectors/http_inspect/ips_http_num_hdrs.h
src/service_inspectors/http_inspect/ips_http_param.h
src/service_inspectors/http_inspect/ips_http_test.cc
src/service_inspectors/http_inspect/ips_http_test.h
src/service_inspectors/http_inspect/ips_http_version.cc
src/service_inspectors/http_inspect/ips_http_version.h
src/service_inspectors/imap/imap.cc
src/service_inspectors/mms/ips_mms_data.cc
src/service_inspectors/mms/mms.cc
src/service_inspectors/modbus/ips_modbus_data.cc
src/service_inspectors/modbus/modbus.cc
src/service_inspectors/pop/pop.cc
src/service_inspectors/rpc_decode/rpc_decode.cc
src/service_inspectors/s7commplus/ips_s7comm_content.cc
src/service_inspectors/s7commplus/s7comm.cc
src/service_inspectors/sip/ips_sip.cc
src/service_inspectors/sip/sip.cc
src/service_inspectors/smtp/smtp.cc
src/utils/stats.cc
src/utils/stats.h

index 24d984370a0403b1712b43a926ccb4e9c00e1885..d8c037eb370abbf932929df49483146794e3a4d3 100644 (file)
@@ -52,12 +52,8 @@ stream_file = { }
 
 arp_spoof = { }
 back_orifice = { }
-dnp3 = { }
 dns = { }
 imap = { }
-iec104 = { }
-mms = { }
-modbus = { }
 netflow = {}
 normalizer = { }
 pop = { }
@@ -67,6 +63,13 @@ ssh = { }
 ssl = { }
 telnet = { }
 
+cip = { }
+dnp3 = { }
+iec104 = { }
+mms = { }
+modbus = { }
+s7commplus = { }
+
 dce_smb = { }
 dce_tcp = { }
 dce_udp = { }
@@ -119,19 +122,23 @@ binder =
     -- port bindings required for protocols without wizard support
     { when = { proto = 'udp', ports = '53', role='server' },  use = { type = 'dns' } },
     { when = { proto = 'tcp', ports = '53', role='server' },  use = { type = 'dns' } },
+    { when = { proto = 'tcp', ports = '102', role = 'server' }, use = { type = 's7commplus' } },
     { when = { proto = 'tcp', ports = '111', role='server' }, use = { type = 'rpc_decode' } },
     { when = { proto = 'tcp', ports = '502', role='server' }, use = { type = 'modbus' } },
     { when = { proto = 'tcp', ports = '2123 2152 3386', role='server' }, use = { type = 'gtp_inspect' } },
     { when = { proto = 'tcp', ports = '2404', role='server' }, use = { type = 'iec104' } },
+    { when = { proto = 'udp', ports = '22222', role = 'server' }, use = { type = 'cip' } },
+    { when = { proto = 'tcp', ports = '44818', role = 'server' }, use = { type = 'cip' } },
 
-    { when = { proto = 'tcp', service = 'dcerpc' }, use = { type = 'dce_tcp' } },
-    { when = { proto = 'udp', service = 'dcerpc' }, use = { type = 'dce_udp' } },
+    { when = { proto = 'tcp', service = 'dcerpc' },  use = { type = 'dce_tcp' } },
+    { when = { proto = 'udp', service = 'dcerpc' },  use = { type = 'dce_udp' } },
     { when = { proto = 'udp', service = 'netflow' }, use = { type = 'netflow' } },
 
     { when = { service = 'netbios-ssn' },      use = { type = 'dce_smb' } },
     { when = { service = 'dce_http_server' },  use = { type = 'dce_http_server' } },
     { when = { service = 'dce_http_proxy' },   use = { type = 'dce_http_proxy' } },
 
+    { when = { service = 'cip' },              use = { type = 'cip' } },
     { when = { service = 'dnp3' },             use = { type = 'dnp3' } },
     { when = { service = 'dns' },              use = { type = 'dns' } },
     { when = { service = 'ftp' },              use = { type = 'ftp_server' } },
@@ -149,6 +156,7 @@ binder =
     { when = { service = 'smtp' },             use = { type = 'smtp' } },
     { when = { service = 'ssl' },              use = { type = 'ssl' } },
     { when = { service = 'sunrpc' },           use = { type = 'rpc_decode' } },
+    { when = { service = 's7commplus' },       use = { type = 's7commplus' } },
     { when = { service = 'telnet' },           use = { type = 'telnet' } },
 
     { use = { type = 'wizard' } }
index 8b6c727e1c0700febecd8f3452dab7dcea6265a2..55fd00af55d862274c2a092e924f4090a4c1c6a4 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "detection_options.h"
 #include "fp_create.h"
+#include "fp_utils.h"
 #include "ips_context.h"
 #include "pattern_match_data.h"
 
@@ -86,12 +87,11 @@ void print_pkt_info(Packet* p, const char* task)
 void print_pattern(const PatternMatchData* pmd, Packet* p)
 {
     string hex, txt, opts;
+    get_pattern_info(pmd, hex, txt, opts);
 
-    get_pattern_info(pmd, pmd->pattern_buf, pmd->pattern_size, hex, txt, opts);
     debug_logf(detection_trace, TRACE_RULE_EVAL, p,
         "Fast pattern %s[%u] = '%s' |%s| %s\n",
-        pm_type_strings[pmd->pm_type],  pmd->pattern_size,
-        txt.c_str(), hex.c_str(), opts.c_str());
+        pmd->sticky_buf,  pmd->pattern_size, txt.c_str(), hex.c_str(), opts.c_str());
 }
 
 void dump_buffer(const uint8_t* buff, unsigned len, Packet* p)
index 81a515d608fe53c9c320d013626c9f1bfd0ca52f..e6dfa65389c5c83255aea7c757cda36a41e7e0ea 100644 (file)
@@ -607,22 +607,27 @@ int detection_option_node_evaluate(
 
                                     continue;
                                 }
-                                else if ( node->option_type != RULE_OPTION_TYPE_BUFFER_SET )
+                                else
                                 {
-                                    // 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*)child_node->option_data;
-                                    PatternMatchData* pmd = opt->get_pattern(0, RULE_WO_DIR);
+                                    IpsOption* opt = (IpsOption*)node->option_data;
 
-                                    if ( pmd and pmd->is_literal() and pmd->is_unbounded() )
+                                    if ( !opt->is_buffer_setter() )
                                     {
-                                        // Only increment result once. Should hit this
-                                        // condition on first loop iteration
-                                        if (loop_count == 1)
-                                            ++result;
-
-                                        continue;
+                                        // Check for an unbounded relative search.  If this
+                                        // failed before, it's going to fail again so don't
+                                        // go down this path again
+                                        opt = (IpsOption*)child_node->option_data;
+                                        PatternMatchData* pmd = opt->get_pattern(0, RULE_WO_DIR);
+
+                                        if ( pmd and pmd->is_literal() and pmd->is_unbounded() )
+                                        {
+                                            // Only increment result once. Should hit this
+                                            // condition on first loop iteration
+                                            if (loop_count == 1)
+                                                ++result;
+
+                                            continue;
+                                        }
                                     }
                                 }
                             }
index e0bb5d7edfaa260ea7541ec889b3e3e7aec4b32b..57c99ff486009ecee1272db693654d80ee8618c9 100644 (file)
@@ -74,8 +74,7 @@ static int fpGetFinalPattern(
     FastPatternConfig*, PatternMatchData*, const char*& ret_pattern, unsigned& ret_bytes);
 
 static void print_nfp_info(const char*, OptTreeNode*);
-static void print_fp_info(const char*, const OptTreeNode*, const PatternMatchData*,
-    const char* pattern, unsigned pattern_length);
+static void print_fp_info(const char*, const OptTreeNode*, const PatternMatchData*);
 
 static OptTreeNode* fixup_tree(
     detection_option_tree_node_t* dot, bool branched, unsigned contents)
@@ -435,8 +434,8 @@ static int fpFinishRuleGroupRule(
         pattern_length = pmd->pattern_size;
     }
 
-    if ( fp->get_debug_print_fast_patterns() and !otn->soid )
-        print_fp_info(s_group, otn, pmd, pattern, pattern_length);
+    if (pmd->pattern_size > otn->longestPatternLen)
+        otn->longestPatternLen = pmd->pattern_size;
 
     PMX* pmx = (PMX*)snort_calloc(sizeof(PMX));
     pmx->rule_node.rnRuleData = otn;
@@ -450,56 +449,22 @@ static int fpFinishRuleGroupRule(
     return 0;
 }
 
-static int fpFinishRuleGroup(SnortConfig* sc, RuleGroup* pg, FastPatternConfig* fp)
+static int fpFinishRuleGroup(SnortConfig* sc, RuleGroup* pg)
 {
-    int rules = 0;
+    assert(pg);
+    bool has_rules = false;
 
-    if (pg == nullptr)
-        return -1;
-
-    if (fp == nullptr)
+    for ( auto& it : pg->pm_list )
     {
-        delete pg;
-        return -1;
-    }
-
-    for (int i = PM_TYPE_PKT; i < PM_TYPE_MAX; i++)
-    {
-        if (pg->mpsegrp[i] != nullptr)
+        if ( it->group.normal_mpse )
         {
-            if (pg->mpsegrp[i]->normal_mpse != nullptr)
-            {
-                if (pg->mpsegrp[i]->normal_mpse->get_pattern_count() != 0)
-                {
-                    queue_mpse(pg->mpsegrp[i]->normal_mpse);
-                    rules = 1;
-                }
-                else
-                {
-                    MpseManager::delete_search_engine(pg->mpsegrp[i]->normal_mpse);
-                    pg->mpsegrp[i]->normal_mpse = nullptr;
-                }
-            }
-            if (pg->mpsegrp[i]->offload_mpse != nullptr)
-            {
-                if (pg->mpsegrp[i]->offload_mpse->get_pattern_count() != 0)
-                {
-                    queue_mpse(pg->mpsegrp[i]->offload_mpse);
-                    rules = 1;
-                }
-                else
-                {
-                    MpseManager::delete_search_engine(pg->mpsegrp[i]->offload_mpse);
-                    pg->mpsegrp[i]->offload_mpse = nullptr;
-                }
-            }
-
-            if ((pg->mpsegrp[i]->normal_mpse == nullptr) and
-                    (pg->mpsegrp[i]->offload_mpse == nullptr))
-            {
-                delete pg->mpsegrp[i];
-                pg->mpsegrp[i] = nullptr;
-            }
+            queue_mpse(it->group.normal_mpse);
+            has_rules = true;
+        }
+        if ( it->group.offload_mpse )
+        {
+            queue_mpse(it->group.offload_mpse);
+            has_rules = true;
         }
     }
 
@@ -507,21 +472,20 @@ static int fpFinishRuleGroup(SnortConfig* sc, RuleGroup* pg, FastPatternConfig*
     {
         RULE_NODE* ruleNode;
 
-        for (ruleNode = pg->nfp_head; ruleNode; ruleNode = ruleNode->rnNext)
+        for ( ruleNode = pg->nfp_head; ruleNode; ruleNode = ruleNode->rnNext )
         {
             OptTreeNode* otn = (OptTreeNode*)ruleNode->rnRuleData;
             otn_create_tree(otn, &pg->nfp_tree, Mpse::MPSE_TYPE_NORMAL);
         }
 
         finalize_detection_option_tree(sc, (detection_option_tree_root_t*)pg->nfp_tree);
-        rules = 1;
+        has_rules = true;
 
         pg->delete_nfp_rules();
     }
 
-    if (!rules)
+    if ( !has_rules )
     {
-        /* Nothing in the port group so we can just free it */
         delete pg;
         return -1;
     }
@@ -529,18 +493,11 @@ static int fpFinishRuleGroup(SnortConfig* sc, RuleGroup* pg, FastPatternConfig*
     return 0;
 }
 
-static void fpAddAlternatePatterns(
-    Mpse* mpse, OptTreeNode* otn, PatternMatchData* pmd, FastPatternConfig* fp)
-{
-    fpFinishRuleGroupRule(mpse, otn, pmd, fp, false);
-}
-
 static int fpAddRuleGroupRule(
     SnortConfig* sc, RuleGroup* pg, OptTreeNode* otn, FastPatternConfig* fp, bool srvc)
 {
     const MpseApi* search_api = nullptr;
     const MpseApi* offload_search_api = nullptr;
-    OptFpList* ofp = nullptr;
     bool exclude;
 
     // skip builtin rules, continue for text and so rules
@@ -553,13 +510,17 @@ static int fpAddRuleGroupRule(
     search_api = fp->get_search_api();
     assert(search_api);
 
+    OptFpList* ofp = nullptr;
+    IpsOption* opt = nullptr;
+
     bool only_literal = !MpseManager::is_regex_capable(search_api);
-    PatternMatchVector pmv = get_fp_content(otn, ofp, srvc, only_literal, exclude);
+    PatternMatchVector pmv = get_fp_content(otn, ofp, opt, srvc, only_literal, exclude);
 
     if ( !pmv.empty() )
     {
         PatternMatchVector pmv_ol;
         OptFpList* ofp_ol = nullptr;
+        IpsOption* opt_ol = nullptr;
         bool add_to_offload = false;
         bool cont = true;
         PatternMatchData* ol_pmd = nullptr;
@@ -568,22 +529,22 @@ static int fpAddRuleGroupRule(
 
         // Only add rule to the offload search engine if the offload search engine
         // is different to the normal search engine.
-        if (offload_search_api and (offload_search_api != search_api))
+        if ( offload_search_api and (offload_search_api != search_api) )
         {
             bool exclude_ol;
             bool only_literal_ol = !MpseManager::is_regex_capable(offload_search_api);
-            pmv_ol = get_fp_content(otn, ofp_ol, srvc, only_literal_ol, exclude_ol);
+            pmv_ol = get_fp_content(otn, ofp_ol, opt_ol, srvc, only_literal_ol, exclude_ol);
 
             // If we can get a fast_pattern for the normal search engine but not for the
             // offload search engine then add rule to the non fast pattern list
-            if (!pmv_ol.empty())
+            if ( !pmv_ol.empty() )
                 add_to_offload = true;
             else
                 cont = false;
         }
 
         // From here on we will create the mpses that are needed and add the patterns
-        if (cont)
+        if ( cont )
         {
             PatternMatchData* main_pmd = pmv.back();
             pmv.pop_back();
@@ -594,21 +555,23 @@ static int fpAddRuleGroupRule(
                 fpDeletePMX, free_detection_option_root, neg_list_free
             };
 
-            if ( !pg->mpsegrp[main_pmd->pm_type] )
-                pg->mpsegrp[main_pmd->pm_type] = new MpseGroup;
+            const char* s = opt ? opt->get_name() : "pkt_data";
+            auto pmt = get_pm_type(s);
+            PatternMatcher* pm = pg->get_pattern_matcher(pmt, s);
+            MpseGroup* mpg = &pm->group;
 
-            if ( !pg->mpsegrp[main_pmd->pm_type]->normal_mpse )
+            if ( !mpg->normal_mpse )
             {
-                if (!pg->mpsegrp[main_pmd->pm_type]->create_normal_mpse(sc, &agent))
+                if ( !mpg->create_normal_mpse(sc, &agent) )
                 {
-                    ParseError("Failed to create normal pattern matcher for %d", main_pmd->pm_type);
+                    ParseError("Failed to create normal pattern matcher for %s", pm->name);
                     return -1;
                 }
 
                 mpse_count++;
             }
 
-            if (add_to_offload)
+            if ( add_to_offload )
             {
                 ol_pmd = pmv_ol.back();
                 pmv_ol.pop_back();
@@ -620,12 +583,11 @@ static int fpAddRuleGroupRule(
                 };
 
                 // Keep the created mpse alongside the same pm type as the main pmd
-                if ( !pg->mpsegrp[main_pmd->pm_type]->offload_mpse )
+                if ( !mpg->offload_mpse )
                 {
-                    if (!pg->mpsegrp[main_pmd->pm_type]->create_offload_mpse(sc, &agent_offload))
+                    if ( !mpg->create_offload_mpse(sc, &agent_offload) )
                     {
-                        ParseError("Failed to create offload pattern matcher for %d",
-                            main_pmd->pm_type);
+                        ParseError("Failed to create offload pattern matcher for %s", pm->name);
                         return -1;
                     }
 
@@ -636,55 +598,73 @@ static int fpAddRuleGroupRule(
             bool add_rule = false;
             bool add_nfp_rule = false;
 
-            if (pg->mpsegrp[main_pmd->pm_type]->normal_mpse)
+            if ( mpg->normal_mpse )
             {
                 add_rule = true;
-                if (main_pmd->is_negated())
+                if ( main_pmd->is_negated() )
                     add_nfp_rule = true;
 
                 // Now add patterns
-                if (fpFinishRuleGroupRule(
-                    pg->mpsegrp[main_pmd->pm_type]->normal_mpse, otn, main_pmd, fp, true) == 0)
+                if ( fpFinishRuleGroupRule(mpg->normal_mpse, otn, main_pmd, fp, true) == 0 )
                 {
-                    if (main_pmd->pattern_size > otn->longestPatternLen)
-                        otn->longestPatternLen = main_pmd->pattern_size;
-
                     if ( make_fast_pattern_only(ofp, main_pmd) )
                     {
                         otn->normal_fp_only = ofp;
                         fp_only++;
                     }
 
+                    if ( !pm->fp_opt )
+                        pm->fp_opt = opt;
+
+                    main_pmd->sticky_buf = pm->name;
+
+                    if ( fp->get_debug_print_fast_patterns() and !otn->soid )
+                        print_fp_info(s_group, otn, main_pmd);
+
                     // Add Alternative patterns
-                    for (auto p : pmv)
-                        fpAddAlternatePatterns(
-                            pg->mpsegrp[main_pmd->pm_type]->normal_mpse, otn, p, fp);
+                    for ( auto alt_pmd : pmv )
+                    {
+                        fpFinishRuleGroupRule(mpg->normal_mpse, otn, alt_pmd, fp, false);
+                        alt_pmd->sticky_buf = pm->name;
+
+                        if ( fp->get_debug_print_fast_patterns() and !otn->soid )
+                            print_fp_info(s_group, otn, alt_pmd);
+                    }
                 }
             }
 
-            if (ol_pmd and pg->mpsegrp[main_pmd->pm_type]->offload_mpse)
+            if ( ol_pmd and mpg->offload_mpse )
             {
                 add_rule = true;
-                if (ol_pmd->is_negated())
+                if ( ol_pmd->is_negated() )
                     add_nfp_rule = true;
 
                 // Now add patterns
-                if (fpFinishRuleGroupRule(
-                    pg->mpsegrp[main_pmd->pm_type]->offload_mpse, otn, ol_pmd, fp, true) == 0)
+                if ( fpFinishRuleGroupRule(mpg->offload_mpse, otn, ol_pmd, fp, true) == 0 )
                 {
-                    if (ol_pmd->pattern_size > otn->longestPatternLen)
-                        otn->longestPatternLen = ol_pmd->pattern_size;
-
                     if ( make_fast_pattern_only(ofp_ol, ol_pmd) )
                     {
                         otn->offload_fp_only = ofp_ol;
                         fp_only++;
                     }
 
+                    if ( !pm->fp_opt )
+                        pm->fp_opt = opt_ol;
+
+                    main_pmd->sticky_buf = pm->name;
+
+                    if ( fp->get_debug_print_fast_patterns() and !otn->soid )
+                        print_fp_info(s_group, otn, main_pmd);
+
                     // Add Alternative patterns
-                    for (auto p : pmv_ol)
-                        fpAddAlternatePatterns(
-                            pg->mpsegrp[main_pmd->pm_type]->offload_mpse, otn, p, fp);
+                    for (auto alt_pmd : pmv_ol)
+                    {
+                        fpFinishRuleGroupRule(mpg->offload_mpse, otn, alt_pmd, fp, false);
+                        alt_pmd->sticky_buf = pm->name;
+
+                        if ( fp->get_debug_print_fast_patterns() and !otn->soid )
+                            print_fp_info(s_group, otn, alt_pmd);
+                    }
                 }
             }
 
@@ -950,28 +930,18 @@ static int fpGetFinalPattern(
 
 static void fpRuleGroupPrintRuleCount(RuleGroup* pg, const char* what)
 {
-    int type;
-
-    if (pg == nullptr)
-        return;
-
     LogMessage("RuleGroup rule summary (%s):\n", what);
 
-    for (type = PM_TYPE_PKT; type < PM_TYPE_MAX; type++)
+    for ( auto& it : pg->pm_list )
     {
-        if (pg->mpsegrp[type])
-        {
-            int count = pg->mpsegrp[type]->normal_mpse ?
-                pg->mpsegrp[type]->normal_mpse->get_pattern_count() : 0;
-            int count_ol = pg->mpsegrp[type]->offload_mpse ?
-                pg->mpsegrp[type]->offload_mpse->get_pattern_count() : 0;
+        int count = it->group.normal_mpse ?  it->group.normal_mpse->get_pattern_count() : 0;
+        int count_ol = it->group.offload_mpse ?  it->group.offload_mpse->get_pattern_count() : 0;
 
-            if ( count )
-                LogMessage("\tNormal Pattern Matcher %s: %d\n", pm_type_strings[type], count);
+        if ( count )
+            LogMessage("\tNormal Pattern Matcher %s: %d\n", it->name, count);
 
-            if ( count_ol )
-                LogMessage("\tOffload Pattern Matcher %s: %d\n", pm_type_strings[type], count_ol);
-        }
+        if ( count_ol )
+            LogMessage("\tOffload Pattern Matcher %s: %d\n", it->name, count_ol);
     }
 
     if ( pg->nfp_rule_count )
@@ -1058,7 +1028,7 @@ static void fpCreatePortObject2RuleGroup(SnortConfig* sc, PortObject2* po, PortO
     }
 
     // This might happen if there was ip proto only rules...Don't return failure
-    if (fpFinishRuleGroup(sc, pg, fp) != 0)
+    if (fpFinishRuleGroup(sc, pg) != 0)
         return;
 
     po->group = pg;
@@ -1238,7 +1208,7 @@ static void fpBuildServiceRuleGroupByServiceOtnList(
         fpAddRuleGroupRule(sc, pg, otn, fp, true);
     }
 
-    if (fpFinishRuleGroup(sc, pg, fp) != 0)
+    if (fpFinishRuleGroup(sc, pg) != 0)
         return;
 
     /* Add the port_group using it's service name */
@@ -1387,18 +1357,19 @@ static void fp_print_service_rules_by_proto(SnortConfig* sc)
     fp_print_service_rules(sc, sc->srmmTable->to_srv, sc->srmmTable->to_cli);
 }
 
-static void fp_sum_port_groups(RuleGroup* pg, unsigned c[PM_TYPE_MAX])
+static void fp_sum_port_groups(RuleGroup* pg, unsigned& c)
 {
     if ( !pg )
         return;
 
-    for ( int i = PM_TYPE_PKT; i < PM_TYPE_MAX; ++i )
-        if ( pg->mpsegrp[i] and pg->mpsegrp[i]->normal_mpse and
-            pg->mpsegrp[i]->normal_mpse->get_pattern_count() )
-            c[i]++;
+    for ( const auto& it : pg->pm_list )
+    {
+        if ( it->group.normal_mpse and it->group.normal_mpse->get_pattern_count() )
+            c++;
+    }
 }
 
-static void fp_sum_service_groups(GHash* h, unsigned c[PM_TYPE_MAX])
+static void fp_sum_service_groups(GHash* h, unsigned& c)
 {
     for (GHashNode* node = h->find_first();
          node;
@@ -1409,31 +1380,22 @@ static void fp_sum_service_groups(GHash* h, unsigned c[PM_TYPE_MAX])
     }
 }
 
-static void fp_print_service_groups(srmm_table_t* srmm)
+static void fp_print_service_groups(srmm_table_t* srmm, bool label)
 {
-    unsigned to_srv[PM_TYPE_MAX] = { };
-    unsigned to_cli[PM_TYPE_MAX] = { };
+    unsigned to_srv = 0;
+    unsigned to_cli = 0;
 
     fp_sum_service_groups(srmm->to_srv, to_srv);
     fp_sum_service_groups(srmm->to_cli, to_cli);
 
-    bool label = true;
+    if ( label and (to_srv or to_cli) )
+        LogLabel("fast pattern groups");
 
-    for ( int i = PM_TYPE_PKT; i < PM_TYPE_MAX; ++i )
-    {
-        if ( !to_srv[i] and !to_cli[i] )
-            continue;
-
-        if ( label )
-        {
-            LogLabel("fast pattern service groups  to-srv  to-cli");
-            label = false;
-        }
-        LogMessage("%25.25s: %8u%8u\n", pm_type_strings[i], to_srv[i], to_cli[i]);
-    }
+    LogCount("to_server", to_srv);
+    LogCount("to_client", to_cli);
 }
 
-static void fp_sum_port_groups(PortTable* tab, unsigned c[PM_TYPE_MAX])
+static void fp_sum_port_groups(PortTable* tab, unsigned& c)
 {
     for (GHashNode* node = tab->pt_mpo_hash->find_first();
          node;
@@ -1446,11 +1408,11 @@ static void fp_sum_port_groups(PortTable* tab, unsigned c[PM_TYPE_MAX])
     PortTableFinalize(tab);
 }
 
-static void fp_print_port_groups(RulePortTables* port_tables)
+static bool fp_print_port_groups(RulePortTables* port_tables)
 {
-    unsigned src[PM_TYPE_MAX] = { };
-    unsigned dst[PM_TYPE_MAX] = { };
-    unsigned any[PM_TYPE_MAX] = { };
+    unsigned src = 0;
+    unsigned dst = 0;
+    unsigned any = 0;
 
     fp_sum_port_groups(port_tables->ip.src, src);
     fp_sum_port_groups(port_tables->ip.dst, dst);
@@ -1480,20 +1442,15 @@ static void fp_print_port_groups(RulePortTables* port_tables)
     PortObjectFinalize(port_tables->udp.any);
     PortObjectFinalize(port_tables->udp.nfp);
 
-    bool label = true;
-
-    for ( int i = PM_TYPE_PKT; i < PM_TYPE_MAX; ++i )
+    if ( src or dst or any )
     {
-        if ( !src[i] and !dst[i] and !any[i] )
-            continue;
-
-        if ( label )
-        {
-            LogLabel("fast pattern port groups        src     dst     any");
-            label = false;
-        }
-        LogMessage("%25.25s: %8u%8u%8u\n", pm_type_strings[i], src[i], dst[i], any[i]);
+        LogLabel("fast pattern groups");
+        LogCount("src", src);
+        LogCount("dst", dst);
+        LogCount("any", any);
+        return true;
     }
+    return false;
 }
 
 /*
@@ -1607,8 +1564,8 @@ int fpCreateFastPacketDetection(SnortConfig* sc)
             ParseError("Failed to compile %u search engines", expected - c);
     }
 
-    fp_print_port_groups(port_tables);
-    fp_print_service_groups(sc->spgmmTable);
+    bool label = fp_print_port_groups(port_tables);
+    fp_print_service_groups(sc->spgmmTable, !label);
 
     if ( !sc->rule_db_dir.empty() )
         mpse_dumped = fp_serialize(sc, sc->rule_db_dir);
@@ -1664,16 +1621,15 @@ static void print_nfp_info(const char* group, OptTreeNode* otn)
     otn->set_warned_fp();
 }
 
-void get_pattern_info(const PatternMatchData* pmd,
-    const char* pattern, int pattern_length, string& hex, string& txt, string& opts)
+void get_pattern_info(const PatternMatchData* pmd, string& hex, string& txt, string& opts)
 {
     char buf[8];
 
-    for ( int i = 0; i < pattern_length; ++i )
+    for ( unsigned i = 0; i < pmd->pattern_size; ++i )
     {
-        snprintf(buf, sizeof(buf), "%2.02X ", (uint8_t)pattern[i]);
+        snprintf(buf, sizeof(buf), "%2.02X ", (uint8_t)pmd->pattern_buf[i]);
         hex += buf;
-        txt += isprint(pattern[i]) ? pattern[i] : '.';
+        txt += isprint(pmd->pattern_buf[i]) ? pmd->pattern_buf[i] : '.';
     }
     opts = "(";
     if ( pmd->is_fast_pattern() )
@@ -1683,15 +1639,13 @@ void get_pattern_info(const PatternMatchData* pmd,
     opts += " )";
 }
 
-static void print_fp_info(
-    const char* group, const OptTreeNode* otn, const PatternMatchData* pmd,
-    const char* pattern, unsigned pattern_length)
+static void print_fp_info(const char* group, const OptTreeNode* otn, const PatternMatchData* pmd)
 {
     std::string hex, txt, opts;
 
-    get_pattern_info(pmd, pattern, pattern_length, hex, txt, opts);
+    get_pattern_info(pmd, hex, txt, opts);
     LogMessage("FP %s %u:%u:%u %s[%d] = '%s' |%s| %s\n",
         group, otn->sigInfo.gid, otn->sigInfo.sid, otn->sigInfo.rev,
-        pm_type_strings[pmd->pm_type], pattern_length,
-        txt.c_str(), hex.c_str(), opts.c_str());
+        pmd->sticky_buf, pmd->pattern_size, txt.c_str(), hex.c_str(), opts.c_str());
 }
+
index f5e76a4ed47b000aa75af19d3c39b4af831f5581..2a4c01d43af7f48654882e466d78e60a44cb5c3b 100644 (file)
@@ -55,9 +55,7 @@ struct NCListNode
 */
 int fpCreateFastPacketDetection(snort::SnortConfig*);
 void fpDeleteFastPacketDetection(snort::SnortConfig*);
-void get_pattern_info(const PatternMatchData* pmd,
-    const char* pattern, int pattern_length, std::string& hex, std::string& txt,
-    std::string& opts);
+void get_pattern_info(const PatternMatchData* pmd, std::string& hex, std::string& txt, std::string& opts);
 
 #endif
 
index 0cf5fb35d2bda360133fa0e60d9a42b9684ea5db..e356ee8a5b0d35cf826c1ea23dc0240fb6fcaa26 100644 (file)
@@ -75,6 +75,7 @@
 #include "detection_options.h"
 #include "fp_config.h"
 #include "fp_create.h"
+#include "fp_utils.h"
 #include "ips_context.h"
 #include "pattern_match_data.h"
 #include "pcrm.h"
@@ -856,21 +857,21 @@ static int rule_tree_queue(
 }
 
 static inline int batch_search(
-    MpseGroup* so, Packet* p, const uint8_t* buf, unsigned len, PegCount& cnt)
+    MpseGroup* mpg, Packet* p, const uint8_t* buf, unsigned len, PegCount& cnt)
 {
-    assert(so->get_normal_mpse()->get_pattern_count() > 0);
+    assert(mpg->get_normal_mpse()->get_pattern_count() > 0);
     cnt++;
 
     // FIXIT-P Batch outer UDP payload searches for teredo set and the outer header
     // during any signature evaluation
     if ( p->is_udp_tunneled() )
     {
-        fp_immediate(so, p, buf, len);
+        fp_immediate(mpg, p, buf, len);
     }
     else
     {
         MpseBatchKey<> key = MpseBatchKey<>(buf, len);
-        p->context->searches.items[key].so.push_back(so);
+        p->context->searches.items[key].so.push_back(mpg);
     }
 
     dump_buffer(buf, len, p);
@@ -880,109 +881,83 @@ static inline int batch_search(
     return 0;
 }
 
-static inline void search_buffer(
-    Inspector* gadget, InspectionBuffer& buf, InspectionBuffer::Type ibt,
-    Packet* p, RuleGroup* pg, PmType pmt, PegCount& cnt)
-{
-    if ( MpseGroup* so = pg->mpsegrp[pmt] )
-    {
-        if ( gadget->get_fp_buf(ibt, p, buf) )
-        {
-            debug_logf(detection_trace, TRACE_FP_SEARCH, p,
-                "%" PRIu64 " fp %s.%s[%d]\n", p->context->packet_number,
-                gadget->get_name(), pm_type_strings[pmt], buf.len);
-
-            batch_search(so, p, buf.data, buf.len, cnt);
-        }
-    }
-}
-
 static int fp_search(RuleGroup* port_group, Packet* p, bool srvc)
 {
+    p->packet_flags |= PKT_FAST_PAT_EVAL;
     Inspector* gadget = p->flow ? p->flow->gadget : nullptr;
-    InspectionBuffer buf;
 
     debug_log(detection_trace, TRACE_RULE_EVAL, p, "Fast pattern search\n");
 
-    // ports search raw packet only
-    if ( p->dsize )
+    for ( const auto it : port_group->pm_list )
     {
-        assert(p->data);
-
-        if ( MpseGroup* so = port_group->mpsegrp[PM_TYPE_PKT] )
+        switch ( it->type )
         {
-            if ( uint16_t pattern_match_size = p->get_detect_limit() )
+        case PatternMatcher::PMT_PKT:
             {
-                debug_logf(detection_trace, TRACE_FP_SEARCH, p,
-                    "%" PRIu64 " fp %s[%u]\n", p->context->packet_number,
-                    pm_type_strings[PM_TYPE_PKT], pattern_match_size);
-
-                batch_search(so, p, p->data, pattern_match_size, pc.pkt_searches);
-                p->is_cooked() ?  pc.cooked_searches++ : pc.raw_searches++;
-            }
-        }
-    }
-
-    if ( gadget )
-    {
-        // FIXIT-L PM_TYPE_ALT will never be set unless we add
-        // norm_data keyword or telnet, rpc_decode, smtp keywords
-        // until then we must use the standard packet mpse
-        search_buffer(gadget, buf, buf.IBT_ALT, p, port_group, PM_TYPE_PKT, pc.alt_searches);
-    }
-
-    if ( !srvc )
-        return 0;
-
-    // service searches PDU buffers and file
-    if ( gadget )
-    {
-        search_buffer(gadget, buf, buf.IBT_KEY, p, port_group, PM_TYPE_KEY, pc.key_searches);
-
-        search_buffer(gadget, buf, buf.IBT_HEADER, p, port_group, PM_TYPE_HEADER, pc.header_searches);
-
-        search_buffer(gadget, buf, buf.IBT_BODY, p, port_group, PM_TYPE_BODY, pc.body_searches);
-
-        search_buffer(
-            gadget, buf, buf.IBT_RAW_KEY, p, port_group, PM_TYPE_RAW_KEY, pc.raw_key_searches);
+                bool alt_search = false;
+                if ( gadget )
+                {
+                    // need to add a norm_data keyword or telnet, rpc_decode, smtp keywords
+                    // until then we must use the standard packet mpse
+                    const DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
 
-        search_buffer(
-            gadget, buf, buf.IBT_RAW_HEADER, p, port_group, PM_TYPE_RAW_HEADER, pc.raw_header_searches);
+                    if ( buf.len )
+                    {
+                        debug_logf(detection_trace, TRACE_FP_SEARCH, p,
+                            "%" PRIu64 " fp alt_data[%u]\n", p->context->packet_number, buf.len);
 
-        search_buffer(
-            gadget, buf, buf.IBT_METHOD, p, port_group, PM_TYPE_METHOD, pc.method_searches);
+                        batch_search(&it->group, p, buf.data, buf.len, pc.alt_searches);
+                        alt_search = true;
+                    }
+                }
+                if ( p->dsize and (!alt_search or it->raw_data) )
+                {
+                    assert(p->data);
 
-        search_buffer(
-            gadget, buf, buf.IBT_STAT_CODE, p, port_group, PM_TYPE_STAT_CODE, pc.stat_code_searches);
+                    if ( uint16_t length = p->get_detect_limit() )
+                    {
+                        debug_logf(detection_trace, TRACE_FP_SEARCH, p,
+                            "%" PRIu64 " fp pkt_data[%u]\n", p->context->packet_number, length);
 
-        search_buffer(
-            gadget, buf, buf.IBT_STAT_MSG, p, port_group, PM_TYPE_STAT_MSG, pc.stat_msg_searches);
+                        batch_search(&it->group, p, p->data, length, pc.pkt_searches);
+                        p->is_cooked() ?  pc.cooked_searches++ : pc.raw_searches++;
+                    }
+                }
+            }
+            break;
 
-        search_buffer(
-            gadget, buf, buf.IBT_COOKIE, p, port_group, PM_TYPE_COOKIE, pc.cookie_searches);
+        case PatternMatcher::PMT_PDU:
+            if ( srvc and gadget )
+            {
+                Cursor c;
 
-        search_buffer(gadget, buf, buf.IBT_VBA, p, port_group, PM_TYPE_VBA, pc.vba_searches);
+                if ( it->fp_opt->eval(c, p) == IpsOption::MATCH )
+                {
+                    debug_logf(detection_trace, TRACE_FP_SEARCH, p,
+                        "%" PRIu64 " fp %s[%d]\n", p->context->packet_number, c.get_name(), c.size());
 
-        search_buffer(gadget, buf, buf.IBT_JS_DATA, p, port_group, PM_TYPE_JS_DATA, pc.js_data_searches);
-    }
+                    batch_search(&it->group, p, c.buffer(), c.size(), pc.pdu_searches);
+                }
+            }
+            break;
 
-    // file searches file only
-    if ( MpseGroup* so = port_group->mpsegrp[PM_TYPE_FILE] )
-    {
-        // FIXIT-M file data should be obtained from
-        // inspector gadget as is done with search_buffer
-        DataPointer file_data = p->context->file_data;
+        case PatternMatcher::PMT_FILE:
+            if ( srvc )
+            {
+                DataPointer file_data = p->context->file_data;
 
-        if ( file_data.len )
-        {
-            debug_logf(detection_trace, TRACE_FP_SEARCH, p,
-                "%" PRIu64 " fp search %s[%d]\n", p->context->packet_number,
-                pm_type_strings[PM_TYPE_FILE], file_data.len);
+                if ( file_data.len )
+                {
+                    debug_logf(detection_trace, TRACE_FP_SEARCH, p,
+                        "%" PRIu64 " fp search file_data[%d]\n", p->context->packet_number, file_data.len);
 
-            batch_search(so, p, file_data.data, file_data.len, pc.file_searches);
+                    batch_search(&it->group, p, file_data.data, file_data.len, pc.file_searches);
+                }
+            }
+            break;
         }
     }
-
+    p->packet_flags &= ~PKT_FAST_PAT_EVAL;
     return 0;
 }
 
@@ -1367,13 +1342,13 @@ static void fp_immediate(Packet* p)
     }
 }
 
-static void fp_immediate(MpseGroup* so, Packet* p, const uint8_t* buf, unsigned len)
+static void fp_immediate(MpseGroup* mpg, Packet* p, const uint8_t* buf, unsigned len)
 {
     MpseStash* stash = p->context->stash;
     {
         Profile mpse_profile(mpsePerfStats);
         int start_state = 0;
-        so->get_normal_mpse()->search(buf, len, rule_tree_queue, p->context, &start_state);
+        mpg->get_normal_mpse()->search(buf, len, rule_tree_queue, p->context, &start_state);
     }
     {
         Profile rule_profile(rulePerfStats);
index e262db52291a577d267b2125c9d0f122ef3f3948..e60e2ffe5ff31fdd89e4bb78ac47478b4d2c4645 100644 (file)
@@ -30,7 +30,9 @@
 #include <mutex>
 #include <sstream>
 #include <thread>
+#include <unordered_map>
 
+#include "framework/inspector.h"
 #include "framework/mpse.h"
 #include "framework/mpse_batch.h"
 #include "hash/ghash.h"
@@ -77,78 +79,93 @@ static bool pmd_can_be_fp(
     return pmd->can_be_fp();
 }
 
-PmType get_pm_type(CursorActionType cat)
+PatternMatcher::Type get_pm_type(const std::string& buf)
 {
-    switch ( cat )
-    {
-    case CAT_SET_RAW:
-    case CAT_SET_OTHER:
-        return PM_TYPE_PKT;
+    if ( buf == "pkt_data" or buf == "raw_data" )
+        return PatternMatcher::PMT_PKT;
 
-    case CAT_SET_COOKIE:
-        return PM_TYPE_COOKIE;
+    if ( buf == "file_data" )
+        return PatternMatcher::PMT_FILE;
 
-    case CAT_SET_JS_DATA:
-        return PM_TYPE_JS_DATA;
+    return PatternMatcher::PMT_PDU;
+}
 
-    case CAT_SET_STAT_MSG:
-        return PM_TYPE_STAT_MSG;
+static RuleDirection get_dir(OptTreeNode* otn)
+{
+    if ( otn->to_client() )
+        return RULE_FROM_SERVER;
 
-    case CAT_SET_STAT_CODE:
-        return PM_TYPE_STAT_CODE;
+    if ( otn->to_server() )
+        return RULE_FROM_CLIENT;
 
-    case CAT_SET_METHOD:
-        return PM_TYPE_METHOD;
+    return RULE_WO_DIR;
+}
 
-    case CAT_SET_RAW_HEADER:
-        return PM_TYPE_RAW_HEADER;
+using SvcList = std::vector<std::string>;
+static std::unordered_map<std::string, SvcList> buffer_map;
 
-    case CAT_SET_RAW_KEY:
-        return PM_TYPE_RAW_KEY;
+static const char* get_service(const char* buf)
+{
+    auto it = buffer_map.find(buf);
 
-    case CAT_SET_FILE:
-        return PM_TYPE_FILE;
+    if ( it == buffer_map.end() )
+        return nullptr;
 
-    case CAT_SET_BODY:
-        return PM_TYPE_BODY;
+    return it->second[0].c_str();
+}
 
-    case CAT_SET_HEADER:
-        return PM_TYPE_HEADER;
+static unsigned get_num_services(const char* buf)
+{
+    auto it = buffer_map.find(buf);
 
-    case CAT_SET_KEY:
-        return PM_TYPE_KEY;
+    if ( it == buffer_map.end() )
+        return 0;
 
-    case CAT_SET_VBA:
-        return PM_TYPE_VBA;
+    return it->second.size();
+}
 
-    default:
-        break;
+void update_buffer_map(const char** bufs, const char* svc)
+{
+    if ( !bufs )
+        return;
+
+    if ( !svc )
+    {
+        assert(svc);
+        return;
+    }
+
+    // FIXIT-M update NHI and H2I api.buffers and remove the hard-coded foo below
+    for ( int i = 0; bufs[i]; ++i )
+    {
+        buffer_map[bufs[i]].push_back(svc);
+        if ( !strcmp(svc, "http") )
+            buffer_map[bufs[i]].push_back("http2");
+    }
+
+    if ( !strcmp(svc, "http") )
+    {
+        buffer_map["file_data"].push_back("http");
+        buffer_map["file_data"].push_back("http2");
     }
-    assert(false);
-    return PM_TYPE_MAX;
 }
 
-static RuleDirection get_dir(OptTreeNode* otn)
+void add_default_services(SnortConfig* sc, const std::string& buf, OptTreeNode* otn)
 {
-    if ( otn->to_client() )
-        return RULE_FROM_SERVER;
+    SvcList& list = buffer_map[buf];
 
-    if ( otn->to_server() )
-        return RULE_FROM_CLIENT;
-
-    return RULE_WO_DIR;
+    for ( auto& svc : list )
+        add_service_to_otn(sc, otn, svc.c_str());
 }
 
-// this will be made extensible when fast patterns are extensible
-static const char* get_service(const char* opt)
+// FIXIT-L this will be removed when ips option api
+// is updated to include service
+static const char* guess_service(const char* opt)
 {
     if ( !strncmp(opt, "http_", 5) )
         return "http";
 
-    if ( !strncmp(opt, "js_data", 7) )
-        return "http";
-
-    if ( !strncmp(opt, "cip_", 4) )  // NO FP BUF
+    if ( !strncmp(opt, "cip_", 4) or !strncmp(opt, "enip_", 5) )
         return "cip";
 
     if ( !strncmp(opt, "dce_", 4) )
@@ -157,9 +174,12 @@ static const char* get_service(const char* opt)
     if ( !strncmp(opt, "dnp3_", 5) )
         return "dnp3";
 
-    if ( !strncmp(opt, "gtp_", 4) )  // NO FP BUF
+    if ( !strncmp(opt, "gtp_", 4) )
         return "gtp";
 
+    if ( !strncmp(opt, "mms_", 4) )
+        return "mms";
+
     if ( !strncmp(opt, "modbus_", 7) )
         return "modbus";
 
@@ -169,8 +189,8 @@ static const char* get_service(const char* opt)
     if ( !strncmp(opt, "sip_", 4) )
         return "sip";
 
-    if ( !strncmp(opt, "vba_data", 8) )
-        return "file";
+    if ( !strncmp(opt, "ssl_", 4) )
+        return "ssl";
 
     return nullptr;
 }
@@ -293,20 +313,17 @@ static std::string make_db_name(
 
 static bool db_dump(const std::string& path, const char* proto, const char* dir, RuleGroup* g)
 {
-    for ( auto i = 0; i < PM_TYPE_MAX; ++i )
+    for ( auto it : g->pm_list )
     {
-        if ( !g->mpsegrp[i] )
-            continue;
-
         std::string id;
-        g->mpsegrp[i]->normal_mpse->get_hash(id);
+        it->group.normal_mpse->get_hash(id);
 
-        std::string file = make_db_name(path, proto, dir, pm_type_strings[i], id);
+        std::string file = make_db_name(path, proto, dir, it->name, id);
 
         uint8_t* db = nullptr;
         size_t len = 0;
 
-        if ( g->mpsegrp[i]->normal_mpse->serialize(db, len) and db and len > 0 )
+        if ( it->group.normal_mpse->serialize(db, len) and db and len > 0 )
         {
             store(file, db, len);
             free(db);
@@ -323,15 +340,12 @@ static bool db_dump(const std::string& path, const char* proto, const char* dir,
 
 static bool db_load(const std::string& path, const char* proto, const char* dir, RuleGroup* g)
 {
-    for ( auto i = 0; i < PM_TYPE_MAX; ++i )
+    for ( auto it : g->pm_list )
     {
-        if ( !g->mpsegrp[i] )
-            continue;
-
         std::string id;
-        g->mpsegrp[i]->normal_mpse->get_hash(id);
+        it->group.normal_mpse->get_hash(id);
 
-        std::string file = make_db_name(path, proto, dir, pm_type_strings[i], id);
+        std::string file = make_db_name(path, proto, dir, it->name, id);
 
         uint8_t* db = nullptr;
         size_t len = 0;
@@ -341,7 +355,7 @@ static bool db_load(const std::string& path, const char* proto, const char* dir,
             ParseWarning(WARN_RULES, "Failed to read %s", file.c_str());
             return false;
         }
-        else if ( !g->mpsegrp[i]->normal_mpse->deserialize(db, len) )
+        else if ( !it->group.normal_mpse->deserialize(db, len) )
         {
             ParseWarning(WARN_RULES, "Failed to deserialize %s", file.c_str());
             return false;
@@ -431,8 +445,8 @@ unsigned fp_deserialize(const SnortConfig* sc, const std::string& dir)
 
 void validate_services(SnortConfig* sc, OptTreeNode* otn)
 {
-    std::string svc;
-    bool file = false;
+    std::string svc, multi_svc_buf;
+    const char* guess = nullptr;
 
     for (OptFpList* ofl = otn->opt_func; ofl; ofl = ofl->next)
     {
@@ -440,24 +454,29 @@ void validate_services(SnortConfig* sc, OptTreeNode* otn)
             continue;
 
         CursorActionType cat = ofl->ips_opt->get_cursor_type();
+        const char* s = ofl->ips_opt->get_name();
 
         if ( cat <= CAT_ADJUST )
+        {
+            if ( !guess )
+                guess = guess_service(s);
+
             continue;
+        }
 
-        const char* s = ofl->ips_opt->get_name();
+        unsigned n = get_num_services(s);
+
+        if ( !n )
+            continue;
 
-        // special case file_data because it could be any subset of file carving services
-        if ( !strcmp(s, "file_data") )
+        if ( n > 1 )
         {
-            file = true;
+            multi_svc_buf = s;
             continue;
         }
 
         s = get_service(s);
 
-        if ( !s )
-            continue;
-
         if ( !svc.empty() and svc != s )
         {
             ParseWarning(WARN_RULES, "%u:%u:%u has mixed service buffers (%s and %s)",
@@ -478,21 +497,35 @@ void validate_services(SnortConfig* sc, OptTreeNode* otn)
 
         add_service_to_otn(sc, otn, svc.c_str());
     }
-    if ( otn->sigInfo.services.empty() and file )
+    if ( otn->sigInfo.services.empty() and !multi_svc_buf.empty() )
     {
-        ParseWarning(WARN_RULES, "%u:%u:%u has no service with file_data",
-            otn->sigInfo.gid, otn->sigInfo.sid, otn->sigInfo.rev);
-        add_service_to_otn(sc, otn, "file");
+        ParseWarning(WARN_RULES, "%u:%u:%u has no service with %s",
+            otn->sigInfo.gid, otn->sigInfo.sid, otn->sigInfo.rev, multi_svc_buf.c_str());
+
+        add_default_services(sc, multi_svc_buf, otn);
+    }
+    if ( !otn->sigInfo.services.size() and guess )
+    {
+        ParseWarning(WARN_RULES, "%u:%u:%u has no service with %s option",
+            otn->sigInfo.gid, otn->sigInfo.sid, otn->sigInfo.rev, guess);
+
+        add_service_to_otn(sc, otn, guess);
+
+        if ( !strcmp(guess, "netbios-ssn") )  // :(
+            add_service_to_otn(sc, otn, "dcerpc");
+
+        otn->set_service_only();
     }
 }
 
 PatternMatchVector get_fp_content(
-    OptTreeNode* otn, OptFpList*& node, bool srvc, bool only_literals, bool& exclude)
+    OptTreeNode* otn, OptFpList*& node, IpsOption*& fp_opt, bool srvc, bool only_literals, bool& exclude)
 {
     CursorActionType curr_cat = CAT_SET_RAW;
     FpSelector best;
     bool content = false;
     PatternMatchVector pmds;
+    IpsOption* curr_opt = nullptr, * best_opt = nullptr;
 
     for (OptFpList* ofl = otn->opt_func; ofl; ofl = ofl->next)
     {
@@ -502,7 +535,12 @@ PatternMatchVector get_fp_content(
         CursorActionType cat = ofl->ips_opt->get_cursor_type();
 
         if ( cat > CAT_ADJUST )
+        {
+            if ( cat == CAT_SET_FAST_PATTERN or cat == CAT_SET_RAW )
+                curr_opt = ofl->ips_opt;
+
             curr_cat = cat;
+        }
 
         RuleDirection dir = get_dir(otn);
         PatternMatchData* tmp = ofl->ips_opt->get_pattern(otn->snort_protocol_id, dir);
@@ -518,6 +556,7 @@ PatternMatchVector get_fp_content(
         {
             best = curr;
             node = ofl;
+            best_opt = curr_opt;
         }
     }
 
@@ -533,6 +572,7 @@ PatternMatchVector get_fp_content(
         if (alt_pmd)
             pmds.emplace_back(alt_pmd);
         pmds.emplace_back(best.pmd); // add primary pattern last
+        fp_opt = best_opt;
     }
     return pmds;
 }
@@ -638,8 +678,6 @@ unsigned compile_mpses(struct SnortConfig* sc, bool parallel)
 #ifdef UNIT_TEST
 static void set_pmd(PatternMatchData& pmd, unsigned flags, const char* s)
 {
-    memset(&pmd, 0, sizeof(pmd));
-
     if ( flags & 0x01 )
         pmd.set_negated();
     if ( flags & 0x02 )
@@ -657,49 +695,49 @@ static void set_pmd(PatternMatchData& pmd, unsigned flags, const char* s)
 
 TEST_CASE("pmd_no_options", "[PatternMatchData]")
 {
-    PatternMatchData pmd;
+    PatternMatchData pmd = { };
     set_pmd(pmd, 0x0, "foo");
     CHECK(pmd.can_be_fp());
 }
 
 TEST_CASE("pmd_negated", "[PatternMatchData]")
 {
-    PatternMatchData pmd;
+    PatternMatchData pmd = { };
     set_pmd(pmd, 0x1, "foo");
     CHECK(!pmd.can_be_fp());
 }
 
 TEST_CASE("pmd_no_case", "[PatternMatchData]")
 {
-    PatternMatchData pmd;
+    PatternMatchData pmd = { };
     set_pmd(pmd, 0x2, "foo");
     CHECK(pmd.can_be_fp());
 }
 
 TEST_CASE("pmd_relative", "[PatternMatchData]")
 {
-    PatternMatchData pmd;
+    PatternMatchData pmd = { };
     set_pmd(pmd, 0x4, "foo");
     CHECK(pmd.can_be_fp());
 }
 
 TEST_CASE("pmd_negated_no_case", "[PatternMatchData]")
 {
-    PatternMatchData pmd;
+    PatternMatchData pmd = { };
     set_pmd(pmd, 0x3, "foo");
     CHECK(pmd.can_be_fp());
 }
 
 TEST_CASE("pmd_negated_relative", "[PatternMatchData]")
 {
-    PatternMatchData pmd;
+    PatternMatchData pmd = { };
     set_pmd(pmd, 0x5, "foo");
     CHECK(!pmd.can_be_fp());
 }
 
 TEST_CASE("pmd_negated_no_case_offset", "[PatternMatchData]")
 {
-    PatternMatchData pmd;
+    PatternMatchData pmd = { };
     set_pmd(pmd, 0x1, "foo");
     pmd.offset = 3;
     CHECK(!pmd.can_be_fp());
@@ -707,7 +745,7 @@ TEST_CASE("pmd_negated_no_case_offset", "[PatternMatchData]")
 
 TEST_CASE("pmd_negated_no_case_depth", "[PatternMatchData]")
 {
-    PatternMatchData pmd;
+    PatternMatchData pmd = { };
     set_pmd(pmd, 0x3, "foo");
     pmd.depth = 1;
     CHECK(!pmd.can_be_fp());
@@ -716,7 +754,7 @@ TEST_CASE("pmd_negated_no_case_depth", "[PatternMatchData]")
 TEST_CASE("fp_simple", "[FastPatternSelect]")
 {
     FpSelector test;
-    PatternMatchData pmd;
+    PatternMatchData pmd = { };
     set_pmd(pmd, 0x0, "foo");
     FpSelector left(CAT_SET_RAW, nullptr, &pmd);
     CHECK(left.is_better_than(test, false, RULE_WO_DIR));
@@ -727,11 +765,11 @@ TEST_CASE("fp_simple", "[FastPatternSelect]")
 
 TEST_CASE("fp_negated", "[FastPatternSelect]")
 {
-    PatternMatchData p0;
+    PatternMatchData p0 = { };
     set_pmd(p0, 0x0, "foo");
     FpSelector s0(CAT_SET_RAW, nullptr, &p0);
 
-    PatternMatchData p1;
+    PatternMatchData p1 = { };
     set_pmd(p1, 0x1, "foo");
     FpSelector s1(CAT_SET_RAW, nullptr, &p1);
 
@@ -741,26 +779,26 @@ TEST_CASE("fp_negated", "[FastPatternSelect]")
 
 TEST_CASE("fp_cat1", "[FastPatternSelect]")
 {
-    PatternMatchData p0;
+    PatternMatchData p0 = { };
     set_pmd(p0, 0x0, "longer");
-    FpSelector s0(CAT_SET_FILE, nullptr, &p0);
+    FpSelector s0(CAT_SET_FAST_PATTERN, nullptr, &p0);
 
-    PatternMatchData p1;
+    PatternMatchData p1 = { };
     set_pmd(p1, 0x0, "short");
-    FpSelector s1(CAT_SET_BODY, nullptr, &p1);
+    FpSelector s1(CAT_SET_FAST_PATTERN, nullptr, &p1);
 
     CHECK(s0.is_better_than(s1, true, RULE_WO_DIR));
 }
 
 TEST_CASE("fp_cat2", "[FastPatternSelect]")
 {
-    PatternMatchData p0;
+    PatternMatchData p0 = { };
     set_pmd(p0, 0x0, "foo");
     FpSelector s0(CAT_SET_RAW, nullptr, &p0);
 
-    PatternMatchData p1;
+    PatternMatchData p1 = { };
     set_pmd(p1, 0x0, "foo");
-    FpSelector s1(CAT_SET_FILE, nullptr, &p1);
+    FpSelector s1(CAT_SET_FAST_PATTERN, nullptr, &p1);
 
     CHECK(!s0.is_better_than(s1, false, RULE_WO_DIR));
     CHECK(!s1.is_better_than(s0, false, RULE_WO_DIR));
@@ -768,117 +806,117 @@ TEST_CASE("fp_cat2", "[FastPatternSelect]")
 
 TEST_CASE("fp_cat3", "[FastPatternSelect]")
 {
-    PatternMatchData p0;
+    PatternMatchData p0 = { };
     set_pmd(p0, 0x0, "foo");
     FpSelector s0(CAT_SET_RAW, nullptr, &p0);
 
-    PatternMatchData p1;
+    PatternMatchData p1 = { };
     set_pmd(p1, 0x0, "foo");
-    FpSelector s1(CAT_SET_FILE, nullptr, &p1);
+    FpSelector s1(CAT_SET_FAST_PATTERN, nullptr, &p1);
 
     CHECK(!s0.is_better_than(s1, true, RULE_WO_DIR));
 }
 
 TEST_CASE("fp_size", "[FastPatternSelect]")
 {
-    PatternMatchData p0;
+    PatternMatchData p0 = { };
     set_pmd(p0, 0x0, "longer");
-    FpSelector s0(CAT_SET_HEADER, nullptr, &p0);
+    FpSelector s0(CAT_SET_FAST_PATTERN, nullptr, &p0);
 
-    PatternMatchData p1;
+    PatternMatchData p1 = { };
     set_pmd(p1, 0x0, "short");
-    FpSelector s1(CAT_SET_HEADER, nullptr, &p1);
+    FpSelector s1(CAT_SET_FAST_PATTERN, nullptr, &p1);
 
     CHECK(s0.is_better_than(s1, false, RULE_WO_DIR));
 }
 
 TEST_CASE("fp_pkt_key_port", "[FastPatternSelect]")
 {
-    PatternMatchData p0;
+    PatternMatchData p0 = { };
     set_pmd(p0, 0x0, "short");
     FpSelector s0(CAT_SET_RAW, nullptr, &p0);
 
-    PatternMatchData p1;
+    PatternMatchData p1 = { };
     set_pmd(p1, 0x0, "longer");
-    FpSelector s1(CAT_SET_KEY, nullptr, &p1);
+    FpSelector s1(CAT_SET_FAST_PATTERN, nullptr, &p1);
 
     CHECK(!s0.is_better_than(s1, false, RULE_WO_DIR));
 }
 
 TEST_CASE("fp_pkt_key_port_user", "[FastPatternSelect]")
 {
-    PatternMatchData p0;
+    PatternMatchData p0 = { };
     set_pmd(p0, 0x10, "short");
-    FpSelector s0(CAT_SET_KEY, nullptr, &p0);
+    FpSelector s0(CAT_SET_FAST_PATTERN, nullptr, &p0);
 
-    PatternMatchData p1;
+    PatternMatchData p1 = { };
     set_pmd(p1, 0x0, "longer");
-    FpSelector s1(CAT_SET_KEY, nullptr, &p1);
+    FpSelector s1(CAT_SET_FAST_PATTERN, nullptr, &p1);
 
     CHECK(s0.is_better_than(s1, false, RULE_WO_DIR));
 }
 
 TEST_CASE("fp_pkt_key_port_user_user", "[FastPatternSelect]")
 {
-    PatternMatchData p0;
+    PatternMatchData p0 = { };
     set_pmd(p0, 0x10, "longer");
-    FpSelector s0(CAT_SET_KEY, nullptr, &p0);
+    FpSelector s0(CAT_SET_FAST_PATTERN, nullptr, &p0);
 
-    PatternMatchData p1;
+    PatternMatchData p1 = { };
     set_pmd(p1, 0x10, "short");
-    FpSelector s1(CAT_SET_KEY, nullptr, &p1);
+    FpSelector s1(CAT_SET_FAST_PATTERN, nullptr, &p1);
 
     CHECK(!s0.is_better_than(s1, false, RULE_WO_DIR));
 }
 
 TEST_CASE("fp_pkt_key_port_user_user2", "[FastPatternSelect]")
 {
-    PatternMatchData p0;
+    PatternMatchData p0 = { };
     set_pmd(p0, 0x0, "longer");
-    FpSelector s0(CAT_SET_KEY, nullptr, &p0);
+    FpSelector s0(CAT_SET_FAST_PATTERN, nullptr, &p0);
 
-    PatternMatchData p1;
+    PatternMatchData p1 = { };
     set_pmd(p1, 0x10, "short");
-    FpSelector s1(CAT_SET_KEY, nullptr, &p1);
+    FpSelector s1(CAT_SET_FAST_PATTERN, nullptr, &p1);
 
     CHECK(!s0.is_better_than(s1, false, RULE_WO_DIR));
 }
 
 TEST_CASE("fp_pkt_key_srvc_1", "[FastPatternSelect]")
 {
-    PatternMatchData p0;
+    PatternMatchData p0 = { };
     set_pmd(p0, 0x0, "short");
     FpSelector s0(CAT_SET_RAW, nullptr, &p0);
 
-    PatternMatchData p1;
+    PatternMatchData p1 = { };
     set_pmd(p1, 0x0, "longer");
-    FpSelector s1(CAT_SET_KEY, nullptr, &p1);
+    FpSelector s1(CAT_SET_FAST_PATTERN, nullptr, &p1);
 
     CHECK(s1.is_better_than(s0, true, RULE_WO_DIR));
 }
 
 TEST_CASE("fp_pkt_key_srvc_2", "[FastPatternSelect]")
 {
-    PatternMatchData p0;
+    PatternMatchData p0 = { };
     set_pmd(p0, 0x0, "longer");
     FpSelector s0(CAT_SET_RAW, nullptr, &p0);
 
-    PatternMatchData p1;
+    PatternMatchData p1 = { };
     set_pmd(p1, 0x0, "short");
-    FpSelector s1(CAT_SET_KEY, nullptr, &p1);
+    FpSelector s1(CAT_SET_FAST_PATTERN, nullptr, &p1);
 
     CHECK(s0.is_better_than(s1, true, RULE_WO_DIR));
 }
 
 TEST_CASE("fp_pkt_key_srvc_rsp", "[FastPatternSelect]")
 {
-    PatternMatchData p0;
+    PatternMatchData p0 = { };
     set_pmd(p0, 0x0, "short");
     FpSelector s0(CAT_SET_RAW, nullptr, &p0);
 
-    PatternMatchData p1;
+    PatternMatchData p1 = { };
     set_pmd(p1, 0x0, "longer");
-    FpSelector s1(CAT_SET_KEY, nullptr, &p1);
+    FpSelector s1(CAT_SET_FAST_PATTERN, nullptr, &p1);
 
     CHECK(!s0.is_better_than(s1, true, RULE_FROM_SERVER));
     CHECK(s1.is_better_than(s0, true, RULE_FROM_SERVER));
index 7bc80a2bbae171fba5b3b53b69210f3b30431488..293ca6d652c24cffc0442c3647fdbabebc0b9fbc 100644 (file)
@@ -38,12 +38,12 @@ struct PatternMatchData* get_pmd(OptFpList*, SnortProtocolId, snort::RuleDirecti
 bool make_fast_pattern_only(const OptFpList*, const PatternMatchData*);
 bool is_fast_pattern_only(const OptTreeNode*, const OptFpList*, snort::Mpse::MpseType);
 
-PmType get_pm_type(snort::CursorActionType);
+PatternMatcher::Type get_pm_type(const std::string& buf);
 
 bool set_fp_content(OptTreeNode*);
 
 std::vector <PatternMatchData*> get_fp_content(
-    OptTreeNode*, OptFpList*&, bool srvc, bool only_literals, bool& exclude);
+    OptTreeNode*, OptFpList*& pat, snort::IpsOption*& buf, bool srvc, bool only_literals, bool& exclude);
 
 void queue_mpse(snort::Mpse*);
 unsigned compile_mpses(struct snort::SnortConfig*, bool parallel = false);
@@ -53,5 +53,8 @@ void validate_services(struct snort::SnortConfig*, OptTreeNode*);
 unsigned fp_serialize(const struct snort::SnortConfig*, const std::string& dir);
 unsigned fp_deserialize(const struct snort::SnortConfig*, const std::string& dir);
 
+void update_buffer_map(const char** bufs, const char* svc);
+void add_default_services(struct snort::SnortConfig*, const std::string&, OptTreeNode*);
+
 #endif
 
index 9295f136b06a0fbd822739da15034bdd8558314d..98bb5a391f092072c7b9912f7476fd6289444260 100644 (file)
@@ -140,6 +140,7 @@ void IpsContext::post_detection()
         callback(this);
 
     post_callbacks.clear();
+    alt_data.len = 0;
 }
 
 void IpsContext::disable_detection()
index dbe49d7f16fc3d3e551dd44066ede970f566507a..8297ea6f0c929ca19e3464304681fd96a8431101 100644 (file)
@@ -22,6 +22,9 @@
 #define PATTERN_MATCH_DATA_H
 
 #include <sys/time.h>
+
+#include <cctype>
+#include <string>
 #include <vector>
 
 #include "framework/ips_option.h"  // FIXIT-L not a good dependency
@@ -36,8 +39,6 @@ struct PmdLastCheck
 
 struct PatternMatchData
 {
-    const char* pattern_buf; // app layer pattern to match on
-
     // FIXIT-L wasting some memory here:
     // - this is not used by content option logic directly
     // - and only used on current eval (not across packets)
@@ -47,7 +48,12 @@ struct PatternMatchData
        but the rule option specifies a negated content. Only
        applies to negative contents that are not relative */
     PmdLastCheck* last_check;
+    const char* sticky_buf = nullptr;  // provides context to contents
+    //----------------------------------------------------------------
+    // data above this point is for framework use only!
+    //----------------------------------------------------------------
 
+    const char* pattern_buf; // app layer pattern to match on
     unsigned pattern_size;   // size of app layer pattern
 
     int offset;              // pattern search start offset
@@ -69,9 +75,6 @@ struct PatternMatchData
     uint16_t fp_offset;
     uint16_t fp_length;
 
-    // not used by ips_content
-    uint8_t pm_type;
-
     bool is_unbounded() const
     { return !depth; }
 
@@ -106,6 +109,8 @@ struct PatternMatchData
     { return (flags & LITERAL) != 0; }
 
     bool can_be_fp() const;
+
+    bool has_alpha() const;
 };
 
 typedef std::vector<PatternMatchData*> PatternMatchVector;
@@ -137,5 +142,18 @@ inline bool PatternMatchData::can_be_fp() const
     return true;
 }
 
+inline bool PatternMatchData::has_alpha() const
+{
+    unsigned offset = fp_offset ? fp_offset : 0;
+    unsigned length = fp_length ? fp_length : pattern_size;
+
+    for ( unsigned idx = 0; idx < length; ++idx )
+    {
+        if ( isalpha(pattern_buf[offset + idx]) )
+            return true;
+    }
+    return false;
+}
+
 #endif
 
index c1dbc2c37723ca3d3946c0cfb9dba2ac5567d1f2..9ac505c28f5726e79e0331104d9e5b92fc87029b 100644 (file)
 #ifndef RULE_OPTION_TYPES_H
 #define RULE_OPTION_TYPES_H
 
-// if you change this, you must also update detection_options.cc::option_type_str[].
 enum option_type_t
 {
     RULE_OPTION_TYPE_LEAF_NODE,    // internal use by rule compiler
-    RULE_OPTION_TYPE_BUFFER_SET,   // sets sticky buffer
-    RULE_OPTION_TYPE_BUFFER_USE,   // uses sticky buffer
-    RULE_OPTION_TYPE_CONTENT,      // ideally would be eliminated (implies _BUFFER_USE)
+    RULE_OPTION_TYPE_CONTENT,      // ideally would be eliminated
     RULE_OPTION_TYPE_FLOWBIT,      // ideally would be eliminated
     RULE_OPTION_TYPE_OTHER         // for all new buffer independent rule options
 };
index b98c5fcd12426ec21752c2dc0d5d349a9db37e1f..c8fc3339ed67eab073d3b5c6f2d065a6873a7643 100644 (file)
@@ -22,6 +22,8 @@
 
 // rule header (RTN) and body (OTN) nodes
 
+#include <string>
+
 #include "actions/actions.h"
 #include "detection/signature.h"
 #include "detection/rule_option_types.h"
@@ -173,6 +175,7 @@ struct OptTreeNode
     static constexpr Flag TO_CLIENT  = 0x10;
     static constexpr Flag TO_SERVER  = 0x20;
     static constexpr Flag BIT_CHECK  = 0x40;
+    static constexpr Flag SVC_ONLY   = 0x80;
 
     /* metadata about signature */
     SigInfo sigInfo;
@@ -202,8 +205,6 @@ struct OptTreeNode
     IpsPolicy::Enable enable;
     Flag flags = 0;
 
-    uint8_t sticky_buf = PM_TYPE_PKT; // parsing only
-
     void set_warned_fp()
     { flags |= WARNED_FP; }
 
@@ -255,6 +256,12 @@ struct OptTreeNode
     bool checks_flowbits() const
     { return (flags & BIT_CHECK) != 0; }
 
+    void set_service_only()
+    { flags |= SVC_ONLY; }
+
+    bool service_only() const
+    { return (flags & SVC_ONLY) != 0; }
+
     void update_fp(snort::IpsOption*);
 };
 
index 0b945ab8302275d7c83e1396aa58add5f9e09293..c772815a9288d337ab4c7b431791c6166a28f930 100644 (file)
@@ -29,7 +29,6 @@
 #include "flow/session.h"
 #include "framework/data_bus.h"
 #include "helpers/bitop.h"
-#include "ips_options/ips_flowbits.h"
 #include "memory/memory_cap.h"
 #include "protocols/packet.h"
 #include "protocols/tcp.h"
index 850c2ec2905db6526e09ed574df527a6c4750804..8630ece926ebc69fa8d8064953193ccecec4b089 100644 (file)
@@ -28,7 +28,6 @@
 #include "hash/hash_defs.h"
 #include "hash/zhash.h"
 #include "helpers/flag_context.h"
-#include "ips_options/ips_flowbits.h"
 #include "main/snort_debug.h"
 #include "memory/memory_cap.h"
 #include "packet_io/active.h"
index 8fc6e4ca62a739c1172d6c23d6a1fbcd30ea444f..f4c32cbaa8295fe2544bf7ff5367f3e50290405b 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "cursor.h"
 
+#include "detection/detection_engine.h"
 #include "detection/detection_util.h"
 #include "protocols/packet.h"
 
@@ -94,16 +95,17 @@ void Cursor::set_data(CursorData* cd)
 
 void Cursor::reset(Packet* p)
 {
-    InspectionBuffer buf;
-
-    if ( p->flow and p->flow->gadget and
-        p->flow->gadget->get_buf(buf.IBT_ALT, p, buf) )
-    {
-        set("alt_data", buf.data, buf.len);
-    }
-    else
+    if ( p->flow and p->flow->gadget )
     {
-        set("pkt_data", p->data, p->get_detect_limit());
+        const DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+
+        if ( buf.len )
+        {
+            set("alt_data", buf.data, buf.len);
+            return;
+        }
     }
+
+    set("pkt_data", p->data, p->get_detect_limit());
 }
 
index f598ecaf5b5cbd5449ba5b9f643a9a6dd86482cc..db3b25da4e120f37f1c23e107136673506b64d4a 100644 (file)
@@ -47,10 +47,16 @@ struct InspectionBuffer
 {
     enum Type
     {
-        // FIXIT-L file data is tbd
-        IBT_KEY, IBT_HEADER, IBT_BODY, IBT_FILE, IBT_ALT,
-        IBT_RAW_KEY, IBT_RAW_HEADER, IBT_METHOD, IBT_STAT_CODE,
-        IBT_STAT_MSG, IBT_COOKIE, IBT_JS_DATA, IBT_VBA, IBT_MAX
+        // this is the only generic rule option
+        IBT_VBA,
+
+        // FIXIT-M all of these should be eliminated after NHI is updated
+        IBT_KEY, IBT_HEADER, IBT_BODY,
+        IBT_RAW_KEY, IBT_RAW_HEADER, IBT_METHOD,
+        IBT_STAT_CODE, IBT_STAT_MSG, IBT_COOKIE,
+        IBT_JS_DATA,
+
+        IBT_MAX
     };
     const uint8_t* data;
     unsigned len;
index b6a900fcd07417ffadb697ae8107fea825855abd..f3feecd9c066d62cc46930da1e6042f1c1154005 100644 (file)
 
 using namespace snort;
 
-static const char* s_buffer = nullptr;
-
-void IpsOption::set_buffer(const char* s)
-{ s_buffer = s; }
-
 //-------------------------------------------------------------------------
 
 IpsOption::IpsOption(const char* s, option_type_t t)
 {
     name = s;
     type = t;
-
-    switch ( t )
-    {
-    case RULE_OPTION_TYPE_BUFFER_SET: buffer = s_buffer = s; break;
-    case RULE_OPTION_TYPE_CONTENT:
-    case RULE_OPTION_TYPE_BUFFER_USE: buffer = s_buffer; break;
-    default: buffer = "n/a";
-    }
 }
 
 uint32_t IpsOption::hash() const
 {
     uint32_t a = 0, b = 0, c = 0;
     mix_str(a, b, c, get_name());
-    mix_str(a, b, c, get_buffer());
     finalize(a, b, c);
     return c;
 }
 
 bool IpsOption::operator==(const IpsOption& ips) const
 {
-    return !strcmp(get_name(), ips.get_name()) and
-        !strcmp(get_buffer(), ips.get_buffer());
+    return !strcmp(get_name(), ips.get_name());
 }
 
 //-------------------------------------------------------------------------
@@ -84,10 +69,16 @@ TEST_CASE("IpsOption test", "[ips_option]")
     StubIpsOption main_ips("ips_test",
         option_type_t::RULE_OPTION_TYPE_OTHER);
 
+    SECTION("buffer test")
+    {
+        REQUIRE(main_ips.get_buffer());  // only until api is updated
+    }
+
     SECTION("IpsOperator == test")
     {
         StubIpsOption case_diff_name("not_hello_world",
-            option_type_t::RULE_OPTION_TYPE_BUFFER_USE);
+            option_type_t::RULE_OPTION_TYPE_LEAF_NODE);
+
         REQUIRE((main_ips == case_diff_name) == false);
 
         StubIpsOption case_diff_option("hello_world",
index e5165374f699c5e063ac20acc7b6b6cb4df1f075..cbd935bcaeefce1ca42d68656e9c28c98de96860 100644 (file)
@@ -52,18 +52,7 @@ enum CursorActionType
     CAT_ADJUST,
     CAT_SET_OTHER,
     CAT_SET_RAW,
-    CAT_SET_COOKIE,
-    CAT_SET_STAT_MSG,
-    CAT_SET_STAT_CODE,
-    CAT_SET_METHOD,
-    CAT_SET_RAW_HEADER,
-    CAT_SET_RAW_KEY,
-    CAT_SET_FILE,
-    CAT_SET_BODY,
-    CAT_SET_HEADER,
-    CAT_SET_KEY,
-    CAT_SET_JS_DATA,
-    CAT_SET_VBA,
+    CAT_SET_FAST_PATTERN,
 };
 
 enum RuleDirection
@@ -95,10 +84,6 @@ public:
     enum EvalStatus { NO_MATCH, MATCH, NO_ALERT, FAILED_BIT };
     virtual EvalStatus eval(Cursor&, Packet*) { return MATCH; }
 
-    option_type_t get_type() const { return type; }
-    const char* get_name() const { return name; }
-    const char* get_buffer() const { return buffer; }
-
     virtual CursorActionType get_cursor_type() const
     { return CAT_NONE; }
 
@@ -109,14 +94,21 @@ public:
     virtual PatternMatchData* get_alternate_pattern()
     { return nullptr; }
 
-    static void set_buffer(const char*);
+    option_type_t get_type() const { return type; }
+    const char* get_name() const { return name; }
+
+    bool is_buffer_setter() const
+    { return get_cursor_type() > CAT_ADJUST; }
+
+    const char* get_buffer()
+    { return buffer; }
 
 protected:
     IpsOption(const char* s, option_type_t t = RULE_OPTION_TYPE_OTHER);
 
 private:
     const char* name;
-    const char* buffer;
+    const char* buffer = "error"; // FIXIT-API to be deleted; here to avoid an api update
     option_type_t type;
 };
 
index 7bf5660fd45387b849ca5d5e2f9cdd36193da1a2..fd500a98e4a07f1e576474efeb27e9906084b91a 100644 (file)
@@ -130,8 +130,7 @@ struct MpseBatch
 
 inline void MpseBatch::search()
 {
-    items.begin()->second.so[0]->get_normal_mpse()->
-        search(*this, Mpse::MPSE_TYPE_NORMAL);
+    items.begin()->second.so[0]->get_normal_mpse()->search(*this, Mpse::MPSE_TYPE_NORMAL);
 }
 
 inline Mpse::MpseRespType MpseBatch::receive_responses()
index 4263008289c07ce3376139978ada3dbec436ab46..f8c43efe9835fc5b8b89c28536dd4748b054d069 100644 (file)
@@ -86,7 +86,7 @@ static THREAD_LOCAL ProfileStats asn1PerfStats;
 class Asn1Option : public IpsOption
 {
 public:
-    Asn1Option(const ASN1_CTXT& c) : IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_USE)
+    Asn1Option(const ASN1_CTXT& c) : IpsOption(s_name)
     { config = c; }
 
     uint32_t hash() const override;
index c78104327eb084f58025990e5b01d189bdfa2219..672b871ba143b19bd28920790eacf34e1dc9ba63 100644 (file)
@@ -59,7 +59,7 @@ struct Base64DecodeData
 class Base64DecodeOption : public IpsOption
 {
 public:
-    Base64DecodeOption(const Base64DecodeData& c) : IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_USE)
+    Base64DecodeOption(const Base64DecodeData& c) : IpsOption(s_name)
     { config = c; }
 
 
@@ -274,7 +274,7 @@ static const IpsApi base64_decode_api =
 class Base64DataOption : public IpsOption
 {
 public:
-    Base64DataOption() : IpsOption(s_data_name, RULE_OPTION_TYPE_BUFFER_SET) { }
+    Base64DataOption() : IpsOption(s_data_name) { }
 
     CursorActionType get_cursor_type() const override
     { return CAT_SET_OTHER; }
index c62b7c2d478236980a213bea3286f3092e0a7fdc..0fd708acd4deb7b618d3ca3330f4f70867e03948 100644 (file)
@@ -48,6 +48,9 @@ public:
 
     EvalStatus eval(Cursor&, Packet*) override;
 
+    CursorActionType get_cursor_type() const override
+    { return CAT_ADJUST; }
+
 private:
     uint32_t type;
 };
index 0d305ab99c272da5835602bf8aedb1b29c8d8cfd..8addd34efee8d6753ec2f5874cdbe14695aa7289 100644 (file)
@@ -48,6 +48,9 @@ public:
 
     EvalStatus eval(Cursor&, Packet*) override;
 
+    CursorActionType get_cursor_type() const override
+    { return CAT_ADJUST; }
+
 private:
     uint32_t type;
     bool optional;
index fdb53a49b7cbbba3364cbc979d88e962ae4a6832..cfa68f9561007ef37775781a3ff72a97b31be0b3 100644 (file)
@@ -40,13 +40,15 @@ static THREAD_LOCAL ProfileStats lenCheckPerfStats;
 class LenOption : public IpsOption
 {
 public:
-    LenOption(const RangeCheck& c, bool r) :
-        IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_USE)
+    LenOption(const RangeCheck& c, bool r) : IpsOption(s_name)
     { config = c; relative = r; }
 
     uint32_t hash() const override;
     bool operator==(const IpsOption&) const override;
 
+    bool is_relative() override
+    { return relative; }
+
     EvalStatus eval(Cursor&, Packet*) override;
 
 private:
index 0e0717540a8e9a06bae3a0af19cd2265e34607db..518fcee1baa95bba75fec1fb96d357afc50f831d 100644 (file)
@@ -61,7 +61,7 @@ class ByteExtractOption : public IpsOption
 {
 public:
     ByteExtractOption(const ByteExtractData& c) :
-        IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_USE), config(c)
+        IpsOption(s_name), config(c)
     { }
 
     ~ByteExtractOption() override
@@ -510,22 +510,12 @@ static ByteExtractDataMatcher ByteExtractDataEquals(const ByteExtractData& value
     return {value};
 }
 
-class SetBufferOptionHelper : public IpsOption
-{
-public:
-    SetBufferOptionHelper(const char* value)
-        : IpsOption(value, RULE_OPTION_TYPE_BUFFER_SET)
-    { }
-};
-
 //-------------------------------------------------------------------------
 // option tests
 //-------------------------------------------------------------------------
 
 TEST_CASE("ByteExtractOption::operator== valid", "[ips_byte_extract]")
 {
-    SetBufferOptionHelper set_buf("test");
-
     char* lhs_name = new char[9];
     strcpy(lhs_name, "test_lhs");
     ByteExtractData data_lhs;
@@ -543,19 +533,12 @@ TEST_CASE("ByteExtractOption::operator== valid", "[ips_byte_extract]")
 
 TEST_CASE("ByteExtractOption::operator== invalid", "[ips_byte_extract]")
 {
-    SetBufferOptionHelper set_buf("test");
-
     char* lhs_name = new char[5];
     strcpy(lhs_name, "test");
     ByteExtractData data_lhs;
     INITIALIZE(data_lhs, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, nullptr);
     ByteExtractOption lhs(data_lhs);
 
-    SECTION("not equal to IpsOption object")
-    {
-        CHECK(lhs != set_buf);
-        delete[] lhs_name;
-    }
     SECTION("all fields is different")
     {
         ByteExtractData data_rhs;
@@ -647,8 +630,6 @@ TEST_CASE("ByteExtractOption::operator== invalid", "[ips_byte_extract]")
 
 TEST_CASE("ByteExtractOption::hash", "[ips_byte_extract]")
 {
-    SetBufferOptionHelper set_buf("test");
-
     ByteExtractData data_lhs;
     INITIALIZE(data_lhs, 0, 0, 0, 0, 0, 0, 8, 1, 0, 0, nullptr);
     ByteExtractOption lhs(data_lhs);
index 6931e426db04037f70626b0aaa6d9b573030ab51..11a73e5aad1da0e9ea7cfefa6e9815f7d84a3aac 100644 (file)
@@ -109,9 +109,7 @@ struct ByteJumpData : public ByteData
 class ByteJumpOption : public IpsOption
 {
 public:
-    ByteJumpOption(const ByteJumpData& c) : IpsOption(s_name,
-        RULE_OPTION_TYPE_BUFFER_USE), config(c)
-    { }
+    ByteJumpOption(const ByteJumpData& c) : IpsOption(s_name), config(c) { }
 
     uint32_t hash() const override;
     bool operator==(const IpsOption&) const override;
@@ -597,14 +595,6 @@ static void SetByteJumpMaxValue(ByteJumpData &byte_jump)
     byte_jump.post_offset_var = SCHAR_MAX;
 }
 
-class StubIpsOption : public IpsOption
-{
-public:
-    StubIpsOption(const char* name, option_type_t option_type) :
-        IpsOption(name, option_type)
-    { }
-};
-
 class StubEndianness : public Endianness
 {
 public:
@@ -617,7 +607,6 @@ TEST_CASE("ByteJumpOption test", "[ips_byte_jump]")
 {
     ByteJumpData byte_jump;
     SetByteJumpData(byte_jump, 1);
-    snort::IpsOption::set_buffer("hello_world");
 
     SECTION("method hash")
     {
@@ -663,13 +652,6 @@ TEST_CASE("ByteJumpOption test", "[ips_byte_jump]")
     {
         ByteJumpOption jump(byte_jump);
 
-        SECTION("Compare IpsOptions with different names")
-        {
-            StubIpsOption case_diff_name("not_hello_world",
-                option_type_t::RULE_OPTION_TYPE_BUFFER_USE);
-            REQUIRE(jump != case_diff_name);
-        }
-
         ByteJumpData byte_jump2;
         SetByteJumpData(byte_jump2, 1);
 
index 02aefcd2859acd86d163363b19b92583cc7eaf9f..3cf4b6efdd99f4abb048b3c2013a34a6bdd8d737 100644 (file)
@@ -75,7 +75,7 @@ class ByteMathOption : public IpsOption
 {
 public:
     ByteMathOption(const ByteMathData& c) :
-        IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_USE), config(c)
+        IpsOption(s_name), config(c)
     { }
 
     ~ByteMathOption() override
@@ -84,9 +84,6 @@ public:
     uint32_t hash() const override;
     bool operator==(const IpsOption&) const override;
 
-    CursorActionType get_cursor_type() const override
-    { return CAT_ADJUST; }
-
     bool is_relative() override
     { return config.relative_flag; }
 
@@ -619,22 +616,12 @@ static ByteMathDataMatcher ByteMathDataEquals(const ByteMathData& value)
     return {value};
 }
 
-class SetBufferOptionHelper : public IpsOption
-{
-public:
-    SetBufferOptionHelper(const char* value)
-        : IpsOption(value, RULE_OPTION_TYPE_BUFFER_SET)
-    { }
-};
-
 //-------------------------------------------------------------------------
 // option tests
 //-------------------------------------------------------------------------
 
 TEST_CASE("ByteMathOption::operator== valid", "[ips_byte_math]")
 {
-    SetBufferOptionHelper set_buf("test");
-
     char* lhs_name = new char[9];
     strcpy(lhs_name, "test_lhs");
     ByteMathData data_lhs;
@@ -654,8 +641,6 @@ TEST_CASE("ByteMathOption::operator== valid", "[ips_byte_math]")
 
 TEST_CASE("ByteMathOption::operator== invalid", "[ips_byte_math]")
 {
-    SetBufferOptionHelper set_buf("test");
-
     char* lhs_name = new char[5];
     strcpy(lhs_name, "test");
     ByteMathData data_lhs;
@@ -666,11 +651,6 @@ TEST_CASE("ByteMathOption::operator== invalid", "[ips_byte_math]")
     char* rhs_name = new char[5];
     strcpy(rhs_name, "test");
 
-    SECTION("not equal to IpsOption object")
-    {
-        CHECK(lhs != set_buf);
-        delete[] rhs_name;
-    }
     SECTION("all fields is different")
     {
         delete[] rhs_name;
@@ -793,8 +773,6 @@ TEST_CASE("ByteMathOption::operator== invalid", "[ips_byte_math]")
 
 TEST_CASE("ByteMathOption::hash", "[ips_byte_math]")
 {
-    SetBufferOptionHelper set_buf("test");
-
     char* lhs_name = new char[5];
     strcpy(lhs_name, "test");
     ByteMathData data_lhs;
index 0a25f418104aca31601f6228441f896b6f299edb..a3daed4b0e3eb57a6aaa61db2d0525e5310bf632 100644 (file)
@@ -188,9 +188,7 @@ static inline bool byte_test_check(ByteTestOper op, uint32_t val, uint32_t cmp,
 class ByteTestOption : public IpsOption
 {
 public:
-    ByteTestOption(const ByteTestData& c) : IpsOption(s_name,
-        RULE_OPTION_TYPE_BUFFER_USE), config(c)
-    { }
+    ByteTestOption(const ByteTestData& c) : IpsOption(s_name), config(c) { }
 
     uint32_t hash() const override;
     bool operator==(const IpsOption&) const override;
@@ -656,14 +654,6 @@ static void SetByteTestDataMax(ByteTestData& byte_test)
     byte_test.offset_var = CHAR_MAX;
 }
 
-class StubIpsOption : public IpsOption
-{
-public:
-    StubIpsOption(const char* name, option_type_t option_type) :
-        IpsOption(name, option_type)
-    { }
-};
-
 class StubEndianness : public Endianness
 {
 public:
@@ -731,7 +721,6 @@ TEST_CASE("ByteTestOption test", "[ips_byte_test]")
 {
     ByteTestData byte_test;
     SetByteTestData(byte_test, 1);
-    snort::IpsOption::set_buffer("hello_world");
 
     SECTION("method hash")
     {
@@ -777,13 +766,6 @@ TEST_CASE("ByteTestOption test", "[ips_byte_test]")
     {
         ByteTestOption test(byte_test);
 
-        SECTION("Compare IpsOptions with different names")
-        {
-            StubIpsOption case_diff_name("not_hello_world",
-                option_type_t::RULE_OPTION_TYPE_BUFFER_USE);
-            REQUIRE(test != case_diff_name);
-        }
-
         SECTION("Compare between equals objects")
         {
             ByteTestOption test_1(byte_test);
index 29877d8108eacb240db1d75fec6d45f49599c837..3fe853233833d31aef2f380812e45ff975bc1150 100644 (file)
@@ -192,7 +192,6 @@ uint32_t ContentOption::hash() const
 
     mix(a,b,c);
 
-    a += config->pmd.pm_type;
     b += IpsOption::hash();
 
     mix(a, b, c);
@@ -255,7 +254,6 @@ bool ContentOption::operator==(const IpsOption& ips) const
         (left.pmd.depth == right.pmd.depth) and
         (left.pmd.fp_offset == right.pmd.fp_offset) and
         (left.pmd.fp_length == right.pmd.fp_length) and
-        (left.pmd.pm_type == right.pmd.pm_type) and
         (left.match_delta == right.match_delta) and
         (left.offset_var == right.offset_var) and
         (left.depth_var == right.depth_var) )
@@ -681,6 +679,9 @@ bool ContentModule::end(const char*, int, SnortConfig*)
     }
     cd->setup_bm();
 
+    if ( !cd->pmd.has_alpha() )
+        cd->pmd.set_no_case();
+
     if ( cd->pmd.is_negated() )
     {
         cd->pmd.last_check = (PmdLastCheck*)snort_calloc(
@@ -740,11 +741,10 @@ static void mod_dtor(Module* m)
     delete m;
 }
 
-static IpsOption* content_ctor(Module* p, OptTreeNode* otn)
+static IpsOption* content_ctor(Module* p, OptTreeNode*)
 {
     ContentModule* m = (ContentModule*)p;
     ContentData* cd = m->get_data();
-    cd->pmd.pm_type = otn->sticky_buf;
     return new ContentOption(cd);
 }
 
index ecdf3e9c634f6d67c6e88aabcc6a8f1bc460b2a0..d69ca107210e8782c4afcc663d5623ca0bdd2aa2 100644 (file)
@@ -37,10 +37,10 @@ static THREAD_LOCAL ProfileStats fileDataPerfStats;
 class FileDataOption : public IpsOption
 {
 public:
-    FileDataOption() : IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_SET) { }
+    FileDataOption() : IpsOption(s_name) { }
 
     CursorActionType get_cursor_type() const override
-    { return CAT_SET_FILE; }
+    { return CAT_SET_FAST_PATTERN; }
 
     EvalStatus eval(Cursor&, Packet*) override;
 };
index 80bb4031ece59304290534d328e1e283eb4e3112..856b135411237a651ae4dcc9937e116d3e5add8d 100644 (file)
@@ -45,9 +45,6 @@ public:
     uint32_t hash() const override;
     bool operator==(const IpsOption& ips) const override;
 
-    CursorActionType get_cursor_type() const override
-    { return CAT_NONE; }
-
     EvalStatus eval(Cursor&, Packet*) override;
 
     FileTypeBitSet types;
index e3f7638b61c232fe79b2a6babe04dbb79a9a26ba..658dbe61a01ff2288af53b251cfad74f0b48d5f7 100644 (file)
@@ -331,6 +331,29 @@ void get_flowbits_dependencies(void* option_data, bool& set, std::vector<std::st
     p->get_dependencies(set, bits);
 }
 
+void flowbits_counts(unsigned& total, unsigned& unchecked, unsigned& unset)
+{
+    unchecked = unset = 0;
+
+    for ( const auto& it : bit_map )
+    {
+        if ((it.second.sets > 0) and (it.second.checks == 0))
+        {
+            ParseWarning(WARN_FLOWBITS, "%s key '%s' is set but not checked.",
+                s_name, it.first.c_str());
+            unchecked++;
+        }
+        else if ((it.second.checks > 0) and (it.second.sets == 0))
+        {
+            ParseWarning(WARN_FLOWBITS, "%s key '%s' is checked but not set.",
+                s_name, it.first.c_str());
+            unset++;
+        }
+    }
+
+    total = bit_map.size();
+}
+
 //-------------------------------------------------------------------------
 // parsing methods
 //-------------------------------------------------------------------------
@@ -401,35 +424,6 @@ static bool parse_flowbits(const char* flowbits_names, FlowBitCheck* check)
     return true;
 }
 
-static void flowbits_verify()
-{
-    unsigned unchecked = 0, unset = 0;
-
-    for ( const auto& it : bit_map )
-    {
-        if ((it.second.sets > 0) and (it.second.checks == 0))
-        {
-            ParseWarning(WARN_FLOWBITS, "%s key '%s' is set but not checked.",
-                s_name, it.first.c_str());
-            unchecked++;
-        }
-        else if ((it.second.checks > 0) and (it.second.sets == 0))
-        {
-            ParseWarning(WARN_FLOWBITS, "%s key '%s' is checked but not set.",
-                s_name, it.first.c_str());
-            unset++;
-        }
-    }
-
-    if ( !bit_map.size() )
-        return;
-
-    LogLabel(s_name);
-    LogCount("defined", bit_map.size());
-    LogCount("not checked", unchecked);
-    LogCount("not set", unset);
-}
-
 //-------------------------------------------------------------------------
 // module
 //-------------------------------------------------------------------------
@@ -541,11 +535,6 @@ static void flowbits_dtor(IpsOption* p)
     delete p;
 }
 
-static void flowbits_verify(const SnortConfig*)
-{
-    flowbits_verify();
-}
-
 static const IpsApi flowbits_api =
 {
     {
@@ -568,7 +557,7 @@ static const IpsApi flowbits_api =
     nullptr,
     flowbits_ctor,
     flowbits_dtor,
-    flowbits_verify
+    nullptr
 };
 
 const BaseApi* ips_flowbits = &flowbits_api.base;
index caaee576699d400d8730c2d099c4ae8a35fd613b..db5c6fdb821339d552385bb03df51d9700231a0e 100644 (file)
@@ -24,6 +24,7 @@
 
 bool flowbits_setter(void*);
 void get_flowbits_dependencies(void*, bool& set, std::vector<std::string>& bits);
+void flowbits_counts(unsigned& total, unsigned& unchecked, unsigned& unset);
 
 #endif
 
index e2003f9e938d1d8df5a6760ef0177a75edb82459..4cb6fdfa274c74a82160d4945b0e371ecbec0115 100644 (file)
@@ -68,7 +68,7 @@ class HashOption : public IpsOption
 {
 public:
     HashOption(const char* s, HashPsIdx hpi, HashMatchData* c, HashFunc f, unsigned n) :
-        IpsOption(s, RULE_OPTION_TYPE_BUFFER_USE)
+        IpsOption(s)
     { config = c; hashf = f; size = n; idx = hpi; assert(n <= MAX_HASH_SIZE); }
 
     ~HashOption() override { delete config; }
index b1a1cd174f557c8d7c22daf56138ff712130e042..7cdfef35da649ddd1f4f1f9f643a7db0fb79cb21 100644 (file)
@@ -134,7 +134,7 @@ private:
 
 LuaJitOption::LuaJitOption(
     const char* name, std::string& chunk, LuaJitModule* mod)
-    : IpsOption((my_name = snort_strdup(name)), RULE_OPTION_TYPE_BUFFER_USE)
+    : IpsOption((my_name = snort_strdup(name)))
 {
     // create an args table with any rule options
     config = "args = { ";
index ff87c05421e206255c7c3fc3eb47e6cfe019c10b..c53f6d9ffff7e9c0fe8dcdf12249815e8a61cb49 100644 (file)
@@ -36,7 +36,7 @@ static THREAD_LOCAL ProfileStats pktDataPerfStats;
 class PktDataOption : public IpsOption
 {
 public:
-    PktDataOption() : IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_SET) { }
+    PktDataOption() : IpsOption(s_name) { }
 
     CursorActionType get_cursor_type() const override
     { return CAT_SET_RAW; }
index b2976d0e24eb95abe5dbca85808377143f664c84..edb040c43e98f7fa01f6fae0ccd4ce92e002c9c6 100644 (file)
@@ -36,7 +36,7 @@ static THREAD_LOCAL ProfileStats rawDataPerfStats;
 class RawDataOption : public IpsOption
 {
 public:
-    RawDataOption() : IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_SET) { }
+    RawDataOption() : IpsOption(s_name) { }
 
     CursorActionType get_cursor_type() const override
     { return CAT_SET_RAW; }
index 21617a4f334b3875f56217c206908968fc457792..8dae412b30f5b5a00690ed341a863c9a46ea5613 100644 (file)
@@ -50,7 +50,7 @@ struct RegexConfig
 {
     hs_database_t* db;
     std::string re;
-    PatternMatchData pmd;
+    PatternMatchData pmd = { };
     bool pcre_upgrade;
 
     RegexConfig()
@@ -58,7 +58,6 @@ struct RegexConfig
 
     void reset()
     {
-        memset(&pmd, 0, sizeof(pmd));
         re.clear();
         db = nullptr;
         pcre_upgrade = false;
@@ -123,12 +122,11 @@ uint32_t RegexOption::hash() const
 {
     uint32_t a = config.pmd.flags;
     uint32_t b = config.pmd.mpse_flags;
-    uint32_t c = config.pmd.pm_type;
+    uint32_t c = IpsOption::hash();
 
     mix(a, b, c);
-    a += IpsOption::hash();
-
     mix_str(a, b, c, config.re.c_str());
+
     finalize(a, b, c);
 
     return c;
@@ -142,7 +140,6 @@ bool RegexOption::operator==(const IpsOption& ips) const
     const RegexOption& rhs = (const RegexOption&)ips;
 
     if ( config.re == rhs.config.re and
-         config.pmd.pm_type == rhs.config.pmd.pm_type and
          config.pmd.flags == rhs.config.pmd.flags and
          config.pmd.mpse_flags == rhs.config.pmd.mpse_flags )
         return true;
@@ -409,12 +406,11 @@ static Module* mod_ctor()
 static void mod_dtor(Module* p)
 { delete p; }
 
-static IpsOption* regex_ctor(Module* m, OptTreeNode* otn)
+static IpsOption* regex_ctor(Module* m, OptTreeNode*)
 {
     RegexModule* mod = (RegexModule*)m;
     RegexConfig c;
     mod->get_data(c);
-    c.pmd.pm_type = otn->sticky_buf;
     return new RegexOption(c);
 }
 
index d5000bdd70cb7e402cd286407f1cc2afa1ca4f9b..c44c4e5434a83d83944fdcf5ab8f89500b4eb6af 100644 (file)
@@ -72,7 +72,7 @@ static THREAD_LOCAL SdStats s_stats;
 
 struct SdPatternConfig
 {
-    PatternMatchData pmd;
+    PatternMatchData pmd = { };
     hs_database_t* db;
 
     std::string pii;
@@ -93,7 +93,6 @@ struct SdPatternConfig
 
     void reset()
     {
-        memset(&pmd, 0, sizeof(pmd));
         pii.clear();
         threshold = 1;
         obfuscate_pii = false;
@@ -128,7 +127,7 @@ private:
 };
 
 SdPatternOption::SdPatternOption(const SdPatternConfig& c) :
-    IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_USE), config(c)
+    IpsOption(s_name), config(c)
 {
     if ( !scratcher->allocate(config.db) )
         ParseError("can't allocate scratch for sd_pattern '%s'", config.pii.c_str());
@@ -148,13 +147,14 @@ SdPatternOption::~SdPatternOption()
 uint32_t SdPatternOption::hash() const
 {
     uint32_t a = config.pmd.pattern_size;
-    uint32_t b = config.pmd.pm_type;
+    uint32_t b = IpsOption::hash();
     uint32_t c = config.threshold;
 
     mix(a, b, c);
-    a += IpsOption::hash();
 
     mix_str(a, b, c, config.pii.c_str());
+    //mix_str(a, b, c, config.pmd.sticky_buf.c_str());
+
     finalize(a, b, c);
 
     return c;
@@ -402,12 +402,11 @@ static void mod_dtor(Module* p)
     delete p;
 }
 
-static IpsOption* sd_pattern_ctor(Module* m, OptTreeNode* otn)
+static IpsOption* sd_pattern_ctor(Module* m, OptTreeNode*)
 {
     SdPatternModule* mod = (SdPatternModule*)m;
     SdPatternConfig c;
     mod->get_data(c);
-    c.pmd.pm_type = otn->sticky_buf;
     return new SdPatternOption(c);
 }
 
index 1a049507c982d7e7d005ae04280b6daabd34373e..671eaaa11ab81af9817adc54748d59191f6f4edd 100644 (file)
@@ -33,7 +33,7 @@ LiteralSearch::Handle* search_handle = nullptr;
 const LiteralSearch* searcher = nullptr;
 
 CursorActionType VbaDataOption::get_cursor_type() const
-{ return CAT_SET_VBA; }
+{ return CAT_SET_FAST_PATTERN; }
 
 IpsOption::EvalStatus VbaDataOption::eval(Cursor& c, Packet* p)
 {
index ead07a3b51d0d158ecbbbbcb6c5543b510228f21..2ab31ff9918e2707e826f168af77e104614c298c 100644 (file)
@@ -39,7 +39,7 @@ extern const snort::LiteralSearch* searcher ;
 class VbaDataOption : public snort::IpsOption
 {
 public:
-    VbaDataOption() : IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_SET) { }
+    VbaDataOption() : IpsOption(s_name) { }
 
     snort::CursorActionType get_cursor_type() const override;
 
index 6f18b8128b142ebc3138063af25c80efd8a4c12f..3559143de5226d376ace0901c01e317bf672d983 100644 (file)
@@ -144,11 +144,9 @@ static IpsOption* get_option(Module* mod, const char* pat)
     mod->end(ips_regex->name, 0, nullptr);
 
     OptTreeNode otn;
-    otn.sticky_buf = 0;
 
     const IpsApi* api = (const IpsApi*) ips_regex;
     IpsOption* opt = api->ctor(mod, &otn);
-    IpsOption::set_buffer("pkt_data");
 
     return opt;
 }
index ce4d2c7b0f59e1d50236be21ee417b84d8dfd074..8d5fc9df6e5a5f3717e7665cbfc359597aba6da8 100644 (file)
@@ -318,7 +318,6 @@ void SnortConfig::setup()
     }
 
     ParseRulesFinish(this);
-    ShowPolicyStats(this);
 
     /* Need to do this after dynamic detection stuff is initialized, too */
     IpsManager::verify(this);
index 7f440f4464b6bceb1e11f2d7fd9a4e54b1f821de..220a0a769458c83f130e0b59feca3713d5561055 100644 (file)
@@ -30,6 +30,7 @@
 #include "binder/bind_module.h"
 #include "detection/detect.h"
 #include "detection/detection_engine.h"
+#include "detection/fp_utils.h"
 #include "flow/flow.h"
 #include "flow/session.h"
 #include "log/messages.h"
@@ -862,6 +863,7 @@ void InspectorManager::add_plugin(const InspectApi* api)
 {
     PHObject* g = new PHObject(*api);
     s_handlers.emplace_back(g);
+    update_buffer_map(api->buffers, api->service);
 }
 
 static const InspectApi* get_plugin(const char* keyword)
index 22753c8b539df42eebf62505933c30cc6f0c4957..fca81c8868f9e8a2ae153bd4ab5f52714d77284b 100644 (file)
@@ -349,9 +349,6 @@ void IpsManager::reset_options()
 {
     for ( auto& p : s_options )
         p.second->count = 0;
-
-    // this is the default when we start parsing a rule body
-    IpsOption::set_buffer("pkt_data");
 }
 
 void IpsManager::setup_options(const SnortConfig* sc)
index 832c91a1d51ac226a2fed924b000028550fa716f..5d81ab2fe98f790db96fe0f9ef438de17b480a08 100644 (file)
@@ -38,6 +38,7 @@ void BinderModule::add(const char*, const char*) { }
 void BinderModule::add(unsigned, const char*) { }
 
 void set_default_policy(const snort::SnortConfig*) { }
+void update_buffer_map(const char**, const char*) { }
 
 namespace snort
 {
index 0bd3a3b2eed106864cbd47ce39305d6adffa46f3..7589d037ee0910dfcacd1760fb3d8f46ea19cb7f 100644 (file)
@@ -66,7 +66,7 @@ Inspector::Inspector()
 }
 Inspector::~Inspector() = default;
 bool Inspector::likes(Packet*) { return true; }
-bool Inspector::get_buf(const char*, Packet*, InspectionBuffer&) { return true; }
+bool Inspector::get_buf(const char*, Packet*, InspectionBuffer&) { return false; }
 class StreamSplitter* Inspector::get_splitter(bool) { return nullptr; }
 
 // Stubs for module
index c867565788a87ed7b22191449231a76d9568a562..e5e95f6474ffb519701f60e9fac9104c546cd921 100644 (file)
@@ -33,6 +33,7 @@
 #include <fstream>
 #include <stack>
 
+#include "detection/fp_utils.h"
 #include "log/messages.h"
 #include "main/snort_config.h"
 #include "managers/module_manager.h"
@@ -244,12 +245,8 @@ void add_service_to_otn(SnortConfig* sc, OptTreeNode* otn, const char* svc_name)
     {
         // well-known services supporting file_data
         // applies to both alert file and service:file rules
-        add_service_to_otn(sc, otn, "ftp-data");
-        add_service_to_otn(sc, otn, "netbios-ssn");
-        add_service_to_otn(sc, otn, "http");
-        add_service_to_otn(sc, otn, "pop3");
-        add_service_to_otn(sc, otn, "imap");
-        add_service_to_otn(sc, otn, "smtp");
+        std::string buf = "file_data";
+        add_default_services(sc, buf, otn);
         add_service_to_otn(sc, otn, "file");
         return;
     }
index 5d5cfb389c1b4b9fbe39e0a57d45fd22f5a42acf..f648f57fb4caadb9a67bc40ad9dc1fb282f913d0 100644 (file)
@@ -699,7 +699,7 @@ void parse_rule_init()
 void parse_rule_term()
 { }
 
-void parse_rule_print()
+void parse_rule_print(unsigned fb_total, unsigned fb_unchk, unsigned fb_unset)
 {
     if ( !rule_count and !skip_count )
         return;
@@ -713,6 +713,9 @@ void parse_rule_print()
     LogCount("so rules", so_rule_count);
     LogCount("option chains", otn_count);
     LogCount("chain headers", head_count);
+    LogCount("flowbits", fb_total);
+    LogCount("flowbits not checked", fb_unchk);
+    LogCount("flowbits not set", fb_unset);
 
     unsigned ip = ipCnt.src + ipCnt.dst + ipCnt.any + ipCnt.both;
     unsigned icmp = icmpCnt.src + icmpCnt.dst + icmpCnt.any + icmpCnt.both;
@@ -975,7 +978,10 @@ void parse_rule_opt_end(SnortConfig* sc, const char* key, OptTreeNode* otn)
     CursorActionType cat = ips ? ips->get_cursor_type() : CAT_NONE;
 
     if ( cat > CAT_ADJUST )
-        otn->sticky_buf = get_pm_type(cat);
+    {
+        if ( cat != CAT_SET_RAW )
+            otn->set_service_only();
+    }
 
     if ( type != OPT_TYPE_META )
         otn->num_detection_opts++;
index ca281a02baabe03371cc47162dc2eb310958d038..a9d78fd893f827ec2c5dfcc53bb0d28746cfb219 100644 (file)
@@ -34,7 +34,7 @@ struct RuleTreeNode;
 
 void parse_rule_init();
 void parse_rule_term();
-void parse_rule_print();
+void parse_rule_print(unsigned fb_total, unsigned fb_unchk, unsigned fb_unset);
 int get_policy_loaded_rule_count();
 int get_policy_shared_rule_count();
 
index a7e9bf95dbf11fde19102326010bdd5fbc72ab96..84620e28e828704dc23fe3db09a63f2fad9ef35c 100644 (file)
@@ -41,6 +41,7 @@
 #include "hash/hash_key_operations.h"
 #include "hash/xhash.h"
 #include "helpers/directory.h"
+#include "ips_options/ips_flowbits.h"
 #include "log/messages.h"
 #include "main/modules.h"
 #include "main/shell.h"
@@ -512,7 +513,8 @@ static void reduce_rtns(SnortConfig* sc)
     for ( auto node = sc->otn_map->find_first(); node; node = sc->otn_map->find_next() )
     {
         OptTreeNode* otn = (OptTreeNode*)node->data;
-        if ( !otn )
+
+        if ( !otn or otn->service_only() )
             continue;
 
         for ( auto pid = 0; pid < otn->proto_node_num; ++pid )
@@ -528,19 +530,7 @@ static void reduce_rtns(SnortConfig* sc)
     }
 }
 
-void ParseRulesFinish(SnortConfig* sc)
-{
-    if ( !sc->dump_rule_info() )
-        reduce_rtns(sc);
-
-    set_ips_policy(sc, 0);
-
-    /* Compile/Finish and Print the PortList Tables */
-    PortTablesFinish(sc->port_tables, sc->fast_pattern_config);
-    parse_rule_print();
-}
-
-void ShowPolicyStats(const SnortConfig* sc)
+static void ShowPolicyStats(const SnortConfig* sc)
 {
     std::unordered_map<PolicyId, int> stats;
     std::multimap<PolicyId, PolicyRuleStats> sorted_stats;
@@ -600,6 +590,23 @@ void ShowPolicyStats(const SnortConfig* sc)
             s.second.enabled, " ", s.second.file);
 }
 
+void ParseRulesFinish(SnortConfig* sc)
+{
+    ShowPolicyStats(sc);
+
+    if ( !sc->dump_rule_info() )
+        reduce_rtns(sc);
+
+    set_ips_policy(sc, 0);
+
+    /* Compile/Finish and Print the PortList Tables */
+    PortTablesFinish(sc->port_tables, sc->fast_pattern_config);
+
+    unsigned total, unchk, unset;
+    flowbits_counts(total, unchk, unset);
+    parse_rule_print(total, unchk, unset);
+}
+
 /****************************************************************************
  *
  * Function: CreateRuleType
index fa1beb7fb80f6f8f6c070e609ed041f55be9085a..3311259c331fad1a14b0ca1eb5c5c2a2783f7f6f 100644 (file)
@@ -45,7 +45,6 @@ void inc_parse_position();
 snort::SnortConfig* ParseSnortConf(const snort::SnortConfig*, const char* fname = nullptr);
 void ParseRules(snort::SnortConfig*);
 void ParseRulesFinish(snort::SnortConfig*);
-void ShowPolicyStats(const snort::SnortConfig*);
 
 char* ProcessFileOption(snort::SnortConfig*, const char*);
 void SetRuleStates(snort::SnortConfig*);
index 6ba1df06aad747ed549d73ffe362c2fb0068e1b3..6adfc7c6b5dc263b31b2a05dcd9c2847ef549e55 100644 (file)
@@ -96,7 +96,7 @@ Inspector::Inspector()
 
 Inspector::~Inspector() = default;
 bool Inspector::likes(Packet*) { return true; }
-bool Inspector::get_buf(const char*, Packet*, InspectionBuffer&) { return true; }
+bool Inspector::get_buf(const char*, Packet*, InspectionBuffer&) { return false; }
 class StreamSplitter* Inspector::get_splitter(bool) { return nullptr; }
 }
 
index 1ece7a3265ad06e713bf5c98657b4a6c935db16c..f39b7b924ce69ccf52b9022ce03da053aa582a90 100644 (file)
@@ -24,8 +24,8 @@
 #include "port_group.h"
 
 #include "detection/detection_options.h"
+#include "framework/ips_option.h"
 #include "framework/mpse.h"
-#include "framework/mpse_batch.h"
 #include "utils/util.h"
 
 void RuleGroup::add_rule()
@@ -35,11 +35,10 @@ void RuleGroup::add_rule()
 
 RuleGroup::~RuleGroup()
 {
-    delete_nfp_rules();
-
-    for (int i = PM_TYPE_PKT; i < PM_TYPE_MAX; i++)
-        delete mpsegrp[i];
+    for ( auto* it : pm_list )
+        delete it;
 
+    delete_nfp_rules();
     free_detection_option_root(&nfp_tree);
 }
 
@@ -80,3 +79,24 @@ void RuleGroup::delete_nfp_rules()
     nfp_head = nullptr;
 }
 
+PatternMatcher* RuleGroup::get_pattern_matcher(PatternMatcher::Type t, const char* s)
+{
+    bool raw = false;
+
+    if ( !strcmp(s, "raw_data") )
+    {
+        s = "pkt_data";
+        raw = true;
+    }
+    for ( auto& it : pm_list )
+    {
+        if ( it->type == t and !strcmp(it->name, s) )
+        {
+            it->raw_data = raw;
+            return it;
+        }
+    }
+    pm_list.push_back(new PatternMatcher(t, s, raw));
+    return pm_list.back();
+}
+
index 1d44e33cf931a2e1b42cb8e5373ac2138f8feb2e..c66a52b8478c6c29cfb46f43181f51d1a14fa429 100644 (file)
 #ifndef PORT_GROUP_H
 #define PORT_GROUP_H
 
-namespace snort
-{
-    class MpseGroup;
-}
+#include <cassert>
+#include <vector>
+
+#include "framework/mpse_batch.h"
 
 // RuleGroup contains a set of fast patterns in the form of an MPSE and a
 // set of non-fast-pattern (nfp) rules.  when a RuleGroup is selected, the
@@ -36,30 +36,10 @@ namespace snort
 // patterns.  it will always run nfp rules since there is no way to filter
 // them out.
 
-enum PmType
-{
-    PM_TYPE_PKT = 0,
-    PM_TYPE_ALT,
-    PM_TYPE_KEY,
-    PM_TYPE_HEADER,
-    PM_TYPE_BODY,
-    PM_TYPE_FILE,
-    PM_TYPE_RAW_KEY,
-    PM_TYPE_RAW_HEADER,
-    PM_TYPE_METHOD,
-    PM_TYPE_STAT_CODE,
-    PM_TYPE_STAT_MSG,
-    PM_TYPE_COOKIE,
-    PM_TYPE_JS_DATA,
-    PM_TYPE_VBA,
-    PM_TYPE_MAX
-};
-
-const char* const pm_type_strings[PM_TYPE_MAX] =
+namespace snort
 {
-    "packet", "alt", "key", "header", "body", "file", "raw_key", "raw_header",
-    "method", "stat_code", "stat_msg", "cookie", "js_data", "vba"
-};
+    class IpsOption;
+}
 
 struct RULE_NODE
 {
@@ -68,6 +48,21 @@ struct RULE_NODE
     int iRuleNodeID;
 };
 
+struct PatternMatcher
+{
+    enum Type { PMT_PKT, PMT_FILE, PMT_PDU };
+
+    PatternMatcher(Type t, const char* s, bool r = false)
+    { type = t; name = s; raw_data = r; }
+
+    Type type;
+    const char* name;
+    bool raw_data;
+
+    snort::MpseGroup group;
+    snort::IpsOption* fp_opt = nullptr;
+};
+
 struct RuleGroup
 {
     RuleGroup() = default;
@@ -78,7 +73,8 @@ struct RuleGroup
     RULE_NODE* nfp_tail = nullptr;
 
     // pattern matchers
-    snort::MpseGroup* mpsegrp[PM_TYPE_MAX] = { };
+    using PmList = std::vector<PatternMatcher*>;
+    PmList pm_list;
 
     // detection option tree
     void* nfp_tree = nullptr;
@@ -89,6 +85,8 @@ struct RuleGroup
     void add_rule();
     bool add_nfp_rule(void*);
     void delete_nfp_rules();
+
+    PatternMatcher* get_pattern_matcher(PatternMatcher::Type, const char*);
 };
 
 #endif
index f5f1949a1b0f2dcbbae62b740cc1c3aa82c56b9d..60481652bdd52eeeb63344e20366862e627b9893 100644 (file)
@@ -40,56 +40,54 @@ class IpsContext;
 class Obfuscator;
 class SFDAQInstance;
 
-/* packet status flags */
-#define PKT_REBUILT_FRAG     0x00000001  /* is a rebuilt fragment */
-#define PKT_REBUILT_STREAM   0x00000002  /* is a rebuilt stream */
-#define PKT_STREAM_UNEST_UNI 0x00000004  /* is from an unestablished stream and
-                                          * we've only seen traffic in one direction */
-#define PKT_STREAM_EST       0x00000008  /* is from an established stream */
-
-#define PKT_STREAM_INSERT    0x00000010  /* this packet has been queued for stream reassembly */
-#define PKT_STREAM_TWH       0x00000020  /* packet completes the 3-way handshake */
-#define PKT_FROM_SERVER      0x00000040  /* this packet came from the server
-                                            side of a connection (TCP) */
-#define PKT_FROM_CLIENT      0x00000080  /* this packet came from the client
-                                            side of a connection (TCP) */
-
-#define PKT_PDU_HEAD         0x00000100  /* start of PDU */
-#define PKT_PDU_TAIL         0x00000200  /* end of PDU */
-#define PKT_DETECT_LIMIT     0x00000400  /* alt_dsize is valid */
-
-#define PKT_ALLOW_MULTIPLE_DETECT 0x00000800  /* packet has multiple PDUs */
+#define PKT_REBUILT_FRAG          0x00000001  // is a rebuilt fragment
+#define PKT_REBUILT_STREAM        0x00000002  // is a rebuilt stream
+#define PKT_STREAM_UNEST_UNI      0x00000004  // is from an unestablished stream and
+                                         // we've only seen traffic in one direction
+#define PKT_STREAM_EST            0x00000008  // is from an established stream
+
+#define PKT_STREAM_INSERT         0x00000010  // this packet has been queued for stream reassembly
+#define PKT_STREAM_TWH            0x00000020  // packet completes the 3-way handshake
+#define PKT_FROM_SERVER           0x00000040  // this packet came from the server side of a connection (TCP)
+#define PKT_FROM_CLIENT           0x00000080  // this packet came from the client side of a connection (TCP)
+
+#define PKT_PDU_HEAD              0x00000100  // start of PDU
+#define PKT_PDU_TAIL              0x00000200  // end of PDU
+#define PKT_DETECT_LIMIT          0x00000400  // alt_dsize is valid
+
+#define PKT_ALLOW_MULTIPLE_DETECT 0x00000800  // packet has multiple PDUs
 #define PKT_PAYLOAD_OBFUSCATE     0x00001000
 
-#define PKT_STATELESS        0x00002000  /* Packet has matched a stateless rule */
-#define PKT_PASS_RULE        0x00004000  /* this packet has matched a pass rule */
-#define PKT_IP_RULE          0x00008000  /* this packet is being evaluated against an IP rule */
-#define PKT_IP_RULE_2ND      0x00010000  /* this packet is being evaluated against an IP rule */
+#define PKT_STATELESS             0x00002000  // Packet has matched a stateless rule
+#define PKT_PASS_RULE             0x00004000  // this packet has matched a pass rule
+#define PKT_IP_RULE               0x00008000  // this packet is being evaluated against an IP rule
+#define PKT_IP_RULE_2ND           0x00010000  // this packet is being evaluated against an IP rule
 
-#define PKT_PSEUDO           0x00020000  /* is a pseudo packet */
-#define PKT_MODIFIED         0x00040000  /* packet had normalizations, etc. */
-#define PKT_RESIZED          0x00080000  /* packet has new size */
+#define PKT_PSEUDO                0x00020000  // is a pseudo packet
+#define PKT_MODIFIED              0x00040000  // packet had normalizations, etc.
+#define PKT_RESIZED               0x00080000  // packet has new size
 
 // neither of these flags will be set for (full) retransmissions or non-data segments
 // a partial overlap results in out of sequence condition
 // out of sequence condition is sticky
-#define PKT_STREAM_ORDER_OK  0x00100000  /* this segment is in order, w/o gaps */
-#define PKT_STREAM_ORDER_BAD 0x00200000  /* this stream had at least one gap */
+#define PKT_STREAM_ORDER_OK       0x00100000  // this segment is in order, w/o gaps
+#define PKT_STREAM_ORDER_BAD      0x00200000  // this stream had at least one gap
 
-#define PKT_FILE_EVENT_SET   0x00400000
-#define PKT_IGNORE           0x00800000  /* this packet should be ignored, based on port */
-#define PKT_RETRANSMIT       0x01000000  // packet is a re-transmitted pkt.
-#define PKT_RETRY            0x02000000  /* this packet is being re-evaluated from the internal retry queue */
-#define PKT_USE_DIRECT_INJECT 0x04000000  /* Use ioctl when injecting. */
-#define PKT_HAS_PARENT       0x08000000  /* derived pseudo packet from current wire packet */
+#define PKT_FILE_EVENT_SET        0x00400000
+#define PKT_IGNORE                0x00800000  // this packet should be ignored, based on port
+#define PKT_RETRANSMIT            0x01000000  // packet is a re-transmitted pkt.
+#define PKT_RETRY                 0x02000000  // this packet is being re-evaluated from the internal retry queue
+#define PKT_USE_DIRECT_INJECT     0x04000000  // Use ioctl when injecting.
+#define PKT_HAS_PARENT            0x08000000  // derived pseudo packet from current wire packet
 
-#define PKT_WAS_SET          0x10000000  /* derived pseudo packet (PDU) from current wire packet */
+#define PKT_WAS_SET               0x10000000  // derived pseudo packet (PDU) from current wire packet
 
-#define PKT_MORE_TO_FLUSH    0x20000000 /* when more data is available to StreamSplitter::scan */
+#define PKT_MORE_TO_FLUSH         0x20000000 // when more data is available to StreamSplitter::scan
+#define PKT_FAST_PAT_EVAL         0x40000000 // temporary until IpsOption api updated
 
-#define PKT_UNUSED_FLAGS     0xC0000000
+#define PKT_UNUSED_FLAGS          0x80000000
 
-#define PKT_TS_OFFLOADED        0x01
+#define TS_PKT_OFFLOADED          0x01
 
 #define PKT_PDU_FULL (PKT_PDU_HEAD | PKT_PDU_TAIL)
 
@@ -319,13 +317,13 @@ struct SO_PUBLIC Packet
     { return (packet_flags & PKT_RETRY) != 0; }
 
     bool is_offloaded() const
-    { return (ts_packet_flags & PKT_TS_OFFLOADED) != 0; }
+    { return (ts_packet_flags & TS_PKT_OFFLOADED) != 0; }
 
     void set_offloaded()
-    { ts_packet_flags |= PKT_TS_OFFLOADED; }
+    { ts_packet_flags |= TS_PKT_OFFLOADED; }
 
     void clear_offloaded()
-    { ts_packet_flags &= (~PKT_TS_OFFLOADED); }
+    { ts_packet_flags &= (~TS_PKT_OFFLOADED); }
 
     bool has_parent() const
     { return (packet_flags & PKT_HAS_PARENT) != 0; }
index 0a9fc29834d8e8fcc06aa07e6f791659b3dbbed7..1d75de9eaea9749c67759903c8324bb27deac1a0 100644 (file)
@@ -152,6 +152,14 @@ static void dce2_smb_dtor(Inspector* p)
     delete p;
 }
 
+static const char* dce2_bufs[] =
+{
+    "dce_iface",
+    "dce_stub_data",
+    "file_data",
+    nullptr
+};
+
 const InspectApi dce2_smb_api =
 {
     {
@@ -168,7 +176,7 @@ const InspectApi dce2_smb_api =
     },
     IT_SERVICE,
     PROTO_BIT__PDU,
-    nullptr,  // buffers
+    dce2_bufs,
     DCE_SMB_PROTOCOL_ID,
     dce2_smb_init,
     nullptr,
index f581fe43d4b408ac6f087132ff89bdb1fc96fc1a..c04be5ef544f22f72f048ad97f1d7006d287d6e8 100644 (file)
@@ -198,6 +198,14 @@ static void dce2_tcp_init()
     DceContextData::init(DCE2_TRANS_TYPE__TCP);
 }
 
+static const char* dce2_tcp_bufs[] =
+{
+    "dce_iface",
+    "dce_stub_data",
+    "file_data",
+    nullptr
+};
+
 const InspectApi dce2_tcp_api =
 {
     {
@@ -214,7 +222,7 @@ const InspectApi dce2_tcp_api =
     },
     IT_SERVICE,
     PROTO_BIT__PDU,
-    nullptr,  // buffers
+    dce2_tcp_bufs,
     DCE_RPC_SERVICE_NAME,
     dce2_tcp_init,
     nullptr, // pterm
index 24425e6a4b32b93fbd181131742decdf05b17d0b..94a40963057ec070e4dd92674acaa7f42256fb1d 100644 (file)
@@ -197,6 +197,14 @@ static void dce2_udp_init()
     DceContextData::init(DCE2_TRANS_TYPE__UDP);
 }
 
+static const char* dce2_udp_bufs[] =
+{
+    "dce_iface",
+    "dce_stub_data",
+    "file_data",
+    nullptr
+};
+
 const InspectApi dce2_udp_api =
 {
     {
@@ -213,7 +221,7 @@ const InspectApi dce2_udp_api =
     },
     IT_SERVICE,
     PROTO_BIT__UDP,
-    nullptr,  // buffers
+    dce2_udp_bufs,
     DCE_RPC_SERVICE_NAME,
     dce2_udp_init,
     nullptr, // pterm
index 8d256dd3fa4fa8d472cc9863afc8f217cdcefa5b..47e25fcca86d5dc7e9be9baa549b2f54cbf2da21 100644 (file)
@@ -26,6 +26,7 @@
 #include <cerrno>
 
 #include "detection/pattern_match_data.h"
+#include "framework/cursor.h"
 #include "framework/module.h"
 #include "framework/ips_option.h"
 #include "framework/range.h"
@@ -219,6 +220,9 @@ public:
     PatternMatchData* get_alternate_pattern() override;
     ~Dce2IfaceOption() override;
 
+    CursorActionType get_cursor_type() const override
+    { return CAT_SET_FAST_PATTERN; }
+
 private:
     const RangeCheck version;
     const bool any_frag;
@@ -363,7 +367,7 @@ bool Dce2IfaceOption::operator==(const IpsOption& ips) const
     return this == &ips;
 }
 
-IpsOption::EvalStatus Dce2IfaceOption::eval(Cursor&, Packet* p)
+IpsOption::EvalStatus Dce2IfaceOption::eval(Cursor& c, Packet* p)
 {
     RuleProfile profile(dce2_iface_perf_stats);
 
@@ -392,6 +396,12 @@ IpsOption::EvalStatus Dce2IfaceOption::eval(Cursor&, Packet* p)
         return NO_MATCH;
     }
 
+    if (p->packet_flags & PKT_FAST_PAT_EVAL)
+    {
+        c.set("pkt_data", p->data, p->dsize);
+        return MATCH;
+    }
+
     if (DCE2_UuidCompare((void*)&ropts->iface, &uuid) != 0)
     {
         return NO_MATCH;
index ccf0b571c20131e7ce91480c473dbcd79ddeb252..d6e1bd7ae9056fec035f388f0d058b11e62d3cfb 100644 (file)
@@ -46,12 +46,15 @@ static THREAD_LOCAL ProfileStats dce2_stub_data_perf_stats;
 class Dce2StubDataOption : public IpsOption
 {
 public:
-    Dce2StubDataOption() : IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_SET) { }
+    Dce2StubDataOption() : IpsOption(s_name) { }
 
     uint32_t hash() const override;
     bool operator==(const IpsOption&) const override;
 
     EvalStatus eval(Cursor&, Packet*) override;
+
+    CursorActionType get_cursor_type() const override
+    { return CAT_SET_FAST_PATTERN; }
 };
 
 uint32_t Dce2StubDataOption::hash() const
index e23efaa29348eccd2eb42a633ba5ba4dfd91fd91..f4bba511a1bd082212e90538e668aaf5f582dabf 100644 (file)
@@ -66,30 +66,6 @@ static dnp3_session_data_t* set_new_dnp3_session(Packet* p)
     return(&fd->dnp3_session);
 }
 
-static const uint8_t* dnp3_get_alt_buffer(Packet* p, unsigned& len)
-{
-    dnp3_session_data_t* dnp3_sess = get_session_data(p->flow);
-    len = 0;
-
-    if (dnp3_sess)
-    {
-        dnp3_reassembly_data_t* rdata;
-        /* rdata->buffer will be the alt decode buffer.
-           This will be returned via the get_buf inspector API*/
-
-        if (dnp3_sess->direction == DNP3_CLIENT)
-            rdata = &(dnp3_sess->client_rdata);
-        else
-            rdata = &(dnp3_sess->server_rdata);
-        if (rdata->state == DNP3_REASSEMBLY_STATE__DONE)
-        {
-            len = rdata->buflen;
-            return (const uint8_t*)rdata->buffer;
-        }
-    }
-    return nullptr;
-}
-
 static void dnp3_reset_alt_buffer(const Packet* p)
 {
     dnp3_session_data_t* dnp3_sess = get_session_data(p->flow);
@@ -220,13 +196,10 @@ public:
 
     void show(const SnortConfig*) const override;
     void eval(Packet*) override;
-    bool get_buf(InspectionBuffer::Type, Packet*, InspectionBuffer&) override;
     void clear(Packet*) override;
 
     StreamSplitter* get_splitter(bool c2s) override
-    {
-        return new Dnp3Splitter(c2s);
-    }
+    { return new Dnp3Splitter(c2s); }
 
 private:
     dnp3ProtoConf config;
@@ -255,17 +228,6 @@ void Dnp3::eval(Packet* p)
     process_dnp3(config, p);
 }
 
-bool Dnp3::get_buf(
-    InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
-{
-    if ( ibt != InspectionBuffer::IBT_ALT )
-        return false;
-
-    b.data = dnp3_get_alt_buffer(p,b.len);
-
-    return (b.data != nullptr);
-}
-
 void Dnp3::clear(Packet* p)
 {
     dnp3_reset_alt_buffer(p);
@@ -303,6 +265,12 @@ static void dnp3_dtor(Inspector* p)
     delete p;
 }
 
+static const char* dnp3_bufs[] =
+{
+    "dnp3_data",
+    nullptr
+};
+
 const InspectApi dnp3_api =
 {
     {
@@ -319,7 +287,7 @@ const InspectApi dnp3_api =
     },
     IT_SERVICE,
     PROTO_BIT__UDP | PROTO_BIT__PDU,
-    nullptr,  // buffers
+    dnp3_bufs,
     "dnp3",
     dnp3_init,
     nullptr, // pterm
index 8ce9b05338dc2cc94282f74dc757a54f072eecb7..5e4903453a4af8ed3f3dbcaaae6935433004b98b 100644 (file)
@@ -47,12 +47,15 @@ static THREAD_LOCAL ProfileStats dnp3_data_perf_stats;
 class Dnp3DataOption : public IpsOption
 {
 public:
-    Dnp3DataOption() : IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_SET) { }
+    Dnp3DataOption() : IpsOption(s_name) { }
 
     uint32_t hash() const override;
     bool operator==(const IpsOption&) const override;
 
     EvalStatus eval(Cursor&, Packet*) override;
+
+    CursorActionType get_cursor_type() const override
+    { return CAT_SET_FAST_PATTERN; }
 };
 
 uint32_t Dnp3DataOption::hash() const
index f8a530172e9f4fc2ace680b4c090a98581e8683e..b87c257e3bf28dc68bc6b2fc535004934607393e 100644 (file)
@@ -348,6 +348,12 @@ static void fd_dtor(Inspector* p)
     delete p;
 }
 
+static const char* fd_bufs[] =
+{
+    "file_data",
+    nullptr
+};
+
 // exported in ftp.cc
 const InspectApi fd_api =
 {
@@ -365,7 +371,7 @@ const InspectApi fd_api =
     },
     IT_SERVICE,
     PROTO_BIT__PDU,
-    nullptr, // buffers
+    fd_bufs,
     fd_svc_name,
     fd_init,
     nullptr, // pterm
index 8fb2b473be743934e256a3b714728ff99892cd3b..9d0049abb5bfd26268a2e2ecc4f16e820909ac28 100644 (file)
@@ -186,9 +186,8 @@ public:
 
     bool configure(SnortConfig*) override;
     void show(const SnortConfig*) const override;
-    void eval(Packet*) override;
 
-    bool get_buf(InspectionBuffer::Type, Packet*, InspectionBuffer&) override;
+    void eval(Packet*) override;
     void clear(Packet*) override;
 
 private:
@@ -231,17 +230,6 @@ void Telnet::eval(Packet* p)
     snort_telnet(config, p);
 }
 
-bool Telnet::get_buf(
-    InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
-{
-    if ( ibt != InspectionBuffer::IBT_ALT )
-        return false;
-
-    b.data = get_telnet_buffer(p, b.len);
-
-    return (b.data != nullptr);
-}
-
 void Telnet::clear(Packet* p)
 {
     reset_telnet_buffer(p);
index 7b28c21c46ad2d451a4866a6886fa8d125cdde1c..bfd0e4093c44680ef540421327438fc96e60e5b4 100644 (file)
@@ -220,6 +220,12 @@ static void gtp_dtor(Inspector* p)
 
 //-------------------------------------------------------------------------
 
+static const char* gtp_bufs[] =
+{
+    "gtp_info",
+    nullptr
+};
+
 static const InspectApi gtp_api =
 {
     {
@@ -236,7 +242,7 @@ static const InspectApi gtp_api =
     },
     IT_SERVICE,
     PROTO_BIT__UDP,
-    nullptr,
+    gtp_bufs,
     "gtp",
     gtp_init,
     gtp_term,
index 752097d5c38ec9ce04641851620025d749daed1d..bb6785adfd486e15b49e10e0ffdb83799e9e0406 100644 (file)
@@ -49,12 +49,12 @@ class GtpInfoOption : public IpsOption
 public:
     GtpInfoOption(const uint8_t*);
 
-    CursorActionType get_cursor_type() const override
-    { return CAT_SET_OTHER; }
-
     uint32_t hash() const override;
     bool operator==(const IpsOption&) const override;
 
+    CursorActionType get_cursor_type() const override
+    { return CAT_SET_OTHER; }
+
     EvalStatus eval(Cursor&, Packet*) override;
 
 public:
@@ -63,7 +63,7 @@ public:
     uint8_t types[MAX_GTP_VERSION_CODE + 1];
 };
 
-GtpInfoOption::GtpInfoOption(const uint8_t* t) : IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_SET)
+GtpInfoOption::GtpInfoOption(const uint8_t* t) : IpsOption(s_name)
 {
     for ( int v = 0; v <= MAX_GTP_VERSION_CODE; ++v )
         types[v] = t[v];
index a358bc894411eae726643723b4255b0ce6afafdd..4c27b25d0c7cd76c87ac607fc4dcc544dd284cb7 100644 (file)
@@ -48,9 +48,6 @@ class GtpTypeOption : public IpsOption
 public:
     GtpTypeOption(ByteBitSet*);
 
-    CursorActionType get_cursor_type() const override
-    { return CAT_SET_OTHER; }
-
     uint32_t hash() const override;
     bool operator==(const IpsOption&) const override;
 
index 1853acb112bbf60cec277ec5d67be8bf270602e3..7f7bd8a01f6a3a18163ebdb6bfb91cd8636bf55f 100644 (file)
@@ -67,7 +67,7 @@ class Http2IpsOption : public snort::IpsOption
 {
 public:
     Http2IpsOption(const Http2CursorModule* cm) :
-        snort::IpsOption(cm->key, RULE_OPTION_TYPE_BUFFER_SET), key(cm->key),
+        snort::IpsOption(cm->key), key(cm->key),
         buffer_index(cm->buffer_index), cat(cm->cat), psi(cm->psi) {}
     snort::CursorActionType get_cursor_type() const override { return cat; }
     EvalStatus eval(Cursor&, snort::Packet*) override;
index 7408ad05efd6291d4fadc42b2d3747bfa2af458e..a0e14a0f839d9b332ded5d4c2098de8d2c0d6bf8 100644 (file)
@@ -137,6 +137,7 @@ HttpInspect const* HttpIpsOption::eval_helper(Packet* p)
         return nullptr;
 
     const bool section_match =
+        (p->packet_flags & PKT_FAST_PAT_EVAL) ||
         (HttpInspect::get_latest_is(p) == inspect_section) ||
         ((HttpInspect::get_latest_is(p) == IS_HEADER) && (inspect_section == IS_FLEX_HEADER)) ||
         ((HttpInspect::get_latest_is(p) == IS_FIRST_BODY) && (inspect_section == IS_BODY)) ||
index 50b025d89fc6b9191af1eb7d195d9f00a2136a00..8981132362db64bba7b08aad05bc9825562336d6 100644 (file)
@@ -82,8 +82,8 @@ private:
 class HttpIpsOption : public snort::IpsOption
 {
 public:
-    HttpIpsOption(const HttpRuleOptModule* cm, option_type_t type) :
-        snort::IpsOption(cm->key, type),
+    HttpIpsOption(const HttpRuleOptModule* cm) :
+        snort::IpsOption(cm->key),
         buffer_info(cm->rule_opt_index, cm->sub_id, cm->form),
         cat(cm->cat), inspect_section(cm->inspect_section) {}
     snort::CursorActionType get_cursor_type() const override { return cat; }
index 9326dfde324b27c8bc8baca3fc46b310baf5ef9e..15f0e071889d76985fa39391c18a69252c4efd97 100644 (file)
@@ -133,15 +133,60 @@ bool HttpBufferRuleOptModule::end(const char*, int, SnortConfig*)
     return HttpRuleOptModule::end(nullptr, 0, nullptr);
 }
 
+static InspectionBuffer::Type buf_map[] =
+{
+#if 0
+    BUFFER_PSI_CLIENT_BODY, BUFFER_PSI_COOKIE, BUFFER_PSI_HEADER, BUFFER_PSI_METHOD,
+    BUFFER_PSI_RAW_BODY, BUFFER_PSI_RAW_COOKIE, BUFFER_PSI_RAW_HEADER, BUFFER_PSI_RAW_REQUEST,
+    BUFFER_PSI_RAW_STATUS, BUFFER_PSI_RAW_TRAILER, BUFFER_PSI_RAW_URI, BUFFER_PSI_STAT_CODE,
+    BUFFER_PSI_STAT_MSG, BUFFER_PSI_TRAILER, BUFFER_PSI_TRUE_IP, BUFFER_PSI_URI, BUFFER_PSI_VERSION,
+    BUFFER_PSI_JS_DATA, BUFFER_PSI_VBA_DATA, BUFFER_PSI_MAX
+#endif
+    InspectionBuffer::IBT_BODY,
+    InspectionBuffer::IBT_COOKIE,
+    InspectionBuffer::IBT_HEADER,
+    InspectionBuffer::IBT_METHOD,
+    InspectionBuffer::IBT_MAX,
+    InspectionBuffer::IBT_MAX,
+    InspectionBuffer::IBT_RAW_HEADER,
+    InspectionBuffer::IBT_MAX,
+    InspectionBuffer::IBT_MAX,
+    InspectionBuffer::IBT_RAW_HEADER,
+    InspectionBuffer::IBT_RAW_KEY,
+    InspectionBuffer::IBT_STAT_CODE,
+    InspectionBuffer::IBT_STAT_MSG,
+    InspectionBuffer::IBT_HEADER,
+    InspectionBuffer::IBT_MAX,
+    InspectionBuffer::IBT_KEY,
+    InspectionBuffer::IBT_MAX,
+    InspectionBuffer::IBT_JS_DATA,
+    InspectionBuffer::IBT_VBA,
+    InspectionBuffer::IBT_MAX
+};
 
 IpsOption::EvalStatus HttpBufferIpsOption::eval(Cursor& c, Packet* p)
 {
     RuleProfile profile(HttpBufferRuleOptModule::http_buffer_ps[idx]);
 
-    const HttpInspect* const hi = eval_helper(p);
+    HttpInspect* hi = const_cast<HttpInspect*>(eval_helper(p));
     if (hi == nullptr)
         return NO_MATCH;
-    
+
+    if (p->packet_flags & PKT_FAST_PAT_EVAL)
+    {
+        InspectionBuffer buf;
+        InspectionBuffer::Type ibt = buf_map[idx];
+
+        if (ibt == InspectionBuffer::IBT_MAX)
+            return NO_MATCH;
+
+        if (!hi->get_fp_buf(ibt, p, buf))
+            return NO_MATCH;
+
+        c.set(key, buf.data, buf.len);
+        return MATCH;
+    }
+
     const Field& http_buffer = hi->http_get_buf(p, buffer_info);
     if (http_buffer.length() <= 0)
         return NO_MATCH;
@@ -163,7 +208,7 @@ IpsOption::EvalStatus HttpBufferIpsOption::eval(Cursor& c, Packet* p)
 
 static Module* client_body_mod_ctor()
 {
-    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_CLIENT_BODY, CAT_SET_BODY,
+    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_CLIENT_BODY, CAT_SET_FAST_PATTERN,
         BUFFER_PSI_CLIENT_BODY);
 }
 
@@ -216,8 +261,8 @@ static const Parameter http_cookie_params[] =
 
 static Module* cookie_mod_ctor()
 {
-    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_COOKIE, CAT_SET_COOKIE, BUFFER_PSI_COOKIE,
-        http_cookie_params);
+    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_COOKIE, CAT_SET_FAST_PATTERN,
+        BUFFER_PSI_COOKIE, http_cookie_params);
 }
 
 static const IpsApi cookie_api =
@@ -277,7 +322,7 @@ static const Parameter http_header_params[] =
 
 static Module* header_mod_ctor()
 {
-    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_HEADER, CAT_SET_HEADER,
+    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_HEADER, CAT_SET_FAST_PATTERN,
         BUFFER_PSI_HEADER, http_header_params);
 }
 
@@ -328,8 +373,8 @@ static const Parameter http_method_params[] =
 
 static Module* method_mod_ctor()
 {
-    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_METHOD, CAT_SET_METHOD, BUFFER_PSI_METHOD,
-        http_method_params);
+    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_METHOD, CAT_SET_FAST_PATTERN,
+        BUFFER_PSI_METHOD, http_method_params);
 }
 
 static const IpsApi method_api =
@@ -476,7 +521,7 @@ static const Parameter http_raw_header_params[] =
 
 static Module* raw_header_mod_ctor()
 {
-    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_HEADER, CAT_SET_RAW_HEADER,
+    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_HEADER, CAT_SET_FAST_PATTERN,
         BUFFER_PSI_RAW_HEADER, http_raw_header_params);
 }
 
@@ -630,7 +675,7 @@ static const Parameter http_raw_trailer_params[] =
 
 static Module* raw_trailer_mod_ctor()
 {
-    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_TRAILER, CAT_SET_RAW_HEADER,
+    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_TRAILER, CAT_SET_FAST_PATTERN,
         BUFFER_PSI_RAW_TRAILER, http_raw_trailer_params);
 }
 
@@ -693,7 +738,7 @@ static const Parameter http_raw_uri_params[] =
 
 static Module* raw_uri_mod_ctor()
 {
-    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_URI, CAT_SET_RAW_KEY,
+    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_URI, CAT_SET_FAST_PATTERN,
         BUFFER_PSI_RAW_URI, http_raw_uri_params);
 }
 
@@ -742,7 +787,7 @@ static const Parameter http_stat_code_params[] =
 
 static Module* stat_code_mod_ctor()
 {
-    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_STAT_CODE, CAT_SET_STAT_CODE,
+    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_STAT_CODE, CAT_SET_FAST_PATTERN,
         BUFFER_PSI_STAT_CODE, http_stat_code_params);
 }
 
@@ -791,7 +836,7 @@ static const Parameter http_stat_msg_params[] =
 
 static Module* stat_msg_mod_ctor()
 {
-    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_STAT_MSG, CAT_SET_STAT_MSG,
+    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_STAT_MSG, CAT_SET_FAST_PATTERN,
         BUFFER_PSI_STAT_MSG, http_stat_msg_params);
 }
 
@@ -844,7 +889,7 @@ static const Parameter http_trailer_params[] =
 
 static Module* trailer_mod_ctor()
 {
-    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_TRAILER, CAT_SET_HEADER,
+    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_TRAILER, CAT_SET_FAST_PATTERN,
         BUFFER_PSI_TRAILER, http_trailer_params);
 }
 
@@ -958,8 +1003,8 @@ static const Parameter http_uri_params[] =
 
 static Module* uri_mod_ctor()
 {
-    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_URI, CAT_SET_KEY, BUFFER_PSI_URI,
-        http_uri_params);
+    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_URI, CAT_SET_FAST_PATTERN,
+        BUFFER_PSI_URI, http_uri_params);
 }
 
 static const IpsApi uri_api =
@@ -1051,7 +1096,7 @@ static const IpsApi version_api =
 #define IPS_HELP "rule option to set detection cursor to normalized JavaScript data"
 static Module* js_data_mod_ctor()
 {
-    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, BUFFER_JS_DATA, CAT_SET_JS_DATA,
+    return new HttpBufferRuleOptModule(IPS_OPT, IPS_HELP, BUFFER_JS_DATA, CAT_SET_FAST_PATTERN,
         BUFFER_PSI_JS_DATA);
 }
 
index cd568db32ae09896e2d761e0f2b52c918675ba6c..8af7d0c7fb18fcaabb7ca848b143798443c1679c 100644 (file)
@@ -69,7 +69,7 @@ class HttpBufferIpsOption : public HttpIpsOption
 {
 public:
     HttpBufferIpsOption(const HttpBufferRuleOptModule* cm) :
-        HttpIpsOption(cm, RULE_OPTION_TYPE_BUFFER_SET), idx(cm->idx),
+        HttpIpsOption(cm), idx(cm->idx),
         key(cm->key) {}
     EvalStatus eval(Cursor&, snort::Packet*) override;
 
index c3c4d5d0dab4cd77e1242f6bd2b6fededc5671b3..7a11aba2e3f705c26a57b6dff785d91534cf6ccd 100644 (file)
@@ -126,7 +126,7 @@ static const Parameter http_num_hdrs_params[] =
 
 static Module* num_hdrs_mod_ctor()
 {
-    return new HttpNumHdrsRuleOptModule(IPS_OPT, IPS_HELP, HTTP_RANGE_NUM_HDRS, CAT_SET_OTHER,
+    return new HttpNumHdrsRuleOptModule(IPS_OPT, IPS_HELP, HTTP_RANGE_NUM_HDRS, CAT_NONE,
        NUM_HDRS_PSI_HDRS, http_num_hdrs_params);
 }
 
@@ -165,7 +165,7 @@ static const IpsApi num_headers_api =
 
 static Module* num_trailers_mod_ctor()
 {
-    return new HttpNumHdrsRuleOptModule(IPS_OPT, IPS_HELP, HTTP_RANGE_NUM_TRAILERS, CAT_SET_OTHER,
+    return new HttpNumHdrsRuleOptModule(IPS_OPT, IPS_HELP, HTTP_RANGE_NUM_TRAILERS, CAT_NONE,
         NUM_HDRS_PSI_TRAILERS, http_num_hdrs_params);
 }
 
index 54a8da2057e180fe00958c7e941233c0fb541b65..ccb3f83065facd5fc88b3b36a3f4afcbf9126f4c 100644 (file)
@@ -58,7 +58,7 @@ class HttpNumHdrsIpsOption : public HttpIpsOption
 {
 public:
     HttpNumHdrsIpsOption(const HttpNumHdrsRuleOptModule* cm) :
-        HttpIpsOption(cm, RULE_OPTION_TYPE_OTHER), idx(cm->idx), range(cm->range) {}
+        HttpIpsOption(cm), idx(cm->idx), range(cm->range) {}
     EvalStatus eval(Cursor&, snort::Packet*) override;
     uint32_t hash() const override;
     bool operator==(const snort::IpsOption& ips) const override;
index 40cf593a276e24de85ad959945e189c5730df958..9557363c5a008f1c389ccd70e5c6696aa801e903 100644 (file)
@@ -53,7 +53,7 @@ class HttpParamIpsOption : public HttpIpsOption
 {
 public:
     HttpParamIpsOption(const HttpParamRuleOptModule* cm) :
-        HttpIpsOption(cm, RULE_OPTION_TYPE_BUFFER_SET),
+        HttpIpsOption(cm),
         key(cm->key), http_param(cm->param, cm->nocase) {}
     EvalStatus eval(Cursor&, snort::Packet*) override;
     uint32_t hash() const override;
index 835054a73d9ae0a81192775862c754c57d3f17bf..d78d2eae050a1f372fa036e8bb044db1f4ab94bc 100644 (file)
@@ -206,7 +206,7 @@ static const Parameter hdr_test_params[] =
 
 static Module* http_header_test_mod_ctor()
 {
-    return new HttpTestRuleOptModule(IPS_OPT, IPS_HELP, HTTP_HEADER_TEST, CAT_SET_OTHER,
+    return new HttpTestRuleOptModule(IPS_OPT, IPS_HELP, HTTP_HEADER_TEST, CAT_NONE,
         TEST_PSI_HEADER_TEST, hdr_test_params);
 }
 
@@ -265,7 +265,7 @@ check whether it is a number, or check if the field is absent"
 
 static Module* http_trailer_test_mod_ctor()
 {
-    return new HttpTestRuleOptModule(IPS_OPT, IPS_HELP, HTTP_TRAILER_TEST, CAT_SET_OTHER,
+    return new HttpTestRuleOptModule(IPS_OPT, IPS_HELP, HTTP_TRAILER_TEST, CAT_NONE,
         TEST_PSI_TRAILER_TEST, trailer_test_params);
 }
 
index 681e47a15c2281a38015010d68d71cb8792bc0da..b98f753471fec345bd6d576ea6110f4c99221a30 100644 (file)
@@ -63,7 +63,7 @@ class HttpTestIpsOption : public HttpIpsOption
 {
 public:
     HttpTestIpsOption(const HttpTestRuleOptModule* cm) :
-        HttpIpsOption(cm, RULE_OPTION_TYPE_OTHER), idx(cm->idx), check(cm->check),
+        HttpIpsOption(cm), idx(cm->idx), check(cm->check),
         numeric(cm->numeric), absent(cm->absent) {}
     EvalStatus eval(Cursor&, snort::Packet*) override;
     uint32_t hash() const override;
index 90b2e3ffb376cb0dcb62a3df45411fa7213d3a09..23c9980f5bd3c1eeb9a474c96eb7cac850ec9bc7 100644 (file)
@@ -153,7 +153,7 @@ static const Parameter version_match_params[] =
 
 static Module* version_match_mod_ctor()
 {
-    return new HttpVersionRuleOptModule(IPS_OPT, IPS_HELP, HTTP_VERSION_MATCH, CAT_SET_OTHER,
+    return new HttpVersionRuleOptModule(IPS_OPT, IPS_HELP, HTTP_VERSION_MATCH, CAT_NONE,
         version_match_params);
 }
 
index 2a89c62036899eff50b99eef1be56633d94755de..873309be0b60daba8ad1517642e6c68c63195c7e 100644 (file)
@@ -53,7 +53,7 @@ class HttpVersionIpsOption : public HttpIpsOption
 {
 public:
     HttpVersionIpsOption(const HttpVersionRuleOptModule* cm) :
-        HttpIpsOption(cm, RULE_OPTION_TYPE_OTHER), version_flags(cm->version_flags) {}
+        HttpIpsOption(cm), version_flags(cm->version_flags) {}
     EvalStatus eval(Cursor&, snort::Packet*) override;
     uint32_t hash() const override;
     bool operator==(const snort::IpsOption& ips) const override;
index 9277e32787fdf5c5da5301ee5a69188e928073ec..afb6a8055dec0029dc63a1d722da831a53d2dde0 100644 (file)
@@ -839,6 +839,13 @@ static void imap_dtor(Inspector* p)
     delete p;
 }
 
+static const char* imap_bufs[] =
+{
+    "file_data",
+    "vba_data",
+    nullptr
+};
+
 const InspectApi imap_api =
 {
     {
@@ -855,7 +862,7 @@ const InspectApi imap_api =
     },
     IT_SERVICE,
     PROTO_BIT__PDU,
-    nullptr, // buffers
+    imap_bufs,
     "imap",
     imap_init,
     imap_term, // pterm
index dc50af24d522b12a7fc855cd811a65376f95f890..08e02747b33c9a098afb869073def6b7b0e34ddb 100644 (file)
@@ -45,10 +45,10 @@ static THREAD_LOCAL ProfileStats mms_data_prof;
 class MmsDataOption : public IpsOption
 {
 public:
-    MmsDataOption() : IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_SET) { }
+    MmsDataOption() : IpsOption(s_name) { }
 
     CursorActionType get_cursor_type() const override
-    { return CAT_SET_OTHER; }
+    { return CAT_SET_FAST_PATTERN; }
 
     EvalStatus eval(Cursor&, Packet*) override;
 };
index 3b6008d3a34ba643c2964cbccd276b847d382fef..98620dcc0f9d2f736db49b86e68618f56e4f784a 100644 (file)
@@ -149,6 +149,12 @@ static void mms_dtor(Inspector* p)
 
 //-------------------------------------------------------------------------
 
+static const char* mms_bufs[] =
+{
+    "mms_data",
+    nullptr
+};
+
 static const InspectApi mms_api =
 {
     {
@@ -165,7 +171,7 @@ static const InspectApi mms_api =
     },
     IT_SERVICE,
     PROTO_BIT__PDU,
-    nullptr,
+    mms_bufs,
     "mms",
     mms_init,
     nullptr,
index 651c0de85e3230e46443c538b11b12ae0378d3c5..a323cb37043febd493a4ca4cc473a14e71c979e4 100644 (file)
@@ -45,12 +45,15 @@ static THREAD_LOCAL ProfileStats modbus_data_prof;
 class ModbusDataOption : public IpsOption
 {
 public:
-    ModbusDataOption() : IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_SET) { }
+    ModbusDataOption() : IpsOption(s_name) { }
 
     uint32_t hash() const override;
     bool operator==(const IpsOption&) const override;
 
     EvalStatus eval(Cursor&, Packet*) override;
+
+    CursorActionType get_cursor_type() const override
+    { return CAT_SET_FAST_PATTERN; }
 };
 
 uint32_t ModbusDataOption::hash() const
index beed02e223e42fc2866955b1d4dc05e92530bc10..e4b9e7472dc8c9a1770b784f4238820f739de639 100644 (file)
@@ -71,6 +71,7 @@ class Modbus : public Inspector
 public:
     // default ctor / dtor
     void eval(Packet*) override;
+    bool get_buf(InspectionBuffer::Type, Packet*, InspectionBuffer&) override;
 
     int get_message_type(int version, const char* name);
     int get_info_type(int version, const char* name);
@@ -118,6 +119,16 @@ void Modbus::eval(Packet* p)
         mfd->reset();
 }
 
+bool Modbus::get_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
+{
+    if ( ibt !=  InspectionBuffer::IBT_BODY or p->dsize <= MODBUS_MIN_LEN )
+        return false;
+
+    b.data = p->data + MODBUS_MIN_LEN;
+    b.len = p->dsize - MODBUS_MIN_LEN;
+    return true;
+}
+
 //-------------------------------------------------------------------------
 // plugin stuff
 //-------------------------------------------------------------------------
@@ -145,6 +156,12 @@ static void modbus_dtor(Inspector* p)
 
 //-------------------------------------------------------------------------
 
+static const char* modbus_bufs[] =
+{
+    "modbus_data",
+    nullptr
+};
+
 static const InspectApi modbus_api =
 {
     {
@@ -161,7 +178,7 @@ static const InspectApi modbus_api =
     },
     IT_SERVICE,
     PROTO_BIT__PDU,
-    nullptr,
+    modbus_bufs,
     "modbus",
     modbus_init,
     nullptr,
index 0f4ff54bb1e6480037cfd19b8e03bcde54c8f232..8c9e676345999f7ac0dbc5ac58fe114c29f4ac67 100644 (file)
@@ -778,6 +778,13 @@ static void pop_dtor(Inspector* p)
     delete p;
 }
 
+static const char* pop_bufs[] =
+{
+    "file_data",
+    "vba_data",
+    nullptr
+};
+
 const InspectApi pop_api =
 {
     {
@@ -794,7 +801,7 @@ const InspectApi pop_api =
     },
     IT_SERVICE,
     PROTO_BIT__PDU,
-    nullptr, // buffers
+    pop_bufs,
     "pop3",
     pop_init,
     pop_term, // pterm
index d20b2c75bb452e31c7c62dfbe828a68517222292..5b5d530c4655a39cf9785cb3260ecdf5b9e2d558 100644 (file)
@@ -763,8 +763,6 @@ public:
     void eval(Packet*) override;
     void clear(Packet*) override;
 
-    bool get_buf(InspectionBuffer::Type, Packet*, InspectionBuffer&) override;
-
     StreamSplitter* get_splitter(bool c2s) override
     { return c2s ? new LogSplitter(c2s) : nullptr; }
 };
@@ -823,18 +821,6 @@ void RpcDecode::eval(Packet* p)
     RpcPreprocEvent(rsdata, ConvertRPC(rsdata, p));
 }
 
-bool RpcDecode::get_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
-{
-    if ( ibt != InspectionBuffer::IBT_ALT )
-        return false;
-
-    const DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
-    b.len = buf.len;
-    b.data = (b.len > 0) ? buf.data : nullptr;
-
-    return (b.data != nullptr);
-}
-
 void RpcDecode::clear(Packet* p)
 {
     DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
index ba58dcf7515796ce84ac1e5c2f0f3026a08aba6a..034d2b454cc6c8e257df99b1ae4a94412e7e5752 100644 (file)
@@ -45,12 +45,15 @@ static THREAD_LOCAL ProfileStats s7commplus_content_prof;
 class S7commplusContentOption : public IpsOption
 {
 public:
-    S7commplusContentOption() : IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_SET) { }
+    S7commplusContentOption() : IpsOption(s_name) { }
 
     uint32_t hash() const override;
     bool operator==(const IpsOption&) const override;
 
     EvalStatus eval(Cursor&, Packet*) override;
+
+    CursorActionType get_cursor_type() const override
+    { return CAT_SET_FAST_PATTERN; }
 };
 
 uint32_t S7commplusContentOption::hash() const
index cc27d101bc25cdd87d02621fc6e8110188e07cf5..d63ea36df3afb2aa83d8d7e1155e8ba74efad779 100644 (file)
@@ -145,6 +145,12 @@ static void s7commplus_dtor(Inspector* p)
 
 //-------------------------------------------------------------------------
 
+static const char* s7commplus_bufs[] =
+{
+    "s7commplus_content",
+    nullptr
+};
+
 static const InspectApi s7commplus_api =
 {
     {
@@ -161,7 +167,7 @@ static const InspectApi s7commplus_api =
     },
     IT_SERVICE,
     PROTO_BIT__PDU,
-    nullptr,
+    s7commplus_bufs,
     "s7commplus",
     s7commplus_init,
     nullptr,
index 9818881558aec7258a25dd5a683ddcaef3a76720..525ad4fdfd8bff05f70fd4b4802a4fe6bb043a6a 100644 (file)
@@ -82,9 +82,7 @@ static void opt_dtor(IpsOption* p)
 class SipIpsOption : public IpsOption
 {
 public:
-    SipIpsOption(
-        const char* s, SipIdx psi, CursorActionType c) :
-        IpsOption(s, RULE_OPTION_TYPE_BUFFER_SET)
+    SipIpsOption(const char* s, SipIdx psi, CursorActionType c) : IpsOption(s)
     { key = s; cat = c; idx = psi; }
 
     CursorActionType get_cursor_type() const override
@@ -155,7 +153,7 @@ static Module* header_mod_ctor()
 
 static IpsOption* header_opt_ctor(Module*, OptTreeNode*)
 {
-    return new SipIpsOption(IPS_OPT, SIP_HEADER, CAT_SET_HEADER);
+    return new SipIpsOption(IPS_OPT, SIP_HEADER, CAT_SET_FAST_PATTERN);
 }
 
 static const IpsApi header_api =
@@ -200,7 +198,7 @@ static Module* body_mod_ctor()
 
 static IpsOption* body_opt_ctor(Module*, OptTreeNode*)
 {
-    return new SipIpsOption(IPS_OPT, SIP_BODY, CAT_SET_BODY);
+    return new SipIpsOption(IPS_OPT, SIP_BODY, CAT_SET_FAST_PATTERN);
 }
 
 static const IpsApi body_api =
index 9fe05f878f237f33445f1db22dde8c3a909a2326..e66902118e1aea7e8904c6882a14434b2954a270 100644 (file)
@@ -187,7 +187,6 @@ public:
 
     void show(const SnortConfig*) const override;
     void eval(Packet*) override;
-    bool get_buf(InspectionBuffer::Type, Packet*, InspectionBuffer&) override;
 
     class StreamSplitter* get_splitter(bool to_server) override
     { return new SipSplitter(to_server); }
@@ -243,47 +242,6 @@ void Sip::eval(Packet* p)
     snort_sip(config, p);
 }
 
-bool Sip::get_buf(
-    InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
-{
-    SIPData* sd;
-    SIP_Roptions* ropts;
-    const uint8_t* data = nullptr;
-    unsigned len = 0;
-
-    sd = get_sip_session_data(p->flow);
-    if (!sd)
-        return false;
-
-    ropts = &sd->ropts;
-
-    switch ( ibt )
-    {
-    case InspectionBuffer::IBT_HEADER:
-        data = ropts->header_data;
-        len = ropts->header_len;
-        break;
-
-    case InspectionBuffer::IBT_BODY:
-        data = ropts->body_data;
-        len = ropts->body_len;
-        break;
-
-    default:
-        break;
-    }
-
-    if (!len)
-        return false;
-
-    assert(data);
-
-    b.data = data;
-    b.len = len;
-
-    return true;
-}
-
 //-------------------------------------------------------------------------
 // api stuff
 //-------------------------------------------------------------------------
@@ -310,6 +268,13 @@ static void sip_dtor(Inspector* p)
     delete p;
 }
 
+static const char* sip_bufs[] =
+{
+    "sip_header",
+    "sip_body",
+    nullptr
+};
+
 const InspectApi sip_api =
 {
     {
@@ -326,7 +291,7 @@ const InspectApi sip_api =
     },
     IT_SERVICE,
     PROTO_BIT__UDP | PROTO_BIT__PDU,
-    nullptr, // buffers
+    sip_bufs,
     "sip",
     sip_init,
     nullptr, // pterm
index c27691e05e3fa2f25334f7cac6a5862afc1182d0..92e77602cb8b183c8f0adffd732cd34a66690e84 100644 (file)
@@ -1446,8 +1446,8 @@ public:
 
     bool configure(SnortConfig*) override;
     void show(const SnortConfig*) const override;
+
     void eval(Packet*) override;
-    bool get_buf(InspectionBuffer::Type, Packet*, InspectionBuffer&) override;
     void clear(Packet*) override;
 
     StreamSplitter* get_splitter(bool c2s) override
@@ -1461,8 +1461,7 @@ public:
 
     void ProcessSmtpCmdsList(const SmtpCmd*);
 
-    bool get_fp_buf(snort::InspectionBuffer::Type ibt, snort::Packet* p,
-        snort::InspectionBuffer& b) override;
+    bool get_fp_buf(snort::InspectionBuffer::Type, snort::Packet*, snort::InspectionBuffer&) override;
 
 private:
     SmtpProtoConf* config;
@@ -1516,40 +1515,6 @@ void Smtp::eval(Packet* p)
     snort_smtp(config, p);
 }
 
-bool Smtp::get_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
-{
-    // Fast pattern buffers only supplied at specific times
-    switch (ibt)
-    {
-        case InspectionBuffer::IBT_ALT:
-            b.data = SMTP_GetAltBuffer(p, b.len);
-            return (b.data != nullptr);
-
-        case InspectionBuffer::IBT_VBA:
-        {
-            SMTPData* smtp_ssn = get_session_data(p->flow);
-
-            if (!smtp_ssn)
-                return false;
-
-            const BufferData& vba_buf = smtp_ssn->mime_ssn->get_vba_inspect_buf();
-
-            if (vba_buf.data_ptr() && vba_buf.length())
-            {
-                b.data = vba_buf.data_ptr();
-                b.len = vba_buf.length();
-                return true;
-            }
-            else
-                return false;
-        }
-        default:
-            break;
-    }
-    return false;
-
-}
-
 void Smtp::clear(Packet* p)
 {
     SMTP_ResetAltBuffer(p);
@@ -1590,7 +1555,23 @@ void Smtp::ProcessSmtpCmdsList(const SmtpCmd* sc)
 
 bool Smtp::get_fp_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
 {
-    return get_buf(ibt, p, b);
+    if ( ibt != InspectionBuffer::IBT_VBA )
+        return false;
+
+    SMTPData* smtp_ssn = get_session_data(p->flow);
+
+    if (!smtp_ssn)
+        return false;
+
+    const BufferData& vba_buf = smtp_ssn->mime_ssn->get_vba_inspect_buf();
+
+    if ( vba_buf.data_ptr() && vba_buf.length() )
+    {
+        b.data = vba_buf.data_ptr();
+        b.len = vba_buf.length();
+        return true;
+    }
+    return false;
 }
 
 //-------------------------------------------------------------------------
@@ -1633,6 +1614,13 @@ static void smtp_dtor(Inspector* p)
     delete p;
 }
 
+static const char* smtp_bufs[] =
+{
+    "file_data",
+    "vba_data",
+    nullptr
+};
+
 const InspectApi smtp_api =
 {
     {
@@ -1649,7 +1637,7 @@ const InspectApi smtp_api =
     },
     IT_SERVICE,
     PROTO_BIT__PDU,
-    nullptr,                // buffers
+    smtp_bufs,
     "smtp",
     smtp_init,
     smtp_term,
index f1e11e6a9f47b2d31aa63725ed3d3cfb5924bbce..f8f052c3c1d73c5b78d253d92231aaad653c167f 100644 (file)
@@ -192,18 +192,8 @@ const PegInfo pc_names[] =
     { CountType::SUM, "cooked_searches", "fast pattern searches in cooked packet data" },
     { CountType::SUM, "pkt_searches", "fast pattern searches in packet data" },
     { CountType::SUM, "alt_searches", "alt fast pattern searches in packet data" },
-    { CountType::SUM, "key_searches", "fast pattern searches in key buffer" },
-    { CountType::SUM, "header_searches", "fast pattern searches in header buffer" },
-    { CountType::SUM, "body_searches", "fast pattern searches in body buffer" },
+    { CountType::SUM, "pdu_searches", "fast pattern searches in service buffers" },
     { CountType::SUM, "file_searches", "fast pattern searches in file buffer" },
-    { CountType::SUM, "raw_key_searches", "fast pattern searches in raw key buffer" },
-    { CountType::SUM, "raw_header_searches", "fast pattern searches in raw header buffer" },
-    { CountType::SUM, "method_searches", "fast pattern searches in method buffer" },
-    { CountType::SUM, "stat_code_searches", "fast pattern searches in status code buffer" },
-    { CountType::SUM, "stat_msg_searches", "fast pattern searches in status message buffer" },
-    { CountType::SUM, "cookie_searches", "fast pattern searches in cookie buffer" },
-    { CountType::SUM, "js_data_searches", "fast pattern searches in js_data buffer" },
-    { CountType::SUM, "vba_searches", "fast pattern searches in MS Office Visual Basic for Applications buffer" },
     { CountType::SUM, "offloads", "fast pattern searches that were offloaded" },
     { CountType::SUM, "alerts", "alerts not including IP reputation" },
     { CountType::SUM, "total_alerts", "alerts including IP reputation" },
index c215eeea2ae35a838d3b6346e9b0a9ae91f00f64..8e548b062e95e3ac69fb84eff69840dfbafebb81 100644 (file)
@@ -42,18 +42,8 @@ struct PacketCount
     PegCount cooked_searches;
     PegCount pkt_searches;
     PegCount alt_searches;
-    PegCount key_searches;
-    PegCount header_searches;
-    PegCount body_searches;
+    PegCount pdu_searches;
     PegCount file_searches;
-    PegCount raw_key_searches;
-    PegCount raw_header_searches;
-    PegCount method_searches;
-    PegCount stat_code_searches;
-    PegCount stat_msg_searches;
-    PegCount cookie_searches;
-    PegCount js_data_searches;
-    PegCount vba_searches;
     PegCount offloads;
     PegCount alert_pkts;
     PegCount total_alert_pkts;