1 //-------------------------------------------------------------------------- 2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved. 3 // 4 // This program is free software; you can redistribute it and/or modify it 5 // under the terms of the GNU General Public License Version 2 as published 6 // by the Free Software Foundation. You may not use, modify or distribute 7 // this program under any other version of the GNU General Public License. 8 // 9 // This program is distributed in the hope that it will be useful, but 10 // WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 // General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License along 15 // with this program; if not, write to the Free Software Foundation, Inc., 16 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 //-------------------------------------------------------------------------- 18 // data_bus.h author Russ Combs <rucombs@cisco.com> 19 20 #ifndef DATA_BUS_H 21 #define DATA_BUS_H 22 23 // DataEvents are the product of inspection, not detection. They can be 24 // used to implement flexible processing w/o hardcoding the logic to call 25 // specific functions under specific conditions. By using DataEvents with 26 // a publish-subscribe mechanism, it is possible to add custom processing 27 // at arbitrary points, eg when service is identified, or when a URI is 28 // available, or when a flow clears. 29 30 #include <string> 31 #include <unordered_map> 32 #include <unordered_set> 33 #include <vector> 34 35 #include "main/snort_types.h" 36 37 namespace snort 38 { 39 class Flow; 40 struct Packet; 41 42 class DataEvent 43 { 44 public: 45 virtual ~DataEvent() = default; 46 get_packet()47 virtual const Packet* get_packet() 48 { return nullptr; } 49 get_data()50 virtual const uint8_t* get_data() 51 { return nullptr; } 52 get_data(unsigned & len)53 virtual const uint8_t* get_data(unsigned& len) 54 { len = 0; return nullptr; } 55 get_normalized_data(unsigned & len)56 virtual const uint8_t* get_normalized_data(unsigned& len) 57 { return get_data(len); } 58 59 protected: 60 DataEvent() = default; 61 }; 62 63 class BareDataEvent final : public DataEvent 64 { 65 public: 66 BareDataEvent() = default; 67 ~BareDataEvent() override = default; 68 }; 69 70 class DataHandler 71 { 72 public: 73 virtual ~DataHandler() = default; 74 handle(DataEvent &,Flow *)75 virtual void handle(DataEvent&, Flow*) { } 76 const char* module_name; 77 bool cloned; 78 79 // order is desired position in the call sequence of handlers: 1 = first, 0 = last 80 // the sequence among subscribers with the same order is not specified 81 unsigned order = 0; 82 83 protected: 84 DataHandler(std::nullptr_t) = delete; DataHandler(const char * mod_name)85 DataHandler(const char* mod_name) : module_name(mod_name), cloned(false) { } 86 }; 87 88 // FIXIT-P evaluate perf; focus is on correctness 89 typedef std::vector<DataHandler*> DataList; 90 typedef std::unordered_map<std::string, DataList> DataMap; 91 92 class SO_PUBLIC DataBus 93 { 94 public: 95 DataBus(); 96 ~DataBus(); 97 98 // configure time methods - main thread only 99 void clone(DataBus& from, const char* exclude_name = nullptr); 100 101 // FIXIT-L ideally these would not be static or would take an inspection policy* 102 static void subscribe(const char* key, DataHandler*); 103 static void subscribe_network(const char* key, DataHandler*); 104 105 // FIXIT-L these should be called during cleanup 106 static void unsubscribe(const char* key, DataHandler*); 107 static void unsubscribe_network(const char* key, DataHandler*); 108 109 // runtime methods 110 static void publish(const char* key, DataEvent&, Flow* = nullptr); 111 112 // convenience methods 113 static void publish(const char* key, const uint8_t*, unsigned, Flow* = nullptr); 114 static void publish(const char* key, Packet*, Flow* = nullptr); 115 116 private: 117 void _subscribe(const char* key, DataHandler*); 118 void _unsubscribe(const char* key, DataHandler*); 119 void _publish(const char* key, DataEvent&, Flow*); 120 121 private: 122 DataMap map; 123 }; 124 } 125 126 // 127 // Common core functionality data events 128 // 129 130 #define PACKET_EVENT "detection.packet" 131 #define FLOW_STATE_EVENT "flow.state_change" 132 #define THREAD_IDLE_EVENT "thread.idle" 133 #define THREAD_ROTATE_EVENT "thread.rotate" 134 135 // A packet is being detained. 136 #define DETAINED_PACKET_EVENT "analyzer.detained.packet" 137 138 // A flow changed its service 139 #define FLOW_SERVICE_CHANGE_EVENT "flow.service_change_event" 140 // A flow has found the service inspector 141 #define SERVICE_INSPECTOR_CHANGE_EVENT "flow.service_inspector.changed" 142 // No service has been found for the flow 143 #define FLOW_NO_SERVICE_EVENT "flow.no_service_event" 144 // search of SSL is abandoned on this flow 145 #define SSL_SEARCH_ABANDONED "flow.ssl_search_abandoned" 146 147 // A flow has entered the setup state 148 #define FLOW_STATE_SETUP_EVENT "flow.state_setup" 149 150 // A new flow is created on this packet 151 #define STREAM_ICMP_NEW_FLOW_EVENT "stream.icmp_new_flow" 152 #define STREAM_IP_NEW_FLOW_EVENT "stream.ip_new_flow" 153 #define STREAM_UDP_NEW_FLOW_EVENT "stream.udp_new_flow" 154 155 // A flow has been determined to be bidirectional 156 #define STREAM_ICMP_BIDIRECTIONAL_EVENT "stream.icmp_bidirectional" 157 #define STREAM_IP_BIDIRECTIONAL_EVENT "stream.ip.bidirectional" 158 #define STREAM_UDP_BIDIRECTIONAL_EVENT "stream.udp.bidirectional" 159 160 // A TCP flow has the flag; a midstream flow may not publish other events 161 #define STREAM_TCP_SYN_EVENT "stream.tcp_syn" 162 #define STREAM_TCP_SYN_ACK_EVENT "stream.tcp_syn_ack" 163 #define STREAM_TCP_MIDSTREAM_EVENT "stream.tcp_midstream" 164 165 // A new standby flow was generated by stream high availability 166 #define STREAM_HA_NEW_FLOW_EVENT "stream.ha.new_flow" 167 168 #endif 169 170