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_segment_descriptor.h author davis mcpherson <davmcphe@cisco.com>
20 // Created on: Jul 30, 2015
21 
22 #ifndef TCP_SEGMENT_DESCRIPTOR_H
23 #define TCP_SEGMENT_DESCRIPTOR_H
24 
25 #include <cassert>
26 
27 #include <daq_common.h>
28 
29 #include "flow/flow.h"
30 #include "detection/ips_context.h"
31 #include "packet_io/active.h"
32 #include "protocols/packet.h"
33 #include "protocols/tcp.h"
34 #include "stream/tcp/tcp_event_logger.h"
35 
36 class TcpStreamTracker;
37 
38 class TcpSegmentDescriptor
39 {
40 public:
41     TcpSegmentDescriptor(snort::Flow*, snort::Packet*, TcpEventLogger&);
42     TcpSegmentDescriptor(snort::Flow*, snort::Packet*, uint32_t meta_ack, uint16_t window);
43 
44     virtual ~TcpSegmentDescriptor() = default;
45 
46     static void setup();
47     static void clear();
48 
is_policy_inline()49     bool is_policy_inline()
50     { return pkt->context->conf->inline_mode(); }
51 
52     uint32_t init_mss(uint16_t* value);
53     uint32_t init_wscale(uint16_t* value);
54     bool has_wscale();
55     void set_retransmit_flag();
56 
get_flow()57     snort::Flow* get_flow() const
58     { return flow; }
59 
get_pkt()60     snort::Packet* get_pkt() const
61     { return pkt; }
62 
get_tcph()63     const snort::tcp::TCPHdr* get_tcph() const
64     { return tcph; }
65 
set_seq(uint32_t seq_num)66     void set_seq(uint32_t seq_num)
67     { seq = seq_num; }
68 
update_seq(int32_t offset)69     void update_seq(int32_t offset)
70     { seq += offset; }
71 
get_seq()72     uint32_t get_seq() const
73     { return seq; }
74 
get_ack()75     uint32_t get_ack() const
76     { return ack; }
77 
set_ack(uint32_t ack_num)78     void set_ack(uint32_t ack_num)
79     { ack = ack_num; }
80 
set_end_seq(uint32_t seq)81     void set_end_seq(uint32_t seq)
82     { end_seq = seq; }
83 
get_end_seq()84     uint32_t get_end_seq() const
85     { return end_seq; }
86 
set_timestamp(uint32_t timestamp)87     void set_timestamp(uint32_t timestamp)
88     { timestamp_option = timestamp; }
89 
get_timestamp()90     uint32_t get_timestamp() const
91     { return timestamp_option; }
92 
scale_wnd(uint16_t wscale)93     void scale_wnd(uint16_t wscale)
94     { wnd <<= wscale; }
95 
get_wnd()96     uint32_t get_wnd() const
97     { return wnd; }
98 
get_dst_port()99     uint16_t get_dst_port() const
100     { return dst_port; }
101 
get_src_port()102     uint16_t get_src_port() const
103     { return src_port; }
104 
get_direction()105     uint8_t get_direction() const
106     { return flow->ssn_state.direction; }
107 
get_len()108     uint16_t get_len() const
109     { return pkt->dsize; }
110 
set_len(uint16_t seg_len)111     void set_len(uint16_t seg_len)
112     { pkt->dsize = seg_len; }
113 
is_data_segment()114     bool is_data_segment() const
115     { return pkt->dsize > 0; }
116 
is_packet_from_client()117     bool is_packet_from_client() const
118     { return packet_from_client; }
119 
is_packet_from_server()120     bool is_packet_from_server() const
121     { return !packet_from_client; }
122 
slide_segment_in_rcv_window(int32_t offset)123     void slide_segment_in_rcv_window(int32_t offset)
124     {
125         seq += offset;
126         pkt->data += offset;
127         pkt->dsize -= offset;
128     }
129 
set_packet_flags(uint32_t flags)130     void set_packet_flags(uint32_t flags) const
131     { pkt->packet_flags |= flags; }
132 
are_packet_flags_set(uint32_t flags)133     bool are_packet_flags_set(uint32_t flags) const
134     { return (pkt->packet_flags & flags) == flags; }
135 
get_packet_timestamp()136     uint32_t get_packet_timestamp() const
137     { return packet_timestamp; }
138 
drop_packet()139     void drop_packet() const
140     {
141         pkt->active->drop_packet(pkt);
142         pkt->active->set_drop_reason("stream");
143     }
144 
is_meta_ack_packet()145     bool is_meta_ack_packet() const
146     { return meta_ack_packet; }
147 
get_packet_number()148     uint64_t get_packet_number() const
149     { return packet_number; }
150 
rewrite_payload(uint16_t offset,uint8_t * from,uint16_t length)151     void rewrite_payload(uint16_t offset, uint8_t* from, uint16_t length)
152     {
153         memcpy(const_cast<uint8_t*>(pkt->data + offset), from, length);
154         set_packet_flags(PKT_MODIFIED);
155     }
156 
rewrite_payload(uint16_t offset,uint8_t * from)157     void rewrite_payload(uint16_t offset, uint8_t* from)
158     { rewrite_payload(offset, from, pkt->dsize); }
159 
get_listener()160     TcpStreamTracker* get_listener() const
161     { return listener; }
162 
set_listener(TcpStreamTracker & tracker)163     void set_listener(TcpStreamTracker& tracker)
164     { listener = &tracker; }
165 
get_talker()166     TcpStreamTracker* get_talker() const
167     { return talker; }
168 
set_talker(TcpStreamTracker & tracker)169     void set_talker(TcpStreamTracker& tracker)
170     { talker = &tracker; }
171 
172 private:
173     snort::Flow* const flow;
174     snort::Packet* const pkt;
175     const snort::tcp::TCPHdr* const tcph;
176     TcpStreamTracker* talker = nullptr;
177     TcpStreamTracker* listener = nullptr;
178 
179     const uint64_t packet_number;
180     uint32_t seq;
181     uint32_t ack;
182     uint32_t wnd;
183     uint32_t end_seq;
184     uint32_t timestamp_option;
185     uint16_t src_port;
186     uint16_t dst_port;
187     uint32_t packet_timestamp;
188     bool packet_from_client;
189     bool meta_ack_packet = false;
190 };
191 
192 #endif
193 
194