diff --git a/src/Analyzer.cc b/src/Analyzer.cc index ff159f5b11..81f3b6575c 100644 --- a/src/Analyzer.cc +++ b/src/Analyzer.cc @@ -58,6 +58,9 @@ const Analyzer::Config Analyzer::analyzer_configs[] = { { AnalyzerTag::ICMP_Echo, "ICMP_ECHO", ICMP_Echo_Analyzer::InstantiateAnalyzer, ICMP_Echo_Analyzer::Available, 0, false }, + { AnalyzerTag::ICMP_Redir, "ICMP_REDIR", + ICMP_Redir_Analyzer::InstantiateAnalyzer, + ICMP_Redir_Analyzer::Available, 0, false }, { AnalyzerTag::TCP, "TCP", TCP_Analyzer::InstantiateAnalyzer, TCP_Analyzer::Available, 0, false }, diff --git a/src/AnalyzerTags.h b/src/AnalyzerTags.h index e5760c41f8..00ff481413 100644 --- a/src/AnalyzerTags.h +++ b/src/AnalyzerTags.h @@ -22,7 +22,9 @@ namespace AnalyzerTag { PIA_TCP, PIA_UDP, // Transport-layer analyzers. - ICMP, ICMP_TimeExceeded, ICMP_Unreachable, ICMP_Echo, TCP, UDP, + ICMP, + ICMP_TimeExceeded, ICMP_Unreachable, ICMP_Echo, ICMP_Redir, + TCP, UDP, // Application-layer analyzers (hand-written). BitTorrent, BitTorrentTracker, diff --git a/src/DPM.cc b/src/DPM.cc index 3e27a0501d..95c219182e 100644 --- a/src/DPM.cc +++ b/src/DPM.cc @@ -229,6 +229,14 @@ bool DPM::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn, } break; + case ICMP_REDIRECT: + if ( ICMP_Redir_Analyzer::Available() ) + { + root = new ICMP_Redir_Analyzer(conn); + DBG_DPD(conn, "activated ICMP Redir analyzer"); + } + break; + case ICMP_UNREACH: if ( ICMP_Unreachable_Analyzer::Available() ) { diff --git a/src/ICMP.cc b/src/ICMP.cc index a72e249d81..95169cd518 100644 --- a/src/ICMP.cc +++ b/src/ICMP.cc @@ -321,6 +321,24 @@ void ICMP_Echo_Analyzer::NextICMP(double t, const struct icmp* icmpp, int len, ConnectionEvent(f, vl); } +ICMP_Redir_Analyzer::ICMP_Redir_Analyzer(Connection* c) +: ICMP_Analyzer(AnalyzerTag::ICMP_Redir, c) + { + } + +void ICMP_Redir_Analyzer::NextICMP(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data) + { + uint32 addr = ntohl(icmpp->icmp_hun.ih_void); + + val_list* vl = new val_list; + vl->append(BuildConnVal()); + vl->append(BuildICMPVal()); + vl->append(new AddrVal(htonl(addr))); + + ConnectionEvent(icmp_redirect, vl); + } + void ICMP_Context_Analyzer::NextICMP(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data) diff --git a/src/ICMP.h b/src/ICMP.h index db1984e860..62b859beba 100644 --- a/src/ICMP.h +++ b/src/ICMP.h @@ -74,6 +74,22 @@ protected: int len, int caplen, const u_char*& data); }; +class ICMP_Redir_Analyzer : public ICMP_Analyzer { +public: + ICMP_Redir_Analyzer(Connection* conn); + + static Analyzer* InstantiateAnalyzer(Connection* conn) + { return new ICMP_Redir_Analyzer(conn); } + + static bool Available() { return icmp_redirect; } + +protected: + ICMP_Redir_Analyzer() { } + + virtual void NextICMP(double t, const struct icmp* icmpp, + int len, int caplen, const u_char*& data); +}; + class ICMP_Context_Analyzer : public ICMP_Analyzer { public: ICMP_Context_Analyzer(AnalyzerTag::Tag tag, Connection* conn) diff --git a/src/event.bif b/src/event.bif index 270f1b0d0b..74bfaa3e03 100644 --- a/src/event.bif +++ b/src/event.bif @@ -52,6 +52,7 @@ event icmp_echo_request%(c: connection, icmp: icmp_conn, id: count, seq: count, event icmp_echo_reply%(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string%); event icmp_unreachable%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); event icmp_time_exceeded%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%); +event icmp_redirect%(c: connection, icmp: icmp_conn, a: addr%); event net_stats_update%(t: time, ns: net_stats%); event conn_stats%(c: connection, os: endpoint_stats, rs: endpoint_stats%); event conn_weird%(name: string, c: connection%);