From d8adfaef65a4612bbc7b782334680b4ff30dee4d Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 14 Apr 2021 09:43:59 -0700 Subject: [PATCH] Add new ICMP packet analyzer, remove old one --- src/analyzer/Manager.cc | 7 - src/analyzer/protocol/CMakeLists.txt | 1 - src/analyzer/protocol/icmp/CMakeLists.txt | 9 - src/analyzer/protocol/icmp/ICMP.cc | 908 ------------------ src/analyzer/protocol/icmp/ICMP.h | 99 -- src/analyzer/protocol/icmp/Plugin.cc | 22 - .../protocol/icmp/CMakeLists.txt | 3 +- src/packet_analysis/protocol/icmp/ICMP.cc | 831 +++++++++++++++- src/packet_analysis/protocol/icmp/ICMP.h | 99 +- src/packet_analysis/protocol/icmp/Plugin.cc | 4 +- .../protocol/icmp/events.bif | 0 src/session/Manager.cc | 3 - .../canonified_loaded_scripts.log | 2 +- .../canonified_loaded_scripts.log | 2 +- 14 files changed, 933 insertions(+), 1057 deletions(-) delete mode 100644 src/analyzer/protocol/icmp/CMakeLists.txt delete mode 100644 src/analyzer/protocol/icmp/ICMP.cc delete mode 100644 src/analyzer/protocol/icmp/ICMP.h delete mode 100644 src/analyzer/protocol/icmp/Plugin.cc rename src/{analyzer => packet_analysis}/protocol/icmp/events.bif (100%) diff --git a/src/analyzer/Manager.cc b/src/analyzer/Manager.cc index 3d44017d97..a111d36c4f 100644 --- a/src/analyzer/Manager.cc +++ b/src/analyzer/Manager.cc @@ -8,7 +8,6 @@ #include "zeek/RunState.h" #include "zeek/analyzer/protocol/conn-size/ConnSize.h" -#include "zeek/analyzer/protocol/icmp/ICMP.h" #include "zeek/analyzer/protocol/pia/PIA.h" #include "zeek/analyzer/protocol/stepping-stone/SteppingStone.h" #include "zeek/analyzer/protocol/tcp/TCP.h" @@ -383,12 +382,6 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn) DBG_ANALYZER(conn, "activated UDP analyzer"); break; - case TRANSPORT_ICMP: { - root = new analyzer::icmp::ICMP_Analyzer(conn); - DBG_ANALYZER(conn, "activated ICMP analyzer"); - break; - } - default: reporter->InternalWarning("unknown protocol can't build analyzer tree"); return false; diff --git a/src/analyzer/protocol/CMakeLists.txt b/src/analyzer/protocol/CMakeLists.txt index 49dde00190..1a6e241ece 100644 --- a/src/analyzer/protocol/CMakeLists.txt +++ b/src/analyzer/protocol/CMakeLists.txt @@ -14,7 +14,6 @@ add_subdirectory(gnutella) add_subdirectory(gssapi) add_subdirectory(gtpv1) add_subdirectory(http) -add_subdirectory(icmp) add_subdirectory(ident) add_subdirectory(imap) add_subdirectory(irc) diff --git a/src/analyzer/protocol/icmp/CMakeLists.txt b/src/analyzer/protocol/icmp/CMakeLists.txt deleted file mode 100644 index 875b3597ec..0000000000 --- a/src/analyzer/protocol/icmp/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ - -include(ZeekPlugin) - -include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) - -zeek_plugin_begin(Zeek ICMP) -zeek_plugin_cc(ICMP.cc Plugin.cc) -zeek_plugin_bif(events.bif) -zeek_plugin_end() diff --git a/src/analyzer/protocol/icmp/ICMP.cc b/src/analyzer/protocol/icmp/ICMP.cc deleted file mode 100644 index 4abcca8f62..0000000000 --- a/src/analyzer/protocol/icmp/ICMP.cc +++ /dev/null @@ -1,908 +0,0 @@ -// See the file "COPYING" in the main distribution directory for copyright. - -#include "zeek/zeek-config.h" -#include "zeek/analyzer/protocol/icmp/ICMP.h" - -#include -#include - -#include "zeek/IP.h" -#include "zeek/RunState.h" -#include "zeek/NetVar.h" -#include "zeek/Event.h" -#include "zeek/Conn.h" -#include "zeek/Desc.h" -#include "zeek/Reporter.h" - -#include "zeek/analyzer/protocol/icmp/events.bif.h" - -namespace zeek::analyzer::icmp { - -ICMP_Analyzer::ICMP_Analyzer(Connection* c) - : TransportLayerAnalyzer("ICMP", c), - icmp_conn_val(), type(), code(), request_len(-1), reply_len(-1) - { - c->SetInactivityTimeout(zeek::detail::icmp_inactivity_timeout); - } - -void ICMP_Analyzer::Done() - { - TransportLayerAnalyzer::Done(); - icmp_conn_val = nullptr; - matcher_state.FinishEndpointMatcher(); - } - -void ICMP_Analyzer::DeliverPacket(int len, const u_char* data, - bool is_orig, uint64_t seq, const IP_Hdr* ip, int caplen) - { - assert(ip); - - TransportLayerAnalyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); - - // We need the min() here because Ethernet frame padding can lead to - // caplen > len. - if ( packet_contents ) - // Subtract off the common part of ICMP header. - PacketContents(data + 8, std::min(len, caplen) - 8); - - const struct icmp* icmpp = (const struct icmp*) data; - - if ( ! zeek::detail::ignore_checksums && - ! zeek::id::find_val("ignore_checksums_nets")->Contains(ip->IPHeaderSrcAddr()) && - caplen >= len ) - { - int chksum = 0; - - switch ( ip->NextProto() ) - { - case IPPROTO_ICMP: - chksum = icmp_checksum(icmpp, len); - break; - - case IPPROTO_ICMPV6: - chksum = icmp6_checksum(icmpp, ip, len); - break; - - default: - reporter->AnalyzerError( - this, "unexpected IP proto in ICMP analyzer: %d", ip->NextProto()); - return; - } - - if ( chksum != 0xffff ) - { - Weird("bad_ICMP_checksum"); - return; - } - } - - Conn()->SetLastTime(run_state::current_timestamp); - - if ( zeek::detail::rule_matcher ) - { - if ( ! matcher_state.MatcherInitialized(is_orig) ) - matcher_state.InitEndpointMatcher(this, ip, len, is_orig, nullptr); - } - - type = icmpp->icmp_type; - code = icmpp->icmp_code; - - // Move past common portion of ICMP header. - data += 8; - caplen -= 8; - len -= 8; - - int& len_stat = is_orig ? request_len : reply_len; - if ( len_stat < 0 ) - len_stat = len; - else - len_stat += len; - - if ( ip->NextProto() == IPPROTO_ICMP ) - NextICMP4(run_state::current_timestamp, icmpp, len, caplen, data, ip); - else if ( ip->NextProto() == IPPROTO_ICMPV6 ) - NextICMP6(run_state::current_timestamp, icmpp, len, caplen, data, ip); - else - { - reporter->AnalyzerError( - this, "expected ICMP as IP packet's protocol, got %d", ip->NextProto()); - return; - } - - - if ( caplen >= len ) - ForwardPacket(len, data, is_orig, seq, ip, caplen); - - if ( zeek::detail::rule_matcher ) - matcher_state.Match(zeek::detail::Rule::PAYLOAD, data, len, is_orig, - false, false, true); - } - -void ICMP_Analyzer::NextICMP4(double t, const struct icmp* icmpp, int len, int caplen, - const u_char*& data, const IP_Hdr* ip_hdr ) - { - switch ( icmpp->icmp_type ) - { - case ICMP_ECHO: - case ICMP_ECHOREPLY: - Echo(t, icmpp, len, caplen, data, ip_hdr); - break; - - case ICMP_UNREACH: - case ICMP_TIMXCEED: - Context4(t, icmpp, len, caplen, data, ip_hdr); - break; - - default: - ICMP_Sent(icmpp, len, caplen, 0, data, ip_hdr); - break; - } - } - -void ICMP_Analyzer::NextICMP6(double t, const struct icmp* icmpp, int len, int caplen, - const u_char*& data, const IP_Hdr* ip_hdr ) - { - switch ( icmpp->icmp_type ) - { - // Echo types. - case ICMP6_ECHO_REQUEST: - case ICMP6_ECHO_REPLY: - Echo(t, icmpp, len, caplen, data, ip_hdr); - break; - - // Error messages all have the same structure for their context, - // and are handled by the same function. - case ICMP6_PARAM_PROB: - case ICMP6_TIME_EXCEEDED: - case ICMP6_PACKET_TOO_BIG: - case ICMP6_DST_UNREACH: - Context6(t, icmpp, len, caplen, data, ip_hdr); - break; - - // Router related messages. - case ND_REDIRECT: - Redirect(t, icmpp, len, caplen, data, ip_hdr); - break; - case ND_ROUTER_ADVERT: - RouterAdvert(t, icmpp, len, caplen, data, ip_hdr); - break; - case ND_NEIGHBOR_ADVERT: - NeighborAdvert(t, icmpp, len, caplen, data, ip_hdr); - break; - case ND_NEIGHBOR_SOLICIT: - NeighborSolicit(t, icmpp, len, caplen, data, ip_hdr); - break; - case ND_ROUTER_SOLICIT: - RouterSolicit(t, icmpp, len, caplen, data, ip_hdr); - break; - case ICMP6_ROUTER_RENUMBERING: - ICMP_Sent(icmpp, len, caplen, 1, data, ip_hdr); - break; - -#if 0 - // Currently not specifically implemented. - case MLD_LISTENER_QUERY: - case MLD_LISTENER_REPORT: - case MLD_LISTENER_REDUCTION: -#endif - default: - // Error messages (i.e., ICMPv6 type < 128) all have - // the same structure for their context, and are - // handled by the same function. - if ( icmpp->icmp_type < 128 ) - Context6(t, icmpp, len, caplen, data, ip_hdr); - else - ICMP_Sent(icmpp, len, caplen, 1, data, ip_hdr); - break; - } - } - -void ICMP_Analyzer::ICMP_Sent(const struct icmp* icmpp, int len, int caplen, - int icmpv6, const u_char* data, - const IP_Hdr* ip_hdr) - { - if ( icmp_sent ) - EnqueueConnEvent(icmp_sent, - ConnVal(), - BuildInfo(icmpp, len, icmpv6, ip_hdr) - ); - - if ( icmp_sent_payload ) - { - String* payload = new String(data, std::min(len, caplen), false); - - EnqueueConnEvent(icmp_sent_payload, - ConnVal(), - BuildInfo(icmpp, len, icmpv6, ip_hdr), - make_intrusive(payload) - ); - } - } - -RecordValPtr ICMP_Analyzer::BuildInfo(const struct icmp* icmpp, int len, - bool icmpv6, const IP_Hdr* ip_hdr) - { - static auto icmp_info = id::find_type("icmp_info"); - auto rval = make_intrusive(icmp_info); - rval->Assign(0, static_cast(icmpv6)); - rval->Assign(1, icmpp->icmp_type); - rval->Assign(2, icmpp->icmp_code); - rval->Assign(3, len); - rval->Assign(4, ip_hdr->TTL()); - return rval; - } - -TransportProto ICMP_Analyzer::GetContextProtocol(const IP_Hdr* ip_hdr, uint32_t* src_port, uint32_t* dst_port) - { - const u_char* transport_hdr; - uint32_t ip_hdr_len = ip_hdr->HdrLen(); - bool ip4 = ip_hdr->IP4_Hdr(); - - if ( ip4 ) - transport_hdr = ((u_char *) ip_hdr->IP4_Hdr() + ip_hdr_len); - else - transport_hdr = ((u_char *) ip_hdr->IP6_Hdr() + ip_hdr_len); - - TransportProto proto; - - switch ( ip_hdr->NextProto() ) { - case 1: proto = TRANSPORT_ICMP; break; - case 6: proto = TRANSPORT_TCP; break; - case 17: proto = TRANSPORT_UDP; break; - case 58: proto = TRANSPORT_ICMP; break; - default: proto = TRANSPORT_UNKNOWN; break; - } - - switch ( proto ) { - case TRANSPORT_ICMP: - { - const struct icmp* icmpp = - (const struct icmp *) transport_hdr; - bool is_one_way; // dummy - *src_port = ntohs(icmpp->icmp_type); - - if ( ip4 ) - *dst_port = ntohs(ICMP4_counterpart(icmpp->icmp_type, - icmpp->icmp_code, is_one_way)); - else - *dst_port = ntohs(ICMP6_counterpart(icmpp->icmp_type, - icmpp->icmp_code, is_one_way)); - - break; - } - - case TRANSPORT_TCP: - { - const struct tcphdr* tp = - (const struct tcphdr *) transport_hdr; - *src_port = ntohs(tp->th_sport); - *dst_port = ntohs(tp->th_dport); - break; - } - - case TRANSPORT_UDP: - { - const struct udphdr* up = - (const struct udphdr *) transport_hdr; - *src_port = ntohs(up->uh_sport); - *dst_port = ntohs(up->uh_dport); - break; - } - - default: - *src_port = *dst_port = ntohs(0); - break; - } - - return proto; - } - -RecordValPtr ICMP_Analyzer::ExtractICMP4Context(int len, const u_char*& data) - { - const IP_Hdr ip_hdr_data((const struct ip*) data, false); - const IP_Hdr* ip_hdr = &ip_hdr_data; - - uint32_t ip_hdr_len = ip_hdr->HdrLen(); - - uint32_t ip_len, frag_offset; - TransportProto proto = TRANSPORT_UNKNOWN; - int DF, MF, bad_hdr_len, bad_checksum; - IPAddr src_addr, dst_addr; - uint32_t src_port, dst_port; - - if ( len < (int)sizeof(struct ip) || ip_hdr_len > uint32_t(len) ) - { - // We don't have an entire IP header. - bad_hdr_len = 1; - ip_len = frag_offset = 0; - DF = MF = bad_checksum = 0; - src_port = dst_port = 0; - } - - else - { - bad_hdr_len = 0; - ip_len = ip_hdr->TotalLen(); - bad_checksum = ! run_state::current_pkt->l3_checksummed && - (detail::in_cksum(reinterpret_cast(ip_hdr->IP4_Hdr()), - ip_hdr_len) != 0xffff); - - src_addr = ip_hdr->SrcAddr(); - dst_addr = ip_hdr->DstAddr(); - - DF = ip_hdr->DF(); - MF = ip_hdr->MF(); - frag_offset = ip_hdr->FragOffset(); - - if ( uint32_t(len) >= ip_hdr_len + 4 ) - proto = GetContextProtocol(ip_hdr, &src_port, &dst_port); - else - { - // 4 above is the magic number meaning that both - // port numbers are included in the ICMP. - src_port = dst_port = 0; - bad_hdr_len = 1; - } - } - - static auto icmp_context = id::find_type("icmp_context"); - auto iprec = make_intrusive(icmp_context); - auto id_val = make_intrusive(id::conn_id); - - id_val->Assign(0, make_intrusive(src_addr)); - id_val->Assign(1, val_mgr->Port(src_port, proto)); - id_val->Assign(2, make_intrusive(dst_addr)); - id_val->Assign(3, val_mgr->Port(dst_port, proto)); - - iprec->Assign(0, std::move(id_val)); - iprec->Assign(1, ip_len); - iprec->Assign(2, proto); - iprec->Assign(3, frag_offset); - iprec->Assign(4, static_cast(bad_hdr_len)); - iprec->Assign(5, static_cast(bad_checksum)); - iprec->Assign(6, static_cast(MF)); - iprec->Assign(7, static_cast(DF)); - - return iprec; - } - -RecordValPtr ICMP_Analyzer::ExtractICMP6Context(int len, const u_char*& data) - { - int DF = 0, MF = 0, bad_hdr_len = 0; - TransportProto proto = TRANSPORT_UNKNOWN; - - IPAddr src_addr; - IPAddr dst_addr; - uint32_t ip_len, frag_offset = 0; - uint32_t src_port, dst_port; - - if ( len < (int)sizeof(struct ip6_hdr) ) - { - bad_hdr_len = 1; - ip_len = 0; - src_port = dst_port = 0; - } - else - { - const IP_Hdr ip_hdr_data((const struct ip6_hdr*) data, false, len); - const IP_Hdr* ip_hdr = &ip_hdr_data; - - ip_len = ip_hdr->TotalLen(); - src_addr = ip_hdr->SrcAddr(); - dst_addr = ip_hdr->DstAddr(); - frag_offset = ip_hdr->FragOffset(); - MF = ip_hdr->MF(); - DF = ip_hdr->DF(); - - if ( uint32_t(len) >= uint32_t(ip_hdr->HdrLen() + 4) ) - proto = GetContextProtocol(ip_hdr, &src_port, &dst_port); - else - { - // 4 above is the magic number meaning that both - // port numbers are included in the ICMP. - src_port = dst_port = 0; - bad_hdr_len = 1; - } - } - - static auto icmp_context = id::find_type("icmp_context"); - auto iprec = make_intrusive(icmp_context); - auto id_val = make_intrusive(id::conn_id); - - id_val->Assign(0, make_intrusive(src_addr)); - id_val->Assign(1, val_mgr->Port(src_port, proto)); - id_val->Assign(2, make_intrusive(dst_addr)); - id_val->Assign(3, val_mgr->Port(dst_port, proto)); - - iprec->Assign(0, std::move(id_val)); - iprec->Assign(1, ip_len); - iprec->Assign(2, proto); - iprec->Assign(3, frag_offset); - iprec->Assign(4, static_cast(bad_hdr_len)); - // bad_checksum is always false since IPv6 layer doesn't have a checksum. - iprec->Assign(5, false); - iprec->Assign(6, static_cast(MF)); - iprec->Assign(7, static_cast(DF)); - - return iprec; - } - -bool ICMP_Analyzer::IsReuse(double /* t */, const u_char* /* pkt */) - { - return false; - } - -void ICMP_Analyzer::Describe(ODesc* d) const - { - d->Add(Conn()->StartTime()); - d->Add("("); - d->Add(Conn()->LastTime()); - d->AddSP(")"); - - d->Add(Conn()->OrigAddr()); - d->Add("."); - d->Add(type); - d->Add("."); - d->Add(code); - - d->SP(); - d->AddSP("->"); - - d->Add(Conn()->RespAddr()); - } - -void ICMP_Analyzer::UpdateConnVal(RecordVal *conn_val) - { - const auto& orig_endp = conn_val->GetField("orig"); - const auto& resp_endp = conn_val->GetField("resp"); - - UpdateEndpointVal(orig_endp, true); - UpdateEndpointVal(resp_endp, false); - - // Call children's UpdateConnVal - Analyzer::UpdateConnVal(conn_val); - } - -void ICMP_Analyzer::UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig) - { - Conn()->EnableStatusUpdateTimer(); - - int size = is_orig ? request_len : reply_len; - auto endp = endp_arg->AsRecordVal(); - - if ( size < 0 ) - { - endp->Assign(0, 0); - endp->Assign(1, ICMP_INACTIVE); - } - - else - { - endp->Assign(0, size); - endp->Assign(1, ICMP_ACTIVE); - } - } - -unsigned int ICMP_Analyzer::MemoryAllocation() const - { - return Analyzer::MemoryAllocation() - + padded_sizeof(*this) - padded_sizeof(Connection) - + (icmp_conn_val ? icmp_conn_val->MemoryAllocation() : 0); - } - - -void ICMP_Analyzer::Echo(double t, const struct icmp* icmpp, int len, - int caplen, const u_char*& data, const IP_Hdr* ip_hdr) - { - // For handling all Echo related ICMP messages - EventHandlerPtr f = nullptr; - - if ( ip_hdr->NextProto() == IPPROTO_ICMPV6 ) - f = (icmpp->icmp_type == ICMP6_ECHO_REQUEST) - ? icmp_echo_request : icmp_echo_reply; - else - f = (icmpp->icmp_type == ICMP_ECHO) - ? icmp_echo_request : icmp_echo_reply; - - if ( ! f ) - return; - - int iid = ntohs(icmpp->icmp_hun.ih_idseq.icd_id); - int iseq = ntohs(icmpp->icmp_hun.ih_idseq.icd_seq); - - String* payload = new String(data, caplen, false); - - EnqueueConnEvent(f, - ConnVal(), - BuildInfo(icmpp, len, ip_hdr->NextProto() != IPPROTO_ICMP, ip_hdr), - val_mgr->Count(iid), - val_mgr->Count(iseq), - make_intrusive(payload) - ); - } - - -void ICMP_Analyzer::RouterAdvert(double t, const struct icmp* icmpp, int len, - int caplen, const u_char*& data, const IP_Hdr* ip_hdr) - { - EventHandlerPtr f = icmp_router_advertisement; - - if ( ! f ) - return; - - uint32_t reachable = 0, retrans = 0; - - if ( caplen >= (int)sizeof(reachable) ) - memcpy(&reachable, data, sizeof(reachable)); - - if ( caplen >= (int)sizeof(reachable) + (int)sizeof(retrans) ) - memcpy(&retrans, data + sizeof(reachable), sizeof(retrans)); - - int opt_offset = sizeof(reachable) + sizeof(retrans); - - EnqueueConnEvent(f, - ConnVal(), - BuildInfo(icmpp, len, 1, ip_hdr), - val_mgr->Count(icmpp->icmp_num_addrs), // Cur Hop Limit - val_mgr->Bool(icmpp->icmp_wpa & 0x80), // Managed - val_mgr->Bool(icmpp->icmp_wpa & 0x40), // Other - val_mgr->Bool(icmpp->icmp_wpa & 0x20), // Home Agent - val_mgr->Count((icmpp->icmp_wpa & 0x18)>>3), // Pref - val_mgr->Bool(icmpp->icmp_wpa & 0x04), // Proxy - val_mgr->Count(icmpp->icmp_wpa & 0x02), // Reserved - make_intrusive((double)ntohs(icmpp->icmp_lifetime), Seconds), - make_intrusive((double)ntohl(reachable), Milliseconds), - make_intrusive((double)ntohl(retrans), Milliseconds), - BuildNDOptionsVal(caplen - opt_offset, data + opt_offset) - ); - } - - -void ICMP_Analyzer::NeighborAdvert(double t, const struct icmp* icmpp, int len, - int caplen, const u_char*& data, const IP_Hdr* ip_hdr) - { - EventHandlerPtr f = icmp_neighbor_advertisement; - - if ( ! f ) - return; - - IPAddr tgtaddr; - - if ( caplen >= (int)sizeof(in6_addr) ) - tgtaddr = IPAddr(*((const in6_addr*)data)); - - int opt_offset = sizeof(in6_addr); - - EnqueueConnEvent(f, - ConnVal(), - BuildInfo(icmpp, len, 1, ip_hdr), - val_mgr->Bool(icmpp->icmp_num_addrs & 0x80), // Router - val_mgr->Bool(icmpp->icmp_num_addrs & 0x40), // Solicited - val_mgr->Bool(icmpp->icmp_num_addrs & 0x20), // Override - make_intrusive(tgtaddr), - BuildNDOptionsVal(caplen - opt_offset, data + opt_offset) - ); - } - - -void ICMP_Analyzer::NeighborSolicit(double t, const struct icmp* icmpp, int len, - int caplen, const u_char*& data, const IP_Hdr* ip_hdr) - { - EventHandlerPtr f = icmp_neighbor_solicitation; - - if ( ! f ) - return; - - IPAddr tgtaddr; - - if ( caplen >= (int)sizeof(in6_addr) ) - tgtaddr = IPAddr(*((const in6_addr*)data)); - - int opt_offset = sizeof(in6_addr); - - EnqueueConnEvent(f, - ConnVal(), - BuildInfo(icmpp, len, 1, ip_hdr), - make_intrusive(tgtaddr), - BuildNDOptionsVal(caplen - opt_offset, data + opt_offset) - ); - } - - -void ICMP_Analyzer::Redirect(double t, const struct icmp* icmpp, int len, - int caplen, const u_char*& data, const IP_Hdr* ip_hdr) - { - EventHandlerPtr f = icmp_redirect; - - if ( ! f ) - return; - - IPAddr tgtaddr, dstaddr; - - if ( caplen >= (int)sizeof(in6_addr) ) - tgtaddr = IPAddr(*((const in6_addr*)data)); - - if ( caplen >= 2 * (int)sizeof(in6_addr) ) - dstaddr = IPAddr(*((const in6_addr*)(data + sizeof(in6_addr)))); - - int opt_offset = 2 * sizeof(in6_addr); - - EnqueueConnEvent(f, - ConnVal(), - BuildInfo(icmpp, len, 1, ip_hdr), - make_intrusive(tgtaddr), - make_intrusive(dstaddr), - BuildNDOptionsVal(caplen - opt_offset, data + opt_offset) - ); - } - - -void ICMP_Analyzer::RouterSolicit(double t, const struct icmp* icmpp, int len, - int caplen, const u_char*& data, const IP_Hdr* ip_hdr) - { - EventHandlerPtr f = icmp_router_solicitation; - - if ( ! f ) - return; - - EnqueueConnEvent(f, - ConnVal(), - BuildInfo(icmpp, len, 1, ip_hdr), - BuildNDOptionsVal(caplen, data) - ); - } - - -void ICMP_Analyzer::Context4(double t, const struct icmp* icmpp, - int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr) - { - EventHandlerPtr f = nullptr; - - switch ( icmpp->icmp_type ) - { - case ICMP_UNREACH: - f = icmp_unreachable; - break; - - case ICMP_TIMXCEED: - f = icmp_time_exceeded; - break; - } - - if ( f ) - EnqueueConnEvent(f, - ConnVal(), - BuildInfo(icmpp, len, 0, ip_hdr), - val_mgr->Count(icmpp->icmp_code), - ExtractICMP4Context(caplen, data) - ); - } - - -void ICMP_Analyzer::Context6(double t, const struct icmp* icmpp, - int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr) - { - EventHandlerPtr f = nullptr; - - switch ( icmpp->icmp_type ) - { - case ICMP6_DST_UNREACH: - f = icmp_unreachable; - break; - - case ICMP6_PARAM_PROB: - f = icmp_parameter_problem; - break; - - case ICMP6_TIME_EXCEEDED: - f = icmp_time_exceeded; - break; - - case ICMP6_PACKET_TOO_BIG: - f = icmp_packet_too_big; - break; - - default: - f = icmp_error_message; - break; - } - - if ( f ) - EnqueueConnEvent(f, - ConnVal(), - BuildInfo(icmpp, len, 1, ip_hdr), - val_mgr->Count(icmpp->icmp_code), - ExtractICMP6Context(caplen, data) - ); - } - -VectorValPtr ICMP_Analyzer::BuildNDOptionsVal(int caplen, const u_char* data) - { - static auto icmp6_nd_option_type = id::find_type("icmp6_nd_option"); - static auto icmp6_nd_prefix_info_type = id::find_type("icmp6_nd_prefix_info"); - - auto vv = make_intrusive( - id::find_type("icmp6_nd_options")); - - while ( caplen > 0 ) - { - // Must have at least type & length to continue parsing options. - if ( caplen < 2 ) - { - Weird("truncated_ICMPv6_ND_options"); - break; - } - - uint8_t type = *((const uint8_t*)data); - uint16_t length = *((const uint8_t*)(data + 1)); - - if ( length == 0 ) - { - Weird("zero_length_ICMPv6_ND_option"); - break; - } - - auto rv = make_intrusive(icmp6_nd_option_type); - rv->Assign(0, type); - rv->Assign(1, length); - - // Adjust length to be in units of bytes, exclude type/length fields. - length = length * 8 - 2; - - data += 2; - caplen -= 2; - - bool set_payload_field = false; - - // Only parse out known options that are there in full. - switch ( type ) { - case 1: - case 2: - // Source/Target Link-layer Address option - { - if ( caplen >= length ) - { - String* link_addr = new String(data, length, false); - rv->Assign(2, link_addr); - } - else - set_payload_field = true; - - break; - } - - case 3: - // Prefix Information option - { - if ( caplen >= 30 ) - { - auto info = make_intrusive(icmp6_nd_prefix_info_type); - uint8_t prefix_len = *((const uint8_t*)(data)); - bool L_flag = (*((const uint8_t*)(data + 1)) & 0x80) != 0; - bool A_flag = (*((const uint8_t*)(data + 1)) & 0x40) != 0; - uint32_t valid_life = *((const uint32_t*)(data + 2)); - uint32_t prefer_life = *((const uint32_t*)(data + 6)); - in6_addr prefix = *((const in6_addr*)(data + 14)); - info->Assign(0, prefix_len); - info->Assign(1, L_flag); - info->Assign(2, A_flag); - info->AssignInterval(3, double(ntohl(valid_life))); - info->AssignInterval(4, double(ntohl(prefer_life))); - info->Assign(5, make_intrusive(IPAddr(prefix))); - rv->Assign(3, std::move(info)); - } - - else - set_payload_field = true; - break; - } - - case 4: - // Redirected Header option - { - if ( caplen >= length ) - { - const u_char* hdr = data + 6; - rv->Assign(4, ExtractICMP6Context(length - 6, hdr)); - } - - else - set_payload_field = true; - - break; - } - - case 5: - // MTU option - { - if ( caplen >= 6 ) - rv->Assign(5, ntohl(*((const uint32_t*)(data + 2)))); - else - set_payload_field = true; - - break; - } - - default: - { - set_payload_field = true; - break; - } - } - - if ( set_payload_field ) - { - String* payload = new String(data, std::min((int)length, caplen), false); - rv->Assign(6, payload); - } - - data += length; - caplen -= length; - - vv->Assign(vv->Size(), std::move(rv)); - } - - return vv; - } - -int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way) - { - is_one_way = false; - - // Return the counterpart type if one exists. This allows us - // to track corresponding ICMP requests/replies. - // Note that for the two-way ICMP messages, icmp_code is - // always 0 (RFC 792). - switch ( icmp_type ) { - case ICMP_ECHO: return ICMP_ECHOREPLY; - case ICMP_ECHOREPLY: return ICMP_ECHO; - - case ICMP_TSTAMP: return ICMP_TSTAMPREPLY; - case ICMP_TSTAMPREPLY: return ICMP_TSTAMP; - - case ICMP_IREQ: return ICMP_IREQREPLY; - case ICMP_IREQREPLY: return ICMP_IREQ; - - case ICMP_ROUTERSOLICIT: return ICMP_ROUTERADVERT; - case ICMP_ROUTERADVERT: return ICMP_ROUTERSOLICIT; - - case ICMP_MASKREQ: return ICMP_MASKREPLY; - case ICMP_MASKREPLY: return ICMP_MASKREQ; - - default: is_one_way = true; return icmp_code; - } - } - -int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way) - { - is_one_way = false; - - switch ( icmp_type ) { - case ICMP6_ECHO_REQUEST: return ICMP6_ECHO_REPLY; - case ICMP6_ECHO_REPLY: return ICMP6_ECHO_REQUEST; - - case ND_ROUTER_SOLICIT: return ND_ROUTER_ADVERT; - case ND_ROUTER_ADVERT: return ND_ROUTER_SOLICIT; - - case ND_NEIGHBOR_SOLICIT: return ND_NEIGHBOR_ADVERT; - case ND_NEIGHBOR_ADVERT: return ND_NEIGHBOR_SOLICIT; - - case MLD_LISTENER_QUERY: return MLD_LISTENER_REPORT; - case MLD_LISTENER_REPORT: return MLD_LISTENER_QUERY; - - // ICMP node information query and response respectively (not defined in - // icmp6.h) - case 139: return 140; - case 140: return 139; - - // Home Agent Address Discovery Request Message and reply - case 144: return 145; - case 145: return 144; - - // TODO: Add further counterparts. - - default: is_one_way = true; return icmp_code; - } - } - -} // namespace zeek::analyzer::icmp diff --git a/src/analyzer/protocol/icmp/ICMP.h b/src/analyzer/protocol/icmp/ICMP.h deleted file mode 100644 index ef9aeddf92..0000000000 --- a/src/analyzer/protocol/icmp/ICMP.h +++ /dev/null @@ -1,99 +0,0 @@ -// See the file "COPYING" in the main distribution directory for copyright. - -#pragma once - -#include "zeek/RuleMatcher.h" -#include "zeek/analyzer/Analyzer.h" -#include "zeek/net_util.h" - -namespace zeek { - -class VectorVal; -using VectorValPtr = IntrusivePtr; - -namespace analyzer::icmp { - -enum ICMP_EndpointState { - ICMP_INACTIVE, // no packet seen - ICMP_ACTIVE, // packets seen -}; - -// We do not have an PIA for ICMP (yet) and therefore derive from -// RuleMatcherState to perform our own matching. -class ICMP_Analyzer final : public analyzer::TransportLayerAnalyzer { -public: - explicit ICMP_Analyzer(Connection* conn); - - void UpdateConnVal(RecordVal *conn_val) override; - - static analyzer::Analyzer* Instantiate(Connection* conn) - { return new ICMP_Analyzer(conn); } - -protected: - void Done() override; - void DeliverPacket(int len, const u_char* data, bool orig, - uint64_t seq, const IP_Hdr* ip, int caplen) override; - bool IsReuse(double t, const u_char* pkt) override; - unsigned int MemoryAllocation() const override; - - void ICMP_Sent(const struct icmp* icmpp, int len, int caplen, int icmpv6, - const u_char* data, const IP_Hdr* ip_hdr); - - void Echo(double t, const struct icmp* icmpp, int len, - int caplen, const u_char*& data, const IP_Hdr* ip_hdr); - void Redirect(double t, const struct icmp* icmpp, int len, - int caplen, const u_char*& data, const IP_Hdr* ip_hdr); - void RouterAdvert(double t, const struct icmp* icmpp, int len, - int caplen, const u_char*& data, const IP_Hdr* ip_hdr); - void NeighborAdvert(double t, const struct icmp* icmpp, int len, - int caplen, const u_char*& data, const IP_Hdr* ip_hdr); - void NeighborSolicit(double t, const struct icmp* icmpp, int len, - int caplen, const u_char*& data, const IP_Hdr* ip_hdr); - void RouterSolicit(double t, const struct icmp* icmpp, int len, - int caplen, const u_char*& data, const IP_Hdr* ip_hdr); - - void Describe(ODesc* d) const; - - RecordValPtr BuildInfo(const struct icmp* icmpp, int len, - bool icmpv6, const IP_Hdr* ip_hdr); - - void NextICMP4(double t, const struct icmp* icmpp, int len, int caplen, - const u_char*& data, const IP_Hdr* ip_hdr ); - - RecordValPtr ExtractICMP4Context(int len, const u_char*& data); - - void Context4(double t, const struct icmp* icmpp, int len, int caplen, - const u_char*& data, const IP_Hdr* ip_hdr); - - TransportProto GetContextProtocol(const IP_Hdr* ip_hdr, uint32_t* src_port, - uint32_t* dst_port); - - void NextICMP6(double t, const struct icmp* icmpp, int len, int caplen, - const u_char*& data, const IP_Hdr* ip_hdr ); - - RecordValPtr ExtractICMP6Context(int len, const u_char*& data); - - void Context6(double t, const struct icmp* icmpp, int len, int caplen, - const u_char*& data, const IP_Hdr* ip_hdr); - - // RFC 4861 Neighbor Discover message options - VectorValPtr BuildNDOptionsVal(int caplen, const u_char* data); - - RecordValPtr icmp_conn_val; - int type; - int code; - int request_len, reply_len; - - detail::RuleMatcherState matcher_state; - -private: - void UpdateEndpointVal(const ValPtr& endp, bool is_orig); -}; - -// Returns the counterpart type to the given type (e.g., the counterpart -// to ICMP_ECHOREPLY is ICMP_ECHO). -extern int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way); -extern int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way); - -} // namespace analyzer::icmp -} // namespace zeek diff --git a/src/analyzer/protocol/icmp/Plugin.cc b/src/analyzer/protocol/icmp/Plugin.cc deleted file mode 100644 index 7326604034..0000000000 --- a/src/analyzer/protocol/icmp/Plugin.cc +++ /dev/null @@ -1,22 +0,0 @@ -// See the file in the main distribution directory for copyright. - -#include "zeek/plugin/Plugin.h" -#include "zeek/analyzer/Component.h" -#include "zeek/analyzer/protocol/icmp/ICMP.h" - -namespace zeek::plugin::detail::Zeek_ICMP { - -class Plugin : public zeek::plugin::Plugin { -public: - zeek::plugin::Configuration Configure() override - { - AddComponent(new zeek::analyzer::Component("ICMP", zeek::analyzer::icmp::ICMP_Analyzer::Instantiate)); - - zeek::plugin::Configuration config; - config.name = "Zeek::ICMP"; - config.description = "ICMP analyzer"; - return config; - } -} plugin; - -} // namespace zeek::plugin::detail::Zeek_ICMP diff --git a/src/packet_analysis/protocol/icmp/CMakeLists.txt b/src/packet_analysis/protocol/icmp/CMakeLists.txt index 7b4eb86231..875b3597ec 100644 --- a/src/packet_analysis/protocol/icmp/CMakeLists.txt +++ b/src/packet_analysis/protocol/icmp/CMakeLists.txt @@ -3,6 +3,7 @@ include(ZeekPlugin) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) -zeek_plugin_begin(PacketAnalyzer ICMP_PKT) +zeek_plugin_begin(Zeek ICMP) zeek_plugin_cc(ICMP.cc Plugin.cc) +zeek_plugin_bif(events.bif) zeek_plugin_end() diff --git a/src/packet_analysis/protocol/icmp/ICMP.cc b/src/packet_analysis/protocol/icmp/ICMP.cc index 2eaf18b621..30b929e621 100644 --- a/src/packet_analysis/protocol/icmp/ICMP.cc +++ b/src/packet_analysis/protocol/icmp/ICMP.cc @@ -5,13 +5,30 @@ #include #include "zeek/RunState.h" +#include "zeek/Conn.h" +#include "zeek/Reporter.h" +#include "zeek/Desc.h" +#include "zeek/Val.h" +#include "zeek/analyzer/Manager.h" #include "zeek/session/Manager.h" +#include "zeek/analyzer/protocol/conn-size/ConnSize.h" + +#include "zeek/ZeekString.h" + +#include "zeek/packet_analysis/protocol/icmp/events.bif.h" + +enum ICMP_EndpointState { + ICMP_INACTIVE, // no packet seen + ICMP_ACTIVE, // packets seen +}; using namespace zeek::packet_analysis::ICMP; using namespace zeek::packet_analysis::IP; ICMPAnalyzer::ICMPAnalyzer() : IPBasedAnalyzer("ICMP", TRANSPORT_ICMP, ICMP_PORT_MASK, false) { + // TODO: remove once the other plugins are done + new_plugin = true; } ICMPAnalyzer::~ICMPAnalyzer() @@ -46,13 +63,742 @@ bool ICMPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet void ICMPAnalyzer::ContinueProcessing(Connection* c, double t, bool is_orig, int remaining, Packet* pkt) { + auto* ta = static_cast(c->GetRootAnalyzer()); + + const u_char* data = pkt->ip_hdr->Payload(); + int len = pkt->ip_hdr->PayloadLen(); + + if ( packet_contents && len > 0 ) + ta->PacketContents(data + 8, std::min(len, remaining) - 8); + + const struct icmp* icmpp = (const struct icmp*) data; + const std::unique_ptr& ip = pkt->ip_hdr; + + if ( ! zeek::detail::ignore_checksums && + ! zeek::id::find_val("ignore_checksums_nets")->Contains(ip->IPHeaderSrcAddr()) && + remaining >= len ) + { + int chksum = 0; + + switch ( ip->NextProto() ) + { + case IPPROTO_ICMP: + chksum = icmp_checksum(icmpp, len); + break; + + case IPPROTO_ICMPV6: + chksum = icmp6_checksum(icmpp, ip.get(), len); + break; + + default: + reporter->Error("unexpected IP proto in ICMP analyzer: %d", ip->NextProto()); + return; + } + + if ( chksum != 0xffff ) + { + ta->Weird("bad_ICMP_checksum"); + return; + } + } + + c->SetLastTime(run_state::current_timestamp); + ta->InitEndpointMatcher(ip.get(), len, is_orig); + + // Move past common portion of ICMP header. + data += 8; + remaining -= 8; + len -= 8; + + ta->UpdateLength(is_orig, len); + + if ( ip->NextProto() == IPPROTO_ICMP ) + NextICMP4(run_state::current_timestamp, icmpp, len, remaining, data, ip.get(), ta); + else if ( ip->NextProto() == IPPROTO_ICMPV6 ) + NextICMP6(run_state::current_timestamp, icmpp, len, remaining, data, ip.get(), ta); + else + { + reporter->Error("expected ICMP as IP packet's protocol, got %d", ip->NextProto()); + return; + } + + ForwardPacket(len, data, pkt); + + if ( remaining >= len ) + ta->ForwardPacket(len, data, is_orig, -1, ip.get(), remaining); + + ta->MatchEndpoint(data, len, is_orig); } -void ICMPAnalyzer::CreateTransportAnalyzer(Connection* conn, IPBasedTransportAnalyzer*& root, - analyzer::pia::PIA*& pia, bool& check_port) +void ICMPAnalyzer::NextICMP4(double t, const struct icmp* icmpp, int len, int caplen, + const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer) { + switch ( icmpp->icmp_type ) + { + case ICMP_ECHO: + case ICMP_ECHOREPLY: + Echo(t, icmpp, len, caplen, data, ip_hdr, analyzer); + break; + + case ICMP_UNREACH: + case ICMP_TIMXCEED: + Context4(t, icmpp, len, caplen, data, ip_hdr, analyzer); + break; + + default: + ICMP_Sent(icmpp, len, caplen, 0, data, ip_hdr, analyzer); + break; + } } +void ICMPAnalyzer::NextICMP6(double t, const struct icmp* icmpp, int len, int caplen, + const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer) + { + switch ( icmpp->icmp_type ) + { + // Echo types. + case ICMP6_ECHO_REQUEST: + case ICMP6_ECHO_REPLY: + Echo(t, icmpp, len, caplen, data, ip_hdr, analyzer); + break; + + // Error messages all have the same structure for their context, + // and are handled by the same function. + case ICMP6_PARAM_PROB: + case ICMP6_TIME_EXCEEDED: + case ICMP6_PACKET_TOO_BIG: + case ICMP6_DST_UNREACH: + Context6(t, icmpp, len, caplen, data, ip_hdr, analyzer); + break; + + // Router related messages. + case ND_REDIRECT: + Redirect(t, icmpp, len, caplen, data, ip_hdr, analyzer); + break; + case ND_ROUTER_ADVERT: + RouterAdvert(t, icmpp, len, caplen, data, ip_hdr, analyzer); + break; + case ND_NEIGHBOR_ADVERT: + NeighborAdvert(t, icmpp, len, caplen, data, ip_hdr, analyzer); + break; + case ND_NEIGHBOR_SOLICIT: + NeighborSolicit(t, icmpp, len, caplen, data, ip_hdr, analyzer); + break; + case ND_ROUTER_SOLICIT: + RouterSolicit(t, icmpp, len, caplen, data, ip_hdr, analyzer); + break; + case ICMP6_ROUTER_RENUMBERING: + ICMP_Sent(icmpp, len, caplen, 1, data, ip_hdr, analyzer); + break; + +#if 0 + // Currently not specifically implemented. + case MLD_LISTENER_QUERY: + case MLD_LISTENER_REPORT: + case MLD_LISTENER_REDUCTION: +#endif + default: + // Error messages (i.e., ICMPv6 type < 128) all have + // the same structure for their context, and are + // handled by the same function. + if ( icmpp->icmp_type < 128 ) + Context6(t, icmpp, len, caplen, data, ip_hdr, analyzer); + else + ICMP_Sent(icmpp, len, caplen, 1, data, ip_hdr, analyzer); + break; + } + } + +void ICMPAnalyzer::ICMP_Sent(const struct icmp* icmpp, int len, int caplen, + int icmpv6, const u_char* data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer) + { + if ( icmp_sent ) + analyzer->EnqueueConnEvent(icmp_sent, analyzer->ConnVal(), + BuildInfo(icmpp, len, icmpv6, ip_hdr)); + + if ( icmp_sent_payload ) + { + String* payload = new String(data, std::min(len, caplen), false); + + analyzer->EnqueueConnEvent(icmp_sent_payload, analyzer->ConnVal(), + BuildInfo(icmpp, len, icmpv6, ip_hdr), + make_intrusive(payload)); + } + } + +zeek::RecordValPtr ICMPAnalyzer::BuildInfo(const struct icmp* icmpp, int len, + bool icmpv6, const IP_Hdr* ip_hdr) + { + static auto icmp_info = id::find_type("icmp_info"); + auto rval = make_intrusive(icmp_info); + rval->Assign(0, val_mgr->Bool(icmpv6)); + rval->Assign(1, val_mgr->Count(icmpp->icmp_type)); + rval->Assign(2, val_mgr->Count(icmpp->icmp_code)); + rval->Assign(3, val_mgr->Count(len)); + rval->Assign(4, val_mgr->Count(ip_hdr->TTL())); + return rval; + } + +TransportProto ICMPAnalyzer::GetContextProtocol(const IP_Hdr* ip_hdr, uint32_t* src_port, uint32_t* dst_port) + { + const u_char* transport_hdr; + uint32_t ip_hdr_len = ip_hdr->HdrLen(); + bool ip4 = ip_hdr->IP4_Hdr(); + + if ( ip4 ) + transport_hdr = ((u_char *) ip_hdr->IP4_Hdr() + ip_hdr_len); + else + transport_hdr = ((u_char *) ip_hdr->IP6_Hdr() + ip_hdr_len); + + TransportProto proto; + + switch ( ip_hdr->NextProto() ) { + case 1: proto = TRANSPORT_ICMP; break; + case 6: proto = TRANSPORT_TCP; break; + case 17: proto = TRANSPORT_UDP; break; + case 58: proto = TRANSPORT_ICMP; break; + default: proto = TRANSPORT_UNKNOWN; break; + } + + switch ( proto ) { + case TRANSPORT_ICMP: + { + const struct icmp* icmpp = + (const struct icmp *) transport_hdr; + bool is_one_way; // dummy + *src_port = ntohs(icmpp->icmp_type); + + if ( ip4 ) + *dst_port = ntohs(ICMP4_counterpart(icmpp->icmp_type, + icmpp->icmp_code, is_one_way)); + else + *dst_port = ntohs(ICMP6_counterpart(icmpp->icmp_type, + icmpp->icmp_code, is_one_way)); + + break; + } + + case TRANSPORT_TCP: + { + const struct tcphdr* tp = + (const struct tcphdr *) transport_hdr; + *src_port = ntohs(tp->th_sport); + *dst_port = ntohs(tp->th_dport); + break; + } + + case TRANSPORT_UDP: + { + const struct udphdr* up = + (const struct udphdr *) transport_hdr; + *src_port = ntohs(up->uh_sport); + *dst_port = ntohs(up->uh_dport); + break; + } + + default: + *src_port = *dst_port = ntohs(0); + break; + } + + return proto; + } + +zeek::RecordValPtr ICMPAnalyzer::ExtractICMP4Context(int len, const u_char*& data) + { + const IP_Hdr ip_hdr_data((const struct ip*) data, false); + const IP_Hdr* ip_hdr = &ip_hdr_data; + + uint32_t ip_hdr_len = ip_hdr->HdrLen(); + + uint32_t ip_len, frag_offset; + TransportProto proto = TRANSPORT_UNKNOWN; + int DF, MF, bad_hdr_len, bad_checksum; + IPAddr src_addr, dst_addr; + uint32_t src_port, dst_port; + + if ( len < (int)sizeof(struct ip) || ip_hdr_len > uint32_t(len) ) + { + // We don't have an entire IP header. + bad_hdr_len = 1; + ip_len = frag_offset = 0; + DF = MF = bad_checksum = 0; + src_port = dst_port = 0; + } + + else + { + bad_hdr_len = 0; + ip_len = ip_hdr->TotalLen(); + bad_checksum = ! run_state::current_pkt->l3_checksummed && + (detail::in_cksum(reinterpret_cast(ip_hdr->IP4_Hdr()), + ip_hdr_len) != 0xffff); + + src_addr = ip_hdr->SrcAddr(); + dst_addr = ip_hdr->DstAddr(); + + DF = ip_hdr->DF(); + MF = ip_hdr->MF(); + frag_offset = ip_hdr->FragOffset(); + + if ( uint32_t(len) >= ip_hdr_len + 4 ) + proto = GetContextProtocol(ip_hdr, &src_port, &dst_port); + else + { + // 4 above is the magic number meaning that both + // port numbers are included in the ICMP. + src_port = dst_port = 0; + bad_hdr_len = 1; + } + } + + static auto icmp_context = id::find_type("icmp_context"); + auto iprec = make_intrusive(icmp_context); + auto id_val = make_intrusive(id::conn_id); + + id_val->Assign(0, make_intrusive(src_addr)); + id_val->Assign(1, val_mgr->Port(src_port, proto)); + id_val->Assign(2, make_intrusive(dst_addr)); + id_val->Assign(3, val_mgr->Port(dst_port, proto)); + + iprec->Assign(0, std::move(id_val)); + iprec->Assign(1, val_mgr->Count(ip_len)); + iprec->Assign(2, val_mgr->Count(proto)); + iprec->Assign(3, val_mgr->Count(frag_offset)); + iprec->Assign(4, val_mgr->Bool(bad_hdr_len)); + iprec->Assign(5, val_mgr->Bool(bad_checksum)); + iprec->Assign(6, val_mgr->Bool(MF)); + iprec->Assign(7, val_mgr->Bool(DF)); + + return iprec; + } + +zeek::RecordValPtr ICMPAnalyzer::ExtractICMP6Context(int len, const u_char*& data) + { + int DF = 0, MF = 0, bad_hdr_len = 0; + TransportProto proto = TRANSPORT_UNKNOWN; + + IPAddr src_addr; + IPAddr dst_addr; + uint32_t ip_len, frag_offset = 0; + uint32_t src_port, dst_port; + + if ( len < (int)sizeof(struct ip6_hdr) ) + { + bad_hdr_len = 1; + ip_len = 0; + src_port = dst_port = 0; + } + else + { + const IP_Hdr ip_hdr_data((const struct ip6_hdr*) data, false, len); + const IP_Hdr* ip_hdr = &ip_hdr_data; + + ip_len = ip_hdr->TotalLen(); + src_addr = ip_hdr->SrcAddr(); + dst_addr = ip_hdr->DstAddr(); + frag_offset = ip_hdr->FragOffset(); + MF = ip_hdr->MF(); + DF = ip_hdr->DF(); + + if ( uint32_t(len) >= uint32_t(ip_hdr->HdrLen() + 4) ) + proto = GetContextProtocol(ip_hdr, &src_port, &dst_port); + else + { + // 4 above is the magic number meaning that both + // port numbers are included in the ICMP. + src_port = dst_port = 0; + bad_hdr_len = 1; + } + } + + static auto icmp_context = id::find_type("icmp_context"); + auto iprec = make_intrusive(icmp_context); + auto id_val = make_intrusive(id::conn_id); + + id_val->Assign(0, make_intrusive(src_addr)); + id_val->Assign(1, val_mgr->Port(src_port, proto)); + id_val->Assign(2, make_intrusive(dst_addr)); + id_val->Assign(3, val_mgr->Port(dst_port, proto)); + + iprec->Assign(0, std::move(id_val)); + iprec->Assign(1, val_mgr->Count(ip_len)); + iprec->Assign(2, val_mgr->Count(proto)); + iprec->Assign(3, val_mgr->Count(frag_offset)); + iprec->Assign(4, val_mgr->Bool(bad_hdr_len)); + // bad_checksum is always false since IPv6 layer doesn't have a checksum. + iprec->Assign(5, val_mgr->False()); + iprec->Assign(6, val_mgr->Bool(MF)); + iprec->Assign(7, val_mgr->Bool(DF)); + + return iprec; + } + +void ICMPAnalyzer::Echo(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer) + { + // For handling all Echo related ICMP messages + EventHandlerPtr f = nullptr; + + if ( ip_hdr->NextProto() == IPPROTO_ICMPV6 ) + f = (icmpp->icmp_type == ICMP6_ECHO_REQUEST) + ? icmp_echo_request : icmp_echo_reply; + else + f = (icmpp->icmp_type == ICMP_ECHO) + ? icmp_echo_request : icmp_echo_reply; + + if ( ! f ) + return; + + int iid = ntohs(icmpp->icmp_hun.ih_idseq.icd_id); + int iseq = ntohs(icmpp->icmp_hun.ih_idseq.icd_seq); + + String* payload = new String(data, caplen, false); + + analyzer->EnqueueConnEvent(f, + analyzer->ConnVal(), + BuildInfo(icmpp, len, ip_hdr->NextProto() != IPPROTO_ICMP, ip_hdr), + val_mgr->Count(iid), + val_mgr->Count(iseq), + make_intrusive(payload) + ); + } + + +void ICMPAnalyzer::RouterAdvert(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer) + { + EventHandlerPtr f = icmp_router_advertisement; + + if ( ! f ) + return; + + uint32_t reachable = 0, retrans = 0; + + if ( caplen >= (int)sizeof(reachable) ) + memcpy(&reachable, data, sizeof(reachable)); + + if ( caplen >= (int)sizeof(reachable) + (int)sizeof(retrans) ) + memcpy(&retrans, data + sizeof(reachable), sizeof(retrans)); + + int opt_offset = sizeof(reachable) + sizeof(retrans); + + analyzer->EnqueueConnEvent(f, + analyzer->ConnVal(), + BuildInfo(icmpp, len, 1, ip_hdr), + val_mgr->Count(icmpp->icmp_num_addrs), // Cur Hop Limit + val_mgr->Bool(icmpp->icmp_wpa & 0x80), // Managed + val_mgr->Bool(icmpp->icmp_wpa & 0x40), // Other + val_mgr->Bool(icmpp->icmp_wpa & 0x20), // Home Agent + val_mgr->Count((icmpp->icmp_wpa & 0x18)>>3), // Pref + val_mgr->Bool(icmpp->icmp_wpa & 0x04), // Proxy + val_mgr->Count(icmpp->icmp_wpa & 0x02), // Reserved + make_intrusive((double)ntohs(icmpp->icmp_lifetime), Seconds), + make_intrusive((double)ntohl(reachable), Milliseconds), + make_intrusive((double)ntohl(retrans), Milliseconds), + BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, analyzer) + ); + } + + +void ICMPAnalyzer::NeighborAdvert(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer) + { + EventHandlerPtr f = icmp_neighbor_advertisement; + + if ( ! f ) + return; + + IPAddr tgtaddr; + + if ( caplen >= (int)sizeof(in6_addr) ) + tgtaddr = IPAddr(*((const in6_addr*)data)); + + int opt_offset = sizeof(in6_addr); + + analyzer->EnqueueConnEvent(f, + analyzer->ConnVal(), + BuildInfo(icmpp, len, 1, ip_hdr), + val_mgr->Bool(icmpp->icmp_num_addrs & 0x80), // Router + val_mgr->Bool(icmpp->icmp_num_addrs & 0x40), // Solicited + val_mgr->Bool(icmpp->icmp_num_addrs & 0x20), // Override + make_intrusive(tgtaddr), + BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, analyzer) + ); + } + + +void ICMPAnalyzer::NeighborSolicit(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer) + { + EventHandlerPtr f = icmp_neighbor_solicitation; + + if ( ! f ) + return; + + IPAddr tgtaddr; + + if ( caplen >= (int)sizeof(in6_addr) ) + tgtaddr = IPAddr(*((const in6_addr*)data)); + + int opt_offset = sizeof(in6_addr); + + analyzer->EnqueueConnEvent(f, + analyzer->ConnVal(), + BuildInfo(icmpp, len, 1, ip_hdr), + make_intrusive(tgtaddr), + BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, analyzer) + ); + } + + +void ICMPAnalyzer::Redirect(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer) + { + EventHandlerPtr f = icmp_redirect; + + if ( ! f ) + return; + + IPAddr tgtaddr, dstaddr; + + if ( caplen >= (int)sizeof(in6_addr) ) + tgtaddr = IPAddr(*((const in6_addr*)data)); + + if ( caplen >= 2 * (int)sizeof(in6_addr) ) + dstaddr = IPAddr(*((const in6_addr*)(data + sizeof(in6_addr)))); + + int opt_offset = 2 * sizeof(in6_addr); + + analyzer->EnqueueConnEvent(f, + analyzer->ConnVal(), + BuildInfo(icmpp, len, 1, ip_hdr), + make_intrusive(tgtaddr), + make_intrusive(dstaddr), + BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, analyzer) + ); + } + + +void ICMPAnalyzer::RouterSolicit(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer) + { + EventHandlerPtr f = icmp_router_solicitation; + + if ( ! f ) + return; + + analyzer->EnqueueConnEvent(f, + analyzer->ConnVal(), + BuildInfo(icmpp, len, 1, ip_hdr), + BuildNDOptionsVal(caplen, data, analyzer) + ); + } + + +void ICMPAnalyzer::Context4(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer) + { + EventHandlerPtr f = nullptr; + + switch ( icmpp->icmp_type ) + { + case ICMP_UNREACH: + f = icmp_unreachable; + break; + + case ICMP_TIMXCEED: + f = icmp_time_exceeded; + break; + } + + if ( f ) + analyzer->EnqueueConnEvent(f, + analyzer->ConnVal(), + BuildInfo(icmpp, len, 0, ip_hdr), + val_mgr->Count(icmpp->icmp_code), + ExtractICMP4Context(caplen, data) + ); + } + + +void ICMPAnalyzer::Context6(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer) + { + EventHandlerPtr f = nullptr; + + switch ( icmpp->icmp_type ) + { + case ICMP6_DST_UNREACH: + f = icmp_unreachable; + break; + + case ICMP6_PARAM_PROB: + f = icmp_parameter_problem; + break; + + case ICMP6_TIME_EXCEEDED: + f = icmp_time_exceeded; + break; + + case ICMP6_PACKET_TOO_BIG: + f = icmp_packet_too_big; + break; + + default: + f = icmp_error_message; + break; + } + + if ( f ) + analyzer->EnqueueConnEvent(f, + analyzer->ConnVal(), + BuildInfo(icmpp, len, 1, ip_hdr), + val_mgr->Count(icmpp->icmp_code), + ExtractICMP6Context(caplen, data) + ); + } + +zeek::VectorValPtr ICMPAnalyzer::BuildNDOptionsVal(int caplen, const u_char* data, + ICMPTransportAnalyzer* analyzer) + { + static auto icmp6_nd_option_type = id::find_type("icmp6_nd_option"); + static auto icmp6_nd_prefix_info_type = id::find_type("icmp6_nd_prefix_info"); + + auto vv = make_intrusive( + id::find_type("icmp6_nd_options")); + + while ( caplen > 0 ) + { + // Must have at least type & length to continue parsing options. + if ( caplen < 2 ) + { + analyzer->Weird("truncated_ICMPv6_ND_options"); + break; + } + + uint8_t type = *((const uint8_t*)data); + uint16_t length = *((const uint8_t*)(data + 1)); + + if ( length == 0 ) + { + analyzer->Weird("zero_length_ICMPv6_ND_option"); + break; + } + + auto rv = make_intrusive(icmp6_nd_option_type); + rv->Assign(0, val_mgr->Count(type)); + rv->Assign(1, val_mgr->Count(length)); + + // Adjust length to be in units of bytes, exclude type/length fields. + length = length * 8 - 2; + + data += 2; + caplen -= 2; + + bool set_payload_field = false; + + // Only parse out known options that are there in full. + switch ( type ) { + case 1: + case 2: + // Source/Target Link-layer Address option + { + if ( caplen >= length ) + { + String* link_addr = new String(data, length, false); + rv->Assign(2, make_intrusive(link_addr)); + } + else + set_payload_field = true; + + break; + } + + case 3: + // Prefix Information option + { + if ( caplen >= 30 ) + { + auto info = make_intrusive(icmp6_nd_prefix_info_type); + uint8_t prefix_len = *((const uint8_t*)(data)); + bool L_flag = (*((const uint8_t*)(data + 1)) & 0x80) != 0; + bool A_flag = (*((const uint8_t*)(data + 1)) & 0x40) != 0; + uint32_t valid_life = *((const uint32_t*)(data + 2)); + uint32_t prefer_life = *((const uint32_t*)(data + 6)); + in6_addr prefix = *((const in6_addr*)(data + 14)); + info->Assign(0, val_mgr->Count(prefix_len)); + info->Assign(1, val_mgr->Bool(L_flag)); + info->Assign(2, val_mgr->Bool(A_flag)); + info->Assign(3, make_intrusive((double)ntohl(valid_life), Seconds)); + info->Assign(4, make_intrusive((double)ntohl(prefer_life), Seconds)); + info->Assign(5, make_intrusive(IPAddr(prefix))); + rv->Assign(3, std::move(info)); + } + + else + set_payload_field = true; + break; + } + + case 4: + // Redirected Header option + { + if ( caplen >= length ) + { + const u_char* hdr = data + 6; + rv->Assign(4, ExtractICMP6Context(length - 6, hdr)); + } + + else + set_payload_field = true; + + break; + } + + case 5: + // MTU option + { + if ( caplen >= 6 ) + rv->Assign(5, val_mgr->Count(ntohl(*((const uint32_t*)(data + 2))))); + else + set_payload_field = true; + + break; + } + + default: + { + set_payload_field = true; + break; + } + } + + if ( set_payload_field ) + { + String* payload = new String(data, std::min((int)length, caplen), false); + rv->Assign(6, make_intrusive(payload)); + } + + data += length; + caplen -= length; + + vv->Assign(vv->Size(), std::move(rv)); + } + + return vv; + } int ICMPAnalyzer::ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way) { @@ -113,3 +859,84 @@ int ICMPAnalyzer::ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_w default: is_one_way = true; return icmp_code; } } + +void ICMPAnalyzer::CreateTransportAnalyzer(Connection* conn, IPBasedTransportAnalyzer*& root, + analyzer::pia::PIA*& pia, bool& check_port) + { + root = new ICMPTransportAnalyzer(conn); + root->SetParent(this); + conn->SetInactivityTimeout(zeek::detail::icmp_inactivity_timeout); + + pia = nullptr; + check_port = false; + } + +void ICMPTransportAnalyzer::AddExtraAnalyzers(Connection* conn) + { + static analyzer::Tag analyzer_connsize = analyzer_mgr->GetComponentTag("CONNSIZE"); + + if ( analyzer_mgr->IsEnabled(analyzer_connsize) ) + // Add ConnSize analyzer. Needs to see packets, not stream. + AddChildAnalyzer(new analyzer::conn_size::ConnSize_Analyzer(conn)); + } + +void ICMPTransportAnalyzer::UpdateConnVal(zeek::RecordVal* conn_val) + { + const auto& orig_endp = conn_val->GetField("orig"); + const auto& resp_endp = conn_val->GetField("resp"); + + UpdateEndpointVal(orig_endp, true); + UpdateEndpointVal(resp_endp, false); + + analyzer::Analyzer::UpdateConnVal(conn_val); + } + +void ICMPTransportAnalyzer::UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig) + { + Conn()->EnableStatusUpdateTimer(); + + int size = is_orig ? request_len : reply_len; + auto endp = endp_arg->AsRecordVal(); + + if ( size < 0 ) + { + endp->Assign(0, val_mgr->Count(0)); + endp->Assign(1, val_mgr->Count(int(ICMP_INACTIVE))); + } + else + { + endp->Assign(0, val_mgr->Count(size)); + endp->Assign(1, val_mgr->Count(int(ICMP_ACTIVE))); + } + } + +void ICMPTransportAnalyzer::UpdateLength(bool is_orig, int len) + { + int& len_stat = is_orig ? request_len : reply_len; + if ( len_stat < 0 ) + len_stat = len; + else + len_stat += len; + } + +void ICMPTransportAnalyzer::InitEndpointMatcher(const IP_Hdr* ip_hdr, int len, bool is_orig) + { + if ( zeek::detail::rule_matcher ) + { + if ( ! matcher_state.MatcherInitialized(is_orig) ) + matcher_state.InitEndpointMatcher(this, ip_hdr, len, is_orig, nullptr); + } + } + +void ICMPTransportAnalyzer::MatchEndpoint(const u_char* data, int len, bool is_orig) + { + if ( zeek::detail::rule_matcher ) + matcher_state.Match(zeek::detail::Rule::PAYLOAD, data, len, is_orig, + false, false, true); + } + +void ICMPTransportAnalyzer::Done() + { + TransportLayerAnalyzer::Done(); + matcher_state.FinishEndpointMatcher(); + } diff --git a/src/packet_analysis/protocol/icmp/ICMP.h b/src/packet_analysis/protocol/icmp/ICMP.h index c0acc8d6f0..9b1835311a 100644 --- a/src/packet_analysis/protocol/icmp/ICMP.h +++ b/src/packet_analysis/protocol/icmp/ICMP.h @@ -5,8 +5,19 @@ #include "zeek/packet_analysis/Analyzer.h" #include "zeek/packet_analysis/Component.h" #include "zeek/packet_analysis/protocol/ip/IPBasedAnalyzer.h" +#include "zeek/analyzer/Analyzer.h" +#include "zeek/RuleMatcher.h" -namespace zeek::packet_analysis::ICMP { +namespace zeek { + +class VectorVal; +using VectorValPtr = IntrusivePtr; +class RecordVal; +using RecordValPtr = IntrusivePtr; + +namespace packet_analysis::ICMP { + +class ICMPTransportAnalyzer; class ICMPAnalyzer final : public IP::IPBasedAnalyzer { public: @@ -30,11 +41,95 @@ protected: private: + void NextICMP4(double t, const struct icmp* icmpp, int len, int caplen, + const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer); + + void NextICMP6(double t, const struct icmp* icmpp, int len, int caplen, + const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer); + + void ICMP_Sent(const struct icmp* icmpp, int len, int caplen, int icmpv6, + const u_char* data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer); + + void Echo(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer); + void Redirect(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer); + void RouterAdvert(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer); + void NeighborAdvert(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer); + void NeighborSolicit(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer); + void RouterSolicit(double t, const struct icmp* icmpp, int len, + int caplen, const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer); + + RecordValPtr BuildInfo(const struct icmp* icmpp, int len, + bool icmpv6, const IP_Hdr* ip_hdr); + + RecordValPtr ExtractICMP4Context(int len, const u_char*& data); + + void Context4(double t, const struct icmp* icmpp, int len, int caplen, + const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer); + + TransportProto GetContextProtocol(const IP_Hdr* ip_hdr, uint32_t* src_port, + uint32_t* dst_port); + + RecordValPtr ExtractICMP6Context(int len, const u_char*& data); + + void Context6(double t, const struct icmp* icmpp, int len, int caplen, + const u_char*& data, const IP_Hdr* ip_hdr, + ICMPTransportAnalyzer* analyzer); + + // RFC 4861 Neighbor Discover message options + VectorValPtr BuildNDOptionsVal(int caplen, const u_char* data, + ICMPTransportAnalyzer* analyzer); + + void UpdateEndpointVal(const ValPtr& endp, bool is_orig); + // Returns the counterpart type to the given type (e.g., the counterpart // to ICMP_ECHOREPLY is ICMP_ECHO). int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way); int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way); + }; +class ICMPTransportAnalyzer final : public IP::IPBasedTransportAnalyzer { + +public: + + ICMPTransportAnalyzer(Connection* conn) : + IP::IPBasedTransportAnalyzer("ICMP", conn) { } + + static zeek::analyzer::Analyzer* Instantiate(Connection* conn) + { + return new ICMPTransportAnalyzer(conn); + } + + void AddExtraAnalyzers(Connection* conn) override; + void UpdateConnVal(RecordVal* conn_val) override; + void UpdateEndpointVal(const ValPtr& endp, bool is_orig); + + void UpdateLength(bool is_orig, int len); + void Done() override; + + void InitEndpointMatcher(const IP_Hdr* ip_hdr, int len, bool is_orig); + void MatchEndpoint(const u_char* data, int len, bool is_orig); + +private: + + detail::RuleMatcherState matcher_state; + int request_len = -1; + int reply_len = -1; }; -} +} // namespace packet_analysis::ICMP +} // namespace zeek diff --git a/src/packet_analysis/protocol/icmp/Plugin.cc b/src/packet_analysis/protocol/icmp/Plugin.cc index b16205e78a..944ca38d02 100644 --- a/src/packet_analysis/protocol/icmp/Plugin.cc +++ b/src/packet_analysis/protocol/icmp/Plugin.cc @@ -12,9 +12,11 @@ public: { AddComponent(new zeek::packet_analysis::Component("ICMP", zeek::packet_analysis::ICMP::ICMPAnalyzer::Instantiate)); + AddComponent(new zeek::analyzer::Component("ICMP", + zeek::packet_analysis::ICMP::ICMPTransportAnalyzer::Instantiate)); zeek::plugin::Configuration config; - config.name = "Zeek::ICMP_PKT"; + config.name = "Zeek::ICMP"; config.description = "Packet analyzer for ICMP"; return config; } diff --git a/src/analyzer/protocol/icmp/events.bif b/src/packet_analysis/protocol/icmp/events.bif similarity index 100% rename from src/analyzer/protocol/icmp/events.bif rename to src/packet_analysis/protocol/icmp/events.bif diff --git a/src/session/Manager.cc b/src/session/Manager.cc index b7e0cddf71..df027c82cf 100644 --- a/src/session/Manager.cc +++ b/src/session/Manager.cc @@ -21,9 +21,6 @@ #include "zeek/session/Session.h" #include "zeek/TunnelEncapsulation.h" #include "zeek/telemetry/Manager.h" - -#include "zeek/analyzer/protocol/icmp/ICMP.h" -#include "zeek/analyzer/protocol/udp/UDP.h" #include "zeek/analyzer/Manager.h" #include "zeek/iosource/IOSource.h" diff --git a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log index 729d4b154e..adcb56753d 100644 --- a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log @@ -131,7 +131,6 @@ scripts/base/init-frameworks-and-bifs.zeek build/scripts/base/bif/plugins/Zeek_GTPv1.events.bif.zeek build/scripts/base/bif/plugins/Zeek_HTTP.events.bif.zeek build/scripts/base/bif/plugins/Zeek_HTTP.functions.bif.zeek - build/scripts/base/bif/plugins/Zeek_ICMP.events.bif.zeek build/scripts/base/bif/plugins/Zeek_Ident.events.bif.zeek build/scripts/base/bif/plugins/Zeek_IMAP.events.bif.zeek build/scripts/base/bif/plugins/Zeek_IRC.events.bif.zeek @@ -211,6 +210,7 @@ scripts/base/init-frameworks-and-bifs.zeek build/scripts/base/bif/plugins/Zeek_VXLAN.events.bif.zeek build/scripts/base/bif/plugins/Zeek_XMPP.events.bif.zeek build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek + build/scripts/base/bif/plugins/Zeek_ICMP.events.bif.zeek build/scripts/base/bif/plugins/Zeek_FileEntropy.events.bif.zeek build/scripts/base/bif/plugins/Zeek_FileExtract.events.bif.zeek build/scripts/base/bif/plugins/Zeek_FileExtract.functions.bif.zeek diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 6b5b777293..0ad2f4a685 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -131,7 +131,6 @@ scripts/base/init-frameworks-and-bifs.zeek build/scripts/base/bif/plugins/Zeek_GTPv1.events.bif.zeek build/scripts/base/bif/plugins/Zeek_HTTP.events.bif.zeek build/scripts/base/bif/plugins/Zeek_HTTP.functions.bif.zeek - build/scripts/base/bif/plugins/Zeek_ICMP.events.bif.zeek build/scripts/base/bif/plugins/Zeek_Ident.events.bif.zeek build/scripts/base/bif/plugins/Zeek_IMAP.events.bif.zeek build/scripts/base/bif/plugins/Zeek_IRC.events.bif.zeek @@ -211,6 +210,7 @@ scripts/base/init-frameworks-and-bifs.zeek build/scripts/base/bif/plugins/Zeek_VXLAN.events.bif.zeek build/scripts/base/bif/plugins/Zeek_XMPP.events.bif.zeek build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek + build/scripts/base/bif/plugins/Zeek_ICMP.events.bif.zeek build/scripts/base/bif/plugins/Zeek_FileEntropy.events.bif.zeek build/scripts/base/bif/plugins/Zeek_FileExtract.events.bif.zeek build/scripts/base/bif/plugins/Zeek_FileExtract.functions.bif.zeek