Branch data Line data Source code
1 : : // $Id: Analyzer.cc,v 1.1.4.28 2006/06/01 17:18:10 sommer Exp $
2 : :
3 : : #include "Analyzer.h"
4 : : #include "PIA.h"
5 : : #include "Event.h"
6 : :
7 : : #include "BackDoor.h"
8 : : #include "BitTorrent.h"
9 : : #include "BitTorrentTracker.h"
10 : : #include "Finger.h"
11 : : #include "InterConn.h"
12 : : #include "NTP.h"
13 : : #include "HTTP.h"
14 : : #include "HTTP-binpac.h"
15 : : #include "ICMP.h"
16 : : #include "SteppingStone.h"
17 : : #include "IRC.h"
18 : : #include "SMTP.h"
19 : : #include "FTP.h"
20 : : #include "FileAnalyzer.h"
21 : : #include "DNS.h"
22 : : #include "DNS-binpac.h"
23 : : #include "DHCP-binpac.h"
24 : : #include "Telnet.h"
25 : : #include "Rlogin.h"
26 : : #include "RSH.h"
27 : : #include "DCE_RPC.h"
28 : : #include "Gnutella.h"
29 : : #include "Ident.h"
30 : : #include "NCP.h"
31 : : #include "NetbiosSSN.h"
32 : : #include "SMB.h"
33 : : #include "NFS.h"
34 : : #include "Portmap.h"
35 : : #include "POP3.h"
36 : : #include "SSH.h"
37 : : #include "SSLProxy.h"
38 : : #include "SSL-binpac.h"
39 : :
40 : : // Keep same order here as in AnalyzerTag definition!
41 : : const Analyzer::Config Analyzer::analyzer_configs[] = {
42 : : { AnalyzerTag::Error, "<ERROR>", 0, 0, 0, false },
43 : :
44 : : { AnalyzerTag::PIA_TCP, "PIA_TCP", PIA_TCP::InstantiateAnalyzer,
45 : : PIA_TCP::Available, 0, false },
46 : : { AnalyzerTag::PIA_UDP, "PIA_UDP", PIA_UDP::InstantiateAnalyzer,
47 : : PIA_UDP::Available, 0, false },
48 : :
49 : : { AnalyzerTag::ICMP, "ICMP", ICMP_Analyzer::InstantiateAnalyzer,
50 : : ICMP_Analyzer::Available, 0, false },
51 : : { AnalyzerTag::ICMP_TimeExceeded, "ICMP_TIMEEXCEEDED",
52 : : ICMP_TimeExceeded_Analyzer::InstantiateAnalyzer,
53 : : ICMP_TimeExceeded_Analyzer::Available, 0, false },
54 : : { AnalyzerTag::ICMP_Unreachable, "ICMP_UNREACHABLE",
55 : : ICMP_Unreachable_Analyzer::InstantiateAnalyzer,
56 : : ICMP_Unreachable_Analyzer::Available, 0, false },
57 : : { AnalyzerTag::ICMP_Echo, "ICMP_ECHO",
58 : : ICMP_Echo_Analyzer::InstantiateAnalyzer,
59 : : ICMP_Echo_Analyzer::Available, 0, false },
60 : :
61 : : { AnalyzerTag::TCP, "TCP", TCP_Analyzer::InstantiateAnalyzer,
62 : : TCP_Analyzer::Available, 0, false },
63 : : { AnalyzerTag::UDP, "UDP", UDP_Analyzer::InstantiateAnalyzer,
64 : : UDP_Analyzer::Available, 0, false },
65 : :
66 : : { AnalyzerTag::BitTorrent, "BITTORRENT",
67 : : BitTorrent_Analyzer::InstantiateAnalyzer,
68 : : BitTorrent_Analyzer::Available, 0, false },
69 : : { AnalyzerTag::BitTorrentTracker, "BITTORRENTTRACKER",
70 : : BitTorrentTracker_Analyzer::InstantiateAnalyzer,
71 : : BitTorrentTracker_Analyzer::Available, 0, false },
72 : : { AnalyzerTag::DCE_RPC, "DCE_RPC",
73 : : DCE_RPC_Analyzer::InstantiateAnalyzer,
74 : : DCE_RPC_Analyzer::Available, 0, false },
75 : : { AnalyzerTag::DNS, "DNS", DNS_Analyzer::InstantiateAnalyzer,
76 : : DNS_Analyzer::Available, 0, false },
77 : : { AnalyzerTag::Finger, "FINGER", Finger_Analyzer::InstantiateAnalyzer,
78 : : Finger_Analyzer::Available, 0, false },
79 : : { AnalyzerTag::FTP, "FTP", FTP_Analyzer::InstantiateAnalyzer,
80 : : FTP_Analyzer::Available, 0, false },
81 : : { AnalyzerTag::Gnutella, "GNUTELLA",
82 : : Gnutella_Analyzer::InstantiateAnalyzer,
83 : : Gnutella_Analyzer::Available, 0, false },
84 : : { AnalyzerTag::HTTP, "HTTP", HTTP_Analyzer::InstantiateAnalyzer,
85 : : HTTP_Analyzer::Available, 0, false },
86 : : { AnalyzerTag::Ident, "IDENT", Ident_Analyzer::InstantiateAnalyzer,
87 : : Ident_Analyzer::Available, 0, false },
88 : : { AnalyzerTag::IRC, "IRC", IRC_Analyzer::InstantiateAnalyzer,
89 : : IRC_Analyzer::Available, 0, false },
90 : : { AnalyzerTag::Login, "LOGIN", 0, 0, 0, false }, // just a base class
91 : : { AnalyzerTag::NCP, "NCP", NCP_Analyzer::InstantiateAnalyzer,
92 : : NCP_Analyzer::Available, 0, false },
93 : : { AnalyzerTag::NetbiosSSN, "NetbiosSSN",
94 : : NetbiosSSN_Analyzer::InstantiateAnalyzer,
95 : : NetbiosSSN_Analyzer::Available, 0, false },
96 : : { AnalyzerTag::NFS, "NFS", NFS_Analyzer::InstantiateAnalyzer,
97 : : NFS_Analyzer::Available, 0, false },
98 : : { AnalyzerTag::NTP, "NTP", NTP_Analyzer::InstantiateAnalyzer,
99 : : NTP_Analyzer::Available, 0, false },
100 : : { AnalyzerTag::POP3, "POP3", POP3_Analyzer::InstantiateAnalyzer,
101 : : POP3_Analyzer::Available, 0, false },
102 : : { AnalyzerTag::Portmapper, "PORTMAPPER",
103 : : Portmapper_Analyzer::InstantiateAnalyzer,
104 : : Portmapper_Analyzer::Available, 0, false },
105 : : { AnalyzerTag::Rlogin, "RLOGIN", Rlogin_Analyzer::InstantiateAnalyzer,
106 : : Rlogin_Analyzer::Available, 0, false },
107 : : { AnalyzerTag::RPC, "RPC", 0, 0, 0, false },
108 : : { AnalyzerTag::Rsh, "RSH", Rsh_Analyzer::InstantiateAnalyzer,
109 : : Rsh_Analyzer::Available, 0, false },
110 : : { AnalyzerTag::SMB, "SMB", SMB_Analyzer::InstantiateAnalyzer,
111 : : SMB_Analyzer::Available, 0, false },
112 : : { AnalyzerTag::SMTP, "SMTP", SMTP_Analyzer::InstantiateAnalyzer,
113 : : SMTP_Analyzer::Available, 0, false },
114 : : { AnalyzerTag::SSH, "SSH", SSH_Analyzer::InstantiateAnalyzer,
115 : : SSH_Analyzer::Available, 0, false },
116 : : { AnalyzerTag::SSL, "SSL", SSLProxy_Analyzer::InstantiateAnalyzer,
117 : : SSLProxy_Analyzer::Available, 0, false },
118 : : { AnalyzerTag::Telnet, "TELNET", Telnet_Analyzer::InstantiateAnalyzer,
119 : : Telnet_Analyzer::Available, 0, false },
120 : :
121 : : { AnalyzerTag::DHCP_BINPAC, "DHCP_BINPAC",
122 : : DHCP_Analyzer_binpac::InstantiateAnalyzer,
123 : : DHCP_Analyzer_binpac::Available, 0, false },
124 : : { AnalyzerTag::DNS_TCP_BINPAC, "DNS_TCP_BINPAC",
125 : : DNS_TCP_Analyzer_binpac::InstantiateAnalyzer,
126 : : DNS_TCP_Analyzer_binpac::Available, 0, false },
127 : : { AnalyzerTag::DNS_UDP_BINPAC, "DNS_UDP_BINPAC",
128 : : DNS_UDP_Analyzer_binpac::InstantiateAnalyzer,
129 : : DNS_UDP_Analyzer_binpac::Available, 0, false },
130 : : { AnalyzerTag::HTTP_BINPAC, "HTTP_BINPAC",
131 : : HTTP_Analyzer_binpac::InstantiateAnalyzer,
132 : : HTTP_Analyzer_binpac::Available, 0, false },
133 : : { AnalyzerTag::RPC_UDP_BINPAC, "RPC_UDP_BINPAC",
134 : : RPC_UDP_Analyzer_binpac::InstantiateAnalyzer,
135 : : RPC_UDP_Analyzer_binpac::Available, 0, false },
136 : : { AnalyzerTag::SSL_BINPAC, "SSL_BINPAC",
137 : : SSL_Analyzer_binpac::InstantiateAnalyzer,
138 : : SSL_Analyzer_binpac::Available, 0, false },
139 : :
140 : : { AnalyzerTag::File, "FILE", File_Analyzer::InstantiateAnalyzer,
141 : : File_Analyzer::Available, 0, false },
142 : : { AnalyzerTag::Backdoor, "BACKDOOR",
143 : : BackDoor_Analyzer::InstantiateAnalyzer,
144 : : BackDoor_Analyzer::Available, 0, false },
145 : : { AnalyzerTag::InterConn, "INTERCONN",
146 : : InterConn_Analyzer::InstantiateAnalyzer,
147 : : InterConn_Analyzer::Available, 0, false },
148 : : { AnalyzerTag::SteppingStone, "STEPPINGSTONE",
149 : : SteppingStone_Analyzer::InstantiateAnalyzer,
150 : : SteppingStone_Analyzer::Available, 0, false },
151 : : { AnalyzerTag::TCPStats, "TCPSTATS",
152 : : TCPStats_Analyzer::InstantiateAnalyzer,
153 : : TCPStats_Analyzer::Available, 0, false },
154 : :
155 : : { AnalyzerTag::Contents, "CONTENTS", 0, 0, 0, false },
156 : : { AnalyzerTag::ContentLine, "CONTENTLINE", 0, 0, 0, false },
157 : : { AnalyzerTag::NVT, "NVT", 0, 0, 0, false },
158 : : { AnalyzerTag::Zip, "ZIP", 0, 0, 0, false },
159 : : { AnalyzerTag::Contents_DNS, "CONTENTS_DNS", 0, 0, 0, false },
160 : : { AnalyzerTag::Contents_NetbiosSSN, "CONTENTS_NETBIOSSSN", 0, 0, 0, false },
161 : : { AnalyzerTag::Contents_NCP, "CONTENTS_NCP", 0, 0, 0, false },
162 : : { AnalyzerTag::Contents_Rlogin, "CONTENTS_Rlogin", 0, 0, 0, false },
163 : : { AnalyzerTag::Contents_Rsh, "CONTENTS_RSH", 0, 0, 0, false },
164 : : { AnalyzerTag::Contents_DCE_RPC, "CONTENTS_DCE_RPC", 0, 0, 0, false },
165 : : { AnalyzerTag::Contents_SMB, "CONTENTS_SMB", 0, 0, 0, false },
166 : : { AnalyzerTag::Contents_RPC, "CONTENTS_RPC", 0, 0, 0, false },
167 : : { AnalyzerTag::Contents_NFS, "CONTENTS_NFS", 0, 0, 0, false },
168 : : { AnalyzerTag::Contents_SSL, "CONTENTS_SSL", 0, 0, 0, false },
169 : : };
170 : :
171 : 18043 : AnalyzerTimer::~AnalyzerTimer()
172 : : {
173 : 18043 : analyzer->RemoveTimer(this);
174 : 18043 : Unref(analyzer->Conn());
175 [ + - ][ # # ]: 18043 : }
[ # # ]
176 : :
177 : 16421 : void AnalyzerTimer::Dispatch(double t, int is_expire)
178 : : {
179 [ - + ][ # # ]: 16421 : if ( is_expire && ! do_expire )
180 : 0 : return;
181 : :
182 : : // Remove ourselves from the connection's set of timers so
183 : : // it doesn't try to cancel us.
184 : 16421 : analyzer->RemoveTimer(this);
185 : :
186 [ - + ]: 16421 : (analyzer->*timer)(t);
187 : : }
188 : :
189 : : void AnalyzerTimer::Init(Analyzer* arg_analyzer, analyzer_timer_func arg_timer,
190 : 18043 : int arg_do_expire)
191 : : {
192 : 18043 : analyzer = arg_analyzer;
193 : 18043 : timer = arg_timer;
194 : 18043 : do_expire = arg_do_expire;
195 : :
196 : : // We need to Ref the connection as the analyzer doesn't do it and
197 : : // we need to have it around until we expire.
198 : 18043 : Ref(analyzer->Conn());
199 : 18043 : }
200 : :
201 : : AnalyzerID Analyzer::id_counter = 0;;
202 : :
203 : 693 : Analyzer* Analyzer::InstantiateAnalyzer(AnalyzerTag::Tag tag, Connection* c)
204 : : {
205 : 693 : Analyzer* a = analyzer_configs[tag].factory(c);
206 [ - + ]: 693 : assert(a);
207 : 693 : return a;
208 : : }
209 : :
210 : 70132 : const char* Analyzer::GetTagName(AnalyzerTag::Tag tag)
211 : : {
212 : 70132 : return analyzer_configs[tag].name;
213 : : }
214 : :
215 : 11 : AnalyzerTag::Tag Analyzer::GetTag(const char* name)
216 : : {
217 [ + - ]: 220 : for ( int i = 1; i < int(AnalyzerTag::LastAnalyzer); i++ )
218 [ + + ]: 220 : if ( strcasecmp(analyzer_configs[i].name, name) == 0 )
219 : 11 : return analyzer_configs[i].tag;
220 : :
221 : 11 : return AnalyzerTag::Error;
222 : : }
223 : :
224 : : // Used in debugging output.
225 : 69439 : static string fmt_analyzer(Analyzer* a)
226 : : {
227 : 69439 : return string(a->GetTagName()) + fmt("[%d]", a->GetID());
228 : : }
229 : :
230 : 5439 : Analyzer::Analyzer(AnalyzerTag::Tag arg_tag, Connection* arg_conn)
231 : : {
232 : : // Don't Ref conn here to avoid circular ref'ing. It can't be deleted
233 : : // before us.
234 : 5439 : conn = arg_conn;
235 : 5439 : tag = arg_tag;
236 : 5439 : id = ++id_counter;
237 : 5439 : protocol_confirmed = false;
238 : 5439 : skip = false;
239 : 5439 : finished = false;
240 : 5439 : parent = 0;
241 : 5439 : orig_supporters = 0;
242 : 5439 : resp_supporters = 0;
243 : 5439 : signature = 0;
244 : 5439 : output_handler = 0;
245 : 5439 : }
246 : :
247 : 5439 : Analyzer::~Analyzer()
248 : : {
249 [ # # ][ # # ]: 5439 : assert(finished);
[ - + ]
250 : :
251 [ # # ][ # # ]: 7754 : LOOP_OVER_CHILDREN(i)
[ + + ]
252 [ # # ][ # # ]: 2315 : delete *i;
[ + - ]
253 : :
254 : 5439 : SupportAnalyzer* next = 0;
255 : :
256 [ # # ][ # # ]: 6132 : for ( SupportAnalyzer* a = orig_supporters; a; a = next )
[ + + ]
257 : : {
258 : 693 : next = a->sibling;
259 [ # # ][ # # ]: 693 : delete a;
[ + - ]
260 : : }
261 : :
262 [ # # ][ # # ]: 6132 : for ( SupportAnalyzer* a = resp_supporters; a; a = next)
[ + + ]
263 : : {
264 : 693 : next = a->sibling;
265 [ # # ][ # # ]: 693 : delete a;
[ + - ]
266 : : }
267 : :
268 [ # # ][ # # ]: 5439 : delete output_handler;
[ + + ]
269 [ # # ][ # # ]: 5439 : }
[ - + ]
270 : :
271 : 4644 : void Analyzer::Init()
272 : : {
273 : 4644 : }
274 : :
275 : 3942 : void Analyzer::InitChildren()
276 : : {
277 : 3942 : AppendNewChildren();
278 : :
279 [ + + ]: 6257 : LOOP_OVER_CHILDREN(i)
280 : : {
281 : 2315 : (*i)->Init();
282 : 2315 : (*i)->InitChildren();
283 : : }
284 : 3942 : }
285 : :
286 : 5439 : void Analyzer::Done()
287 : : {
288 [ - + ]: 5439 : assert(!finished);
289 : :
290 [ + - ]: 5439 : if ( ! skip )
291 : : {
292 : 5439 : EndOfData(true);
293 : 5439 : EndOfData(false);
294 : : }
295 : :
296 : 5439 : CancelTimers();
297 : :
298 : 5439 : AppendNewChildren();
299 : :
300 [ + + ]: 7754 : LOOP_OVER_CHILDREN(i)
301 [ + - ]: 2315 : if ( ! (*i)->finished )
302 : 2315 : (*i)->Done();
303 : :
304 [ + + ]: 6132 : for ( SupportAnalyzer* a = orig_supporters; a; a = a->sibling )
305 [ + - ]: 693 : if ( ! a->finished )
306 : 693 : a->Done();
307 : :
308 [ + + ]: 6132 : for ( SupportAnalyzer* a = resp_supporters; a; a = a->sibling )
309 [ + - ]: 693 : if ( ! a->finished )
310 : 693 : a->Done();
311 : :
312 : 5439 : finished = true;
313 : 5439 : }
314 : :
315 : : void Analyzer::NextPacket(int len, const u_char* data, bool is_orig, int seq,
316 : 21373 : const IP_Hdr* ip, int caplen)
317 : : {
318 [ + - ]: 21373 : if ( skip )
319 : 21373 : return;
320 : :
321 : : // If we have support analyzers, we pass it to them.
322 [ + + ][ - + ]: 21373 : if ( is_orig && orig_supporters )
323 : 0 : orig_supporters->NextPacket(len, data, is_orig, seq, ip, caplen);
324 [ + + ][ - + ]: 21373 : else if ( ! is_orig && resp_supporters )
325 : 0 : resp_supporters->NextPacket(len, data, is_orig, seq, ip, caplen);
326 : : else
327 : : {
328 : : try
329 : : {
330 : 21373 : DeliverPacket(len, data, is_orig, seq, ip, caplen);
331 : : }
332 : 0 : catch ( binpac::Exception const &e )
333 : : {
334 : 0 : Weird(e.c_msg());
335 : : }
336 : : }
337 : : }
338 : :
339 : 69439 : const char* Analyzer::GetTagName() const
340 : : {
341 : 69439 : return GetTagName(tag);
342 : : }
343 : :
344 : 20200 : void Analyzer::NextStream(int len, const u_char* data, bool is_orig)
345 : : {
346 [ + - ]: 20200 : if ( skip )
347 : 20200 : return;
348 : :
349 : : // If we have support analyzers, we pass it to them.
350 [ + + ][ + + ]: 21105 : if ( is_orig && orig_supporters )
351 : 905 : orig_supporters->NextStream(len, data, is_orig);
352 [ + + ][ + + ]: 24171 : else if ( ! is_orig && resp_supporters )
353 : 4876 : resp_supporters->NextStream(len, data, is_orig);
354 : : else
355 : : {
356 : : try
357 : : {
358 : 14419 : DeliverStream(len, data, is_orig);
359 : : }
360 : 0 : catch ( binpac::Exception const &e )
361 : : {
362 : 0 : Weird(e.c_msg());
363 : : }
364 : : }
365 : : }
366 : :
367 : 1243 : void Analyzer::NextUndelivered(int seq, int len, bool is_orig)
368 : : {
369 [ + - ]: 1243 : if ( skip )
370 : 1243 : return;
371 : :
372 : : // If we have support analyzers, we pass it to them.
373 [ + + ][ + + ]: 1441 : if ( is_orig && orig_supporters )
374 : 198 : orig_supporters->NextUndelivered(seq, len, is_orig);
375 [ + + ][ + + ]: 1185 : else if ( ! is_orig && resp_supporters )
376 : 140 : resp_supporters->NextUndelivered(seq, len, is_orig);
377 : : else
378 : : {
379 : : try
380 : : {
381 : 905 : Undelivered(seq, len, is_orig);
382 : : }
383 : 0 : catch ( binpac::Exception const &e )
384 : : {
385 : 0 : Weird(e.c_msg());
386 : : }
387 : : }
388 : : }
389 : :
390 : 0 : void Analyzer::NextEndOfData(bool is_orig)
391 : : {
392 [ # # ]: 0 : if ( skip )
393 : 0 : return;
394 : :
395 : : // If we have support analyzers, we pass it to them.
396 [ # # ][ # # ]: 0 : if ( is_orig && orig_supporters )
397 : 0 : orig_supporters->NextEndOfData(is_orig);
398 [ # # ][ # # ]: 0 : else if ( ! is_orig && resp_supporters )
399 : 0 : resp_supporters->NextEndOfData(is_orig);
400 : : else
401 : 0 : EndOfData(is_orig);
402 : : }
403 : :
404 : : void Analyzer::ForwardPacket(int len, const u_char* data, bool is_orig,
405 : 1683 : int seq, const IP_Hdr* ip, int caplen)
406 : : {
407 [ - + ]: 1683 : if ( output_handler )
408 : : output_handler->DeliverPacket(len, data, is_orig, seq,
409 : 0 : ip, caplen);
410 : :
411 : 1683 : AppendNewChildren();
412 : :
413 : : // Pass to all children.
414 : 1683 : analyzer_list::iterator next;
415 [ + + ]: 3366 : for ( analyzer_list::iterator i = children.begin();
416 : : i != children.end(); i = next )
417 : : {
418 : 1683 : Analyzer* current = *i;
419 : 1683 : next = ++i;
420 : :
421 [ + - ]: 1683 : if ( ! current->finished )
422 : 1683 : current->NextPacket(len, data, is_orig, seq, ip, caplen);
423 : : else
424 : : {
425 : : // Analyzer has already been disabled so delete it.
426 : 0 : DBG_LOG(DBG_DPD, "%s deleted child %s",
427 : : fmt_analyzer(this).c_str(), fmt_analyzer(current).c_str());
428 : 0 : children.erase(--i);
429 [ # # ]: 0 : delete current;
430 : : }
431 : : }
432 : :
433 : 1683 : AppendNewChildren();
434 : 1683 : }
435 : :
436 : 10337 : void Analyzer::ForwardStream(int len, const u_char* data, bool is_orig)
437 : : {
438 [ - + ]: 10337 : if ( output_handler )
439 : 0 : output_handler->DeliverStream(len, data, is_orig);
440 : :
441 : 10337 : AppendNewChildren();
442 : :
443 : 10337 : analyzer_list::iterator next;
444 [ + + ]: 24080 : for ( analyzer_list::iterator i = children.begin();
445 : : i != children.end(); i = next )
446 : : {
447 : 13743 : Analyzer* current = *i;
448 : 13743 : next = ++i;
449 : :
450 [ + - ]: 13743 : if ( ! current->finished )
451 : 13743 : current->NextStream(len, data, is_orig);
452 : : else
453 : : {
454 : : // Analyzer has already been disabled so delete it.
455 : 0 : DBG_LOG(DBG_DPD, "%s deleted child %s",
456 : : fmt_analyzer(this).c_str(), fmt_analyzer(current).c_str());
457 : 0 : children.erase(--i);
458 [ # # ]: 0 : delete current;
459 : : }
460 : : }
461 : :
462 : 10337 : AppendNewChildren();
463 : 10337 : }
464 : :
465 : 567 : void Analyzer::ForwardUndelivered(int seq, int len, bool is_orig)
466 : : {
467 [ - + ]: 567 : if ( output_handler )
468 : 0 : output_handler->Undelivered(seq, len, is_orig);
469 : :
470 : 567 : AppendNewChildren();
471 : :
472 : 567 : analyzer_list::iterator next;
473 [ + + ]: 1472 : for ( analyzer_list::iterator i = children.begin();
474 : : i != children.end(); i = next )
475 : : {
476 : 905 : Analyzer* current = *i;
477 : 905 : next = ++i;
478 : :
479 [ + - ]: 905 : if ( ! current->finished )
480 : 905 : current->NextUndelivered(seq, len, is_orig);
481 : : else
482 : : {
483 : : // Analyzer has already been disabled so delete it.
484 : 0 : DBG_LOG(DBG_DPD, "%s deleted child %s",
485 : : fmt_analyzer(this).c_str(), fmt_analyzer(current).c_str());
486 : 0 : children.erase(--i);
487 [ # # ]: 0 : delete current;
488 : : }
489 : : }
490 : :
491 : 567 : AppendNewChildren();
492 : 567 : }
493 : :
494 : 765 : void Analyzer::ForwardEndOfData(bool orig)
495 : : {
496 : 765 : AppendNewChildren();
497 : :
498 : 765 : analyzer_list::iterator next;
499 [ - + ]: 765 : for ( analyzer_list::iterator i = children.begin();
500 : : i != children.end(); i = next )
501 : : {
502 : 0 : Analyzer* current = *i;
503 : 0 : next = ++i;
504 : :
505 [ # # ]: 0 : if ( ! current->finished )
506 : 0 : current->NextEndOfData(orig);
507 : : else
508 : : {
509 : : // Analyzer has already been disabled so delete it.
510 : 0 : DBG_LOG(DBG_DPD, "%s deleted child %s",
511 : : fmt_analyzer(this).c_str(), fmt_analyzer(current).c_str());
512 : 0 : children.erase(--i);
513 [ # # ]: 0 : delete current;
514 : : }
515 : : }
516 : :
517 : 765 : AppendNewChildren();
518 : 765 : }
519 : :
520 : 2315 : void Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init)
521 : : {
522 [ - + ]: 2315 : if ( HasChildAnalyzer(analyzer->GetTag()) )
523 : : {
524 : 0 : analyzer->Done();
525 [ # # ]: 0 : delete analyzer;
526 : 0 : return;
527 : : }
528 : :
529 : : // We add new children to new_children first. They are then
530 : : // later copied to the "real" child list. This is necessary
531 : : // because this method may be called while somebody is iterating
532 : : // over the children and we might confuse the caller by modifying
533 : : // the list.
534 : :
535 : 2315 : analyzer->parent = this;
536 : 2315 : children.push_back(analyzer);
537 : :
538 [ - + ]: 2315 : if ( init )
539 : 0 : analyzer->Init();
540 : :
541 : 2315 : DBG_LOG(DBG_DPD, "%s added child %s",
542 : : fmt_analyzer(this).c_str(), fmt_analyzer(analyzer).c_str());
543 : : }
544 : :
545 : 0 : Analyzer* Analyzer::AddChildAnalyzer(AnalyzerTag::Tag analyzer)
546 : : {
547 [ # # ]: 0 : if ( ! HasChildAnalyzer(analyzer) )
548 : : {
549 : 0 : Analyzer* a = InstantiateAnalyzer(analyzer, conn);
550 : 0 : AddChildAnalyzer(a);
551 : 0 : return a;
552 : : }
553 : :
554 : 0 : return 0;
555 : : }
556 : :
557 : 0 : void Analyzer::RemoveChildAnalyzer(Analyzer* analyzer)
558 : : {
559 [ # # ]: 0 : LOOP_OVER_CHILDREN(i)
560 [ # # ][ # # ]: 0 : if ( *i == analyzer && ! analyzer->finished )
[ # # ]
561 : : {
562 : 0 : DBG_LOG(DBG_DPD, "%s disabled child %s",
563 : : fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str());
564 : 0 : (*i)->Done();
565 : : // We don't delete it here as we may in fact
566 : : // iterate over the list right now. Done() sets
567 : : // "finished" to true and this is checked
568 : : // later to delete it.
569 : 0 : return;
570 : : }
571 : : }
572 : :
573 : 0 : void Analyzer::RemoveChildAnalyzer(AnalyzerID id)
574 : : {
575 [ # # ]: 0 : LOOP_OVER_CHILDREN(i)
576 [ # # ][ # # ]: 0 : if ( (*i)->id == id && ! (*i)->finished )
[ # # ]
577 : : {
578 : 0 : DBG_LOG(DBG_DPD, "%s disabled child %s", GetTagName(), id,
579 : : fmt_analyzer(this).c_str(), fmt_analyzer(*i).c_str());
580 : 0 : (*i)->Done();
581 : 0 : return;
582 : : }
583 : : }
584 : :
585 : 2315 : bool Analyzer::HasChildAnalyzer(AnalyzerTag::Tag tag)
586 : : {
587 [ + + ]: 3008 : LOOP_OVER_CHILDREN(i)
588 [ - + ]: 693 : if ( (*i)->tag == tag )
589 : 0 : return true;
590 : :
591 [ - + ]: 2315 : LOOP_OVER_GIVEN_CHILDREN(i, new_children)
592 [ # # ]: 0 : if ( (*i)->tag == tag )
593 : 0 : return true;
594 : :
595 : 2315 : return false;
596 : : }
597 : :
598 : 0 : Analyzer* Analyzer::FindChild(AnalyzerID arg_id)
599 : : {
600 [ # # ]: 0 : if ( id == arg_id )
601 : 0 : return this;
602 : :
603 [ # # ]: 0 : LOOP_OVER_CHILDREN(i)
604 : : {
605 : 0 : Analyzer* child = (*i)->FindChild(arg_id);
606 [ # # ]: 0 : if ( child )
607 : 0 : return child;
608 : : }
609 : :
610 : 0 : return 0;
611 : : }
612 : :
613 : 24 : Analyzer* Analyzer::FindChild(AnalyzerTag::Tag arg_tag)
614 : : {
615 [ - + ]: 24 : if ( tag == arg_tag )
616 : 0 : return this;
617 : :
618 [ + + ]: 40 : LOOP_OVER_CHILDREN(i)
619 : : {
620 : 16 : Analyzer* child = (*i)->FindChild(arg_tag);
621 [ - + ]: 16 : if ( child )
622 : 0 : return child;
623 : : }
624 : :
625 : 24 : return 0;
626 : : }
627 : :
628 : 1386 : void Analyzer::AddSupportAnalyzer(SupportAnalyzer* analyzer)
629 : : {
630 [ - + ]: 1386 : if ( HasSupportAnalyzer(analyzer->GetTag(), analyzer->IsOrig()) )
631 : : {
632 [ # # ]: 0 : DBG_LOG(DBG_DPD, "%s already has %s %s",
633 : : fmt_analyzer(this).c_str(),
634 : : analyzer->IsOrig() ? "originator" : "responder",
635 : : fmt_analyzer(analyzer).c_str());
636 : :
637 : 0 : analyzer->Done();
638 [ # # ]: 0 : delete analyzer;
639 : 0 : return;
640 : : }
641 : :
642 : : SupportAnalyzer** head =
643 [ + + ]: 1386 : analyzer->IsOrig() ? &orig_supporters : &resp_supporters;
644 : :
645 : : // Find end of the list.
646 : 1386 : SupportAnalyzer* prev = 0;
647 : : SupportAnalyzer* s;
648 [ - + ]: 1386 : for ( s = *head; s; prev = s, s = s->sibling )
649 : : ;
650 : :
651 [ - + ]: 1386 : if ( prev )
652 : 0 : prev->sibling = analyzer;
653 : : else
654 : 1386 : *head = analyzer;
655 : :
656 : 1386 : analyzer->parent = this;
657 : :
658 : 1386 : analyzer->Init();
659 : :
660 [ + + ]: 1386 : DBG_LOG(DBG_DPD, "%s added %s support %s",
661 : : fmt_analyzer(this).c_str(),
662 : : analyzer->IsOrig() ? "originator" : "responder",
663 : : fmt_analyzer(analyzer).c_str());
664 : : }
665 : :
666 : 0 : void Analyzer::RemoveSupportAnalyzer(SupportAnalyzer* analyzer)
667 : : {
668 : : SupportAnalyzer** head =
669 [ # # ]: 0 : analyzer->IsOrig() ? &orig_supporters : &resp_supporters;
670 : :
671 : 0 : SupportAnalyzer* prev = 0;
672 : : SupportAnalyzer* s;
673 [ # # ][ # # ]: 0 : for ( s = *head; s && s != analyzer; prev = s, s = s->sibling )
674 : : ;
675 : :
676 [ # # ]: 0 : if ( ! s )
677 : 0 : return;
678 : :
679 [ # # ]: 0 : if ( prev )
680 : 0 : prev->sibling = s->sibling;
681 : : else
682 : 0 : *head = s->sibling;
683 : :
684 [ # # ]: 0 : DBG_LOG(DBG_DPD, "%s removed support %s",
685 : : fmt_analyzer(this).c_str(),
686 : : analyzer->IsOrig() ? "originator" : "responder",
687 : : fmt_analyzer(analyzer).c_str());
688 : :
689 [ # # ]: 0 : if ( ! analyzer->finished )
690 : 0 : analyzer->Done();
691 : :
692 [ # # ]: 0 : delete analyzer;
693 : 0 : return;
694 : : }
695 : :
696 : 1386 : bool Analyzer::HasSupportAnalyzer(AnalyzerTag::Tag tag, bool orig)
697 : : {
698 [ + + ]: 1386 : SupportAnalyzer* s = orig ? orig_supporters : resp_supporters;
699 [ - + ]: 1386 : for ( ; s; s = s->sibling )
700 [ # # ]: 0 : if ( s->tag == tag )
701 : 0 : return true;
702 : :
703 : 1386 : return false;
704 : : }
705 : :
706 : : void Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
707 : 21373 : int seq, const IP_Hdr* ip, int caplen)
708 : : {
709 [ + + ][ + + ]: 21373 : DBG_LOG(DBG_DPD, "%s DeliverPacket(%d, %s, %d, %p, %d) [%s%s]",
710 : : fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F", seq, ip, caplen,
711 : : fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
712 : 21373 : }
713 : :
714 : 28881 : void Analyzer::DeliverStream(int len, const u_char* data, bool is_orig)
715 : : {
716 [ + + ][ + + ]: 28881 : DBG_LOG(DBG_DPD, "%s DeliverStream(%d, %s) [%s%s]",
717 : : fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F",
718 : : fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
719 : 28881 : }
720 : :
721 : 905 : void Analyzer::Undelivered(int seq, int len, bool is_orig)
722 : : {
723 [ + + ]: 905 : DBG_LOG(DBG_DPD, "%s Undelivered(%d, %d, %s)",
724 : : fmt_analyzer(this).c_str(), seq, len, is_orig ? "T" : "F");
725 : 905 : }
726 : :
727 : 10878 : void Analyzer::EndOfData(bool is_orig)
728 : : {
729 [ + + ]: 10878 : DBG_LOG(DBG_DPD, "%s EndOfData(%s)",
730 : : fmt_analyzer(this).c_str(), is_orig ? "T" : "F");
731 : 10878 : }
732 : :
733 : 0 : void Analyzer::FlipRoles()
734 : : {
735 : 0 : DBG_LOG(DBG_DPD, "%s FlipRoles()");
736 : :
737 [ # # ]: 0 : LOOP_OVER_CHILDREN(i)
738 : 0 : (*i)->FlipRoles();
739 : :
740 [ # # ]: 0 : LOOP_OVER_GIVEN_CHILDREN(i, new_children)
741 : 0 : (*i)->FlipRoles();
742 : :
743 [ # # ]: 0 : for ( SupportAnalyzer* a = orig_supporters; a; a = a->sibling )
744 : 0 : a->FlipRoles();
745 : :
746 [ # # ]: 0 : for ( SupportAnalyzer* a = resp_supporters; a; a = a->sibling )
747 : 0 : a->FlipRoles();
748 : :
749 : 0 : SupportAnalyzer* tmp = orig_supporters;
750 : 0 : orig_supporters = resp_supporters;
751 : 0 : resp_supporters = tmp;
752 : 0 : }
753 : :
754 : 50878 : int Analyzer::RewritingTrace()
755 : : {
756 [ + + ]: 82590 : LOOP_OVER_CHILDREN(i)
757 [ - + ]: 31712 : if ( (*i)->RewritingTrace() )
758 : 0 : return 1;
759 : :
760 : 50878 : return 0;
761 : : }
762 : :
763 : 441 : void Analyzer::ProtocolConfirmation()
764 : : {
765 [ + + ]: 441 : if ( protocol_confirmed )
766 : 441 : return;
767 : :
768 : 274 : val_list* vl = new val_list;
769 : 274 : vl->append(BuildConnVal());
770 : 274 : vl->append(new Val(tag, TYPE_COUNT));
771 : 274 : vl->append(new Val(id, TYPE_COUNT));
772 : :
773 : : // We immediately raise the event so that the analyzer can quickly
774 : : // react if necessary.
775 : 274 : ::Event* e = new ::Event(protocol_confirmation, vl, SOURCE_LOCAL);
776 : 274 : mgr.Dispatch(e);
777 : :
778 : 274 : protocol_confirmed = true;
779 : : }
780 : :
781 : 0 : void Analyzer::ProtocolViolation(const char* reason, const char* data, int len)
782 : : {
783 : : StringVal* r;
784 : :
785 [ # # ][ # # ]: 0 : if ( data && len )
786 : : {
787 : 0 : const char *tmp = copy_string(reason);
788 : : r = new StringVal(fmt("%s [%s%s]", tmp,
789 : : fmt_bytes(data, min(40, len)),
790 [ # # ]: 0 : len > 40 ? "..." : ""));
791 [ # # ]: 0 : delete [] tmp;
792 : : }
793 : : else
794 : 0 : r = new StringVal(reason);
795 : :
796 : 0 : val_list* vl = new val_list;
797 : 0 : vl->append(BuildConnVal());
798 : 0 : vl->append(new Val(tag, TYPE_COUNT));
799 : 0 : vl->append(new Val(id, TYPE_COUNT));
800 : 0 : vl->append(r);
801 : :
802 : : // We immediately raise the event so that the analyzer can quickly be
803 : : // disabled if necessary.
804 : 0 : ::Event* e = new ::Event(protocol_violation, vl, SOURCE_LOCAL);
805 : 0 : mgr.Dispatch(e);
806 : 0 : }
807 : :
808 : : void Analyzer::AddTimer(analyzer_timer_func timer, double t,
809 : 18043 : int do_expire, TimerType type)
810 : : {
811 : : Timer* analyzer_timer = new
812 : 18043 : AnalyzerTimer(this, timer, t, do_expire, type);
813 : :
814 : 18043 : Conn()->GetTimerMgr()->Add(analyzer_timer);
815 : 18043 : timers.append(analyzer_timer);
816 : 18043 : }
817 : :
818 : 34464 : void Analyzer::RemoveTimer(Timer* t)
819 : : {
820 : 34464 : timers.remove(t);
821 : 34464 : }
822 : :
823 : 6009 : void Analyzer::CancelTimers()
824 : : {
825 : : // We are going to cancel our timers which, in turn, may cause them to
826 : : // call RemoveTimer(), which would then modify the list we're just
827 : : // traversing. Thus, we first make a copy of the list which we then
828 : : // iterate through.
829 : 6009 : timer_list tmp(timers.length());
830 [ + + ]: 7631 : loop_over_list(timers, j)
831 : 1622 : tmp.append(timers[j]);
832 : :
833 [ + + ]: 7631 : loop_over_list(tmp, i)
834 : 1622 : Conn()->GetTimerMgr()->Cancel(tmp[i]);
835 : :
836 : 6009 : timers_canceled = 1;
837 : 6009 : timers.clear();
838 : 6009 : }
839 : :
840 : 36085 : void Analyzer::AppendNewChildren()
841 : : {
842 [ - + ]: 36085 : LOOP_OVER_GIVEN_CHILDREN(i, new_children)
843 : 0 : children.push_back(*i);
844 : 36085 : new_children.clear();
845 : 36085 : }
846 : :
847 : 0 : unsigned int Analyzer::MemoryAllocation() const
848 : : {
849 : : unsigned int mem = padded_sizeof(*this)
850 : 0 : + (timers.MemoryAllocation() - padded_sizeof(timers));
851 : :
852 [ # # ]: 0 : LOOP_OVER_CONST_CHILDREN(i)
853 : 0 : mem += (*i)->MemoryAllocation();
854 : :
855 [ # # ]: 0 : for ( SupportAnalyzer* a = orig_supporters; a; a = a->sibling )
856 : 0 : mem += a->MemoryAllocation();
857 : :
858 [ # # ]: 0 : for ( SupportAnalyzer* a = resp_supporters; a; a = a->sibling )
859 : 0 : mem += a->MemoryAllocation();
860 : :
861 : 0 : return mem;
862 : : }
863 : :
864 : : void SupportAnalyzer::ForwardPacket(int len, const u_char* data, bool is_orig,
865 : 0 : int seq, const IP_Hdr* ip, int caplen)
866 : : {
867 : : // We do not call parent's method, as we're replacing the functionality.
868 [ # # ]: 0 : if ( GetOutputHandler() )
869 : : GetOutputHandler()->DeliverPacket(len, data, is_orig, seq,
870 : 0 : ip, caplen);
871 [ # # ]: 0 : else if ( sibling )
872 : : // Pass to next in chain.
873 : 0 : sibling->NextPacket(len, data, is_orig, seq, ip, caplen);
874 : : else
875 : : // Finished with preprocessing - now it's the parent's turn.
876 : 0 : Parent()->DeliverPacket(len, data, is_orig, seq, ip, caplen);
877 : 0 : }
878 : :
879 : 15342 : void SupportAnalyzer::ForwardStream(int len, const u_char* data, bool is_orig)
880 : : {
881 : : // We do not call parent's method, as we're replacing the functionality.
882 [ + + ]: 15342 : if ( GetOutputHandler() )
883 : 888 : GetOutputHandler()->DeliverStream(len, data, is_orig);
884 : :
885 [ - + ]: 14454 : else if ( sibling )
886 : : // Pass to next in chain.
887 : 0 : sibling->NextStream(len, data, is_orig);
888 : : else
889 : : // Finished with preprocessing - now it's the parent's turn.
890 : 14454 : Parent()->DeliverStream(len, data, is_orig);
891 : 15342 : }
892 : :
893 : 338 : void SupportAnalyzer::ForwardUndelivered(int seq, int len, bool is_orig)
894 : : {
895 : : // We do not call parent's method, as we're replacing the functionality.
896 [ - + ]: 338 : if ( GetOutputHandler() )
897 : 0 : GetOutputHandler()->Undelivered(seq, len, is_orig);
898 : :
899 [ - + ]: 338 : else if ( sibling )
900 : : // Pass to next in chain.
901 : 0 : sibling->NextUndelivered(seq, len, is_orig);
902 : : else
903 : : // Finished with preprocessing - now it's the parent's turn.
904 : 338 : Parent()->Undelivered(seq, len, is_orig);
905 : 338 : }
906 : :
907 : 1627 : TransportLayerAnalyzer::~TransportLayerAnalyzer()
908 : : {
909 [ # # ][ # # ]: 1627 : delete rewriter;
[ - + ]
910 [ # # ][ # # ]: 1627 : }
[ - + ]
911 : :
912 : 5 : void TransportLayerAnalyzer::Done()
913 : : {
914 : 5 : Analyzer::Done();
915 : :
916 [ - + ]: 5 : if ( rewriter )
917 : 0 : rewriter->Done();
918 : 5 : }
919 : :
920 : : void TransportLayerAnalyzer::SetContentsFile(unsigned int /* direction */,
921 : 0 : BroFile* /* f */)
922 : : {
923 : 0 : run_time("analyzer type does not support writing to a contents file");
924 : 0 : }
925 : :
926 : 0 : BroFile* TransportLayerAnalyzer::GetContentsFile(unsigned int /* direction */) const
927 : : {
928 : 0 : run_time("analyzer type does not support writing to a contents file");
929 : 0 : return 0;
930 : : }
931 : :
932 : 0 : void TransportLayerAnalyzer::SetTraceRewriter(Rewriter* r)
933 : : {
934 [ # # ]: 0 : if ( rewriter )
935 : 0 : rewriter->Done();
936 [ # # ]: 0 : delete rewriter;
937 : 0 : rewriter = r;
938 : 0 : }
939 : :
940 : 0 : void TransportLayerAnalyzer::PacketContents(const u_char* data, int len)
941 : : {
942 [ # # ][ # # ]: 0 : if ( packet_contents && len > 0 )
[ # # ]
943 : : {
944 : 0 : BroString* cbs = new BroString(data, len, 1);
945 : 0 : Val* contents = new StringVal(cbs);
946 : 0 : Event(packet_contents, contents);
947 : : }
948 [ + - ][ + - ]: 6 : }
949 : 3 :
|