Branch data Line data Source code
1 : : // $Id: TCP.h 6782 2009-06-28 02:19:03Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #ifndef TCP_H
6 : : #define TCP_H
7 : :
8 : : #include "Analyzer.h"
9 : : #include "TCP.h"
10 : : #include "Rewriter.h"
11 : : #include "PacketDumper.h"
12 : :
13 : : // We define two classes here:
14 : : // - TCP_Analyzer is the analyzer for the TCP protocol itself.
15 : : // - TCP_ApplicationAnalyzer is an abstract base class for analyzers for a
16 : : // protocol running on top of TCP.
17 : :
18 : : class PIA_TCP;
19 : : class TCP_ApplicationAnalyzer;
20 : : class TCP_Reassembler;
21 : : class TCP_Rewriter;
22 : : class TCP_SourcePacketWriter;
23 : :
24 : : class TCP_Flags {
25 : : public:
26 : 17976 : TCP_Flags(const struct tcphdr* tp) { flags = tp->th_flags; }
27 : :
28 : 105591 : bool SYN() { return flags & TH_SYN; }
29 : 74964 : bool FIN() { return flags & TH_FIN; }
30 : 101392 : bool RST() { return flags & TH_RST; }
31 : 27651 : bool ACK() { return flags & TH_ACK; }
32 : 1042 : bool URG() { return flags & TH_URG; }
33 : 0 : bool PUSH() { return flags & TH_PUSH; }
34 : :
35 : : protected:
36 : : u_char flags;
37 : : };
38 : :
39 : : class TCP_Analyzer : public TransportLayerAnalyzer {
40 : : public:
41 : : TCP_Analyzer(Connection* conn);
42 : : virtual ~TCP_Analyzer();
43 : :
44 : : void EnableReassembly();
45 : :
46 : : // Add a child analyzer that will always get the packets,
47 : : // independently of whether we do any reassembly.
48 : 0 : void AddChildPacketAnalyzer(Analyzer* a)
49 : 0 : { packet_children.push_back(a); a->SetParent(this); }
50 : :
51 : : // True if the connection has closed in some sense, false otherwise.
52 [ + + ][ + + ]: 25 : int IsClosed() const { return orig->did_close || resp->did_close; }
53 [ + + ][ - + ]: 524 : int BothClosed() const { return orig->did_close && resp->did_close; }
54 : :
55 : 17866 : int IsPartial() const { return is_partial; }
56 : :
57 : : bool HadGap(bool orig) const;
58 : :
59 : 938 : TCP_Endpoint* Orig() const { return orig; }
60 : 938 : TCP_Endpoint* Resp() const { return resp; }
61 : 0 : int OrigState() const { return orig->state; }
62 : 0 : int RespState() const { return resp->state; }
63 : 0 : int OrigPrevState() const { return orig->prev_state; }
64 : 0 : int RespPrevState() const { return resp->prev_state; }
65 : 0 : uint32 OrigSeq() const { return orig->LastSeq(); }
66 : 0 : uint32 RespSeq() const { return resp->LastSeq(); }
67 : :
68 : : // True if either endpoint still has pending data. closing_endp
69 : : // is an endpoint that has indicated it is closing (i.e., for
70 : : // which we have seen a FIN) - for it, data is pending unless
71 : : // everything's been delivered up to the FIN. For its peer,
72 : : // the test is whether it has any outstanding, un-acked data.
73 : : int DataPending(TCP_Endpoint* closing_endp);
74 : :
75 : : virtual void SetContentsFile(unsigned int direction, BroFile* f);
76 : : virtual BroFile* GetContentsFile(unsigned int direction) const;
77 : :
78 : 0 : TCP_SourcePacketWriter* SourcePacketWriter() const
79 : 0 : { return src_pkt_writer; }
80 : :
81 : : // Callback to process a TCP option.
82 : : typedef int (*proc_tcp_option_t)(unsigned int opt, unsigned int optlen,
83 : : const u_char* option, TCP_Analyzer* analyzer,
84 : : bool is_orig, void* cookie);
85 : :
86 : : // Needs to be static because it's passed as a pointer-to-function
87 : : // rather than pointer-to-member-function.
88 : : static int ParseTCPOptions(const struct tcphdr* tcp,
89 : : proc_tcp_option_t proc, TCP_Analyzer* analyzer,
90 : : bool is_orig, void* cookie);
91 : :
92 : 0 : static Analyzer* InstantiateAnalyzer(Connection* conn)
93 : 0 : { return new TCP_Analyzer(conn); }
94 : :
95 : 1 : static bool Available() { return true; }
96 : :
97 : : protected:
98 : : friend class TCP_ApplicationAnalyzer;
99 : : friend class TCP_Reassembler;
100 : : friend class PIA_TCP;
101 : :
102 : : // Analyzer interface.
103 : : virtual void Init();
104 : : virtual void Done();
105 : : virtual void DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen);
106 : : virtual void DeliverStream(int len, const u_char* data, bool orig);
107 : : virtual void Undelivered(int seq, int len, bool orig);
108 : : virtual void FlipRoles();
109 : : virtual void UpdateEndpointVal(RecordVal* endp, int is_orig);
110 : : virtual bool IsReuse(double t, const u_char* pkt);
111 : :
112 : : // Returns the TCP header pointed to by data (which we assume is
113 : : // aligned), updating data, len & caplen. Returns nil if the header
114 : : // isn't fully present.
115 : : const struct tcphdr* ExtractTCP_Header(const u_char*& data, int& len,
116 : : int& caplen);
117 : :
118 : : // Returns true if the checksum is valid, false if not (and in which
119 : : // case also updates the status history of the endpoint).
120 : : bool ValidateChecksum(const struct tcphdr* tp, TCP_Endpoint* endpoint,
121 : : int len, int caplen);
122 : :
123 : : // Update analysis based on flag combinations. The endpoint, base_seq
124 : : // and len are needed for tracking various history information.
125 : : // dst_port is needed for trimming of FIN packets.
126 : : void CheckFlagCombos(TCP_Flags flags, TCP_Endpoint* endpoint,
127 : : uint32 base_seq, int len, int dst_port);
128 : :
129 : : void UpdateWindow(TCP_Endpoint* endpoint, unsigned int window,
130 : : uint32 base_seq, uint32 ack_seq,
131 : : TCP_Flags flags);
132 : :
133 : : void ProcessSYN(const IP_Hdr* ip, const struct tcphdr* tp,
134 : : uint32 tcp_hdr_len, int& seq_len,
135 : : TCP_Endpoint* endpoint, TCP_Endpoint* peer,
136 : : uint32 base_seq, uint32 ack_seq,
137 : : const uint32* orig_addr,
138 : : int is_orig, TCP_Flags flags);
139 : :
140 : : void ProcessFIN(double t, TCP_Endpoint* endpoint, int& seq_len,
141 : : uint32 base_seq);
142 : :
143 : : bool ProcessRST(double t, TCP_Endpoint* endpoint, const IP_Hdr* ip,
144 : : uint32 base_seq, int len, int& seq_len);
145 : :
146 : : void ProcessACK(TCP_Endpoint* endpoint, TCP_Endpoint* peer,
147 : : uint32 ack_seq, int is_orig, TCP_Flags flags);
148 : :
149 : : int ProcessFlags(double t, const IP_Hdr* ip, const struct tcphdr* tp,
150 : : uint32 tcp_hdr_len, int len, int& seq_len,
151 : : TCP_Endpoint* endpoint, TCP_Endpoint* peer,
152 : : uint32 base_seq, uint32 ack_seq,
153 : : const uint32* orig_addr,
154 : : int is_orig, TCP_Flags flags);
155 : :
156 : : void TransitionFromInactive(double t, TCP_Endpoint* endpoint,
157 : : uint32 base_seq, uint32 last_seq,
158 : : int SYN);
159 : :
160 : : // Update the state machine of the TCPs based on the activity. This
161 : : // includes our pseudo-states such as TCP_ENDPOINT_PARTIAL.
162 : : //
163 : : // On return, do_close is true if we should consider the connection
164 : : // as closed, and gen_event if we shouuld generate an event about
165 : : // this fact.
166 : : void UpdateStateMachine(double t,
167 : : TCP_Endpoint* endpoint, TCP_Endpoint* peer,
168 : : uint32 base_seq, uint32 ack_seq, uint32 last_seq,
169 : : int len, int delta_last, int is_orig, TCP_Flags flags,
170 : : int& do_close, int& gen_event);
171 : :
172 : : void UpdateInactiveState(double t,
173 : : TCP_Endpoint* endpoint, TCP_Endpoint* peer,
174 : : uint32 base_seq, uint32 ack_seq,
175 : : int len, int is_orig, TCP_Flags flags,
176 : : int& do_close, int& gen_event);
177 : :
178 : : void UpdateSYN_SentState(double t,
179 : : TCP_Endpoint* endpoint, TCP_Endpoint* peer,
180 : : uint32 base_seq, uint32 last_seq,
181 : : int len, int is_orig, TCP_Flags flags,
182 : : int& do_close, int& gen_event);
183 : :
184 : : void UpdateEstablishedState(double t,
185 : : TCP_Endpoint* endpoint, TCP_Endpoint* peer,
186 : : uint32 base_seq, uint32 last_seq,
187 : : int is_orig, TCP_Flags flags,
188 : : int& do_close, int& gen_event);
189 : :
190 : : void UpdateClosedState(double t, TCP_Endpoint* endpoint,
191 : : int delta_last, TCP_Flags flags,
192 : : int& do_close);
193 : :
194 : : void UpdateResetState(int len, TCP_Flags flags);
195 : :
196 : : void GeneratePacketEvent(TCP_Endpoint* endpoint, TCP_Endpoint* peer,
197 : : uint32 base_seq, uint32 ack_seq,
198 : : const u_char* data, int len, int caplen,
199 : : int is_orig, TCP_Flags flags);
200 : :
201 : : int DeliverData(double t, const u_char* data, int len, int caplen,
202 : : const IP_Hdr* ip, const struct tcphdr* tp,
203 : : TCP_Endpoint* endpoint, uint32 base_seq,
204 : : int is_orig, TCP_Flags flags);
205 : :
206 : : void CheckRecording(int need_contents, TCP_Flags flags);
207 : : void CheckPIA_FirstPacket(int is_orig, const IP_Hdr* ip);
208 : :
209 : : // Returns the difference between last_seq and the last sequence
210 : : // seen by the endpoint (may be negative).
211 : : int UpdateLastSeq(TCP_Endpoint* endpoint, uint32 last_seq,
212 : : TCP_Flags flags);
213 : :
214 : : friend class ConnectionTimer;
215 : : void AttemptTimer(double t);
216 : : void PartialCloseTimer(double t);
217 : : void ExpireTimer(double t);
218 : : void ResetTimer(double t);
219 : : void DeleteTimer(double t);
220 : 502 : void ConnDeleteTimer(double t) { Conn()->DeleteTimer(t); }
221 : :
222 : : void EndpointEOF(TCP_Reassembler* endp);
223 : : void TraceRewriterEOF(TCP_Reassembler* endp);
224 : : void ConnectionClosed(TCP_Endpoint* endpoint,
225 : : TCP_Endpoint* peer, int gen_event);
226 : : void ConnectionFinished(int half_finished);
227 : : void ConnectionReset();
228 : : void PacketWithRST();
229 : :
230 : : void SetReassembler(TCP_Reassembler* rorig, TCP_Reassembler* rresp);
231 : :
232 : : Val* BuildSYNPacketVal(int is_orig,
233 : : const IP_Hdr* ip, const struct tcphdr* tcp);
234 : :
235 : : RecordVal* BuildOSVal(int is_orig, const IP_Hdr* ip,
236 : : const struct tcphdr* tcp, uint32 tcp_hdr_len);
237 : :
238 : : // Needs to be static because it's passed as a pointer-to-function
239 : : // rather than pointer-to-member-function.
240 : : static int TCPOptionEvent(unsigned int opt, unsigned int optlen,
241 : : const u_char* option, TCP_Analyzer* analyzer,
242 : : bool is_orig, void* cookie);
243 : :
244 : : private:
245 : : TCP_Endpoint* orig;
246 : : TCP_Endpoint* resp;
247 : :
248 : : analyzer_list packet_children;
249 : :
250 : : TCP_SourcePacketWriter* src_pkt_writer;
251 : :
252 : : unsigned int first_packet_seen: 2;
253 : : unsigned int reassembling: 1;
254 : : unsigned int is_partial: 1;
255 : : unsigned int is_active: 1;
256 : : unsigned int finished: 1;
257 : :
258 : : // Whether we're waiting on final data delivery before closing
259 : : // this connection.
260 : : unsigned int close_deferred: 1;
261 : :
262 : : // Whether to generate an event when we finally do close it.
263 : : unsigned int deferred_gen_event: 1;
264 : :
265 : : // Whether we have seen the first ACK from the originator.
266 : : unsigned int seen_first_ACK: 1;
267 : : };
268 : :
269 : : class TCP_ApplicationAnalyzer : public Analyzer {
270 : : public:
271 : 1631 : TCP_ApplicationAnalyzer(AnalyzerTag::Tag tag, Connection* conn)
272 : 1631 : : Analyzer(tag, conn)
273 : 1631 : { tcp = 0; }
274 : :
275 [ - + ][ # # ]: 1631 : virtual ~TCP_ApplicationAnalyzer() { }
[ # # ]
276 : :
277 : : // This may be nil if we are not directly associated with a TCP
278 : : // analyzer (e.g., we're part of a tunnel decapsulation pipeline).
279 : 32288 : TCP_Analyzer* TCP()
280 : : {
281 : : return tcp ?
282 : : tcp :
283 : : static_cast<TCP_Analyzer*>(
284 [ + - ]: 32288 : Conn()->FindAnalyzer(AnalyzerTag::TCP));
285 : : }
286 : :
287 : 2569 : void SetTCP(TCP_Analyzer* arg_tcp) { tcp = arg_tcp; }
288 : :
289 : : // The given endpoint's data delivery is complete.
290 : : virtual void EndpointEOF(bool is_orig);
291 : : virtual void TraceRewriterEOF(bool is_orig);
292 : :
293 : : // Called whenever an end enters TCP_ENDPOINT_CLOSED or
294 : : // TCP_ENDPOINT_RESET. If gen_event is true and the connection
295 : : // is now fully closed, a connection_finished event will be
296 : : // generated; otherwise not.
297 : : virtual void ConnectionClosed(TCP_Endpoint* endpoint,
298 : : TCP_Endpoint* peer, int gen_event);
299 : : virtual void ConnectionFinished(int half_finished);
300 : : virtual void ConnectionReset();
301 : :
302 : : // Called whenever a RST packet is seen - sometimes the invocation
303 : : // of ConnectionReset is delayed.
304 : : virtual void PacketWithRST();
305 : :
306 : : virtual void DeliverPacket(int len, const u_char* data, bool orig,
307 : : int seq, const IP_Hdr* ip, int caplen);
308 : : virtual void Init();
309 : :
310 : : // This suppresses violations if the TCP connection wasn't
311 : : // fully established.
312 : : virtual void ProtocolViolation(const char* reason,
313 : : const char* data = 0, int len = 0);
314 : :
315 : : // "name" and "val" both now belong to this object, which needs to
316 : : // delete them when done with them.
317 : : virtual void SetEnv(bool orig, char* name, char* val);
318 : :
319 : : protected:
320 : : TCP_ApplicationAnalyzer() { };
321 : :
322 : : private:
323 : : TCP_Analyzer* tcp;
324 : : };
325 : :
326 : : class TCP_SupportAnalyzer : public SupportAnalyzer {
327 : : public:
328 : 1497 : TCP_SupportAnalyzer(AnalyzerTag::Tag tag, Connection* conn, bool arg_orig)
329 : 1497 : : SupportAnalyzer(tag, conn, arg_orig) { }
330 : :
331 [ - + ][ # # ]: 1497 : virtual ~TCP_SupportAnalyzer() {}
[ # # ]
332 : :
333 : : // These are passed on from TCP_Analyzer.
334 : 0 : virtual void EndpointEOF(bool is_orig) { }
335 : 717 : virtual void TraceRewriterEOF(bool is_orig) { }
336 : : virtual void ConnectionClosed(TCP_Endpoint* endpoint,
337 : 743 : TCP_Endpoint* peer, int gen_event) { }
338 : 544 : virtual void ConnectionFinished(int half_finished) { }
339 : 82 : virtual void ConnectionReset() { }
340 : 262 : virtual void PacketWithRST() { }
341 : : };
342 : :
343 : :
344 : : class TCPStats_Endpoint {
345 : : public:
346 : : TCPStats_Endpoint(TCP_Endpoint* endp);
347 : :
348 : : int DataSent(double t, int seq, int len, int caplen, const u_char* data,
349 : : const IP_Hdr* ip, const struct tcphdr* tp);
350 : :
351 : : RecordVal* BuildStats();
352 : :
353 : : protected:
354 : : TCP_Endpoint* endp;
355 : : int num_pkts;
356 : : int num_rxmit;
357 : : int num_rxmit_bytes;
358 : : int num_in_order;
359 : : int num_OO;
360 : : int num_repl;
361 : : int max_top_seq;
362 : : int last_id;
363 : : int endian_type;
364 : : };
365 : :
366 : : class TCPStats_Analyzer : public TCP_ApplicationAnalyzer {
367 : : public:
368 : : TCPStats_Analyzer(Connection* c);
369 : : ~TCPStats_Analyzer();
370 : :
371 : : virtual void Init();
372 : : virtual void Done();
373 : :
374 : 0 : static Analyzer* InstantiateAnalyzer(Connection* conn)
375 : 0 : { return new TCPStats_Analyzer(conn); }
376 : :
377 [ + - ][ - + ]: 939 : static bool Available() { return conn_stats || tcp_rexmit; }
378 : :
379 : : protected:
380 : : virtual void DeliverPacket(int len, const u_char* data, bool is_orig,
381 : : int seq, const IP_Hdr* ip, int caplen);
382 : :
383 : : TCPStats_Endpoint* orig_stats;
384 : : TCPStats_Endpoint* resp_stats;
385 : : };
386 : :
387 : : #endif
|