]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #309 in SNORT/snort3 from host_tracker_stats3 to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Wed, 2 Mar 2016 18:25:51 +0000 (13:25 -0500)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Wed, 2 Mar 2016 18:25:51 +0000 (13:25 -0500)
Squashed commit of the following:

commit abba8b36baa782641691a4fd1186611e5f3f21da
Author: Steve Chew <stechew@cisco.com>
Date:   Tue Mar 1 16:51:02 2016 -0500

    Made target_link_libraries more readable.

commit ca7389694b473b71b96849cb5927c55c35d54aaa
Author: Steve Chew <stechew@cisco.com>
Date:   Tue Mar 1 16:42:33 2016 -0500

    Fix finding of library for host_tracker test in ccmake.

commit 86a969c109a40ada599c6a591afe1a605e71b207
Author: Steve Chew <stechew@cisco.com>
Date:   Mon Feb 29 15:04:42 2016 -0500

    Updates baesd on reviews.

commit 81f126cbc8e5eb55be2a675a97e05a823a0d0d9d
Author: Steve Chew <stechew@cisco.com>
Date:   Fri Feb 26 13:40:30 2016 -0500

    Fixes based on reviews.

commit e8e49232e68581003fc9c5215e7a5c5971e4b1ab
Author: Steve Chew <stechew@cisco.com>
Date:   Fri Feb 19 13:31:29 2016 -0500

    Add statistics counters to host_tracker module.

src/host_tracker/CMakeLists.txt
src/host_tracker/Makefile.am
src/host_tracker/host_cache.h
src/host_tracker/host_module.cc
src/host_tracker/host_module.h
src/host_tracker/host_tracker.cc [new file with mode: 0644]
src/host_tracker/host_tracker.h
src/host_tracker/test/CMakeLists.txt [new file with mode: 0644]
src/host_tracker/test/Makefile.am
src/host_tracker/test/host_cache_test.cc
src/host_tracker/test/host_module_test.cc [new file with mode: 0644]

index fc3d43ef08d7412320fdc5122e5f180b2f0bda5c..2d5d29b399b69f7765eb0d2b86bf5d5925c0065a 100644 (file)
@@ -4,5 +4,6 @@ add_library( host_tracker STATIC
     host_cache.h
     host_module.cc
     host_module.h
+    host_tracker.cc
     host_tracker.h
 )
index 317c6ec37fcb299d81b1ac5b9332848a26ccba5e..9a2460fe8d210a625fe9b402e9aeb3104914f68e 100644 (file)
@@ -6,6 +6,7 @@ host_cache.cc \
 host_cache.h \
 host_module.cc \
 host_module.h \
+host_tracker.cc \
 host_tracker.h
 
 if BUILD_UNIT_TESTS
index 3655afeac299cc543150187f7c3a6ab78748e574..6cea2fcb311ab1e7f5307da132e8fa7a2d27fe3c 100644 (file)
 #include "hash/lru_cache_shared.h"
 #include "main/snort_types.h"
 
+
 struct HostIpKey
 {
     static const int key_size = 16;
-    uint8_t ip_addr[key_size] { 0 }; //  Holds either IPv4 or IPv6 addr
+    union host_ip_addr
+    {
+        uint8_t ip8[key_size];
+        uint64_t ip64[key_size/8];
+    } ip_addr = {{0}}; //  Holds either IPv4 or IPv6 addr
 
     HostIpKey()
     {
     }
 
-    HostIpKey(uint8_t ip[key_size])
+    HostIpKey(const uint8_t ip[key_size])
     {
-        memcpy(ip_addr, ip, key_size);
+        memcpy(&ip_addr, ip, key_size);
     }
 
     inline bool operator==(const HostIpKey& rhs) const
     {
-        return !memcmp(ip_addr, rhs.ip_addr, key_size);
+        return !memcmp(&ip_addr, &rhs.ip_addr, key_size);
     }
 };
 
@@ -54,8 +59,8 @@ struct HashHostIpKey
 {
     size_t operator()(const HostIpKey& ip) const
     {
-        return std::hash<long long>() (*((long long*)&ip.ip_addr[0])) ^
-               std::hash<long long>() (*((long long*)&ip.ip_addr[8]));
+        return std::hash<uint64_t>() (ip.ip_addr.ip64[0]) ^
+               std::hash<uint64_t>() (ip.ip_addr.ip64[1]);
     }
 };
 
index eefdaa50ac7b2dbcc46b17eb6e8467c03f3372ac..dae6157ee8e9e5353f7d4cb23755de56e2f645d9 100644 (file)
 #include "stream/stream_api.h"
 #include "target_based/snort_protocols.h"
 
+const PegInfo host_tracker_pegs[] =
+{
+    { "service adds", "host service adds" },
+    { "service finds", "host service finds" },
+    { "service removes", "host service removes" },
+    { nullptr, nullptr },
+};
+
 const Parameter HostTrackerModule::service_params[] =
 {
     { "name", Parameter::PT_STRING, nullptr, nullptr,
@@ -108,3 +116,9 @@ bool HostTrackerModule::end(const char* fqn, int idx, SnortConfig*)
     return true;
 }
 
+const PegInfo* HostTrackerModule::get_pegs() const
+{ return host_tracker_pegs; }
+
+PegCount* HostTrackerModule::get_counts() const
+{ return (PegCount*)&host_tracker_stats; }
+
index fc6f90755378ccc03c3f569fe004e5e5d48a31c7..61f31d83716686d761f26817ba8cc1d0914c0524 100644 (file)
@@ -47,6 +47,9 @@ public:
         assert(!host);
     }
 
+    const PegInfo* get_pegs() const override;
+    PegCount* get_counts() const override;
+
     bool set(const char*, Value&, SnortConfig*) override;
     bool begin(const char*, int, SnortConfig*) override;
     bool end(const char*, int, SnortConfig*) override;
diff --git a/src/host_tracker/host_tracker.cc b/src/host_tracker/host_tracker.cc
new file mode 100644 (file)
index 0000000..862fb0c
--- /dev/null
@@ -0,0 +1,24 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2016 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// host_tracker.cc author Steve Chew <stechew@cisco.com>
+
+#include "host_tracker/host_tracker.h"
+
+THREAD_LOCAL struct HostTrackerStats host_tracker_stats;
+
index c56f23c41851d233a7d95ce62ebacc68e58ead82..3d10b4dfbc7bc6d77136acc315e10cef6c6bda08 100644 (file)
@@ -32,6 +32,8 @@
 #include <algorithm>
 
 #include "sfip/sfip_t.h"
+#include "framework/counts.h"
+#include "main/thread.h"
 
 //  FIXIT-H -- For now this emulates the Snort++ attribute table. Need
 //             to add in sfrnaincludes/host_tracker.h data eventually.
@@ -40,6 +42,15 @@ typedef uint16_t Port;
 typedef uint16_t Protocol;
 typedef uint8_t Policy;
 
+struct HostTrackerStats
+{
+    PegCount service_adds;
+    PegCount service_finds;
+    PegCount service_removes;
+};
+
+extern THREAD_LOCAL struct HostTrackerStats host_tracker_stats;
+
 struct HostApplicationEntry
 {
     Port port = 0;
@@ -127,6 +138,8 @@ public:
     //  false if entry exists already, and true if entry was added.
     bool add_service(const HostApplicationEntry& app_entry)
     {
+        host_tracker_stats.service_adds++;
+
         std::lock_guard<std::mutex> lck(host_tracker_lock);
 
         auto iter = std::find(services.begin(), services.end(), app_entry);
@@ -141,6 +154,8 @@ public:
     //  replace the previous entry with the new entry.
     void add_or_replace_service(const HostApplicationEntry& app_entry)
     {
+        host_tracker_stats.service_adds++;
+
         std::lock_guard<std::mutex> lck(host_tracker_lock);
 
         auto iter = std::find(services.begin(), services.end(), app_entry);
@@ -155,6 +170,7 @@ public:
     bool find_service(Protocol ipproto, Port port, HostApplicationEntry& app_entry)
     {
         HostApplicationEntry tmp_entry(ipproto, port, HostApplicationEntry::UNKNOWN_PROTOCOL);
+        host_tracker_stats.service_finds++;
 
         std::lock_guard<std::mutex> lck(host_tracker_lock);
 
@@ -173,6 +189,7 @@ public:
     bool remove_service(Protocol ipproto, Port port)
     {
         HostApplicationEntry tmp_entry(ipproto, port, HostApplicationEntry::UNKNOWN_PROTOCOL);
+        host_tracker_stats.service_removes++;
 
         std::lock_guard<std::mutex> lck(host_tracker_lock);
 
diff --git a/src/host_tracker/test/CMakeLists.txt b/src/host_tracker/test/CMakeLists.txt
new file mode 100644 (file)
index 0000000..83ed281
--- /dev/null
@@ -0,0 +1,12 @@
+
+
+add_cpputest(host_cache_test host_tracker)
+add_cpputest(host_module_test host_tracker)
+add_cpputest(host_tracker_test host_tracker)
+
+target_link_libraries(host_module_test
+    ${CMAKE_BINARY_DIR}/src/framework/libframework.a
+    ${CMAKE_BINARY_DIR}/src/catch/libcatch_tests.a
+    ${CMAKE_BINARY_DIR}/src/sfip/libsfip.a
+    ${DNET_LIBRARIES})
+
index fd435224fe60936933971664df201c1888d8a2a1..a0c5a01a6c053339a3dc14893898486a33fb4dd3 100644 (file)
@@ -2,14 +2,17 @@
 AM_DEFAULT_SOURCE_EXT = .cc
 
 check_PROGRAMS = \
+host_module_test \
 host_cache_test \
 host_tracker_test
 
 TESTS = $(check_PROGRAMS)
 
+host_module_test_CPPFLAGS = @AM_CPPFLAGS@ @CPPUTEST_CPPFLAGS@
 host_cache_test_CPPFLAGS = @AM_CPPFLAGS@ @CPPUTEST_CPPFLAGS@
 host_tracker_test_CPPFLAGS = @AM_CPPFLAGS@ @CPPUTEST_CPPFLAGS@
 
-host_cache_test_LDADD = ../host_cache.o  @CPPUTEST_LDFLAGS@
-host_tracker_test_LDADD = @CPPUTEST_LDFLAGS@
+host_module_test_LDADD = ../host_module.o ../host_cache.o ../host_tracker.o ../../framework/libframework.a ../../catch/libcatch_tests.a ../../sfip/libsfip.a ../../utils/libutils.a  @CPPUTEST_LDFLAGS@
+host_cache_test_LDADD = ../host_cache.o ../host_tracker.o  @CPPUTEST_LDFLAGS@
+host_tracker_test_LDADD = ../host_tracker.o @CPPUTEST_LDFLAGS@
 
index f8054ad1ea224bc99ed881b812abeb8ba57b7da7..d37eb8050005b8ad7439fbef9e49488b0b63c5a3 100644 (file)
@@ -43,7 +43,7 @@ TEST(host_cache, host_ip_key_test)
     uint8_t expected_hk[16] =
     { 0xde,0xad,0xbe,0xef,0xab,0xcd,0xef,0x01,0x23,0x34,0x56,0x78,0x90,0xab,0xcd,0xef };
 
-    memset(zeroed_hk.ip_addr, 0, sizeof(zeroed_hk.ip_addr));
+    memset(&zeroed_hk.ip_addr, 0, sizeof(zeroed_hk.ip_addr));
 
     HostIpKey hkey1;
     CHECK(hkey1 == zeroed_hk);
diff --git a/src/host_tracker/test/host_module_test.cc b/src/host_tracker/test/host_module_test.cc
new file mode 100644 (file)
index 0000000..0d76e50
--- /dev/null
@@ -0,0 +1,162 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2016 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// host_module_test.cc author Steve Chew <stechew@cisco.com>
+// unit tests for the host module APIs
+
+#include "host_tracker/host_module.h"
+
+#include <CppUTest/CommandLineTestRunner.h>
+#include <CppUTest/TestHarness.h>
+
+#include "host_tracker/host_cache.h"
+#include "sfip/sf_ip.h"
+
+//  Fake AddProtocolReference to avoid bringing in a ton of dependencies.
+int16_t AddProtocolReference(const char* protocol)
+{
+    if (!strcmp("servicename", protocol))
+        return 3;
+    if (!strcmp("tcp", protocol))
+        return 2;
+    return 1;
+}
+
+//  Fake show_stats to avoid bringing in a ton of dependencies.
+void show_stats(
+    PegCount* , const PegInfo* , unsigned , const char* )
+{
+}
+
+#define FRAG_POLICY 33
+#define STREAM_POLICY 100
+
+sfip_t expected_addr;
+
+TEST_GROUP(host_module)
+{
+    void setup()
+    {
+        Value ip_val("10.23.45.56");
+        Value frag_val((double)FRAG_POLICY);
+        Value tcp_val((double)STREAM_POLICY);
+        Value name_val("servicename");
+        Value proto_val("udp");
+        Value port_val((double)2112);
+        Parameter ip_param = { "ip", Parameter::PT_ADDR, nullptr, "0.0.0.0/32", "addr/cidr"};
+        Parameter frag_param = { "frag_policy", Parameter::Parameter::PT_ENUM, "linux | bsd", nullptr, "frag policy"};
+        Parameter tcp_param = { "tcp_policy", Parameter::PT_ENUM, "linux | bsd", nullptr, "tcp policy"};
+        Parameter name_param = {"name", Parameter::PT_STRING, nullptr, nullptr, "name"};
+        Parameter proto_param = {"proto", Parameter::PT_ENUM, "tcp | udp", "tcp", "ip proto"};
+        Parameter port_param = {"port", Parameter::PT_PORT, nullptr, nullptr, "port num"};
+        HostTrackerModule module;
+        const PegInfo *ht_pegs = module.get_pegs();
+        const PegCount *ht_stats = module.get_counts();
+
+        CHECK(!strcmp(ht_pegs[0].name, "service adds"));
+        CHECK(!strcmp(ht_pegs[1].name, "service finds"));
+        CHECK(!strcmp(ht_pegs[2].name, "service removes"));
+        CHECK(!ht_pegs[3].name);
+
+        CHECK(ht_stats[0] == 0);
+        CHECK(ht_stats[1] == 0);
+        CHECK(ht_stats[2] == 0);
+
+        ip_val.set(&ip_param);
+        frag_val.set(&frag_param);
+        tcp_val.set(&tcp_param);
+        name_val.set(&name_param);
+        proto_val.set(&proto_param);
+        port_val.set(&port_param);
+
+        // Change IP from string to integer representation.
+        ip_param.validate(ip_val);
+
+        // Set up the module values and add a service.
+        module.begin("host_tracker", 1, nullptr);
+        module.set(nullptr, ip_val, nullptr);
+        module.set(nullptr, frag_val, nullptr);
+        module.set(nullptr, tcp_val, nullptr);
+        module.set(nullptr, name_val, nullptr);
+        module.set(nullptr, proto_val, nullptr);
+        module.set(nullptr, port_val, nullptr);
+        module.end("host_tracker.services", 1, nullptr);
+        module.end("host_tracker", 1, nullptr);
+
+        ip_val.get_addr(expected_addr);
+    }
+
+    void teardown()
+    {
+        memset(&host_tracker_stats, 0, sizeof(host_tracker_stats));
+        host_cache.clear();    //  Free HostTracker objects
+    }
+};
+
+//  Test that HostModules variables are set correctly.
+TEST(host_module, host_module_test_values)
+{
+    sfip_t cached_addr;
+
+    HostIpKey host_ip_key(expected_addr.ip8);
+    std::shared_ptr<HostTracker> ht;
+
+    bool ret = host_cache.find(host_ip_key, ht);
+    CHECK(ret == true);
+
+    cached_addr = ht->get_ip_addr();
+    CHECK(sfip_fast_equals_raw(&cached_addr, &expected_addr) == 1);
+
+    Policy policy = ht->get_stream_policy();
+    CHECK(policy == STREAM_POLICY + 1);
+
+    policy = ht->get_frag_policy();
+    CHECK(policy == FRAG_POLICY + 1);
+}
+
+
+//  Test that HostModules statistics are correct.
+TEST(host_module, host_module_test_stats)
+{
+    HostIpKey host_ip_key(expected_addr.ip8);
+    std::shared_ptr<HostTracker> ht;
+
+    bool ret = host_cache.find(host_ip_key, ht);
+    CHECK(ret == true);
+
+    HostApplicationEntry app;
+    ret = ht->find_service(1, 2112, app);
+    CHECK(ret == true);
+    CHECK(app.protocol == 3);
+    CHECK(app.ipproto == 1); 
+    CHECK(app.port == 2112);
+
+    ret = ht->remove_service(1, 2112);
+    CHECK(ret == true);
+
+    //  Verify counts are correct.  The add was done during setup.
+    CHECK(host_tracker_stats.service_adds == 1);
+    CHECK(host_tracker_stats.service_finds == 1);
+    CHECK(host_tracker_stats.service_removes == 1);
+}
+
+int main(int argc, char** argv)
+{
+    return CommandLineTestRunner::RunAllTests(argc, argv);
+}
+