From ae85bd1b957d6493764d8e3c1d6bec2143428bfb Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 4 Jun 2012 16:57:46 -0500 Subject: [PATCH] Suppress Teredo weirds unless decapsulation was successful once before. --- src/Analyzer.h | 5 +++++ src/Teredo.cc | 34 +++++++++++++++++----------------- src/Teredo.h | 20 +++++++++++++++++--- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/src/Analyzer.h b/src/Analyzer.h index 7797e215fe..ef596ac696 100644 --- a/src/Analyzer.h +++ b/src/Analyzer.h @@ -215,6 +215,11 @@ public: // analyzer, even if the method is called multiple times. virtual void ProtocolConfirmation(); + // Return whether the analyzer previously called ProtocolConfirmation() + // at least once before. + virtual bool ProtocolConfirmed() const + { return protocol_confirmed; } + // Report that we found a significant protocol violation which might // indicate that the analyzed data is in fact not the expected // protocol. The protocol_violation event is raised once per call to diff --git a/src/Teredo.cc b/src/Teredo.cc index 08eb7d0d2b..c97d4fb8af 100644 --- a/src/Teredo.cc +++ b/src/Teredo.cc @@ -13,7 +13,8 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len, { if ( len < 2 ) { - reporter->Weird(conn, "truncated_Teredo"); + Weird("truncated_Teredo"); + return false; } uint16 tag = ntohs((*((const uint16*)data))); @@ -27,7 +28,7 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len, if ( len < 8 ) { - reporter->Weird(conn, "truncated_Teredo_origin_indication"); + Weird("truncated_Teredo_origin_indication"); return false; } @@ -46,7 +47,7 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len, if ( len < 4 ) { - reporter->Weird(conn, "truncated_Teredo_authentication"); + Weird("truncated_Teredo_authentication"); return false; } @@ -56,7 +57,7 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len, if ( len < tot_len ) { - reporter->Weird(conn, "truncated_Teredo_authentication"); + Weird("truncated_Teredo_authentication"); return false; } @@ -70,13 +71,13 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len, // IPv6 if ( len < 40 ) { - reporter->Weird(conn, "truncated_IPv6_in_Teredo"); + Weird("truncated_IPv6_in_Teredo"); return false; } if ( len - 40 != ntohs(((const struct ip6_hdr*)data)->ip6_plen) ) { - reporter->Weird(conn, "Teredo_payload_len_mismatch"); + Weird("Teredo_payload_len_mismatch"); return false; } @@ -92,25 +93,24 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); - const Encapsulation* e = Conn()->GetEncapsulation(); - - if ( e && e->Depth() >= BifConst::Tunnel::max_depth ) - { - reporter->Weird(Conn(), "tunnel_depth"); - return; - } - - TeredoEncapsulation te(Conn()); + TeredoEncapsulation te(this); if ( ! te.Parse(data, len) ) { - ProtocolViolation("Invalid Teredo encapsulation", (const char*)data, - len); + ProtocolViolation("Bad Teredo encapsulation", (const char*)data, len); return; } ProtocolConfirmation(); + const Encapsulation* e = Conn()->GetEncapsulation(); + + if ( e && e->Depth() >= BifConst::Tunnel::max_depth ) + { + Weird("tunnel_depth"); + return; + } + // TODO: raise Teredo-specific events Encapsulation* outer = new Encapsulation(e); diff --git a/src/Teredo.h b/src/Teredo.h index 0662099233..d5422cdef4 100644 --- a/src/Teredo.h +++ b/src/Teredo.h @@ -24,6 +24,17 @@ public: //TODO: specific option to turn off Teredo analysis? { return BifConst::Tunnel::max_depth > 0; } + /** + * Emits a weird only if the analyzer has previously been able to + * decapsulate a Teredo packet since otherwise the weirds could happen + * frequently enough to be less than helpful. + */ + void Weird(const char* name) const + { + if ( ProtocolConfirmed() ) + reporter->Weird(Conn(), name); + } + protected: friend class AnalyzerTimer; void ExpireTimer(double t); @@ -31,8 +42,8 @@ protected: class TeredoEncapsulation { public: - TeredoEncapsulation(Connection* c) - : inner_ip(0), origin_indication(0), auth(0), conn(c) + TeredoEncapsulation(const Teredo_Analyzer* ta) + : inner_ip(0), origin_indication(0), auth(0), analyzer(ta) {} /** @@ -54,10 +65,13 @@ public: protected: bool DoParse(const u_char* data, int& len, bool found_orig, bool found_au); + void Weird(const char* name) const + { analyzer->Weird(name); } + const u_char* inner_ip; const u_char* origin_indication; const u_char* auth; - Connection* conn; + const Teredo_Analyzer* analyzer; }; #endif