1 //--------------------------------------------------------------------------
2 // Copyright (C) 2015-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 
19 // tcp_stream_session.h author davis mcpherson <davmcphe@cisco.com>
20 // Created on: Feb 18, 2016
21 
22 #ifndef TCP_STREAM_SESSION_H
23 #define TCP_STREAM_SESSION_H
24 
25 #include "detection/detection_engine.h"
26 #include "flow/session.h"
27 #include "protocols/ipv6.h"
28 
29 #include "tcp_stream_config.h"
30 #include "tcp_stream_tracker.h"
31 
32 // FIXIT-L session tracking could be split from reassembly
33 // into a separate module a la ip_session.cc and ip_defrag.cc
34 // (of course defrag should also be cleaned up)
35 class TcpStreamSession : public Session
36 {
37 public:
38     ~TcpStreamSession() override;
39 
40     void clear() override;
41     void cleanup(snort::Packet* = nullptr) override;
42 
43     void set_splitter(bool, snort::StreamSplitter*) override;
44     snort::StreamSplitter* get_splitter(bool) override;
45 
46     bool is_sequenced(uint8_t dir) override;
47     bool are_packets_missing(uint8_t dir) override;
48 
49     void disable_reassembly(snort::Flow*) override;
50     uint8_t get_reassembly_direction() override;
51     uint8_t missing_in_reassembled(uint8_t dir) override;
52     bool are_client_segments_queued() override;
53 
54     bool add_alert(snort::Packet*, uint32_t gid, uint32_t sid) override;
55     bool check_alerted(snort::Packet*, uint32_t gid, uint32_t sid) override;
56     int update_alert(snort::Packet*, uint32_t gid, uint32_t sid,
57         uint32_t event_id, uint32_t event_second) override;
58 
59     bool set_packet_action_to_hold(snort::Packet*) override;
60 
61     uint16_t get_mss(bool to_server) const;
62     uint8_t get_tcp_options_len(bool to_server) const;
63 
64     void reset();
65     void start_proxy();
66 
67     void set_packet_header_foo(const TcpSegmentDescriptor&);
68     void get_packet_header_foo(DAQ_PktHdr_t*, uint32_t dir);
69     void set_no_ack(bool);
no_ack_mode_enabled()70     bool no_ack_mode_enabled() { return no_ack; }
71     virtual void update_perf_base_state(char) = 0;
72     virtual void clear_session(
73         bool free_flow_data, bool flush_segments, bool restart, snort::Packet* p = nullptr) = 0;
74     virtual TcpStreamTracker::TcpState get_talker_state(TcpSegmentDescriptor&) = 0;
75     virtual TcpStreamTracker::TcpState get_listener_state(TcpSegmentDescriptor&) = 0;
get_peer_state(TcpStreamTracker * me)76     TcpStreamTracker::TcpState get_peer_state(TcpStreamTracker* me)
77     { return me == &client ? server.get_tcp_state() : client.get_tcp_state(); }
78 
79     virtual void init_new_tcp_session(TcpSegmentDescriptor&);
80     virtual void update_timestamp_tracking(TcpSegmentDescriptor&) = 0;
81     virtual void update_session_on_syn_ack();
82     virtual void update_session_on_ack();
83     virtual void update_session_on_server_packet(TcpSegmentDescriptor&);
84     virtual void update_session_on_client_packet(TcpSegmentDescriptor&);
85     virtual void update_session_on_rst(TcpSegmentDescriptor&, bool) = 0;
86     virtual bool handle_syn_on_reset_session(TcpSegmentDescriptor&) = 0;
87     virtual void handle_data_on_syn(TcpSegmentDescriptor&) = 0;
88     virtual void update_ignored_session(TcpSegmentDescriptor&) = 0;
generate_no_3whs_event()89     void generate_no_3whs_event()
90     {
91         if ( generate_3whs_alert && flow->two_way_traffic())
92         {
93             tel.set_tcp_event(EVENT_NO_3WHS);
94             generate_3whs_alert = false;
95         }
96     }
97 
set_pkt_action_flag(uint32_t flag)98     void set_pkt_action_flag(uint32_t flag)
99     { pkt_action_mask |= flag; }
100 
101     virtual void update_paws_timestamps(TcpSegmentDescriptor&) = 0;
102     virtual void check_for_repeated_syn(TcpSegmentDescriptor&) = 0;
103     virtual void check_for_session_hijack(TcpSegmentDescriptor&) = 0;
104     virtual bool check_for_window_slam(TcpSegmentDescriptor&) = 0;
105     virtual void mark_packet_for_drop(TcpSegmentDescriptor&) = 0;
106     virtual void handle_data_segment(TcpSegmentDescriptor&) = 0;
107     virtual bool validate_packet_established_session(TcpSegmentDescriptor&) = 0;
108 
109     TcpStreamTracker client;
110     TcpStreamTracker server;
111     bool lws_init = false;
112     bool tcp_init = false;
113     uint32_t pkt_action_mask = ACTION_NOTHING;
114     uint8_t ecn = 0;
115     int32_t ingress_index = DAQ_PKTHDR_UNKNOWN;
116     int16_t ingress_group = DAQ_PKTHDR_UNKNOWN;
117     int32_t egress_index = DAQ_PKTHDR_UNKNOWN;
118     int16_t egress_group = DAQ_PKTHDR_UNKNOWN;
119     uint32_t daq_flags = 0;
120     uint16_t address_space_id = 0;
121     bool generate_3whs_alert = true;
122     TcpStreamConfig* tcp_config = nullptr;
123     TcpEventLogger tel;
124     bool cleaning = false;
125     uint8_t held_packet_dir = SSN_DIR_NONE;
126 
127 private:
128     bool no_ack = false;
129 
130 protected:
131     TcpStreamSession(snort::Flow*);
132     virtual void set_os_policy() = 0;
133 };
134 
135 #endif
136 
137