1 //-------------------------------------------------------------------------- 2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved. 3 // Copyright (C) 2008-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 #ifndef TREENODES_H 21 #define TREENODES_H 22 23 // rule header (RTN) and body (OTN) nodes 24 25 #include "actions/actions.h" 26 #include "detection/signature.h" 27 #include "detection/rule_option_types.h" 28 #include "main/policy.h" 29 #include "main/snort_types.h" 30 #include "ports/port_group.h" 31 #include "time/clock_defs.h" 32 33 namespace snort 34 { 35 class IpsOption; 36 struct Packet; 37 } 38 struct RuleTreeNode; 39 struct PortObject; 40 struct OutputSet; 41 struct TagData; 42 struct sfip_var_t; 43 44 /* same as the rule header FP list */ 45 struct OptFpList 46 { 47 snort::IpsOption* ips_opt; 48 49 int (* OptTestFunc)(void* option_data, class Cursor&, snort::Packet*); 50 51 OptFpList* next; 52 53 unsigned char isRelative; 54 option_type_t type; 55 }; 56 57 struct OtnState 58 { 59 // profiling 60 // FIXIT-L factor the profiling stuff out 61 hr_duration elapsed = 0_ticks; 62 hr_duration elapsed_match = 0_ticks; 63 hr_duration elapsed_no_match = 0_ticks; 64 65 uint64_t checks = 0; 66 uint64_t matches = 0; 67 uint8_t noalerts = 0; 68 uint64_t alerts = 0; 69 70 uint64_t latency_timeouts = 0; 71 uint64_t latency_suspends = 0; 72 73 operator bool() const 74 { return elapsed > 0_ticks || checks > 0; } 75 }; 76 77 /* function pointer list for rule head nodes */ 78 // FIXIT-L use bit mask to determine what header checks to do 79 // cheaper than traversing a list and uses much less memory 80 struct RuleFpList 81 { 82 /* context data for this test */ 83 void* context = nullptr; 84 85 /* rule check function pointer */ 86 int (* RuleHeadFunc)(snort::Packet*, RuleTreeNode*, RuleFpList*, int) = nullptr; 87 88 /* pointer to the next rule function node */ 89 RuleFpList* next = nullptr; 90 }; 91 92 struct RuleHeader 93 { RuleHeaderRuleHeader94 RuleHeader(const char* s) : action(s) { } 95 96 std::string action; 97 std::string proto; 98 std::string src_nets; 99 std::string src_ports; 100 std::string dir; 101 std::string dst_nets; 102 std::string dst_ports; 103 }; 104 105 // one of these per rule per policy 106 // represents head part of rule 107 struct RuleTreeNode 108 { 109 using Flag = uint8_t; 110 static constexpr Flag ENABLED = 0x01; 111 static constexpr Flag ANY_SRC_PORT = 0x02; 112 static constexpr Flag ANY_DST_PORT = 0x04; 113 static constexpr Flag ANY_FLAGS = 0x08; 114 static constexpr Flag BIDIRECTIONAL = 0x10; 115 static constexpr Flag ANY_SRC_IP = 0x20; 116 static constexpr Flag ANY_DST_IP = 0x40; 117 static constexpr Flag USER_MODE = 0x80; 118 119 RuleFpList* rule_func = nullptr; /* match functions.. (Bidirectional etc.. ) */ 120 RuleHeader* header = nullptr; 121 122 sfip_var_t* sip = nullptr; 123 sfip_var_t* dip = nullptr; 124 125 PortObject* src_portobject = nullptr; 126 PortObject* dst_portobject = nullptr; 127 128 struct ListHead* listhead = nullptr; 129 130 SnortProtocolId snort_protocol_id = 0; 131 132 // reference count from otn. 133 // Multiple OTNs can reference this RTN with the same policy. 134 unsigned int otnRefCount = 0; // FIXIT-L shared_ptr? 135 136 Actions::Type action = 0; 137 138 uint8_t flags = 0; 139 set_enabledRuleTreeNode140 void set_enabled() 141 { flags |= ENABLED; } 142 clear_enabledRuleTreeNode143 void clear_enabled() 144 { flags &= (~ENABLED); } 145 enabledRuleTreeNode146 bool enabled() const 147 { return (flags & ENABLED) != 0; } 148 user_modeRuleTreeNode149 bool user_mode() const 150 { return (flags & USER_MODE) != 0; } 151 any_src_portRuleTreeNode152 bool any_src_port() const 153 { return (flags & ANY_SRC_PORT) != 0; } 154 any_dst_portRuleTreeNode155 bool any_dst_port() const 156 { return (flags & ANY_DST_PORT) != 0; } 157 any_any_portRuleTreeNode158 bool any_any_port() const 159 { return any_src_port() and any_dst_port(); } 160 }; 161 162 // one of these for each rule 163 // represents body part of rule 164 struct OptTreeNode 165 { 166 ~OptTreeNode(); 167 168 using Flag = uint8_t; 169 static constexpr Flag WARNED_FP = 0x01; 170 static constexpr Flag STATELESS = 0x02; 171 static constexpr Flag RULE_STATE = 0x04; 172 static constexpr Flag META_MATCH = 0x08; 173 static constexpr Flag TO_CLIENT = 0x10; 174 static constexpr Flag TO_SERVER = 0x20; 175 static constexpr Flag BIT_CHECK = 0x40; 176 177 /* metadata about signature */ 178 SigInfo sigInfo; 179 char* soid = nullptr; 180 181 /* plugin/detection functions go here */ 182 OptFpList* opt_func = nullptr; 183 OutputSet* outputFuncs = nullptr; /* per sid enabled output functions */ 184 snort::IpsOption* agent = nullptr; 185 186 OptFpList* normal_fp_only = nullptr; 187 OptFpList* offload_fp_only = nullptr; 188 189 struct THD_NODE* detection_filter = nullptr; /* if present, evaluated last, after header checks */ 190 TagData* tag = nullptr; 191 192 // ptr to list of RTNs (head part); indexed by policyId 193 RuleTreeNode** proto_nodes = nullptr; 194 OtnState* state = nullptr; 195 196 unsigned evalIndex = 0; /* where this rule sits in the evaluation sets */ 197 unsigned ruleIndex = 0; // unique index 198 uint32_t num_detection_opts = 0; 199 SnortProtocolId snort_protocol_id = 0; // Added for integrity checks during rule parsing. 200 unsigned short proto_node_num = 0; 201 uint16_t longestPatternLen = 0; 202 IpsPolicy::Enable enable; 203 Flag flags = 0; 204 205 uint8_t sticky_buf = PM_TYPE_PKT; // parsing only 206 set_warned_fpOptTreeNode207 void set_warned_fp() 208 { flags |= WARNED_FP; } 209 warned_fpOptTreeNode210 bool warned_fp() const 211 { return (flags & WARNED_FP) != 0; } 212 set_statelessOptTreeNode213 void set_stateless() 214 { flags |= STATELESS; } 215 statelessOptTreeNode216 bool stateless() const 217 { return (flags & STATELESS) != 0; } 218 set_enabledOptTreeNode219 void set_enabled(IpsPolicy::Enable e) 220 { enable = e; flags |= RULE_STATE; } 221 is_rule_state_stubOptTreeNode222 bool is_rule_state_stub() const 223 { return (flags & RULE_STATE) != 0; } 224 enabled_somewhereOptTreeNode225 bool enabled_somewhere() const 226 { 227 for ( unsigned i = 0; i < proto_node_num; i++ ) 228 if ( proto_nodes[i] and proto_nodes[i]->enabled() ) 229 return true; 230 231 return false; 232 } 233 set_metadata_matchOptTreeNode234 void set_metadata_match() 235 { flags |= META_MATCH; } 236 metadata_matchedOptTreeNode237 bool metadata_matched() const 238 { return (flags & META_MATCH) != 0; } 239 set_to_clientOptTreeNode240 void set_to_client() 241 { flags |= TO_CLIENT; } 242 to_clientOptTreeNode243 bool to_client() const 244 { return (flags & TO_CLIENT) != 0; } 245 set_to_serverOptTreeNode246 void set_to_server() 247 { flags |= TO_SERVER; } 248 to_serverOptTreeNode249 bool to_server() const 250 { return (flags & TO_SERVER) != 0; } 251 set_flowbits_checkOptTreeNode252 void set_flowbits_check() 253 { flags |= BIT_CHECK; } 254 checks_flowbitsOptTreeNode255 bool checks_flowbits() const 256 { return (flags & BIT_CHECK) != 0; } 257 258 void update_fp(snort::IpsOption*); 259 }; 260 261 typedef int (* RuleOptEvalFunc)(void*, Cursor&, snort::Packet*); 262 OptFpList* AddOptFuncToList(RuleOptEvalFunc, OptTreeNode*); 263 264 void* get_rule_type_data(OptTreeNode*, const char* name); 265 266 namespace snort 267 { 268 SO_PUBLIC bool otn_has_plugin(OptTreeNode* otn, const char* name); 269 } 270 271 bool otn_set_agent(OptTreeNode*, snort::IpsOption*); 272 273 void otn_trigger_actions(const OptTreeNode*, snort::Packet*); 274 275 #endif 276 277