1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 // Copyright (C) 2006-2013 Sourcefire, Inc.
4 //
5 // This program is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License Version 2 as published
7 // by the Free Software Foundation.  You may not use, modify or distribute
8 // this program under any other version of the GNU General Public License.
9 //
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 //--------------------------------------------------------------------------
19 
20 // host_attributes.h author davis mcpherson <davmcphe@cisco.com>
21 
22 #ifndef HOST_ATTRIBUTES_H
23 #define HOST_ATTRIBUTES_H
24 
25 // Provides attribute table initialization, lookup, swap, and releasing.
26 
27 #include <functional>
28 #include <memory>
29 #include <mutex>
30 #include <vector>
31 
32 #include "framework/counts.h"
33 #include "sfip/sf_ip.h"
34 #include "target_based/snort_protocols.h"
35 
36 namespace snort
37 {
38 struct SnortConfig;
39 }
40 
41 struct HostAttributeStats
42 {
43     PegCount total_hosts = 0;
44     PegCount hosts_pruned = 0;
45     PegCount dynamic_host_adds = 0;
46     PegCount dynamic_service_adds = 0;
47     PegCount dynamic_service_updates = 0;
48     PegCount service_list_overflows = 0;
49 };
50 
51 class HostServiceDescriptor
52 {
53 public:
54     HostServiceDescriptor() = default;
HostServiceDescriptor(uint16_t port,uint16_t protocol,SnortProtocolId spi,bool appid_service)55     HostServiceDescriptor(uint16_t port, uint16_t protocol, SnortProtocolId spi, bool appid_service)
56         : port(port), ipproto(protocol), snort_protocol_id(spi), appid_service(appid_service)
57     { }
58 
59     ~HostServiceDescriptor() = default;
60 
reset()61     void reset()
62     {
63         port = 0;
64         ipproto = 0;
65         snort_protocol_id = UNKNOWN_PROTOCOL_ID;
66     }
67 
68     uint16_t port = 0;
69     uint16_t ipproto = 0;
70     SnortProtocolId snort_protocol_id = UNKNOWN_PROTOCOL_ID;
71     bool appid_service = false;
72 };
73 
74 struct HostPolicyDescriptor
75 {
76     uint8_t streamPolicy = 0;
77     uint8_t fragPolicy = 0;
78 };
79 
80 struct HostAttriInfo
81 {
82     SnortProtocolId snort_protocol_id = UNKNOWN_PROTOCOL_ID;
83     uint8_t stream_policy = 0;
84     uint8_t frag_policy = 0;
85 };
86 
87 class HostAttributesDescriptor
88 {
89 public:
90     HostAttributesDescriptor() = default;
91     ~HostAttributesDescriptor() = default;
92 
93     bool update_service(uint16_t port, uint16_t protocol, SnortProtocolId, bool& updated,
94         bool is_appid_service = false);
95     void clear_appid_services();
96     void get_host_attributes(uint16_t, HostAttriInfo*) const;
97 
98     // Note: the following get/set are only called from main thread on a temp LRU table
get_ip_addr()99     const snort::SfIp& get_ip_addr() const
100     { return ip_address; }
101 
set_ip_addr(const snort::SfIp & host_ip_addr)102     void set_ip_addr(const snort::SfIp& host_ip_addr)
103     {
104         ip_address = host_ip_addr;
105     }
106 
set_frag_policy(const uint8_t frag_policy)107     void set_frag_policy(const uint8_t frag_policy)
108     {
109         policies.fragPolicy = frag_policy;
110     }
111 
set_stream_policy(uint8_t stream_policy)112     void set_stream_policy(uint8_t stream_policy)
113     {
114         policies.streamPolicy = stream_policy;
115     }
116 
117 private:
118     mutable std::mutex host_attributes_lock; // ensure updates to this shared object are safe
119     snort::SfIp ip_address;
120     HostPolicyDescriptor policies;
121     std::vector<HostServiceDescriptor> services;
122 };
123 
124 typedef std::shared_ptr<HostAttributesDescriptor> HostAttributesEntry;
125 
126 #define DEFAULT_MAX_ATTRIBUTE_HOSTS 10000
127 #define DEFAULT_MAX_ATTRIBUTE_SERVICES_PER_HOST 100
128 #define DEFAULT_MAX_METADATA_SERVICES 9
129 
130 // Create a hash key from an IP address stored in a SfIp object.
131 struct HostAttributesCacheKey
132 {
operatorHostAttributesCacheKey133     size_t operator()(const snort::SfIp& ip) const
134     {
135         const uint64_t* ip64 = (const uint64_t*) ip.get_ip6_ptr();
136         return std::hash<uint64_t>() (ip64[0]) ^
137                std::hash<uint64_t>() (ip64[1]);
138     }
139 };
140 
141 class HostAttributesManager
142 {
143 public:
144     static bool load_hosts_file(snort::SnortConfig*, const char* fname);
145     static void activate(snort::SnortConfig*);
146     static void initialize();
147     static void swap_cleanup();
148     static void load_failure_cleanup();
149     static void term();
150 
151     static bool add_host(HostAttributesEntry, snort::SnortConfig*);
152     static bool get_host_attributes(const snort::SfIp&, uint16_t, HostAttriInfo*);
153     static void update_service(const snort::SfIp&, uint16_t port, uint16_t protocol,
154         SnortProtocolId, bool is_appid_service = false);
155     static void clear_appid_services();
156     static int32_t get_num_host_entries();
157     static const PegInfo* get_pegs();
158     static PegCount* get_peg_counts();
159 };
160 
161 #endif
162