00001 //--------------------------------------------------------------------------
00002 // Copyright (C) 2014-2017 Cisco and/or its affiliates. All rights reserved.
00003 //
00004 // This program is free software; you can redistribute it and/or modify it
00005 // under the terms of the GNU General Public License Version 2 as published
00006 // by the Free Software Foundation. You may not use, modify or distribute
00007 // this program under any other version of the GNU General Public License.
00008 //
00009 // This program is distributed in the hope that it will be useful, but
00010 // WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License along
00015 // with this program; if not, write to the Free Software Foundation, Inc.,
00016 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017 //--------------------------------------------------------------------------
00018
00019 // flow.h author Russ Combs <rucombs@cisco.com>
00020
00021 #ifndef FLOW_H
00022 #define FLOW_H
00023
00024 // Flow is the object that captures all the data we know about a session,
00025 // including IP for defragmentation and TCP for desegmentation. For all
00026 // protocols, it used to track connection status bindings, and inspector
00027 // state. Inspector state is stored in FlowData, and Flow manages a list
00028 // of FlowData items.
00029
00030 #include "framework/decode_data.h"
00031 #include "framework/inspector.h"
00032 #include "protocols/layer.h"
00033 #include "sfip/sf_ip.h"
00034
00035 #define SSNFLAG_SEEN_CLIENT 0x00000001
00036 #define SSNFLAG_SEEN_SENDER 0x00000001
00037 #define SSNFLAG_SEEN_SERVER 0x00000002
00038 #define SSNFLAG_SEEN_RESPONDER 0x00000002
00039
00040 #define SSNFLAG_ESTABLISHED 0x00000004
00041 #define SSNFLAG_MIDSTREAM 0x00000008 /* picked up midstream */
00042
00043 #define SSNFLAG_ECN_CLIENT_QUERY 0x00000010
00044 #define SSNFLAG_ECN_SERVER_REPLY 0x00000020
00045 #define SSNFLAG_CLIENT_FIN 0x00000040 /* server sent fin */
00046 #define SSNFLAG_SERVER_FIN 0x00000080 /* client sent fin */
00047
00048 #define SSNFLAG_COUNTED_INITIALIZE 0x00000100
00049 #define SSNFLAG_COUNTED_ESTABLISH 0x00000200
00050 #define SSNFLAG_COUNTED_CLOSING 0x00000400
00051 #define SSNFLAG_COUNTED_CLOSED 0x00000800
00052
00053 #define SSNFLAG_TIMEDOUT 0x00001000
00054 #define SSNFLAG_PRUNED 0x00002000
00055 #define SSNFLAG_RESET 0x00004000
00056
00057 #define SSNFLAG_DROP_CLIENT 0x00010000
00058 #define SSNFLAG_DROP_SERVER 0x00020000
00059 #define SSNFLAG_FORCE_BLOCK 0x00040000
00060
00061 #define SSNFLAG_STREAM_ORDER_BAD 0x00100000
00062 #define SSNFLAG_CLIENT_SWAP 0x00200000
00063 #define SSNFLAG_CLIENT_SWAPPED 0x00400000
00064
00065 #define SSNFLAG_PROXIED 0x01000000
00066
00067 #define SSNFLAG_ABORT_CLIENT 0x10000000
00068 #define SSNFLAG_ABORT_SERVER 0x20000000
00069
00070 #define SSNFLAG_NONE 0x00000000 /* nothing, an MT bag of chips */
00071
00072 #define SSNFLAG_SEEN_BOTH (SSNFLAG_SEEN_SERVER | SSNFLAG_SEEN_CLIENT)
00073 #define SSNFLAG_BLOCK (SSNFLAG_DROP_CLIENT|SSNFLAG_DROP_SERVER)
00074
00075 #define STREAM_STATE_NONE 0x0000
00076 #define STREAM_STATE_SYN 0x0001
00077 #define STREAM_STATE_SYN_ACK 0x0002
00078 #define STREAM_STATE_ACK 0x0004
00079 #define STREAM_STATE_ESTABLISHED 0x0008
00080 #define STREAM_STATE_DROP_CLIENT 0x0010
00081 #define STREAM_STATE_DROP_SERVER 0x0020
00082 #define STREAM_STATE_MIDSTREAM 0x0040
00083 #define STREAM_STATE_TIMEDOUT 0x0080
00084 #define STREAM_STATE_UNREACH 0x0100
00085 #define STREAM_STATE_CLOSED 0x0800
00086 #define STREAM_STATE_IGNORE 0x1000
00087 #define STREAM_STATE_NO_PICKUP 0x2000
00088 #define STREAM_STATE_BLOCK_PENDING 0x4000
00089
00090 #define FLOW_IS_OFFLOADED 0x01
00091 #define FLOW_WAS_OFFLOADED 0x02 // FIXIT-L debug only
00092
00093 struct FlowKey;
00094 struct Packet;
00095
00096 typedef void (* StreamAppDataFree)(void*);
00097
00098 class SO_PUBLIC FlowData
00099 {
00100 public:
00101 FlowData(unsigned u, Inspector* = nullptr);
00102 virtual ~FlowData();
00103
00104 unsigned get_id()
00105 { return id; }
00106
00107 static unsigned create_flow_data_id()
00108 { return ++flow_data_id; }
00109
00110 virtual void handle_expected(Packet*) { }
00111 virtual void handle_retransmit(Packet*) { }
00112 virtual void handle_eof(Packet*) { }
00113
00114 public: // FIXIT-L privatize
00115 FlowData* next;
00116 FlowData* prev;
00117
00118 private:
00119 static unsigned flow_data_id;
00120 Inspector* handler;
00121 unsigned id;
00122 };
00123
00124 struct LwState
00125 {
00126 uint32_t session_flags;
00127
00128 int16_t ipprotocol;
00129 int16_t application_protocol;
00130
00131 char direction;
00132 char ignore_direction;
00133 };
00134
00135
00136
00137
00138
00139 // this struct is organized by member size for compactness
00140 class SO_PUBLIC Flow
00141 {
00142 public:
00143 enum class FlowState : uint8_t
00144 {
00145 SETUP = 0,
00146 INSPECT,
00147 BLOCK,
00148 RESET,
00149 ALLOW
00150 };
00151 Flow();
00152
00153 void init(PktType);
00154 void term();
00155
00156 void reset(bool do_cleanup = true);
00157 void restart(bool dump_flow_data = true);
00158 void clear(bool dump_flow_data = true);
00159
00160 int set_flow_data(FlowData*);
00161 FlowData* get_flow_data(uint32_t proto) const;
00162 void free_flow_data(uint32_t proto);
00163 void free_flow_data(FlowData*);
00164 void free_flow_data();
00165
00166 void call_handlers(Packet* p, bool eof = false);
00167 void markup_packet_flags(Packet*);
00168 void set_direction(Packet*);
00169 void set_expire(const Packet*, uint32_t timeout);
00170 bool expired(const Packet*);
00171 void set_ttl(Packet*, bool client);
00172 void set_mpls_layer_per_dir(Packet*);
00173 Layer get_mpls_layer_per_dir(bool);
00174
00175 uint32_t update_session_flags(uint32_t flags)
00176 { return ssn_state.session_flags = flags; }
00177
00178 uint32_t set_session_flags(uint32_t flags)
00179 { return ssn_state.session_flags |= flags; }
00180
00181 uint32_t get_session_flags()
00182 { return ssn_state.session_flags; }
00183
00184 uint32_t test_session_flags(uint32_t flags)
00185 { return (ssn_state.session_flags & flags) != 0; }
00186
00187 uint32_t clear_session_flags(uint32_t flags)
00188 { return ssn_state.session_flags &= ~flags; }
00189
00190 int get_ignore_direction()
00191 { return ssn_state.ignore_direction; }
00192
00193 int set_ignore_direction(char ignore_direction)
00194 {
00195 if (ssn_state.ignore_direction != ignore_direction)
00196 ssn_state.ignore_direction = ignore_direction;
00197
00198 return ssn_state.ignore_direction;
00199 }
00200
00201 bool two_way_traffic()
00202 { return (ssn_state.session_flags & SSNFLAG_SEEN_BOTH) == SSNFLAG_SEEN_BOTH; }
00203
00204 bool is_pdu_inorder(uint8_t dir);
00205
00206 void set_proxied()
00207 { ssn_state.session_flags |= SSNFLAG_PROXIED; }
00208
00209 bool is_proxied()
00210 { return (ssn_state.session_flags & SSNFLAG_PROXIED) != 0; }
00211
00212 bool is_stream()
00213 { return (to_utype(pkt_type) & to_utype(PktType::STREAM)) != 0; }
00214
00215 void block()
00216 { ssn_state.session_flags |= SSNFLAG_BLOCK; }
00217
00218 bool was_blocked() const
00219 { return (ssn_state.session_flags & SSNFLAG_BLOCK) != 0; }
00220
00221 bool full_inspection() const
00222 { return flow_state <= FlowState::INSPECT; }
00223
00224 void set_state(FlowState fs)
00225 { flow_state = fs; }
00226
00227 void set_client(Inspector* ins)
00228 {
00229 ssn_client = ins;
00230 ssn_client->add_ref();
00231 }
00232
00233 void set_server(Inspector* ins)
00234 {
00235 ssn_server = ins;
00236 ssn_server->add_ref();
00237 }
00238
00239 void set_clouseau(Inspector* ins)
00240 {
00241 clouseau = ins;
00242 clouseau->add_ref();
00243 }
00244
00245 void clear_clouseau()
00246 {
00247 clouseau->rem_ref();
00248 clouseau = nullptr;
00249 }
00250
00251 void set_gadget(Inspector* ins)
00252 {
00253 gadget = ins;
00254 gadget->add_ref();
00255 }
00256
00257 void clear_gadget()
00258 {
00259 gadget->rem_ref();
00260 gadget = nullptr;
00261 }
00262
00263 void set_data(Inspector* pd)
00264 {
00265 data = pd;
00266 data->add_ref();
00267 }
00268
00269 void clear_data()
00270 {
00271 data->rem_ref();
00272 data = nullptr;
00273 }
00274
00275 void disable_inspection()
00276 {
00277 disable_inspect = true;
00278 }
00279
00280 bool is_inspection_disabled()
00281 {
00282 return disable_inspect;
00283 }
00284
00285 bool is_offloaded() const
00286 { return flow_flags & FLOW_IS_OFFLOADED; }
00287
00288 void set_offloaded()
00289 { flow_flags |= (FLOW_IS_OFFLOADED|FLOW_WAS_OFFLOADED); }
00290
00291 void clear_offloaded()
00292 { flow_flags &= ~FLOW_IS_OFFLOADED; }
00293
00294
00295 void set_id(unsigned ident)
00296 { id = ident; }
00297
00298 unsigned get_id()
00299 { return id; }
00300
00301 static unsigned create_flow_id()
00302 { return ++flow_id; }
00303
00304
00305
00306 public: // FIXIT-M privatize if possible
00307 // fields are organized by initialization and size to minimize
00308 // void space and allow for memset of tail end of struct
00309
00310 // these fields are const after initialization
00311 const FlowKey* key;
00312 class Session* session;
00313 class BitOp* bitop;
00314 class FlowHAState* ha_state;
00315
00316 uint8_t ip_proto; // FIXIT-M do we need both of these?
00317 PktType pkt_type; // ^^
00318
00319 // these fields are always set; not zeroed
00320 uint64_t flow_flags; // FIXIT-H required to ensure atomic?
00321 Flow* prev, * next;
00322 Inspector* ssn_client;
00323 Inspector* ssn_server;
00324
00325 long last_data_seen;
00326 Layer mpls_client, mpls_server;
00327
00328 // everything from here down is zeroed
00329 FlowData* flow_data;
00330 Inspector* clouseau; // service identifier
00331 Inspector* gadget; // service handler
00332 Inspector* data;
00333 const char* service;
00334
00335 uint64_t expire_time;
00336
00337 SfIp client_ip;
00338 SfIp server_ip;
00339
00340 LwState ssn_state;
00341 LwState previous_ssn_state;
00342 FlowState flow_state;
00343 unsigned inspection_policy_id;
00344 unsigned ips_policy_id;
00345 unsigned network_policy_id;
00346
00347 uint16_t client_port;
00348 uint16_t server_port;
00349
00350 uint16_t ssn_policy;
00351 uint16_t session_state;
00352
00353 uint8_t inner_client_ttl, inner_server_ttl;
00354 uint8_t outer_client_ttl, outer_server_ttl;
00355
00356 uint8_t response_count;
00357 bool disable_inspect;
00358
00359
00360 private:
00361 void clean();
00362 static unsigned flow_id;
00363 unsigned id;
00364
00365 };
00366
00367
00368
00369
00370
00371
00372 #endif
00373
END OF CODE