Suppress Teredo weirds unless decapsulation was successful once before.

This commit is contained in:
Jon Siwek 2012-06-04 16:57:46 -05:00
parent 9851591317
commit ae85bd1b95
3 changed files with 39 additions and 20 deletions

View file

@ -215,6 +215,11 @@ public:
// analyzer, even if the method is called multiple times. // analyzer, even if the method is called multiple times.
virtual void ProtocolConfirmation(); 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 // Report that we found a significant protocol violation which might
// indicate that the analyzed data is in fact not the expected // indicate that the analyzed data is in fact not the expected
// protocol. The protocol_violation event is raised once per call to // protocol. The protocol_violation event is raised once per call to

View file

@ -13,7 +13,8 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len,
{ {
if ( len < 2 ) if ( len < 2 )
{ {
reporter->Weird(conn, "truncated_Teredo"); Weird("truncated_Teredo");
return false;
} }
uint16 tag = ntohs((*((const uint16*)data))); uint16 tag = ntohs((*((const uint16*)data)));
@ -27,7 +28,7 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len,
if ( len < 8 ) if ( len < 8 )
{ {
reporter->Weird(conn, "truncated_Teredo_origin_indication"); Weird("truncated_Teredo_origin_indication");
return false; return false;
} }
@ -46,7 +47,7 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len,
if ( len < 4 ) if ( len < 4 )
{ {
reporter->Weird(conn, "truncated_Teredo_authentication"); Weird("truncated_Teredo_authentication");
return false; return false;
} }
@ -56,7 +57,7 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len,
if ( len < tot_len ) if ( len < tot_len )
{ {
reporter->Weird(conn, "truncated_Teredo_authentication"); Weird("truncated_Teredo_authentication");
return false; return false;
} }
@ -70,13 +71,13 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len,
// IPv6 // IPv6
if ( len < 40 ) if ( len < 40 )
{ {
reporter->Weird(conn, "truncated_IPv6_in_Teredo"); Weird("truncated_IPv6_in_Teredo");
return false; return false;
} }
if ( len - 40 != ntohs(((const struct ip6_hdr*)data)->ip6_plen) ) 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; 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); Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
const Encapsulation* e = Conn()->GetEncapsulation(); TeredoEncapsulation te(this);
if ( e && e->Depth() >= BifConst::Tunnel::max_depth )
{
reporter->Weird(Conn(), "tunnel_depth");
return;
}
TeredoEncapsulation te(Conn());
if ( ! te.Parse(data, len) ) if ( ! te.Parse(data, len) )
{ {
ProtocolViolation("Invalid Teredo encapsulation", (const char*)data, ProtocolViolation("Bad Teredo encapsulation", (const char*)data, len);
len);
return; return;
} }
ProtocolConfirmation(); ProtocolConfirmation();
const Encapsulation* e = Conn()->GetEncapsulation();
if ( e && e->Depth() >= BifConst::Tunnel::max_depth )
{
Weird("tunnel_depth");
return;
}
// TODO: raise Teredo-specific events // TODO: raise Teredo-specific events
Encapsulation* outer = new Encapsulation(e); Encapsulation* outer = new Encapsulation(e);

View file

@ -24,6 +24,17 @@ public:
//TODO: specific option to turn off Teredo analysis? //TODO: specific option to turn off Teredo analysis?
{ return BifConst::Tunnel::max_depth > 0; } { 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: protected:
friend class AnalyzerTimer; friend class AnalyzerTimer;
void ExpireTimer(double t); void ExpireTimer(double t);
@ -31,8 +42,8 @@ protected:
class TeredoEncapsulation { class TeredoEncapsulation {
public: public:
TeredoEncapsulation(Connection* c) TeredoEncapsulation(const Teredo_Analyzer* ta)
: inner_ip(0), origin_indication(0), auth(0), conn(c) : inner_ip(0), origin_indication(0), auth(0), analyzer(ta)
{} {}
/** /**
@ -54,10 +65,13 @@ public:
protected: protected:
bool DoParse(const u_char* data, int& len, bool found_orig, bool found_au); 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* inner_ip;
const u_char* origin_indication; const u_char* origin_indication;
const u_char* auth; const u_char* auth;
Connection* conn; const Teredo_Analyzer* analyzer;
}; };
#endif #endif