Branch data Line data Source code
1 : : // $Id: Conn.h 6916 2009-09-24 20:48:36Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #ifndef conn_h
6 : : #define conn_h
7 : :
8 : : #include <sys/types.h>
9 : :
10 : : #include "Dict.h"
11 : : #include "Val.h"
12 : : #include "Timer.h"
13 : : #include "Serializer.h"
14 : : #include "PersistenceSerializer.h"
15 : : #include "RuleMatcher.h"
16 : : #include "AnalyzerTags.h"
17 : :
18 : : class Connection;
19 : : class ConnectionTimer;
20 : : class NetSessions;
21 : : class LoginConn;
22 : : class RuleHdrTest;
23 : : class Specific_RE_Matcher;
24 : : class TransportLayerAnalyzer;
25 : : class RuleEndpointState;
26 : : class Rewriter;
27 : :
28 : : typedef enum {
29 : : NUL_IN_LINE,
30 : : SINGULAR_CR,
31 : : SINGULAR_LF,
32 : : NUM_EVENTS_TO_FLAG,
33 : : } ConnEventToFlag;
34 : :
35 : : typedef void (Connection::*timer_func)(double t);
36 : :
37 : : struct ConnID {
38 : : const uint32* src_addr;
39 : : const uint32* dst_addr;
40 : : uint32 src_port;
41 : : uint32 dst_port;
42 : : bool is_one_way; // if true, don't canonicalize
43 : :
44 : : // Returns a ListVal suitable for looking up a connection in
45 : : // a hash table. addr/ports are expected to be in network order.
46 : : // Unless is_one_way is true, the lookup sorts src and dst,
47 : : // so src_addr/src_port and dst_addr/dst_port just have to
48 : : // reflect the two different sides of the connection,
49 : : // neither has to be the particular source/destination
50 : : // or originator/responder.
51 : : HashKey* BuildConnKey() const;
52 : :
53 : : // The structure used internally for hashing.
54 : : struct Key {
55 : : uint32 ip1[NUM_ADDR_WORDS];
56 : : uint32 ip2[NUM_ADDR_WORDS];
57 : : uint16 port1;
58 : : uint16 port2;
59 : : };
60 : : };
61 : :
62 : : static inline int addr_port_canon_lt(const uint32* a1, uint32 p1,
63 : 20247 : const uint32* a2, uint32 p2)
64 : : {
65 : : #ifdef BROv6
66 : : // Because it's a canonical ordering, not a strict ordering,
67 : : // we can choose to give more weight to the least significant
68 : : // word than to the most significant word. This matters
69 : : // because for the common case of IPv4 addresses embedded in
70 : : // a IPv6 address, the top three words are identical, so we can
71 : : // save a few cycles by first testing the bottom word.
72 : : return a1[3] < a2[3] ||
73 : : (a1[3] == a2[3] &&
74 : : (a1[2] < a2[2] ||
75 : : (a1[2] == a2[2] &&
76 : : (a1[1] < a2[1] ||
77 : : (a1[1] == a2[1] &&
78 : : (a1[0] < a2[0] ||
79 : : (a1[0] == a2[0] &&
80 : : p1 < p2)))))));
81 : : #else
82 [ + + ][ - + ]: 20247 : return *a1 < *a2 || (*a1 == *a2 && p1 < p2);
[ # # ]
83 : : #endif
84 : : }
85 : :
86 : : class Analyzer;
87 : :
88 : : class Connection : public BroObj {
89 : : public:
90 : : Connection(NetSessions* s, HashKey* k, double t, const ConnID* id);
91 : : virtual ~Connection();
92 : :
93 : : // Invoked when connection is about to be removed. Use Ref(this)
94 : : // inside Done to keep the connection object around (though it'll
95 : : // no longer be accessible from the dictionary of active
96 : : // connections).
97 : : void Done();
98 : :
99 : : // Process the connection's next packet. "data" points just
100 : : // beyond the IP header. It's updated to point just beyond
101 : : // the transport header (or whatever should be saved, if we
102 : : // decide not to save the full packet contents).
103 : : //
104 : : // If record_packet is true, the packet should be recorded.
105 : : // If record_content is true, then its entire contents should
106 : : // be recorded, otherwise just up through the transport header.
107 : : // Both are assumed set to true when called.
108 : : void NextPacket(double t, int is_orig,
109 : : const IP_Hdr* ip, int len, int caplen,
110 : : const u_char*& data,
111 : : int& record_packet, int& record_content,
112 : : // arguments for reproducing packets
113 : : const struct pcap_pkthdr* hdr,
114 : : const u_char* const pkt,
115 : : int hdr_size);
116 : :
117 : 1624 : HashKey* Key() const { return key; }
118 : 1624 : void ClearKey() { key = 0; }
119 : :
120 : 0 : double StartTime() const { return start_time; }
121 : : void SetStartTime(double t) { start_time = t; }
122 : 16594 : double LastTime() const { return last_time; }
123 : 19204 : void SetLastTime(double t) { last_time = t; }
124 : :
125 : 59323 : const uint32* OrigAddr() const { return orig_addr; }
126 : 39633 : const uint32* RespAddr() const { return resp_addr; }
127 : :
128 : 29042 : uint32 OrigPort() const { return orig_port; }
129 : 23034 : uint32 RespPort() const { return resp_port; }
130 : :
131 : : void FlipRoles();
132 : :
133 : : Analyzer* FindAnalyzer(AnalyzerID id);
134 : : Analyzer* FindAnalyzer(AnalyzerTag::Tag tag); // find first in tree.
135 : :
136 : 4875 : TransportProto ConnTransport() const { return proto; }
137 : :
138 : : // If we are rewriting the trace of the connection, then we do
139 : : // not record original packets. We are rewriting if at least one,
140 : : // then the analyzer is rewriting.
141 : : int RewritingTrace();
142 : :
143 : : // If we are rewriting trace, we need a handle to the rewriter.
144 : : // Returns 0 if not rewriting. (Note that if multiple analyzers
145 : : // want to rewrite, only one of them is returned. It's undefined
146 : : // which one.)
147 : : Rewriter* TraceRewriter() const;
148 : :
149 : : // True if we should record subsequent packets (either headers or
150 : : // in their entirety, depending on record_contents). We still
151 : : // record subsequent SYN/FIN/RST, regardless of how this is set.
152 : 17976 : int RecordPackets() const { return record_packets; }
153 : 0 : void SetRecordPackets(int do_record) { record_packets = do_record; }
154 : :
155 : : // True if we should record full packets for this connection,
156 : : // false if we should just record headers.
157 : 9424 : int RecordContents() const { return record_contents; }
158 : : void SetRecordContents(int do_record) { record_contents = do_record; }
159 : :
160 : : // Set whether to record *current* packet header/full.
161 : 17976 : void SetRecordCurrentPacket(int do_record)
162 : 17976 : { record_current_packet = do_record; }
163 : 17976 : void SetRecordCurrentContent(int do_record)
164 : 17976 : { record_current_content = do_record; }
165 : :
166 : : // FIXME: Now this is in Analyzer and should eventually be removed here.
167 : : //
168 : : // If true, skip processing of remainder of connection. Note
169 : : // that this does not in itself imply that record_packets is false;
170 : : // we might want instead to process the connection off-line.
171 : 0 : void SetSkip(int do_skip) { skip = do_skip; }
172 : 19690 : int Skipping() const { return skip; }
173 : :
174 : : // Arrange for the connection to expire after the given amount of time.
175 : : void SetLifetime(double lifetime);
176 : :
177 : : // Returns true if the packet reflects a reuse of this
178 : : // connection (i.e., not a continuation but the beginning of
179 : : // a new connection).
180 : : bool IsReuse(double t, const u_char* pkt);
181 : :
182 : : // Get/set the inactivity timeout for this connection.
183 : : void SetInactivityTimeout(double timeout);
184 : 0 : double InactivityTimeout() const { return inactivity_timeout; }
185 : :
186 : : // Activate connection_status_update timer.
187 : : void EnableStatusUpdateTimer();
188 : :
189 : : RecordVal* BuildConnVal();
190 : : void AppendAddl(const char* str);
191 : :
192 : : LoginConn* AsLoginConn() { return login_conn; }
193 : :
194 : : void Match(Rule::PatternType type, const u_char* data, int len,
195 : : bool is_orig, bool bol, bool eol, bool clear_state);
196 : :
197 : : // Tries really hard to extract a program name and a version.
198 : : Val* BuildVersionVal(const char* s, int len);
199 : :
200 : : // Raises a software_version_found event based on the
201 : : // given string (returns false if it's not parseable).
202 : : int VersionFoundEvent(const uint32* addr, const char* s, int len,
203 : : Analyzer* analyzer = 0);
204 : :
205 : : // Raises a software_unparsed_version_found event.
206 : : int UnparsedVersionFoundEvent(const uint32* addr,
207 : : const char* full_descr, int len, Analyzer* analyzer);
208 : :
209 : : void Event(EventHandlerPtr f, Analyzer* analyzer, const char* name = 0);
210 : : void Event(EventHandlerPtr f, Analyzer* analyzer, Val* v1, Val* v2 = 0);
211 : : void ConnectionEvent(EventHandlerPtr f, Analyzer* analyzer,
212 : : val_list* vl);
213 : :
214 : : void Weird(const char* name);
215 : : void Weird(const char* name, const char* addl);
216 : : void Weird(const char* name, int addl_len, const char* addl);
217 : 3 : bool DidWeird() const { return weird != 0; }
218 : :
219 : : // Cancel all associated timers.
220 : : void CancelTimers();
221 : :
222 : 0 : inline int FlagEvent(ConnEventToFlag e)
223 : : {
224 [ # # ][ # # ]: 0 : if ( e >= 0 && e < NUM_EVENTS_TO_FLAG )
225 : : {
226 [ # # ]: 0 : if ( suppress_event & (1 << e) )
227 : 0 : return 0;
228 : 0 : suppress_event |= 1 << e;
229 : : }
230 : :
231 : 0 : return 1;
232 : : }
233 : :
234 : 0 : void MakePersistent()
235 : : {
236 : 0 : persistent = 1;
237 : 0 : persistence_serializer->Register(this);
238 : 0 : }
239 : :
240 : 1624 : bool IsPersistent() { return persistent; }
241 : :
242 : : void Describe(ODesc* d) const;
243 : :
244 : : TimerMgr* GetTimerMgr() const;
245 : :
246 : : // Returns true if connection has been received externally.
247 : 1831 : bool IsExternal() const { return conn_timer_mgr != 0; }
248 : :
249 : : bool Serialize(SerialInfo* info) const;
250 : : static Connection* Unserialize(UnserialInfo* info);
251 : :
252 : 0 : DECLARE_SERIAL(Connection);
253 : :
254 : : // Statistics.
255 : :
256 : : // Just a lower bound.
257 : : unsigned int MemoryAllocation() const;
258 : : unsigned int MemoryAllocationConnVal() const;
259 : :
260 : 0 : static unsigned int TotalConnections()
261 : 0 : { return total_connections; }
262 : 0 : static unsigned int CurrentConnections()
263 : 0 : { return current_connections; }
264 : 0 : static unsigned int CurrentExternalConnections()
265 : 0 : { return external_connections; }
266 : :
267 : : // Returns true if the history was already seen, false otherwise.
268 : 19659 : int CheckHistory(uint32 mask, char code)
269 : : {
270 [ + + ]: 19659 : if ( (hist_seen & mask) == 0 )
271 : : {
272 : 5647 : hist_seen |= mask;
273 : 5647 : AddHistory(code);
274 : 5647 : return false;
275 : : }
276 : : else
277 : 19659 : return true;
278 : : }
279 : :
280 : 5746 : void AddHistory(char code) { history += code; }
281 : :
282 : : void DeleteTimer(double t);
283 : :
284 : : // Sets the root of the analyzer tree as well as the primary PIA.
285 : : void SetRootAnalyzer(TransportLayerAnalyzer* analyzer, PIA* pia);
286 : 1624 : TransportLayerAnalyzer* GetRootAnalyzer() { return root_analyzer; }
287 : 1722 : PIA* GetPrimaryPIA() { return primary_PIA; }
288 : :
289 : : // Sets the transport protocol in use.
290 : 1627 : void SetTransport(TransportProto arg_proto) { proto = arg_proto; }
291 : :
292 : : // If the connection compressor is activated, we need a special memory
293 : : // layout for connections. (See ConnCompressor.h)
294 : 1627 : void* operator new(size_t size)
295 : : {
296 [ - + ]: 1627 : if ( ! use_connection_compressor )
297 : 0 : return ::operator new(size);
298 : :
299 : 1627 : void* c = ::operator new(size + 4);
300 : :
301 : : // We have to turn off the is_pending bit. By setting the
302 : : // first four bytes to zero, we'll achieve this.
303 : 1627 : *((uint32*) c) = 0;
304 : :
305 : 1627 : return ((char *) c) + 4;
306 : : }
307 : :
308 : 1627 : void operator delete(void* ptr)
309 : : {
310 [ - + ]: 1627 : if ( ! use_connection_compressor )
311 : 0 : ::operator delete(ptr);
312 : : else
313 : 1627 : ::operator delete(((char*) ptr) - 4);
314 : 1627 : }
315 : :
316 : : protected:
317 : 0 : Connection() { persistent = 0; }
318 : :
319 : : // Add the given timer to expire at time t. If do_expire
320 : : // is true, then the timer is also evaluated when Bro terminates,
321 : : // otherwise not.
322 : : void AddTimer(timer_func timer, double t, int do_expire,
323 : : TimerType type);
324 : :
325 : : void RemoveTimer(Timer* t);
326 : :
327 : : // Allow other classes to access pointers to these:
328 : : friend class ConnectionTimer;
329 : :
330 : : void InactivityTimer(double t);
331 : : void StatusUpdateTimer(double t);
332 : : void RemoveConnectionTimer(double t);
333 : :
334 : : NetSessions* sessions;
335 : : HashKey* key;
336 : :
337 : : // Timer manager to use for this conn (or nil).
338 : : TimerMgr::Tag* conn_timer_mgr;
339 : : timer_list timers;
340 : :
341 : : uint32 orig_addr[NUM_ADDR_WORDS]; // in network order
342 : : uint32 resp_addr[NUM_ADDR_WORDS]; // in network order
343 : : uint32 orig_port, resp_port; // in network order
344 : : TransportProto proto;
345 : : double start_time, last_time;
346 : : double inactivity_timeout;
347 : : RecordVal* conn_val;
348 : : RecordVal* orig_endp;
349 : : RecordVal* resp_endp;
350 : : LoginConn* login_conn; // either nil, or this
351 : : int suppress_event; // suppress certain events to once per conn.
352 : :
353 : : unsigned int installed_status_timer:1;
354 : : unsigned int timers_canceled:1;
355 : : unsigned int is_active:1;
356 : : unsigned int skip:1;
357 : : unsigned int weird:1;
358 : : unsigned int finished:1;
359 : : unsigned int record_packets:1, record_contents:1;
360 : : unsigned int persistent:1;
361 : : unsigned int record_current_packet:1, record_current_content:1;
362 : :
363 : : // Count number of connections.
364 : : static unsigned int total_connections;
365 : : static unsigned int current_connections;
366 : : static unsigned int external_connections;
367 : :
368 : : string history;
369 : : uint32 hist_seen;
370 : :
371 : : TransportLayerAnalyzer* root_analyzer;
372 : : PIA* primary_PIA;
373 : : };
374 : :
375 : : class ConnectionTimer : public Timer {
376 : : public:
377 : : ConnectionTimer(Connection* arg_conn, timer_func arg_timer,
378 : 2048 : double arg_t, int arg_do_expire, TimerType arg_type)
379 : 2048 : : Timer(arg_t, arg_type)
380 : 2048 : { Init(arg_conn, arg_timer, arg_do_expire); }
381 : : virtual ~ConnectionTimer();
382 : :
383 : : void Dispatch(double t, int is_expire);
384 : :
385 : : protected:
386 : 0 : ConnectionTimer() {}
387 : :
388 : : void Init(Connection* conn, timer_func timer, int do_expire);
389 : :
390 : 0 : DECLARE_SERIAL(ConnectionTimer);
391 : :
392 : : Connection* conn;
393 : : timer_func timer;
394 : : int do_expire;
395 : : };
396 : :
397 : : #define ADD_TIMER(timer, t, do_expire, type) \
398 : : AddTimer(timer_func(timer), (t), (do_expire), (type))
399 : :
400 : : #endif
|