1 //--------------------------------------------------------------------------
2 // Copyright (C) 2020-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 // rna_fingerprint_tcp.h author Silviu Minut <sminut@cisco.com>
20 
21 #ifndef RNA_FINGERPRINT_TCP_H
22 #define RNA_FINGERPRINT_TCP_H
23 
24 #include <mutex>
25 #include <unordered_map>
26 #include <vector>
27 
28 #include "main/snort_types.h"
29 #include "protocols/packet.h"
30 #include "protocols/tcp.h"
31 #include "sfip/sf_ip.h"
32 
33 #include "rna_fingerprint.h"
34 
35 class RNAFlow;
36 
37 namespace snort
38 {
39 
40 class SO_PUBLIC TcpFingerprint : public FpFingerprint
41 {
42 public:
43 
44     TcpFingerprint() = default;
45     TcpFingerprint(const RawFingerprint& rfp);
46 
47     std::vector<FpElement> tcp_window;
48     std::vector<FpElement> mss;
49     std::vector<FpElement> id;
50     std::vector<FpElement> topts;
51     std::vector<FpElement> ws;
52     bool df = false;
53 
clear()54     void clear() override
55     {
56         FpFingerprint::clear();
57         tcp_window.clear();
58         mss.clear();
59         id.clear();
60         topts.clear();
61         ws.clear();
62         df = false;
63     }
64 
65     bool operator==(const TcpFingerprint& y) const;
66 };
67 
68 struct FpTcpKey
69 {
70     int synmss;
71     uint8_t *syn_tcpopts;
72     int num_syn_tcpopts;
73     int syn_timestamp;
74 
75     int tcp_window;
76     int mss;
77     int ws;
78 
79     int mss_pos;
80     int ws_pos;
81     int sackok_pos;
82     int timestamp_pos;
83 
84     bool df;
85     bool isIpv6;
86 };
87 
88 class SO_PUBLIC TcpFpProcessor
89 {
90 public:
91 
92     typedef std::unordered_map<uint32_t, TcpFingerprint> TcpFpContainer;
93 
94     enum TCP_FP_MODE { SERVER, CLIENT };
95 
96     bool push(const TcpFingerprint&);
97 
98     void make_tcp_fp_tables(TCP_FP_MODE);
99 
100     const TcpFingerprint* get_tcp_fp(const FpTcpKey&, uint8_t, TCP_FP_MODE) const;
101 
102     const TcpFingerprint* get(const Packet*, RNAFlow*) const;
103 
get(uint32_t fpid)104     const TcpFingerprint* get(uint32_t fpid) const
105     {
106         auto it = tcp_fps.find(fpid);
107         return it != tcp_fps.end() ? &it->second : nullptr;
108     }
109 
get_tcp_fps()110     const TcpFpContainer& get_tcp_fps() const
111     { return tcp_fps; }
112 
113 private:
114 
115     // underlying container for input fingerprints
116     TcpFpContainer tcp_fps;
117 
118     // table_tcp_xxx[i] contains pointers into tcp_fps to all fingerprints
119     // whose tcp window range contains i
120     static constexpr uint32_t table_size = TCP_MAXWIN + 1;
121     std::vector<const snort::TcpFingerprint*> table_tcp_server[table_size];
122     std::vector<const snort::TcpFingerprint*> table_tcp_client[table_size];
123 };
124 
125 }
126 
127 snort::TcpFpProcessor* get_tcp_fp_processor();
128 SO_PUBLIC void set_tcp_fp_processor(snort::TcpFpProcessor*);
129 
130 struct FpFingerprintState
131 {
132     int initial_mss = -1;
133     int timestamp = -1;
134     int numopts = -1;
135     uint8_t tcpopts[4];
136     time_t timeout = -1;
137 
138     bool set(const snort::Packet*);
139 };
140 
141 #endif
142