forked from zeek/zeek
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConn.h
354 lines (272 loc) · 10.4 KB
/
Conn.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
// See the file "COPYING" in the main distribution directory for copyright.
#ifndef conn_h
#define conn_h
#include <sys/types.h>
#include "Dict.h"
#include "Val.h"
#include "Timer.h"
#include "Serializer.h"
#include "PersistenceSerializer.h"
#include "RuleMatcher.h"
#include "IPAddr.h"
#include "TunnelEncapsulation.h"
#include "UID.h"
#include "analyzer/Tag.h"
#include "analyzer/Analyzer.h"
class Connection;
class ConnectionTimer;
class NetSessions;
class LoginConn;
class RuleHdrTest;
class Specific_RE_Matcher;
class RuleEndpointState;
namespace analyzer { class TransportLayerAnalyzer; }
typedef enum {
NUL_IN_LINE,
SINGULAR_CR,
SINGULAR_LF,
NUM_EVENTS_TO_FLAG,
} ConnEventToFlag;
typedef void (Connection::*timer_func)(double t);
struct ConnID {
IPAddr src_addr;
IPAddr dst_addr;
uint32 src_port;
uint32 dst_port;
bool is_one_way; // if true, don't canonicalize order
};
static inline int addr_port_canon_lt(const IPAddr& addr1, uint32 p1,
const IPAddr& addr2, uint32 p2)
{
return addr1 < addr2 || (addr1 == addr2 && p1 < p2);
}
namespace analyzer { class Analyzer; }
class Connection : public BroObj {
public:
Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
uint32 flow, const EncapsulationStack* arg_encap);
virtual ~Connection();
// Invoked when an encapsulation is discovered. It records the
// encapsulation with the connection and raises a "tunnel_changed"
// event if it's different from the previous encapsulation (or the
// first encountered). encap can be null to indicate no
// encapsulation.
void CheckEncapsulation(const EncapsulationStack* encap);
// Invoked when connection is about to be removed. Use Ref(this)
// inside Done to keep the connection object around (though it'll
// no longer be accessible from the dictionary of active
// connections).
void Done();
// Process the connection's next packet. "data" points just
// beyond the IP header. It's updated to point just beyond
// the transport header (or whatever should be saved, if we
// decide not to save the full packet contents).
//
// If record_packet is true, the packet should be recorded.
// If record_content is true, then its entire contents should
// be recorded, otherwise just up through the transport header.
// Both are assumed set to true when called.
void NextPacket(double t, int is_orig,
const IP_Hdr* ip, int len, int caplen,
const u_char*& data,
int& record_packet, int& record_content,
// arguments for reproducing packets
const struct pcap_pkthdr* hdr,
const u_char* const pkt,
int hdr_size);
HashKey* Key() const { return key; }
void ClearKey() { key = 0; }
double StartTime() const { return start_time; }
void SetStartTime(double t) { start_time = t; }
double LastTime() const { return last_time; }
void SetLastTime(double t) { last_time = t; }
const IPAddr& OrigAddr() const { return orig_addr; }
const IPAddr& RespAddr() const { return resp_addr; }
uint32 OrigPort() const { return orig_port; }
uint32 RespPort() const { return resp_port; }
void FlipRoles();
analyzer::Analyzer* FindAnalyzer(analyzer::ID id);
analyzer::Analyzer* FindAnalyzer(analyzer::Tag tag); // find first in tree.
analyzer::Analyzer* FindAnalyzer(const char* name); // find first in tree.
TransportProto ConnTransport() const { return proto; }
// True if we should record subsequent packets (either headers or
// in their entirety, depending on record_contents). We still
// record subsequent SYN/FIN/RST, regardless of how this is set.
int RecordPackets() const { return record_packets; }
void SetRecordPackets(int do_record) { record_packets = do_record; }
// True if we should record full packets for this connection,
// false if we should just record headers.
int RecordContents() const { return record_contents; }
void SetRecordContents(int do_record) { record_contents = do_record; }
// Set whether to record *current* packet header/full.
void SetRecordCurrentPacket(int do_record)
{ record_current_packet = do_record; }
void SetRecordCurrentContent(int do_record)
{ record_current_content = do_record; }
// FIXME: Now this is in Analyzer and should eventually be removed here.
//
// If true, skip processing of remainder of connection. Note
// that this does not in itself imply that record_packets is false;
// we might want instead to process the connection off-line.
void SetSkip(int do_skip) { skip = do_skip; }
int Skipping() const { return skip; }
// Arrange for the connection to expire after the given amount of time.
void SetLifetime(double lifetime);
// Returns true if the packet reflects a reuse of this
// connection (i.e., not a continuation but the beginning of
// a new connection).
bool IsReuse(double t, const u_char* pkt);
// Get/set the inactivity timeout for this connection.
void SetInactivityTimeout(double timeout);
double InactivityTimeout() const { return inactivity_timeout; }
// Activate connection_status_update timer.
void EnableStatusUpdateTimer();
RecordVal* BuildConnVal();
void AppendAddl(const char* str);
LoginConn* AsLoginConn() { return login_conn; }
void Match(Rule::PatternType type, const u_char* data, int len,
bool is_orig, bool bol, bool eol, bool clear_state);
// Tries really hard to extract a program name and a version.
Val* BuildVersionVal(const char* s, int len);
// Raises a software_version_found event based on the
// given string (returns false if it's not parseable).
int VersionFoundEvent(const IPAddr& addr, const char* s, int len,
analyzer::Analyzer* analyzer = 0);
// Raises a software_unparsed_version_found event.
int UnparsedVersionFoundEvent(const IPAddr& addr,
const char* full_descr, int len, analyzer::Analyzer* analyzer);
void Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, const char* name = 0);
void Event(EventHandlerPtr f, analyzer::Analyzer* analyzer, Val* v1, Val* v2 = 0);
void ConnectionEvent(EventHandlerPtr f, analyzer::Analyzer* analyzer,
val_list* vl);
void Weird(const char* name, const char* addl = "");
bool DidWeird() const { return weird != 0; }
// Cancel all associated timers.
void CancelTimers();
inline int FlagEvent(ConnEventToFlag e)
{
if ( e >= 0 && e < NUM_EVENTS_TO_FLAG )
{
if ( suppress_event & (1 << e) )
return 0;
suppress_event |= 1 << e;
}
return 1;
}
void MakePersistent()
{
persistent = 1;
persistence_serializer->Register(this);
}
bool IsPersistent() { return persistent; }
void Describe(ODesc* d) const;
void IDString(ODesc* d) const;
TimerMgr* GetTimerMgr() const;
// Returns true if connection has been received externally.
bool IsExternal() const { return conn_timer_mgr != 0; }
bool Serialize(SerialInfo* info) const;
static Connection* Unserialize(UnserialInfo* info);
DECLARE_SERIAL(Connection);
// Statistics.
// Just a lower bound.
unsigned int MemoryAllocation() const;
unsigned int MemoryAllocationConnVal() const;
static unsigned int TotalConnections()
{ return total_connections; }
static unsigned int CurrentConnections()
{ return current_connections; }
static unsigned int CurrentExternalConnections()
{ return external_connections; }
// Returns true if the history was already seen, false otherwise.
int CheckHistory(uint32 mask, char code)
{
if ( (hist_seen & mask) == 0 )
{
hist_seen |= mask;
AddHistory(code);
return false;
}
else
return true;
}
void AddHistory(char code) { history += code; }
void DeleteTimer(double t);
// Sets the root of the analyzer tree as well as the primary PIA.
void SetRootAnalyzer(analyzer::TransportLayerAnalyzer* analyzer, analyzer::pia::PIA* pia);
analyzer::TransportLayerAnalyzer* GetRootAnalyzer() { return root_analyzer; }
analyzer::pia::PIA* GetPrimaryPIA() { return primary_PIA; }
// Sets the transport protocol in use.
void SetTransport(TransportProto arg_proto) { proto = arg_proto; }
void SetUID(Bro::UID arg_uid) { uid = arg_uid; }
Bro::UID GetUID() const { return uid; }
const EncapsulationStack* GetEncapsulation() const
{ return encapsulation; }
void CheckFlowLabel(bool is_orig, uint32 flow_label);
protected:
Connection() { persistent = 0; }
// Add the given timer to expire at time t. If do_expire
// is true, then the timer is also evaluated when Bro terminates,
// otherwise not.
void AddTimer(timer_func timer, double t, int do_expire,
TimerType type);
void RemoveTimer(Timer* t);
// Allow other classes to access pointers to these:
friend class ConnectionTimer;
void InactivityTimer(double t);
void StatusUpdateTimer(double t);
void RemoveConnectionTimer(double t);
NetSessions* sessions;
HashKey* key;
// Timer manager to use for this conn (or nil).
TimerMgr::Tag* conn_timer_mgr;
timer_list timers;
IPAddr orig_addr;
IPAddr resp_addr;
uint32 orig_port, resp_port; // in network order
TransportProto proto;
uint32 orig_flow_label, resp_flow_label; // most recent IPv6 flow labels
double start_time, last_time;
double inactivity_timeout;
RecordVal* conn_val;
LoginConn* login_conn; // either nil, or this
const EncapsulationStack* encapsulation; // tunnels
int suppress_event; // suppress certain events to once per conn.
unsigned int installed_status_timer:1;
unsigned int timers_canceled:1;
unsigned int is_active:1;
unsigned int skip:1;
unsigned int weird:1;
unsigned int finished:1;
unsigned int record_packets:1, record_contents:1;
unsigned int persistent:1;
unsigned int record_current_packet:1, record_current_content:1;
unsigned int saw_first_orig_packet:1, saw_first_resp_packet:1;
// Count number of connections.
static unsigned int total_connections;
static unsigned int current_connections;
static unsigned int external_connections;
string history;
uint32 hist_seen;
analyzer::TransportLayerAnalyzer* root_analyzer;
analyzer::pia::PIA* primary_PIA;
Bro::UID uid; // Globally unique connection ID.
};
class ConnectionTimer : public Timer {
public:
ConnectionTimer(Connection* arg_conn, timer_func arg_timer,
double arg_t, int arg_do_expire, TimerType arg_type)
: Timer(arg_t, arg_type)
{ Init(arg_conn, arg_timer, arg_do_expire); }
virtual ~ConnectionTimer();
void Dispatch(double t, int is_expire);
protected:
ConnectionTimer() {}
void Init(Connection* conn, timer_func timer, int do_expire);
DECLARE_SERIAL(ConnectionTimer);
Connection* conn;
timer_func timer;
int do_expire;
};
#define ADD_TIMER(timer, t, do_expire, type) \
AddTimer(timer_func(timer), (t), (do_expire), (type))
#endif