]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1755 in SNORT/snort3 from ~RUCOMBS/snort3:rule_mode to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Thu, 3 Oct 2019 18:20:27 +0000 (14:20 -0400)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Thu, 3 Oct 2019 18:20:27 +0000 (14:20 -0400)
Squashed commit of the following:

commit ea9b22df4fe34ec6b5443de7ad700676cd7ece65
Author: russ <rucombs@cisco.com>
Date:   Wed Oct 2 15:07:43 2019 -0400

    detection:  map file rules to services

    alert file and service:file rules will be loaded as if written:
    alert * ( service:ftp-data, netbios-ssn, http, pop3, imap, smtp, user )
    This only applies to rules w/o services.  With file rules folded
    into service groups, we can avoid a separate, and usually extra,
    file_data search.  The 'user' service is required for stream_file
    support.

commit 4fc36a4a5813b0e862fd9059c8f409bfe7bd9fee
Author: russ <rucombs@cisco.com>
Date:   Thu Sep 26 13:59:46 2019 -0400

    detection: update trace to indicate eval task

commit bab6812cb2fa5596c6cbe3c970c89d599c9814b2
Author: russ <rucombs@cisco.com>
Date:   Sun Sep 22 10:45:09 2019 -0400

    detection: non-service rules must match on rule header proto

commit 70c9e81d2a87fe01e40e13a400c5a8c6dae29847
Author: russ <rucombs@cisco.com>
Date:   Sat Sep 21 19:43:07 2019 -0400

    detection: consistently prefer service rules over port rules

commit 2d6092ffce0913a81440dbac11a0aab2c53527c6
Author: russ <rucombs@cisco.com>
Date:   Fri Sep 20 15:31:56 2019 -0400

    detection: do not split service groups by ip proto to avoid extra searches

commit 5e35f65a17de82034d5e48a2810abd4edd6d2a68
Author: russ <rucombs@cisco.com>
Date:   Wed Sep 18 21:19:30 2019 -0400

    detection: support alert file rules w/o optional services

commit 27d3cf25ecc4727468143df5a3c1a7d881982a27
Author: russ <rucombs@cisco.com>
Date:   Wed Sep 18 14:36:08 2019 -0400

    detection: use reference for signature eval data

commit 6cb9fffea37f2f521365927d5098a2ae2f2b8c8c
Author: russ <rucombs@cisco.com>
Date:   Wed Sep 18 14:29:04 2019 -0400

    detection: remove unnecessary match data from eval context

commit 763aa8a73cd15869b8e6f9de0a7908e28404e65c
Author: russ <rucombs@cisco.com>
Date:   Wed Sep 18 14:12:20 2019 -0400

    detection: remove the inappropriate match tracker from mpse batch setup

commit e1342b186cf4bb026c1137fce73f7bdebb525291
Author: russ <rucombs@cisco.com>
Date:   Wed Sep 18 13:43:30 2019 -0400

    detection: remove more cruft from match tracker

    This breaks alert file rules rules which do not contain services but fixes
    the case where alert tcp and alert file coexist in the same FP FSM and
    the service match should override port checks.  The new breakage must
    be fixed differently.

commit 62e271f85b925b7f6eb3b29d68c3459533bf7bfe
Author: russ <rucombs@cisco.com>
Date:   Wed Sep 18 12:36:05 2019 -0400

    detection: remove cruft from match accumulator

18 files changed:
src/detection/detect_trace.cc
src/detection/detect_trace.h
src/detection/detection_options.cc
src/detection/detection_options.h
src/detection/fp_create.cc
src/detection/fp_detect.cc
src/detection/fp_detect.h
src/detection/fp_utils.cc
src/detection/rtn_checks.cc
src/detection/rtn_checks.h
src/detection/service_map.cc
src/detection/service_map.h
src/detection/treenodes.h
src/parser/parse_conf.cc
src/parser/parse_rule.cc
src/target_based/snort_protocols.cc
src/target_based/snort_protocols.h
src/target_based/test/proto_ref_test.cc

index 2d85b1ed403754a564b1123cb7466e65abb58560..99fa1ff412fc0c10d024e47e77420b26a93bd6d8 100644 (file)
@@ -58,7 +58,7 @@ void clear_trace_cursor_info()
     cursor_pos = -1;
 }
 
-void print_pkt_info(Packet* p)
+void print_pkt_info(Packet* p, const char* task)
 {
     const char* dir;
     SfIpString src_addr, dst_addr;
@@ -83,8 +83,8 @@ void print_pkt_info(Packet* p)
         dst_port = p->ptrs.dp;
     }
 
-    trace_logf(detection, TRACE_RULE_EVAL,"packet %" PRIu64 " %s %s:%u %s:%u\n",
-        p->context->packet_number, dir, src_addr, src_port, dst_addr, dst_port);
+    trace_logf(detection, TRACE_RULE_EVAL,"packet %" PRIu64 " %s %s:%u %s:%u (%s)\n",
+        p->context->packet_number, dir, src_addr, src_port, dst_addr, dst_port, task);
 }
 
 void print_pattern(const PatternMatchData* pmd)
@@ -151,7 +151,7 @@ void clear_trace_cursor_info()
 {
 }
 
-void print_pkt_info(Packet*)
+void print_pkt_info(Packet*, const char*)
 {
 }
 
index 1e089ea04f8829a0005ae97b21e94f790eb12bfc..a00c5c2686b6d9db62df7cd03653c832a46e0f6a 100644 (file)
@@ -48,7 +48,7 @@ enum
 };
 
 void clear_trace_cursor_info();
-void print_pkt_info(snort::Packet* p);
+void print_pkt_info(snort::Packet* p, const char*);
 void print_pattern(const PatternMatchData* pmd);
 void dump_buffer(const uint8_t* buff, unsigned len, snort::Packet*);
 void node_eval_trace(const detection_option_tree_node_t* node, const Cursor& cursor, snort::Packet*);
index 2f8222483f2eb042dc688349c2c765eb15e20631..883aa8dbea8131a4f01b994f33f7cc7bee0852b5 100644 (file)
@@ -342,12 +342,10 @@ void* add_detection_option_tree(SnortConfig* sc, detection_option_tree_node_t* o
 }
 
 int detection_option_node_evaluate(
-    detection_option_tree_node_t* node, detection_option_eval_data_t* eval_data,
+    detection_option_tree_node_t* node, detection_option_eval_data_t& eval_data,
     const Cursor& orig_cursor)
 {
-    // need node->state to do perf profiling
-    if ( !node )
-        return 0;
+    assert(node and eval_data.p);
 
     auto& state = node->state[get_instance_id()];
     RuleContext profile(state);
@@ -360,16 +358,11 @@ int detection_option_node_evaluate(
     char flowbits_setoperation = 0;
     int loop_count = 0;
     uint32_t tmp_byte_extract_vars[NUM_IPS_OPTIONS_VARS];
+    uint64_t cur_eval_context_num = eval_data.p->context->context_num;
 
-    if ( !eval_data || !eval_data->p || !eval_data->pomd )
-        return 0;
-
-    uint64_t cur_eval_context_num = eval_data->p->context->context_num;
+    node_eval_trace(node, cursor, eval_data.p);
 
-    node_eval_trace(node, cursor, eval_data->p);
-
-    auto p = eval_data->p;
-    auto pomd = eval_data->pomd;
+    auto p = eval_data.p;
 
     // see if evaluated it before ...
     if ( !node->is_relative )
@@ -393,7 +386,7 @@ int detection_option_node_evaluate(
         }
     }
 
-    state.last_check.ts = eval_data->p->pkth->ts;
+    state.last_check.ts = eval_data.p->pkth->ts;
     state.last_check.run_num = get_run_num();
     state.last_check.context_num = cur_eval_context_num;
     state.last_check.flowbit_failed = 0;
@@ -423,7 +416,7 @@ int detection_option_node_evaluate(
             SnortProtocolId snort_protocol_id = p->get_snort_protocol_id();
             int check_ports = 1;
 
-            if ( snort_protocol_id != UNKNOWN_PROTOCOL_ID and ((OtnxMatchData*)(pomd))->check_ports != 2 )
+            if ( snort_protocol_id != UNKNOWN_PROTOCOL_ID )
             {
                 auto sig_info = otn->sigInfo;
 
@@ -436,7 +429,7 @@ int detection_option_node_evaluate(
                     }
                 }
 
-                if (sig_info.num_services && check_ports)
+                if ( sig_info.num_services and check_ports )
                 {
                     // none of the services match
                     trace_logf(detection, TRACE_RULE_EVAL,
@@ -471,17 +464,14 @@ int detection_option_node_evaluate(
                 {
                     otn->state[get_instance_id()].matches++;
 
-                    if ( !eval_data->flowbit_noalert )
+                    if ( !eval_data.flowbit_noalert )
                     {
-                        PatternMatchData* pmd = (PatternMatchData*)eval_data->pmd;
-                        int pattern_size = pmd ? pmd->pattern_size : 0;
 #ifdef DEBUG_MSGS
                         const SigInfo& si = otn->sigInfo;
                         trace_logf(detection, TRACE_RULE_EVAL,
                             "Matched rule gid:sid:rev %u:%u:%u\n", si.gid, si.sid, si.rev);
 #endif
-
-                        fpAddMatch((OtnxMatchData*)pomd, pattern_size, otn);
+                        fpAddMatch(p->context->otnx, otn);
                     }
                     result = rval = (int)IpsOption::MATCH;
                 }
@@ -528,7 +518,7 @@ int detection_option_node_evaluate(
                     rval = (int)IpsOption::MATCH;
 
                 else
-                    rval = node->evaluate(node->option_data, cursor, eval_data->p);
+                    rval = node->evaluate(node->option_data, cursor, eval_data.p);
             }
             break;
 
@@ -547,7 +537,7 @@ int detection_option_node_evaluate(
         else if ( rval == (int)IpsOption::FAILED_BIT )
         {
             trace_log(detection, TRACE_RULE_EVAL, "failed bit\n");
-            eval_data->flowbit_failed = 1;
+            eval_data.flowbit_failed = 1;
             // clear the timestamp so failed flowbit gets eval'd again
             state.last_check.flowbit_failed = 1;
             state.last_check.result = result;
@@ -557,8 +547,8 @@ int detection_option_node_evaluate(
         {
             // Cache the current flowbit_noalert flag, and set it
             // so nodes below this don't alert.
-            tmp_noalert_flag = eval_data->flowbit_noalert;
-            eval_data->flowbit_noalert = 1;
+            tmp_noalert_flag = eval_data.flowbit_noalert;
+            eval_data.flowbit_noalert = 1;
             trace_log(detection, TRACE_RULE_EVAL, "flowbit no alert\n");
         }
 
@@ -679,7 +669,7 @@ int detection_option_node_evaluate(
         if ( rval == (int)IpsOption::NO_ALERT )
         {
             // Reset the flowbit_noalert flag in eval data
-            eval_data->flowbit_noalert = tmp_noalert_flag;
+            eval_data.flowbit_noalert = tmp_noalert_flag;
         }
 
         if ( continue_loop && rval == (int)IpsOption::MATCH && node->relative_children )
@@ -708,7 +698,7 @@ int detection_option_node_evaluate(
             result = rval;
     }
 
-    if ( eval_data->flowbit_failed )
+    if ( eval_data.flowbit_failed )
     {
         // something deeper in the tree failed a flowbit test, we may need to
         // reeval this node
index dc742751db82f0bbb062d705551f3c7cb40e9035..5f5f760a5c6b249ca89d89cc1ef7e252bdc9d543 100644 (file)
@@ -110,7 +110,6 @@ struct detection_option_tree_root_t
 
 struct detection_option_eval_data_t
 {
-    void* pomd;
     void* pmd;
     snort::Packet* p;
     char flowbit_failed;
@@ -122,7 +121,7 @@ void* add_detection_option(struct snort::SnortConfig*, option_type_t, void*);
 void* add_detection_option_tree(struct snort::SnortConfig*, detection_option_tree_node_t*);
 
 int detection_option_node_evaluate(
-    detection_option_tree_node_t*, detection_option_eval_data_t*, const class Cursor&);
+    detection_option_tree_node_t*, detection_option_eval_data_t&, const class Cursor&);
 
 void DetectionHashTableFree(snort::XHash*);
 void DetectionTreeHashTableFree(snort::XHash*);
index 4e34f3b9d2630b42fe65235824f81aeff1446ba6..4cdc7f55814c9ab49c11dc7f0946ff1568af3485 100644 (file)
@@ -1420,15 +1420,11 @@ static void fpCreateServiceMapPortGroups(SnortConfig* sc)
     sc->spgmmTable = ServicePortGroupMapNew();
     sc->sopgTable = new sopg_table_t(sc->proto_ref->get_count());
 
-    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; i++ )
-    {
-        fpBuildServicePortGroups(sc, sc->spgmmTable->to_srv[i],
-            sc->sopgTable->to_srv[i], sc->srmmTable->to_srv[i], fp);
+    fpBuildServicePortGroups(sc, sc->spgmmTable->to_srv,
+        sc->sopgTable->to_srv, sc->srmmTable->to_srv, fp);
 
-        fpBuildServicePortGroups(sc, sc->spgmmTable->to_cli[i],
-            sc->sopgTable->to_cli[i], sc->srmmTable->to_cli[i], fp);
-    }
-    sc->sopgTable->set_user_mode();
+    fpBuildServicePortGroups(sc, sc->spgmmTable->to_cli,
+        sc->sopgTable->to_cli, sc->srmmTable->to_cli, fp);
 }
 
 /*
@@ -1447,7 +1443,7 @@ static void fpPrintRuleList(SF_LIST* list)
     }
 }
 
-static void fpPrintServiceRuleMapTable(GHash* p, const char* proto, const char* dir)
+static void fpPrintServiceRuleMapTable(GHash* p, const char* dir)
 {
     GHashNode* n;
 
@@ -1455,8 +1451,6 @@ static void fpPrintServiceRuleMapTable(GHash* p, const char* proto, const char*
         return;
 
     std::string label = "service rule counts - ";
-    label += proto;
-    label += " ";
     label += dir;
     LogLabel(label.c_str());
 
@@ -1481,23 +1475,16 @@ static void fpPrintServiceRuleMapTable(GHash* p, const char* proto, const char*
 
 static void fpPrintServiceRuleMaps(SnortConfig* sc)
 {
-    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; ++i )
-    {
-        const char* s = sc->proto_ref->get_name(i);
-        fpPrintServiceRuleMapTable(sc->srmmTable->to_srv[i], s, "to server");
-        fpPrintServiceRuleMapTable(sc->srmmTable->to_cli[i], s, "to client");
-    }
+    fpPrintServiceRuleMapTable(sc->srmmTable->to_srv, "to server");
+    fpPrintServiceRuleMapTable(sc->srmmTable->to_cli, "to client");
 }
 
-static void fp_print_service_rules(SnortConfig* sc, GHash* cli, GHash* srv, const char* msg)
+static void fp_print_service_rules(SnortConfig* sc, GHash* cli, GHash* srv)
 {
     if ( !cli->count and !srv->count )
         return;
 
-    std::string label = "service rule counts - ";
-    label += msg;
-    label += "    to-srv  to-cli";
-    LogLabel(label.c_str());
+    LogLabel("service rule counts          to-srv  to-cli");
 
     uint16_t idx = 0;
     unsigned ctot = 0, stot = 0;
@@ -1524,8 +1511,7 @@ static void fp_print_service_rules(SnortConfig* sc, GHash* cli, GHash* srv, cons
 
 static void fp_print_service_rules_by_proto(SnortConfig* sc)
 {
-    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; ++i )
-        fp_print_service_rules(sc, sc->srmmTable->to_srv[i], sc->srmmTable->to_cli[i], sc->proto_ref->get_name(i));
+    fp_print_service_rules(sc, sc->srmmTable->to_srv, sc->srmmTable->to_cli);
 }
 
 static void fp_sum_port_groups(PortGroup* pg, unsigned c[PM_TYPE_MAX])
@@ -1554,11 +1540,8 @@ static void fp_print_service_groups(srmm_table_t* srmm)
     unsigned to_srv[PM_TYPE_MAX] = { 0 };
     unsigned to_cli[PM_TYPE_MAX] = { 0 };
 
-    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; ++i )
-    {
-        fp_sum_service_groups(srmm->to_srv[i], to_srv);
-        fp_sum_service_groups(srmm->to_cli[i], to_cli);
-    }
+    fp_sum_service_groups(srmm->to_srv, to_srv);
+    fp_sum_service_groups(srmm->to_cli, to_cli);
 
     bool label = true;
 
index e2c8a716c96bb2021db274e8a665c1505b7de811..de460dcb36ded08a776ecc99365248a7c22a7a7d 100644 (file)
@@ -91,18 +91,14 @@ THREAD_LOCAL ProfileStats mpsePerfStats;
 THREAD_LOCAL ProfileStats rulePerfStats;
 
 static void fp_immediate(Packet*);
-static void fp_immediate(MpseGroup*, OtnxMatchData*, const uint8_t*, unsigned);
+static void fp_immediate(MpseGroup*, Packet*, const uint8_t*, unsigned);
 
-// Initialize the OtnxMatchData structure.  We do this for
-// every packet so this only sets the necessary counters to
-// zero which saves us time.
-
-static inline void init_match_info(OtnxMatchData* o)
+static inline void init_match_info(OtnxMatchData* omd)
 {
     for ( int i = 0; i < SnortConfig::get_conf()->num_rule_types; i++ )
-        o->matchInfo[i].iMatchCount = 0;
+        omd->matchInfo[i].iMatchCount = 0;
 
-    o->have_match = false;
+    omd->have_match = false;
 }
 
 // called by fpLogEvent(), which does the filtering etc.
@@ -247,14 +243,13 @@ int fpLogEvent(const RuleTreeNode* rtn, const OptTreeNode* otn, Packet* p)
 **
 **  FORMAL INPUTS
 **    OtnxMatchData    * - the omd to add the event to.
-**    int pLen             - length of pattern that matched, 0 for no content
 **    OptTreeNode        * - the otn to add.
 **
 **  FORMAL OUTPUTS
 **    int - 1 max_events variable hit, 0 successful.
 **
 */
-int fpAddMatch(OtnxMatchData* omd_local, int /*pLen*/, const OptTreeNode* otn)
+int fpAddMatch(OtnxMatchData* omd, const OptTreeNode* otn)
 {
     RuleTreeNode* rtn = getRuntimeRtnFromOtn(otn);
     int evalIndex = rtn->listhead->ruleListNode->evalIndex;
@@ -265,7 +260,7 @@ int fpAddMatch(OtnxMatchData* omd_local, int /*pLen*/, const OptTreeNode* otn)
         pc.match_limit++;
         return 1;
     }
-    MatchInfo* pmi = &omd_local->matchInfo[evalIndex];
+    MatchInfo* pmi = &omd->matchInfo[evalIndex];
 
     /*
     **  If we hit the max number of unique events for any rule type alert,
@@ -289,7 +284,7 @@ int fpAddMatch(OtnxMatchData* omd_local, int /*pLen*/, const OptTreeNode* otn)
     pmi->MatchArray[ pmi->iMatchCount ] = otn;
 
     pmi->iMatchCount++;
-    omd_local->have_match = true;
+    omd->have_match = true;
     return 0;
 }
 
@@ -311,7 +306,8 @@ int fpEvalRTN(RuleTreeNode* rtn, Packet* p, int check_ports)
     if ( !rtn )
         return 0;
 
-    // FIXIT-L maybe add a port test here ...
+    if ( rtn->user_mode() )
+        check_ports = 1;
 
     if (!rtn->rule_func->RuleHeadFunc(p, rtn, rtn->rule_func, check_ports))
     {
@@ -332,17 +328,17 @@ int fp_eval_option(void* v, Cursor& c, Packet* p)
 }
 
 static int detection_option_tree_evaluate(detection_option_tree_root_t* root,
-    detection_option_eval_data_t* eval_data)
+    detection_option_eval_data_t& eval_data)
 {
     if ( !root )
         return 0;
 
-    RuleLatency::Context rule_latency_ctx(root, eval_data->p);
+    RuleLatency::Context rule_latency_ctx(root, eval_data.p);
 
     if ( RuleLatency::suspended() )
         return 0;
 
-    Cursor c(eval_data->p);
+    Cursor c(eval_data.p);
     int rval = 0;
 
     trace_log(detection, TRACE_RULE_EVAL, "Starting tree eval\n");
@@ -361,14 +357,12 @@ static int rule_tree_match(
     void* user, void* tree, int index, void* context, void* neg_list)
 {
     PMX* pmx = (PMX*)user;
-    OtnxMatchData* pomd = ((IpsContext*)context)->otnx;
 
     detection_option_tree_root_t* root = (detection_option_tree_root_t*)tree;
     detection_option_eval_data_t eval_data;
     NCListNode* ncl;
 
-    eval_data.pomd = pomd;
-    eval_data.p = pomd->p;
+    eval_data.p = ((IpsContext*)context)->packet;
     eval_data.pmd = pmx->pmd;
     eval_data.flowbit_failed = 0;
     eval_data.flowbit_noalert = 0;
@@ -396,7 +390,7 @@ static int rule_tree_match(
             last_check->rebuild_flag = (eval_data.p->packet_flags & PKT_REBUILT_STREAM);
         }
 
-        int ret = detection_option_tree_evaluate(root, &eval_data);
+        int ret = detection_option_tree_evaluate(root, eval_data);
 
         if ( ret )
             pmqs.qualified_events++;
@@ -435,9 +429,7 @@ static int rule_tree_match(
                 rule_tree_match(user, tree, index, context, nullptr);
             }
             while (layer::set_inner_ip_api(eval_data.p,
-                eval_data.p->ptrs.ip_api,
-                curr_layer) &&
-                (eval_data.p->ptrs.ip_api != tmp_api));
+                eval_data.p->ptrs.ip_api, curr_layer) && (eval_data.p->ptrs.ip_api != tmp_api));
 
             /*  cleanup restore original data & dsize */
             eval_data.p->packet_flags &= ~PKT_IP_RULE_2ND;
@@ -620,9 +612,9 @@ static inline int fpSessionAlerted(Packet* p, const OptTreeNode* otn)
 **  FORMAL OUTPUT
 **    int - return 0 if no match, 1 if match.
 */
-static inline int fpFinalSelectEvent(OtnxMatchData* o, Packet* p)
+static inline int fpFinalSelectEvent(OtnxMatchData* omd, Packet* p)
 {
-    if ( !o->have_match )
+    if ( !omd->have_match )
         return 0;
 
     int i;
@@ -640,7 +632,7 @@ static inline int fpFinalSelectEvent(OtnxMatchData* o, Packet* p)
         if (!SnortConfig::process_all_events() && (tcnt > 0))
             return 1;
 
-        if (o->matchInfo[i].iMatchCount)
+        if (omd->matchInfo[i].iMatchCount)
         {
             /*
              * We must always sort so if we que 8 and log 3 and they are
@@ -656,12 +648,12 @@ static inline int fpFinalSelectEvent(OtnxMatchData* o, Packet* p)
             /* Sort the rules in this action group */
             if (eq->order == SNORT_EVENTQ_PRIORITY)
             {
-                qsort(o->matchInfo[i].MatchArray, o->matchInfo[i].iMatchCount,
+                qsort(omd->matchInfo[i].MatchArray, omd->matchInfo[i].iMatchCount,
                     sizeof(void*), sortOrderByPriority);
             }
             else if (eq->order == SNORT_EVENTQ_CONTENT_LEN)
             {
-                qsort(o->matchInfo[i].MatchArray, o->matchInfo[i].iMatchCount,
+                qsort(omd->matchInfo[i].MatchArray, omd->matchInfo[i].iMatchCount,
                     sizeof(void*), sortOrderByContentLength);
             }
             else
@@ -670,9 +662,9 @@ static inline int fpFinalSelectEvent(OtnxMatchData* o, Packet* p)
             }
 
             /* Process each event in the action (alert,drop,log,...) groups */
-            for (j=0; j < o->matchInfo[i].iMatchCount; j++)
+            for (j=0; j < omd->matchInfo[i].iMatchCount; j++)
             {
-                otn = o->matchInfo[i].MatchArray[j];
+                otn = omd->matchInfo[i].MatchArray[j];
                 rtn = getRtnFromOtn(otn);
 
                 if (otn && rtn && Actions::is_pass(rtn->action))
@@ -685,7 +677,7 @@ static inline int fpFinalSelectEvent(OtnxMatchData* o, Packet* p)
                 //  Loop here so we don't log the same event multiple times.
                 for (k = 0; k < j; k++)
                 {
-                    if (o->matchInfo[i].MatchArray[k] == otn)
+                    if (omd->matchInfo[i].MatchArray[k] == otn)
                     {
                         otn = nullptr;
                         break;
@@ -854,8 +846,7 @@ void fp_clear_context(IpsContext& c)
 static int rule_tree_queue(
     void* user, void* tree, int index, void* context, void* list)
 {
-    OtnxMatchData* pomd = ((IpsContext*)context)->otnx;
-    MpseStash* stash = pomd->p->context->stash;
+    MpseStash* stash = ((IpsContext*)context)->stash;
 
     if ( stash->push(user, tree, index, list) )
     {
@@ -866,24 +857,24 @@ static int rule_tree_queue(
 }
 
 static inline int batch_search(
-    MpseGroup* so, OtnxMatchData* omd, const uint8_t* buf, unsigned len, PegCount& cnt)
+    MpseGroup* so, Packet* p, const uint8_t* buf, unsigned len, PegCount& cnt)
 {
     assert(so->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 ( omd->p->ptrs.udph && (omd->p->proto_bits & (PROTO_BIT__TEREDO | PROTO_BIT__GTP)) )
+    if ( p->ptrs.udph && (p->proto_bits & (PROTO_BIT__TEREDO | PROTO_BIT__GTP)) )
     {
-        fp_immediate(so, omd, buf, len);
+        fp_immediate(so, p, buf, len);
     }
     else
     {
         MpseBatchKey<> key = MpseBatchKey<>(buf, len);
-        omd->p->context->searches.items[key].so.push_back(so);
+        p->context->searches.items[key].so.push_back(so);
     }
 
-    dump_buffer(buf, len, omd->p);
+    dump_buffer(buf, len, p);
 
     if ( PacketLatency::fastpath() )
         return 1;
@@ -891,39 +882,32 @@ static inline int batch_search(
 }
 
 static inline int search_buffer(
-    Inspector* gadget, OtnxMatchData* omd, InspectionBuffer& buf,
-    InspectionBuffer::Type ibt, PmType pmt, PegCount& cnt)
+    Inspector* gadget, InspectionBuffer& buf, InspectionBuffer::Type ibt,
+    Packet* p, PortGroup* pg, PmType pmt, PegCount& cnt)
 {
-    if ( gadget->get_fp_buf(ibt, omd->p, buf) )
+    if ( gadget->get_fp_buf(ibt, p, buf) )
     {
         // Depending on where we are searching we call the appropriate mpse
-        if ( MpseGroup* so = omd->pg->mpsegrp[pmt] )
+        if ( MpseGroup* so = pg->mpsegrp[pmt] )
         {
             // FIXIT-H DELETE ME done - get the context packet number
             trace_logf(detection, TRACE_FP_SEARCH, "%" PRIu64 " fp %s.%s[%d]\n",
-                omd->p->context->packet_number, gadget->get_name(), pm_type_strings[pmt], buf.len);
+                p->context->packet_number, gadget->get_name(), pm_type_strings[pmt], buf.len);
 
-            batch_search(so, omd, buf.data, buf.len, cnt);
+            batch_search(so, p, buf.data, buf.len, cnt);
         }
     }
     return 0;
 }
 
-static int fp_search(
-    PortGroup* port_group, Packet* p, int check_ports, int type, OtnxMatchData* omd)
+static int fp_search(PortGroup* port_group, Packet* p)
 {
     Inspector* gadget = p->flow ? p->flow->gadget : nullptr;
     InspectionBuffer buf;
 
-    omd->pg = port_group;
-    omd->p = p;
-    omd->check_ports = check_ports;
-
-    bool user_mode = SnortConfig::get_conf()->sopgTable->user_mode;
-
     trace_log(detection, TRACE_RULE_EVAL, "Fast pattern search\n");
 
-    if ( (!user_mode or type < 2) and p->data and p->dsize )
+    if ( p->data and p->dsize )
     {
         // ports search raw packet only
         if ( MpseGroup* so = port_group->mpsegrp[PM_TYPE_PKT] )
@@ -933,32 +917,31 @@ static int fp_search(
                 trace_logf(detection, TRACE_FP_SEARCH, "%" PRIu64 " fp %s[%u]\n",
                     p->context->packet_number, pm_type_strings[PM_TYPE_PKT], pattern_match_size);
 
-                batch_search(so, omd, p->data, pattern_match_size, pc.pkt_searches);
+                batch_search(so, p, p->data, pattern_match_size, pc.pkt_searches);
                 p->is_cooked() ?  pc.cooked_searches++ : pc.raw_searches++;
             }
         }
     }
 
-    if ( (!user_mode or type == 1) and gadget )
+    if ( gadget )
     {
         // service searches PDU buffers and file
-        if ( search_buffer(gadget, omd, buf, buf.IBT_KEY, PM_TYPE_KEY, pc.key_searches) )
+        if ( search_buffer(gadget, buf, buf.IBT_KEY, p, port_group, PM_TYPE_KEY, pc.key_searches) )
             return 1;
 
-        if ( search_buffer(gadget, omd, buf, buf.IBT_HEADER, PM_TYPE_HEADER, pc.header_searches) )
+        if ( search_buffer(gadget, buf, buf.IBT_HEADER, p, port_group, PM_TYPE_HEADER, pc.header_searches) )
             return 1;
 
-        if ( search_buffer(gadget, omd, buf, buf.IBT_BODY, PM_TYPE_BODY, pc.body_searches) )
+        if ( search_buffer(gadget, buf, buf.IBT_BODY, p, port_group, PM_TYPE_BODY, pc.body_searches) )
             return 1;
 
         // 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
-        if ( search_buffer(gadget, omd, buf, buf.IBT_ALT, PM_TYPE_PKT, pc.alt_searches) )
+        if ( search_buffer(gadget, buf, buf.IBT_ALT, p, port_group, PM_TYPE_PKT, pc.alt_searches) )
             return 1;
     }
 
-    if ( !user_mode or type > 0 )
     {
         // file searches file only
         if ( MpseGroup* so = port_group->mpsegrp[PM_TYPE_FILE] )
@@ -972,7 +955,7 @@ static int fp_search(
                 trace_logf(detection, TRACE_FP_SEARCH, "%" PRIu64 " fp search %s[%d]\n",
                     p->context->packet_number, pm_type_strings[PM_TYPE_FILE], file_data.len);
 
-                batch_search(so, omd, file_data.data, file_data.len, pc.file_searches);
+                batch_search(so, p, file_data.data, file_data.len, pc.file_searches);
             }
         }
     }
@@ -980,8 +963,7 @@ static int fp_search(
 }
 
 static inline void eval_fp(
-    PortGroup* port_group, Packet* p, OtnxMatchData* omd, char ip_rule,
-    int check_ports, int type)
+    PortGroup* port_group, Packet* p, char ip_rule)
 {
     const uint8_t* tmp_payload = nullptr;
     uint16_t tmp_dsize = 0;
@@ -1009,7 +991,7 @@ static inline void eval_fp(
         FastPatternConfig* fp = SnortConfig::get_conf()->fast_pattern_config;
 
         if ( fp->get_stream_insert() || !(p->packet_flags & PKT_STREAM_INSERT) )
-            if ( fp_search(port_group, p, check_ports, type, omd) )
+            if ( fp_search(port_group, p) )
                 return;
     }
     if ( ip_rule )
@@ -1020,7 +1002,7 @@ static inline void eval_fp(
 }
 
 static inline void eval_nfp(
-    PortGroup* port_group, Packet* p, OtnxMatchData* omd, char ip_rule)
+    PortGroup* port_group, Packet* p, char ip_rule)
 {
     bool repeat = false;
     int8_t curr_ip_layer = 0;
@@ -1053,7 +1035,6 @@ static inline void eval_nfp(
 
             detection_option_eval_data_t eval_data;
 
-            eval_data.pomd = omd;
             eval_data.p = p;
             eval_data.pmd = nullptr;
             eval_data.flowbit_failed = 0;
@@ -1063,7 +1044,7 @@ static inline void eval_nfp(
             {
                 trace_log(detection, TRACE_RULE_EVAL, "Testing non-content rules\n");
                 rval = detection_option_tree_evaluate(
-                    (detection_option_tree_root_t*)port_group->nfp_tree, &eval_data);
+                    (detection_option_tree_root_t*)port_group->nfp_tree, eval_data);
             }
 
             if (rval)
@@ -1101,24 +1082,21 @@ static inline void eval_nfp(
 //  for non-content.  The otn list search will eventually be redone for
 //  for performance purposes.
 
-static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p,
-    int check_ports, char ip_rule, int type, OtnxMatchData* omd, FPTask task)
+static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p, char ip_rule, FPTask task)
 {
     if ( !p->is_detection_enabled(p->packet_flags & PKT_FROM_CLIENT) )
         return 0;
 
-    print_pkt_info(p);
-
     if ( task & FPTask::FP )
-        eval_fp(port_group, p, omd, ip_rule, check_ports, type);
+        eval_fp(port_group, p, ip_rule);
 
     if ( task & FPTask::NON_FP )
-        eval_nfp(port_group, p, omd, ip_rule);
+        eval_nfp(port_group, p, ip_rule);
 
     return 0;
 }
 
-static inline void fpEvalHeaderIp(Packet* p, OtnxMatchData* omd, FPTask task)
+static inline void fpEvalHeaderIp(Packet* p, FPTask task)
 {
     PortGroup* any = nullptr, * ip_group = nullptr;
 
@@ -1129,13 +1107,13 @@ static inline void fpEvalHeaderIp(Packet* p, OtnxMatchData* omd, FPTask task)
         LogMessage("fpEvalHeaderIp: ip_group=%p, any=%p\n", (void*)ip_group, (void*)any);
 
     if ( ip_group )
-        fpEvalHeaderSW(ip_group, p, 0, 1, 0, omd, task);
+        fpEvalHeaderSW(ip_group, p, 1, task);
 
     if ( any )
-        fpEvalHeaderSW(any, p, 0, 1, 0, omd, task);
+        fpEvalHeaderSW(any, p, 1, task);
 }
 
-static inline void fpEvalHeaderIcmp(Packet* p, OtnxMatchData* omd, FPTask task)
+static inline void fpEvalHeaderIcmp(Packet* p, FPTask task)
 {
     PortGroup* any = nullptr, * type = nullptr;
 
@@ -1143,13 +1121,13 @@ static inline void fpEvalHeaderIcmp(Packet* p, OtnxMatchData* omd, FPTask task)
         return;
 
     if ( type )
-        fpEvalHeaderSW(type, p, 0, 0, 0, omd, task);
+        fpEvalHeaderSW(type, p, 0, task);
 
     if ( any )
-        fpEvalHeaderSW(any, p, 0, 0, 0, omd, task);
+        fpEvalHeaderSW(any, p, 0, task);
 }
 
-static inline void fpEvalHeaderTcp(Packet* p, OtnxMatchData* omd, FPTask task)
+static inline void fpEvalHeaderTcp(Packet* p, FPTask task)
 {
     PortGroup* src = nullptr, * dst = nullptr, * any = nullptr;
 
@@ -1157,16 +1135,16 @@ static inline void fpEvalHeaderTcp(Packet* p, OtnxMatchData* omd, FPTask task)
         return;
 
     if ( dst )
-        fpEvalHeaderSW(dst, p, 1, 0, 0, omd, task);
+        fpEvalHeaderSW(dst, p, 0, task);
 
     if ( src )
-        fpEvalHeaderSW(src, p, 1, 0, 0, omd, task);
+        fpEvalHeaderSW(src, p, 0, task);
 
     if ( any )
-        fpEvalHeaderSW(any, p, 1, 0, 0, omd, task);
+        fpEvalHeaderSW(any, p, 0, task);
 }
 
-static inline void fpEvalHeaderUdp(Packet* p, OtnxMatchData* omd, FPTask task)
+static inline void fpEvalHeaderUdp(Packet* p, FPTask task)
 {
     PortGroup* src = nullptr, * dst = nullptr, * any = nullptr;
 
@@ -1174,49 +1152,37 @@ static inline void fpEvalHeaderUdp(Packet* p, OtnxMatchData* omd, FPTask task)
         return;
 
     if ( dst )
-        fpEvalHeaderSW(dst, p, 1, 0, 0, omd, task);
+        fpEvalHeaderSW(dst, p, 0, task);
 
     if ( src )
-        fpEvalHeaderSW(src, p, 1, 0, 0, omd, task);
+        fpEvalHeaderSW(src, p, 0, task);
 
     if ( any )
-        fpEvalHeaderSW(any, p, 1, 0, 0, omd, task);
+        fpEvalHeaderSW(any, p, 0, task);
 }
 
-static inline bool fpEvalHeaderSvc(Packet* p, OtnxMatchData* omd, SnortProtocolId proto_id, FPTask task)
+static inline bool fpEvalHeaderSvc(Packet* p, FPTask task)
 {
-    PortGroup* svc = nullptr, * file = nullptr;
+    PortGroup* svc = nullptr;
 
     SnortProtocolId snort_protocol_id = p->get_snort_protocol_id();
 
     if (snort_protocol_id != UNKNOWN_PROTOCOL_ID and snort_protocol_id != INVALID_PROTOCOL_ID)
     {
         if (p->is_from_server()) /* to cli */
-        {
-            svc = SnortConfig::get_conf()->sopgTable->get_port_group(proto_id, false, snort_protocol_id);
-            file = SnortConfig::get_conf()->sopgTable->get_port_group(proto_id, false, SNORT_PROTO_FILE);
-        }
+            svc = SnortConfig::get_conf()->sopgTable->get_port_group(false, snort_protocol_id);
 
         if (p->is_from_client()) /* to srv */
-        {
-            svc = SnortConfig::get_conf()->sopgTable->get_port_group(proto_id, true, snort_protocol_id);
-            file = SnortConfig::get_conf()->sopgTable->get_port_group(proto_id, true, SNORT_PROTO_FILE);
-        }
+            svc = SnortConfig::get_conf()->sopgTable->get_port_group(true, snort_protocol_id);
     }
-    // FIXIT-P put alert service rules with file data fp in alert file group and
-    // verify ports and service during rule eval to avoid searching file data 2x.
-    int check_ports = (proto_id == SNORT_PROTO_USER) ? 2 : 1;
-
-    if ( file )
-        fpEvalHeaderSW(file, p, check_ports, 0, 2, omd, task);
 
     if ( svc )
-        fpEvalHeaderSW(svc, p, check_ports, 0, 1, omd, task);
+        fpEvalHeaderSW(svc, p, 0, task);
 
     return svc != nullptr;
 }
 
-static void fpEvalPacketUdp(Packet* p, OtnxMatchData* omd, FPTask task)
+static void fpEvalPacketUdp(Packet* p, FPTask task)
 {
     uint16_t tmp_sp = p->ptrs.sp;
     uint16_t tmp_dp = p->ptrs.dp;
@@ -1243,7 +1209,7 @@ static void fpEvalPacketUdp(Packet* p, OtnxMatchData* omd, FPTask task)
     if ( p->dsize )
         DetectionEngine::enable_content(p);
 
-    fpEvalHeaderUdp(p, omd, task);
+    fpEvalHeaderUdp(p, task);
 
     // FIXIT-P Batch outer UDP payload searches for teredo set and the outer header
     // during any signature evaluation
@@ -1272,54 +1238,38 @@ static void fpEvalPacketUdp(Packet* p, OtnxMatchData* omd, FPTask task)
 */
 static void fpEvalPacket(Packet* p, FPTask task)
 {
-    OtnxMatchData* omd = p->context->otnx;
-
     /* Run UDP rules against the UDP header of Teredo packets */
     // FIXIT-L udph is always inner; need to check for outer
     if ( p->ptrs.udph && (p->proto_bits & (PROTO_BIT__TEREDO | PROTO_BIT__GTP)) )
-        fpEvalPacketUdp(p, omd, task);
+        fpEvalPacketUdp(p, task);
+
+    if ( p->get_snort_protocol_id() != UNKNOWN_PROTOCOL_ID and fpEvalHeaderSvc(p, task) )
+        return;
 
     switch (p->type())
     {
     case PktType::IP:
-        fpEvalHeaderIp(p, omd, task);
-        fpEvalHeaderSvc(p, omd, SNORT_PROTO_IP, task);
+        fpEvalHeaderIp(p, task);
         break;
 
     case PktType::ICMP:
-        fpEvalHeaderIcmp(p, omd, task);
-        fpEvalHeaderSvc(p, omd, SNORT_PROTO_ICMP, task);
+        fpEvalHeaderIcmp(p, task);
         break;
 
     case PktType::TCP:
-        fpEvalHeaderTcp(p, omd, task);
-        fpEvalHeaderSvc(p, omd, SNORT_PROTO_TCP, task);
+        fpEvalHeaderTcp(p, task);
         break;
 
     case PktType::UDP:
-        fpEvalHeaderUdp(p, omd, task);
-        fpEvalHeaderSvc(p, omd, SNORT_PROTO_UDP, task);
+        fpEvalHeaderUdp(p, task);
         break;
 
     case PktType::PDU:
         if ( p->proto_bits & PROTO_BIT__TCP )
-        {
-            if ( p->get_snort_protocol_id() == UNKNOWN_PROTOCOL_ID or !fpEvalHeaderSvc(p, omd, SNORT_PROTO_TCP, task) )
-                fpEvalHeaderTcp(p, omd, task);
-        }
-        else if ( p->proto_bits & PROTO_BIT__UDP )
-        {
-            if ( p->get_snort_protocol_id() == UNKNOWN_PROTOCOL_ID or !fpEvalHeaderSvc(p, omd, SNORT_PROTO_UDP, task) )
-                fpEvalHeaderUdp(p, omd, task);
-        }
-
-        if ( SnortConfig::get_conf()->sopgTable->user_mode )
-            fpEvalHeaderSvc(p, omd, SNORT_PROTO_USER, task);
+            fpEvalHeaderTcp(p, task);
 
-        break;
-
-    case PktType::FILE:
-        fpEvalHeaderSvc(p, omd, SNORT_PROTO_USER, task);
+        else if ( p->proto_bits & PROTO_BIT__UDP )
+            fpEvalHeaderUdp(p, task);
         break;
 
     default:
@@ -1339,6 +1289,7 @@ void fp_partial(Packet* p)
     c->searches.mf = rule_tree_queue;
     c->searches.context = c;
     assert(!c->searches.items.size());
+    print_pkt_info(p, "fast-patterns");
     fpEvalPacket(p, FPTask::FP);
 }
 
@@ -1356,6 +1307,7 @@ void fp_complete(Packet* p, bool search)
     {
         Profile rule_profile(rulePerfStats);
         stash->process(rule_tree_match, c);
+        print_pkt_info(p, "non-fast-patterns");
         fpEvalPacket(p, FPTask::NON_FP);
         fpFinalSelectEvent(c->otnx, p);
         c->searches.items.clear();
@@ -1384,18 +1336,18 @@ static void fp_immediate(Packet* p)
     }
 }
 
-static void fp_immediate(MpseGroup* so, OtnxMatchData* omd, const uint8_t* buf, unsigned len)
+static void fp_immediate(MpseGroup* so, Packet* p, const uint8_t* buf, unsigned len)
 {
-    MpseStash* stash = omd->p->context->stash;
+    MpseStash* stash = p->context->stash;
     {
         Profile mpse_profile(mpsePerfStats);
         int start_state = 0;
         stash->init();
-        so->get_normal_mpse()->search(buf, len, rule_tree_queue, omd->p->context, &start_state);
+        so->get_normal_mpse()->search(buf, len, rule_tree_queue, p->context, &start_state);
     }
     {
         Profile rule_profile(rulePerfStats);
-        stash->process(rule_tree_match, omd->p->context);
+        stash->process(rule_tree_match, p->context);
     }
 }
 
index a85c682363ddef20ab9040637a8bc8563e3b9511..8c2f3d9d9c80983756581b4dca64aa740f9f8f10 100644 (file)
@@ -85,16 +85,11 @@ struct MatchInfo
 */
 struct OtnxMatchData
 {
-    PortGroup* pg;
-    snort::Packet* p;
     MatchInfo* matchInfo;
-
-    int check_ports;
     bool have_match;
-    bool do_fp;
 };
 
-int fpAddMatch(OtnxMatchData*, int pLen, const OptTreeNode*);
+int fpAddMatch(OtnxMatchData*, const OptTreeNode*);
 
 void fp_set_context(snort::IpsContext&);
 void fp_clear_context(snort::IpsContext&);
index c9cf278df5ac5fb72ad4dce4b86c2562bce6a576..59f661fd77684e6c92c538ca8cbf24310a13e224 100644 (file)
@@ -358,13 +358,6 @@ PatternMatchVector get_fp_content(
     else
         exclude = false;
 
-    if ( best.pmd and otn->snort_protocol_id == SNORT_PROTO_FILE and best.cat != CAT_SET_FILE )
-    {
-        ParseWarning(WARN_RULES, "file rule %u:%u does not have file_data fast pattern",
-            otn->sigInfo.gid, otn->sigInfo.sid);
-        pmds.clear();
-    }
-
     if ( content && !best.pmd)
         ParseWarning(WARN_RULES, "content based rule %u:%u has no eligible fast pattern",
             otn->sigInfo.gid, otn->sigInfo.sid);
index ca9c54bc28363b6fae8597c706365aa1dbb7ae21..75745c5a233bd779222c937b04410602028146b8 100644 (file)
@@ -237,6 +237,22 @@ int CheckDstPortNotEq(Packet* p, RuleTreeNode* rtn_idx,
     return 0;
 }
 
+int CheckProto(Packet* p, RuleTreeNode* rtn_idx, RuleFpList*, int)
+{
+    assert(rtn_idx->snort_protocol_id < SNORT_PROTO_MAX);
+
+    const int proto_bits[SNORT_PROTO_MAX] =  // SNORT_PROTO_ to PROTO_BIT__*
+    {
+        /* n/a */  PROTO_BIT__NONE,
+        /* ip */   PROTO_BIT__IP | PROTO_BIT__TCP | PROTO_BIT__UDP,  // legacy
+        /* icmp */ PROTO_BIT__ICMP,
+        /* tcp */  PROTO_BIT__TCP | PROTO_BIT__PDU,
+        /* udp */  PROTO_BIT__UDP,
+        /* user */ PROTO_BIT__PDU
+    };
+    return proto_bits[rtn_idx->snort_protocol_id] & p->proto_bits;
+}
+
 int RuleListEnd(Packet*, RuleTreeNode*, RuleFpList*, int)
 {
     return 1;
index 870a888e50a0be99371708d91a35b7f34e72cbdc..7e4c5d6429ba1c8200cef77129e56ebe48b8f1e9 100644 (file)
@@ -34,8 +34,11 @@ int OptListEnd(void* option_data, class Cursor&, snort::Packet*);
 
 // detection
 int CheckBidirectional(snort::Packet*, RuleTreeNode*, RuleFpList*, int);
+
+int CheckProto(snort::Packet*, RuleTreeNode*, RuleFpList*, int);
 int CheckSrcIP(snort::Packet*, RuleTreeNode*, RuleFpList*, int);
 int CheckDstIP(snort::Packet*, RuleTreeNode*, RuleFpList*, int);
+
 int CheckSrcPortEqual(snort::Packet*, RuleTreeNode*, RuleFpList*, int);
 int CheckDstPortEqual(snort::Packet*, RuleTreeNode*, RuleFpList*, int);
 int CheckSrcPortNotEq(snort::Packet*, RuleTreeNode*, RuleFpList*, int);
index 5795b70b3d0ffcd1c0a8c87ef52afb4a2d843368..474aa08cf1a1e71eab2c98fbe4f724791228e3df 100644 (file)
@@ -71,11 +71,8 @@ srmm_table_t* ServiceMapNew()
 {
     srmm_table_t* table = (srmm_table_t*)snort_calloc(sizeof(srmm_table_t));
 
-    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; i++ )
-    {
-        table->to_srv[i] = alloc_srvmap();
-        table->to_cli[i] = alloc_srvmap();
-    }
+    table->to_srv = alloc_srvmap();
+    table->to_cli = alloc_srvmap();
 
     return table;
 }
@@ -85,14 +82,8 @@ void ServiceMapFree(srmm_table_t* table)
     if ( !table )
         return;
 
-    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; i++ )
-    {
-        if ( table->to_srv[i] )
-            free_srvmap(table->to_srv[i]);
-
-        if ( table->to_cli[i] )
-            free_srvmap(table->to_cli[i]);
-    }
+    free_srvmap(table->to_srv);
+    free_srvmap(table->to_cli);
 
     snort_free(table);
 }
@@ -123,11 +114,8 @@ srmm_table_t* ServicePortGroupMapNew()
 {
     srmm_table_t* table = (srmm_table_t*)snort_calloc(sizeof(srmm_table_t));
 
-    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; i++ )
-    {
-        table->to_srv[i] = alloc_spgmm();
-        table->to_cli[i] = alloc_spgmm();
-    }
+    table->to_srv = alloc_spgmm();
+    table->to_cli = alloc_spgmm();
 
     return table;
 }
@@ -137,14 +125,8 @@ void ServicePortGroupMapFree(srmm_table_t* table)
     if ( !table )
         return;
 
-    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; i++ )
-    {
-        if ( table->to_srv[i] )
-            free_spgmm(table->to_srv[i]);
-
-        if ( table->to_cli[i] )
-            free_spgmm(table->to_cli[i]);
-    }
+    free_spgmm(table->to_srv);
+    free_spgmm(table->to_cli);
 
     snort_free(table);
 }
@@ -163,25 +145,14 @@ void ServicePortGroupMapFree(srmm_table_t* table)
  */
 static void ServiceMapAddOtnRaw(GHash* table, const char* servicename, OptTreeNode* otn)
 {
-    SF_LIST* list;
-
-    list = (SF_LIST*)ghash_find(table, servicename);
+    SF_LIST* list = (SF_LIST*)ghash_find(table, servicename);
 
     if ( !list )
     {
-        /* create the list */
         list = sflist_new();
-        if ( !list )
-            FatalError("service_rule_map: could not create a  service rule-list\n");
-
-        /* add the service list to the table */
-        if ( ghash_add(table, servicename, list) != GHASH_OK )
-        {
-            FatalError("service_rule_map: could not add a rule to the rule-service-map\n");
-        }
+        ghash_add(table, servicename, list);
     }
 
-    /* add the rule */
     sflist_add_tail(list, otn);
 }
 
@@ -191,21 +162,15 @@ static void ServiceMapAddOtnRaw(GHash* table, const char* servicename, OptTreeNo
  *  service name.
  */
 static int ServiceMapAddOtn(
-    srmm_table_t* srmm, SnortProtocolId proto_id, const char* servicename, OptTreeNode* otn)
+    srmm_table_t* srmm, SnortProtocolId, const char* servicename, OptTreeNode* otn)
 {
     assert(servicename and otn);
 
-    if ( proto_id > SNORT_PROTO_USER )
-        proto_id = SNORT_PROTO_USER;
-
-    GHash* to_srv = srmm->to_srv[proto_id];
-    GHash* to_cli = srmm->to_cli[proto_id];
-
     if ( !OtnFlowFromClient(otn) )
-        ServiceMapAddOtnRaw(to_cli, servicename, otn);
+        ServiceMapAddOtnRaw(srmm->to_cli, servicename, otn);
 
     if ( !OtnFlowFromServer(otn) )
-        ServiceMapAddOtnRaw(to_srv, servicename, otn);
+        ServiceMapAddOtnRaw(srmm->to_srv, servicename, otn);
 
     return 0;
 }
@@ -216,14 +181,11 @@ void fpPrintServicePortGroupSummary(SnortConfig* sc)
     LogMessage("| Service-PortGroup Table Summary \n");
     LogMessage("---------------------------------\n");
 
-    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; i++ )
-    {
-        if ( unsigned n = sc->spgmmTable->to_srv[i]->count )
-            LogMessage("| %s to server   : %d services\n", sc->proto_ref->get_name(i), n);
+    if ( unsigned n = sc->spgmmTable->to_srv->count )
+        LogMessage("| server   : %d services\n", n);
 
-        if ( unsigned n = sc->spgmmTable->to_cli[i]->count )
-            LogMessage("| %s to client   : %d services\n", sc->proto_ref->get_name(i), n);
-    }
+    if ( unsigned n = sc->spgmmTable->to_cli->count )
+        LogMessage("| client   : %d services\n", n);
 
     LogMessage("---------------------------------\n");
 }
@@ -280,23 +242,16 @@ int fpCreateServiceMaps(SnortConfig* sc)
 
 sopg_table_t::sopg_table_t(unsigned n)
 {
-    for ( int i = SNORT_PROTO_IP; i < SNORT_PROTO_MAX; ++i )
-    {
-        if ( to_srv[i].size() < n )
-            to_srv[i].resize(n, nullptr);
+    if ( to_srv.size() < n )
+        to_srv.resize(n, nullptr);
 
-        if ( to_cli[i].size() < n )
-            to_cli[i].resize(n, nullptr);
-    }
-    user_mode = false;
+    if ( to_cli.size() < n )
+        to_cli.resize(n, nullptr);
 }
 
-PortGroup* sopg_table_t::get_port_group(
-    SnortProtocolId proto_id, bool c2s, SnortProtocolId snort_protocol_id)
+PortGroup* sopg_table_t::get_port_group(bool c2s, SnortProtocolId snort_protocol_id)
 {
-    assert(proto_id < SNORT_PROTO_MAX);
-
-    PortGroupVector& v = c2s ? to_srv[proto_id] : to_cli[proto_id];
+    PortGroupVector& v = c2s ? to_srv : to_cli;
 
     if ( snort_protocol_id >= v.size() )
         return nullptr;
@@ -304,25 +259,3 @@ PortGroup* sopg_table_t::get_port_group(
     return v[snort_protocol_id];
 }
 
-bool sopg_table_t::set_user_mode()
-{
-    for ( auto* p : to_srv[SNORT_PROTO_USER] )
-    {
-        if ( p )
-        {
-            user_mode = true;
-            return true;
-        }
-    }
-
-    for ( auto* p : to_cli[SNORT_PROTO_USER] )
-    {
-        if ( p )
-        {
-            user_mode = true;
-            break;
-        }
-    }
-    return user_mode;
-}
-
index 6ab53a094b25d3069de862cd3d13e6c2fb4b360d..6304d61d93209710001108bf4a9e72a22ac8e168 100644 (file)
@@ -42,8 +42,8 @@ struct PortGroup;
 //  Service Rule Map Master Table
 struct srmm_table_t
 {
-    snort::GHash* to_srv[SNORT_PROTO_MAX];
-    snort::GHash* to_cli[SNORT_PROTO_MAX];
+    snort::GHash* to_srv;
+    snort::GHash* to_cli;
 };
 
 srmm_table_t* ServiceMapNew();
@@ -61,13 +61,10 @@ typedef std::vector<PortGroup*> PortGroupVector;
 struct sopg_table_t
 {
     sopg_table_t(unsigned size);
-    bool set_user_mode();
-    PortGroup* get_port_group(SnortProtocolId proto_id, bool c2s, SnortProtocolId snort_protocol_id);
+    PortGroup* get_port_group(bool c2s, SnortProtocolId svc);
 
-    PortGroupVector to_srv[SNORT_PROTO_MAX];
-    PortGroupVector to_cli[SNORT_PROTO_MAX];
-
-    bool user_mode;
+    PortGroupVector to_srv;
+    PortGroupVector to_cli;
 };
 
 
index 26ae256afa3ea8c0f8cae30be8d12e7e8fcaeedf..c582f1be979033df25d272007001c931b82311bb 100644 (file)
@@ -99,6 +99,7 @@ struct RuleTreeNode
     static constexpr Flag BIDIRECTIONAL = 0x10;
     static constexpr Flag ANY_SRC_IP    = 0x20;
     static constexpr Flag ANY_DST_IP    = 0x40;
+    static constexpr Flag USER_MODE     = 0x80;
 
     RuleFpList* rule_func = nullptr; /* match functions.. (Bidirectional etc.. ) */
 
@@ -127,7 +128,10 @@ struct RuleTreeNode
     { flags &= (~ENABLED); }
 
     bool enabled() const
-    { return flags & ENABLED; }
+    { return (flags & ENABLED) != 0; }
+
+    bool user_mode()
+    { return (flags & USER_MODE) != 0; }
 };
 
 // one of these for each rule
index 6410ba3e1dd39c7ded76a656aafa372708176a3c..2fcdb49f58ac21ec2ac2ad2d7c32c8e8da400f74 100644 (file)
@@ -237,6 +237,20 @@ void ParseIpVar(SnortConfig* sc, const char* var, const char* val)
 
 void add_service_to_otn(SnortConfig* sc, OptTreeNode* otn, const char* svc_name)
 {
+    if ( !strcmp(svc_name, "file") and !otn->sigInfo.num_services )
+    {
+        // 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");
+        add_service_to_otn(sc, otn, "user");
+        return;
+    }
+
     if (otn->sigInfo.num_services >= sc->max_metadata_services)
     {
         ParseError("too many service's specified for rule, can't add %s", svc_name);
index 11aed247033c1c6a9de4ce1c0be9f735304328ba..11da6a321e4db70c9baa137f4d6a72335639b55e 100644 (file)
@@ -567,7 +567,7 @@ static int ParsePortList(
     PortObject* portobject;  /* src or dst */
 
     /* Get the protocol specific port object */
-    if ( rule_proto & (PROTO_BIT__TCP | PROTO_BIT__UDP) )
+    if ( rule_proto & (PROTO_BIT__TCP | PROTO_BIT__UDP | PROTO_BIT__PDU) )
     {
         portobject = ParsePortListTcpUdpPort(pvt, noname, port_str);
     }
@@ -789,9 +789,8 @@ static void PortToFunc(RuleTreeNode* rtn, int any_flag, int except_flag, int mod
 static void SetupRTNFuncList(RuleTreeNode* rtn)
 {
     if (rtn->flags & RuleTreeNode::BIDIRECTIONAL)
-    {
         AddRuleFuncToList(CheckBidirectional, rtn);
-    }
+
     else
     {
         PortToFunc(rtn, (rtn->flags & RuleTreeNode::ANY_DST_PORT) ? 1 : 0, 0, DST);
@@ -801,6 +800,9 @@ static void SetupRTNFuncList(RuleTreeNode* rtn)
         AddrToFunc(rtn, DST);
     }
 
+    if ( rtn->snort_protocol_id < SNORT_PROTO_MAX )
+        AddRuleFuncToList(CheckProto, rtn);
+
     AddRuleFuncToList(RuleListEnd, rtn);
 }
 
@@ -1019,7 +1021,7 @@ void parse_rule_proto(SnortConfig* sc, const char* s, RuleTreeNode& rtn)
 
     else
         // this will allow other protocols like http to have ports
-        rule_proto = PROTO_BIT__TCP;
+        rule_proto = PROTO_BIT__PDU;
 
     rtn.snort_protocol_id = sc->proto_ref->add(s);
 
index d48b33e78259d77604a45eebb348a3d14642deb1..98102b5248cd789888e64e73e80a394aa24dd7e2 100644 (file)
@@ -113,7 +113,6 @@ void ProtocolReference::init(ProtocolReference* old_proto_ref)
         ok = ( add("tcp") == SNORT_PROTO_TCP ) and ok;
         ok = ( add("udp") == SNORT_PROTO_UDP ) and ok;
         ok = ( add("user") == SNORT_PROTO_USER ) and ok;
-        ok = ( add("file") == SNORT_PROTO_FILE ) and ok;
         assert(ok);
     }
     else
index 66f3cab30c301dc598beb841aaf1f0a4eb87b920..232a8c823273e546512a05d936553af70828b81f 100644 (file)
@@ -41,7 +41,6 @@ enum SnortProtocols : SnortProtocolId
     SNORT_PROTO_TCP,
     SNORT_PROTO_UDP,
     SNORT_PROTO_USER,
-    SNORT_PROTO_FILE,
     SNORT_PROTO_MAX
 };
 
index 2bc480356af9518bd72ec334f674fda25f3a72ab..7e9a3e46c3526727c0fe8d5c0994bd0401e14fdc 100644 (file)
@@ -78,7 +78,7 @@ TEST(protocol_reference, service_protocols)
     CHECK( is_service_protocol(t3) );
 }
 
-// Builtin Protocols (ip, icmp, tcp, udp, user and file)
+// Builtin Protocols (ip, icmp, tcp, udp, user)
 //
 // Verify normal behaviour of the builtin protocols.
 //   1. Check the builtin protocols match the hardcoded ID's
@@ -125,12 +125,6 @@ TEST(protocol_reference, builtin_protocols)
     CHECK( !is_network_protocol(user) );
     CHECK( is_builtin_protocol(user) );
     CHECK( is_service_protocol(user) );
-
-    SnortProtocolId file = refs.add("file");
-    CHECK( file == SNORT_PROTO_FILE );
-    CHECK( !is_network_protocol(file) );
-    CHECK( is_builtin_protocol(file) );
-    CHECK( is_service_protocol(file) );
 }
 
 // Find none