]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2247 in SNORT/snort3 from ~OKHOMIAK/snort3:ips_policy_rule_stats...
authorSteve Chew (stechew) <stechew@cisco.com>
Mon, 15 Jun 2020 14:44:56 +0000 (14:44 +0000)
committerSteve Chew (stechew) <stechew@cisco.com>
Mon, 15 Jun 2020 14:44:56 +0000 (14:44 +0000)
Squashed commit of the following:

commit 198b1151d099bb06de1b7f6db04f81d7f73516cc
Author: Oleksii Khomiakovskyi <okhomiak@cisco.com>
Date:   Wed Jun 10 01:11:07 2020 +0300

    detection: do not apply global rule state to the empty policy

commit 0eba4fd76439efa586eb84e3d12a015501fe3cc8
Author: Oleksii Khomiakovskyi <okhomiak@cisco.com>
Date:   Fri Jun 5 01:09:01 2020 +0300

    parser: print loaded and shared rules for each ips policy

src/detection/rules.cc
src/main/policy.h
src/parser/parse_rule.cc
src/parser/parse_rule.h
src/parser/parser.cc

index 1c39b1a66375aad7f33dabf636550f6a90278380..8317d500dabc2eb169ed912544ab113df3d4b026 100644 (file)
@@ -60,6 +60,7 @@ void RuleStateMap::apply(SnortConfig* sc)
     {
         const RuleKey& k = it.first;
         OptTreeNode* otn = OtnLookup(sc->otn_map, k.gid, k.sid);
+        auto empty_ips_id = get_empty_ips_policy(sc)->policy_id;
 
         if ( !otn )
             ParseWarning(WARN_RULES, "Rule state specified for unknown rule %u:%u", k.gid, k.sid);
@@ -69,7 +70,8 @@ void RuleStateMap::apply(SnortConfig* sc)
             {
                 for ( unsigned i = 0; i < sc->policy_map->ips_policy_count(); i++ )
                 {
-                    if ( sc->policy_map->get_ips_policy(i) )
+                    auto policy = sc->policy_map->get_ips_policy(i);
+                    if ( policy and (policy->policy_id != empty_ips_id) )
                         apply(sc, otn, i, it.second);
                 }
             }
@@ -82,14 +84,19 @@ void RuleStateMap::apply(SnortConfig* sc)
 void RuleStateMap::apply(
     SnortConfig* sc, OptTreeNode* otn, unsigned ips_num, RuleState& s)
 {
+    IpsPolicy* policy = nullptr;
     RuleTreeNode* rtn = getRtnFromOtn(otn, ips_num);
 
     if ( !rtn )
-        rtn = getRtnFromOtn(otn, 0);
+        if ( ips_num and (rtn = getRtnFromOtn(otn, 0)) )
+            policy = sc->policy_map->get_ips_policy(ips_num);
 
     if ( !rtn )
         return;
 
+    if ( policy )
+        policy->rules_shared++;
+
     rtn = dup_rtn(rtn);
     update_rtn(rtn, s);
     addRtnToOtn(sc, otn, rtn, ips_num);
index 78e56b9e001da30f83995c4f94d1269d830b9687..25c7567d2795f5eac018964ed0353f92ae718fd5 100644 (file)
@@ -163,6 +163,8 @@ public:
 
     PolicyMode policy_mode = POLICY_MODE__MAX;
     bool enable_builtin_rules;
+    int rules_loaded = 0;
+    int rules_shared = 0;
 
     std::string includer;
     std::string include;
index fa212ff47f43568216674b744aa02a6b584442cf..68b815b447293253ce09cbb4469e3c5a1a75b7e4 100644 (file)
@@ -68,6 +68,7 @@ struct rule_count_t
 };
 
 static int rule_count = 0;
+static int prev_rule_count = 0;
 static int skip_count = 0;
 static int detect_rule_count = 0;
 static int builtin_rule_count = 0;
@@ -75,6 +76,7 @@ static int so_rule_count = 0;
 static int head_count = 0;          // rule headers
 static int otn_count = 0;           // rule bodies
 static int dup_count = 0;           // rule bodies
+static int prev_dup_count = 0;
 static int rule_proto = 0;
 
 static rule_count_t tcpCnt;
@@ -866,9 +868,24 @@ int get_rule_count()
 { return rule_count; }
 }
 
+int get_policy_loaded_rule_count()
+{
+    auto policy_rule_count = rule_count - prev_rule_count;
+    prev_rule_count = rule_count;
+    return policy_rule_count;
+}
+
+int get_policy_shared_rule_count()
+{
+    auto policy_rule_count = dup_count - prev_dup_count;
+    prev_dup_count = dup_count;
+    return policy_rule_count;
+}
+
 void parse_rule_init()
 {
     rule_count = 0;
+    prev_rule_count = 0;
     skip_count = 0;
     detect_rule_count = 0;
     builtin_rule_count = 0;
@@ -876,6 +893,7 @@ void parse_rule_init()
     head_count = 0;
     otn_count = 0;
     dup_count = 0;
+    prev_dup_count = 0;
     rule_proto = 0;
 
     memset(&ipCnt, 0, sizeof(ipCnt));
index 8c0480d2544df93d96137e11a0ee8b0a86ebf647..e9e1b81bd005eae07e1a105d7deb1fa889e030ea 100644 (file)
@@ -35,6 +35,8 @@ struct RuleTreeNode;
 void parse_rule_init();
 void parse_rule_term();
 void parse_rule_print();
+int get_policy_loaded_rule_count();
+int get_policy_shared_rule_count();
 
 void parse_rule_type(snort::SnortConfig*, const char*, RuleTreeNode&);
 void parse_rule_proto(snort::SnortConfig*, const char*, RuleTreeNode&);
index 7993e1660fc062e580d74eb98ad819ee53fe53e2..5c1d4e5bf3341dea9df7dcbc6d7e6d9af6179fde 100644 (file)
@@ -122,6 +122,14 @@ public:
     }
 };
 
+struct PolicyRuleStats
+{
+    const char* file;
+    int loaded;
+    int shared;
+    int enabled;
+};
+
 //-------------------------------------------------------------------------
 // private / implementation methods
 //-------------------------------------------------------------------------
@@ -447,6 +455,9 @@ void ParseRules(SnortConfig* sc)
             parse_stream(std::cin, sc);
             pop_parse_location();
         }
+
+        p->rules_loaded = get_policy_loaded_rule_count();
+        p->rules_shared = get_policy_shared_rule_count();
     }
 
     set_ips_policy(sc, 0);
@@ -460,7 +471,7 @@ void ParseRules(SnortConfig* sc)
 void ShowPolicyStats(const SnortConfig* sc)
 {
     std::unordered_map<PolicyId, int> stats;
-    std::multimap<PolicyId, std::tuple<const char*, int>> sorted_stats;
+    std::multimap<PolicyId, PolicyRuleStats> sorted_stats;
 
     if ( !sc->otn_map )
         return;
@@ -480,9 +491,13 @@ void ShowPolicyStats(const SnortConfig* sc)
         }
     }
 
-    for (const auto& s : stats)
+    for (unsigned i = 0; i < sc->policy_map->ips_policy_count(); i++)
     {
-        auto shell = sc->policy_map->get_shell_by_policy(s.first);
+        auto policy = sc->policy_map->get_ips_policy(i);
+        if ( !policy )
+            continue;
+
+        auto shell = sc->policy_map->get_shell_by_policy(i);
         if ( !shell )
             continue;
 
@@ -490,24 +505,27 @@ void ShowPolicyStats(const SnortConfig* sc)
         if ( !file or !file[0] )
             continue;
 
-        auto policy = sc->policy_map->get_ips_policy(s.first);
-        auto id = policy ? policy->user_policy_id : 0;
+        auto id = policy->user_policy_id;
+        auto rules_loaded = policy->rules_loaded;
+        auto rules_shared = policy->rules_shared;
+
+        auto res = stats.find(i);
+        auto rules_enabled = (res == stats.end()) ? 0 : res->second;
 
-        sorted_stats.emplace(id, std::make_tuple(file, s.second));
+        if ( rules_loaded or rules_shared or rules_enabled )
+            sorted_stats.emplace(id, PolicyRuleStats{file, rules_loaded,
+                rules_shared, rules_enabled});
     }
 
     if ( !sorted_stats.size() )
         return;
 
-    LogLabel("ips policies");
-    LogMessage("%16s%16s%8s\n", "id", "rules enabled", "file");
+    LogLabel("ips policies rule stats");
+    LogMessage("%16s%8s%8s%8s%8s\n", "id", "loaded", "shared", "enabled", "file");
 
     for (const auto& s : sorted_stats)
-    {
-        auto file = std::get<0>(s.second);
-        auto rules_count = std::get<1>(s.second);
-        LogMessage("%16u%16d%4s%s\n", s.first, rules_count, " ", file);
-    }
+        LogMessage("%16u%8d%8d%8d%4s%s\n", s.first, s.second.loaded, s.second.shared,
+            s.second.enabled, " ", s.second.file);
 }
 
 /****************************************************************************