Branch data Line data Source code
1 : : // $Id:$
2 : : //
3 : : // Main analyzer interface.
4 : :
5 : : #ifndef ANALYZER_H
6 : : #define ANALYZER_H
7 : :
8 : : #include <list>
9 : :
10 : : #include "AnalyzerTags.h"
11 : : #include "Conn.h"
12 : : #include "Obj.h"
13 : :
14 : : class DPM;
15 : : class PIA;
16 : : class Analyzer;
17 : : typedef list<Analyzer*> analyzer_list;
18 : :
19 : : typedef void (Analyzer::*analyzer_timer_func)(double t);
20 : :
21 : : // FIXME: This is a copy of ConnectionTimer, which we may eventually be
22 : : // able to get rid of.
23 : : class AnalyzerTimer : public Timer {
24 : : public:
25 : : AnalyzerTimer(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
26 : 18043 : double arg_t, int arg_do_expire, TimerType arg_type)
27 : 18043 : : Timer(arg_t, arg_type)
28 : 18043 : { Init(arg_analyzer, arg_timer, arg_do_expire); }
29 : : virtual ~AnalyzerTimer();
30 : :
31 : : void Dispatch(double t, int is_expire);
32 : :
33 : : protected:
34 : : AnalyzerTimer() {}
35 : :
36 : : void Init(Analyzer* analyzer, analyzer_timer_func timer, int do_expire);
37 : :
38 : : Analyzer* analyzer;
39 : : analyzer_timer_func timer;
40 : : int do_expire;
41 : : };
42 : :
43 : :
44 : : // Main analyzer interface.
45 : : //
46 : : // Each analyzer is part of a tree, having a parent analyzer and an
47 : : // arbitrary number of child analyzers. Each analyzer also has a list of
48 : : // *suppport analyzers*. All its input first passes through this list of
49 : : // support analyzers, which can perform arbitrary preprocessing. Support
50 : : // analyzers share the same interface as regular analyzers, except that
51 : : // they are unidirectional, i.e., they see only one side of a connection.
52 : : //
53 : : // When overiding any of these methods, always make sure to call the
54 : : // base-class version first.
55 : :
56 : : class SupportAnalyzer;
57 : : class OutputHandler;
58 : :
59 : : class Analyzer {
60 : : public:
61 : : Analyzer(AnalyzerTag::Tag tag, Connection* conn);
62 : : virtual ~Analyzer();
63 : :
64 : : virtual void Init();
65 : : virtual void Done();
66 : :
67 : : // Pass data to the analyzer (it's automatically passed through its
68 : : // support analyzers first). We have packet-wise and stream-wise
69 : : // interfaces. For the packet-interface, some analyzers may require
70 : : // more information than others, so IP/caplen and seq may or may
71 : : // not be set.
72 : : void NextPacket(int len, const u_char* data, bool orig,
73 : : int seq = -1, const IP_Hdr* ip = 0, int caplen = 0);
74 : : void NextStream(int len, const u_char* data, bool is_orig);
75 : :
76 : : // Used for data that can't be delivered (e.g., due to a previous
77 : : // sequence hole/gap).
78 : : void NextUndelivered(int seq, int len, bool is_orig);
79 : :
80 : : // Report message boundary. (See EndOfData() below.)
81 : : void NextEndOfData(bool orig);
82 : :
83 : : // Pass data on to all child analyzer(s). For SupportAnalyzers (see
84 : : // below), this is overridden to pass it on to the next sibling (or
85 : : // finally to the parent, if it's the last support analyzer).
86 : : //
87 : : // If we have an associated OutputHandler (see below), the data is
88 : : // additionally passed to that, too. For SupportAnalyzers, it is *only*
89 : : // delivered to the OutputHandler.
90 : : virtual void ForwardPacket(int len, const u_char* data,
91 : : bool orig, int seq,
92 : : const IP_Hdr* ip, int caplen);
93 : : virtual void ForwardStream(int len, const u_char* data, bool orig);
94 : : virtual void ForwardUndelivered(int seq, int len, bool orig);
95 : :
96 : : // Report a message boundary to all child analyzers
97 : : virtual void ForwardEndOfData(bool orig);
98 : :
99 : 84747 : AnalyzerID GetID() const { return id; }
100 : 246031 : Connection* Conn() const { return conn; }
101 : :
102 : : // An OutputHandler can be used to get access to data extracted by this
103 : : // analyzer (i.e., all data which is passed to
104 : : // Forward{Packet,Stream,Undelivered}). We take the ownership of
105 : : // the handler.
106 : 111 : class OutputHandler {
107 : : public:
108 [ # # ][ # # ]: 0 : virtual ~OutputHandler() { }
109 : :
110 : : virtual void DeliverPacket(int len, const u_char* data,
111 : : bool orig, int seq,
112 : 0 : const IP_Hdr* ip, int caplen)
113 : 0 : { }
114 : : virtual void DeliverStream(int len, const u_char* data,
115 : 0 : bool orig) { }
116 : 0 : virtual void Undelivered(int seq, int len, bool orig) { }
117 : : };
118 : :
119 : 16568 : OutputHandler* GetOutputHandler() const { return output_handler; }
120 : 111 : void SetOutputHandler(OutputHandler* handler)
121 : 111 : { output_handler = handler; }
122 : :
123 : : // If an analyzer was triggered by a signature match, this returns the
124 : : // name of the signature; nil if not.
125 : : const Rule* Signature() const { return signature; }
126 : 0 : void SetSignature(const Rule* sig) { signature = sig; }
127 : :
128 : 0 : void SetSkip(bool do_skip) { skip = do_skip; }
129 : 15720 : bool Skipping() const { return skip; }
130 : :
131 : 2311 : bool IsFinished() const { return finished; }
132 : :
133 : 7208 : AnalyzerTag::Tag GetTag() const { return tag; }
134 : : const char* GetTagName() const;
135 : : static AnalyzerTag::Tag GetTag(const char* tag);
136 : : static const char* GetTagName(AnalyzerTag::Tag tag);
137 : 0 : static bool IsAvailable(AnalyzerTag::Tag tag)
138 : 0 : { return analyzer_configs[tag].available(); }
139 : :
140 : : // Management of the tree.
141 : : //
142 : : // We immediately discard an added analyzer if there's already a child
143 : : // of the same type.
144 : 0 : void AddChildAnalyzer(Analyzer* analyzer)
145 : 0 : { AddChildAnalyzer(analyzer, true); }
146 : : Analyzer* AddChildAnalyzer(AnalyzerTag::Tag tag);
147 : :
148 : : void RemoveChildAnalyzer(Analyzer* analyzer);
149 : : void RemoveChildAnalyzer(AnalyzerID id);
150 : :
151 : : bool HasChildAnalyzer(AnalyzerTag::Tag tag);
152 : :
153 : : // Recursive; returns nil if not found.
154 : : Analyzer* FindChild(AnalyzerID id);
155 : :
156 : : // Recursive; returns first found, or nil.
157 : : Analyzer* FindChild(AnalyzerTag::Tag tag);
158 : :
159 : 6304 : const analyzer_list& GetChildren() { return children; }
160 : :
161 : 23310 : Analyzer* Parent() const { return parent; }
162 : 0 : void SetParent(Analyzer* p) { parent = p; }
163 : :
164 : : // Remove this child analyzer from the parent's list.
165 [ # # ]: 0 : void Remove() { assert(parent); parent->RemoveChildAnalyzer(this); }
166 : :
167 : : // Management of support analyzers. Support analyzers are associated
168 : : // with a direction, and will only see data in the corresponding flow.
169 : : //
170 : : // We immediately discard an added analyzer if there's already a child
171 : : // of the same type for the same direction.
172 : :
173 : : // Adds to tail of list.
174 : : void AddSupportAnalyzer(SupportAnalyzer* analyzer);
175 : :
176 : : void RemoveSupportAnalyzer(SupportAnalyzer* analyzer);
177 : :
178 : : // These are the methods where the analyzer actually gets its input.
179 : : // Each analyzer has only to implement the schemes it supports.
180 : :
181 : : // Packet-wise (or more generally chunk-wise) input. "data" points
182 : : // to the payload that the analyzer is supposed to examine. If it's
183 : : // part of a full packet, "ip" points to its IP header. An analyzer
184 : : // may or may not require to be given the full packet (and its caplen)
185 : : // as well.
186 : : virtual void DeliverPacket(int len, const u_char* data, bool orig,
187 : : int seq, const IP_Hdr* ip, int caplen);
188 : :
189 : : // Stream-wise payload input.
190 : : virtual void DeliverStream(int len, const u_char* data, bool orig);
191 : :
192 : : // If a parent analyzer can't turn a sequence of packets into a stream
193 : : // (e.g., due to holes), it can pass the remaining data through this
194 : : // method to the child.
195 : : virtual void Undelivered(int seq, int len, bool orig);
196 : :
197 : : // Report a message boundary. This is a generic method that can be used
198 : : // by specific Analyzers if all data of a message has been delivered,
199 : : // e.g., to report that HTTP body has been delivered completely by the
200 : : // HTTP analyzer before it starts with the next body. EndOfData() is
201 : : // automatically generated by the analyzer's Done() method.
202 : : virtual void EndOfData(bool is_orig);
203 : :
204 : : // Occasionally we may find during analysis that we got the direction
205 : : // of the connection wrong. In these cases, this method is called
206 : : // to swap state if necessary. This will not happen after payload
207 : : // has already been passed on, so most analyzers don't need to care.
208 : : virtual void FlipRoles();
209 : :
210 : : // Feedback about protocol conformance, to be called by the
211 : : // analyzer's processing. The methods raise the correspondiong
212 : : // protocol_confirmation and protocol_violation events.
213 : :
214 : : // Report that we believe we're parsing the right protocol. This
215 : : // should be called as early as possible during a connection's
216 : : // life-time. The protocol_confirmed event is only raised once per
217 : : // analyzer, even if the method is called multiple times.
218 : : virtual void ProtocolConfirmation();
219 : :
220 : : // Report that we found a significant protocol violation which might
221 : : // indicate that the analyzed data is in fact not the expected
222 : : // protocol. The protocol_violation event is raised once per call to
223 : : // this method so that the script-level may build up some notion of
224 : : // how "severely" protocol semantics are violated.
225 : : virtual void ProtocolViolation(const char* reason,
226 : : const char* data = 0, int len = 0);
227 : :
228 : : // Returns true if the analyzer or one of its children is rewriting
229 : : // the trace.
230 : : virtual int RewritingTrace();
231 : :
232 : : virtual unsigned int MemoryAllocation() const;
233 : :
234 : : // The following methods are proxies: calls are directly forwarded
235 : : // to the connection instance. These are for convenience only,
236 : : // allowing us to reuse more of the old analyzer code unchanged.
237 : 12038 : RecordVal* BuildConnVal()
238 : 12038 : { return conn->BuildConnVal(); }
239 : 3960 : void Event(EventHandlerPtr f, const char* name = 0)
240 : 3960 : { conn->Event(f, this, name); }
241 : 0 : void Event(EventHandlerPtr f, Val* v1, Val* v2 = 0)
242 : 0 : { conn->Event(f, this, v1, v2); }
243 : 11764 : void ConnectionEvent(EventHandlerPtr f, val_list* vl)
244 : 11764 : { conn->ConnectionEvent(f, this, vl); }
245 : 433 : void Weird(const char* name) { conn->Weird(name); }
246 : 0 : void Weird(const char* name, const char* addl)
247 : 0 : { conn->Weird(name, addl); }
248 : 0 : void Weird(const char* name, int addl_len, const char* addl)
249 : 0 : { conn->Weird(name, addl_len, addl); };
250 : :
251 : : // Factory function to instantiate new analyzers.
252 : : static Analyzer* InstantiateAnalyzer(AnalyzerTag::Tag tag, Connection* c);
253 : :
254 : : protected:
255 : : friend class DPM;
256 : : friend class Connection;
257 : : friend class AnalyzerTimer;
258 : : friend class TCP_ApplicationAnalyzer;
259 : :
260 : : Analyzer() { }
261 : :
262 : : // Associates a connection with this analyzer. Must be called if
263 : : // we're using the default ctor.
264 : : void SetConnection(Connection* c) { conn = c; }
265 : :
266 : : // Creates the given timer to expire at time t. If do_expire
267 : : // is true, then the timer is also evaluated when Bro terminates,
268 : : // otherwise not.
269 : : void AddTimer(analyzer_timer_func timer, double t, int do_expire,
270 : : TimerType type);
271 : :
272 : : void RemoveTimer(Timer* t);
273 : : void CancelTimers();
274 : :
275 : : bool HasSupportAnalyzer(AnalyzerTag::Tag tag, bool orig);
276 : :
277 : : void AddChildAnalyzer(Analyzer* analyzer, bool init);
278 : : void InitChildren();
279 : : void AppendNewChildren();
280 : :
281 : : private:
282 : : AnalyzerTag::Tag tag;
283 : : AnalyzerID id;
284 : :
285 : : Connection* conn;
286 : : Analyzer* parent;
287 : : const Rule* signature;
288 : : OutputHandler* output_handler;
289 : :
290 : : analyzer_list children;
291 : : SupportAnalyzer* orig_supporters;
292 : : SupportAnalyzer* resp_supporters;
293 : :
294 : : analyzer_list new_children;
295 : :
296 : : bool protocol_confirmed;
297 : :
298 : : timer_list timers;
299 : : bool timers_canceled;
300 : : bool skip;
301 : : bool finished;
302 : :
303 : : static AnalyzerID id_counter;
304 : :
305 : : typedef bool (*available_callback)();
306 : : typedef Analyzer* (*factory_callback)(Connection* conn);
307 : : typedef bool (*match_callback)(Connection*);
308 : :
309 : : struct Config {
310 : : AnalyzerTag::Tag tag;
311 : : const char* name;
312 : : factory_callback factory;
313 : : available_callback available;
314 : : match_callback match;
315 : : bool partial;
316 : : };
317 : :
318 : : // Table of analyzers.
319 : : static const Config analyzer_configs[];
320 : :
321 : : };
322 : :
323 : : #define ADD_ANALYZER_TIMER(timer, t, do_expire, type) \
324 : : AddTimer(analyzer_timer_func(timer), (t), (do_expire), (type))
325 : :
326 : : #define LOOP_OVER_CHILDREN(var) \
327 : : for ( analyzer_list::iterator var = children.begin(); \
328 : : var != children.end(); var++ )
329 : :
330 : : #define LOOP_OVER_CONST_CHILDREN(var) \
331 : : for ( analyzer_list::const_iterator var = children.begin(); \
332 : : var != children.end(); var++ )
333 : :
334 : : #define LOOP_OVER_GIVEN_CHILDREN(var, the_kids) \
335 : : for ( analyzer_list::iterator var = the_kids.begin(); \
336 : : var != the_kids.end(); var++ )
337 : :
338 : : class SupportAnalyzer : public Analyzer {
339 : : public:
340 : 1497 : SupportAnalyzer(AnalyzerTag::Tag tag, Connection* conn, bool arg_orig)
341 : 1497 : : Analyzer(tag, conn) { orig = arg_orig; sibling = 0; }
342 : :
343 [ - + ][ # # ]: 1497 : virtual ~SupportAnalyzer() {}
344 : :
345 : 19500 : bool IsOrig() const { return orig; }
346 : :
347 : : virtual void ForwardPacket(int len, const u_char* data, bool orig,
348 : : int seq, const IP_Hdr* ip, int caplen);
349 : : virtual void ForwardStream(int len, const u_char* data, bool orig);
350 : : virtual void ForwardUndelivered(int seq, int len, bool orig);
351 : :
352 : 3065 : SupportAnalyzer* Sibling() const { return sibling; }
353 : :
354 : : protected:
355 : : friend class Analyzer;
356 : :
357 : : SupportAnalyzer() { }
358 : : private:
359 : : bool orig;
360 : :
361 : : // Points to next support analyzer in chain. The list is managed by
362 : : // parent analyzer.
363 : : SupportAnalyzer* sibling;
364 : : };
365 : :
366 : :
367 : : class TransportLayerAnalyzer : public Analyzer {
368 : : public:
369 : 1627 : TransportLayerAnalyzer(AnalyzerTag::Tag tag, Connection* conn)
370 : 1627 : : Analyzer(tag, conn) { pia = 0; rewriter = 0; }
371 : :
372 : : virtual ~TransportLayerAnalyzer();
373 : :
374 : : virtual void Done();
375 : : virtual void UpdateEndpointVal(RecordVal* endp, int is_orig) = 0;
376 : : virtual bool IsReuse(double t, const u_char* pkt) = 0;
377 : :
378 : : virtual void SetContentsFile(unsigned int direction, BroFile* f);
379 : : virtual BroFile* GetContentsFile(unsigned int direction) const;
380 : :
381 : 938 : void SetPIA(PIA* arg_PIA) { pia = arg_PIA; }
382 : 0 : PIA* GetPIA() const { return pia; }
383 : :
384 : 21236 : Rewriter* TraceRewriter() { return rewriter; }
385 : :
386 : : // Takes ownership.
387 : : void SetTraceRewriter(Rewriter* r);
388 : :
389 : : // Raises packet_contents event.
390 : : void PacketContents(const u_char* data, int len);
391 : :
392 : : protected:
393 : : TransportLayerAnalyzer() { }
394 : :
395 : : private:
396 : : PIA* pia;
397 : : Rewriter* rewriter;
398 : : };
399 : :
400 : : #endif
|