mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Move ARP analysis into packet analyzer.
This commit is contained in:
parent
0ec7516602
commit
24babf096e
17 changed files with 238 additions and 368 deletions
|
@ -22,8 +22,6 @@
|
||||||
|
|
||||||
#include "analyzer/protocol/stepping-stone/SteppingStone.h"
|
#include "analyzer/protocol/stepping-stone/SteppingStone.h"
|
||||||
#include "analyzer/protocol/stepping-stone/events.bif.h"
|
#include "analyzer/protocol/stepping-stone/events.bif.h"
|
||||||
#include "analyzer/protocol/arp/ARP.h"
|
|
||||||
#include "analyzer/protocol/arp/events.bif.h"
|
|
||||||
#include "Discard.h"
|
#include "Discard.h"
|
||||||
#include "RuleMatcher.h"
|
#include "RuleMatcher.h"
|
||||||
|
|
||||||
|
@ -33,6 +31,8 @@
|
||||||
#include "iosource/IOSource.h"
|
#include "iosource/IOSource.h"
|
||||||
#include "iosource/PktDumper.h"
|
#include "iosource/PktDumper.h"
|
||||||
|
|
||||||
|
#include "pcap.h"
|
||||||
|
|
||||||
// These represent NetBIOS services on ephemeral ports. They're numbered
|
// These represent NetBIOS services on ephemeral ports. They're numbered
|
||||||
// so that we can use a single int to hold either an actual TCP/UDP server
|
// so that we can use a single int to hold either an actual TCP/UDP server
|
||||||
// port or one of these.
|
// port or one of these.
|
||||||
|
@ -96,11 +96,6 @@ NetSessions::NetSessions()
|
||||||
else
|
else
|
||||||
pkt_profiler = nullptr;
|
pkt_profiler = nullptr;
|
||||||
|
|
||||||
if ( arp_request || arp_reply || bad_arp )
|
|
||||||
arp_analyzer = new analyzer::arp::ARP_Analyzer();
|
|
||||||
else
|
|
||||||
arp_analyzer = nullptr;
|
|
||||||
|
|
||||||
memset(&stats, 0, sizeof(SessionStats));
|
memset(&stats, 0, sizeof(SessionStats));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +103,6 @@ NetSessions::~NetSessions()
|
||||||
{
|
{
|
||||||
delete packet_filter;
|
delete packet_filter;
|
||||||
delete pkt_profiler;
|
delete pkt_profiler;
|
||||||
Unref(arp_analyzer);
|
|
||||||
delete discarder;
|
delete discarder;
|
||||||
delete stp_manager;
|
delete stp_manager;
|
||||||
|
|
||||||
|
@ -178,8 +172,8 @@ void NetSessions::NextPacket(double t, const Packet* pkt)
|
||||||
|
|
||||||
else if ( pkt->l3_proto == L3_ARP )
|
else if ( pkt->l3_proto == L3_ARP )
|
||||||
{
|
{
|
||||||
if ( arp_analyzer )
|
// Do nothing here as ARP has moved into a packet analyzer
|
||||||
arp_analyzer->NextPacket(t, pkt);
|
//TODO: Revisit the use of packet's l3_proto
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
|
@ -234,8 +234,6 @@ protected:
|
||||||
using IPTunnelMap = std::map<IPPair, TunnelActivity>;
|
using IPTunnelMap = std::map<IPPair, TunnelActivity>;
|
||||||
IPTunnelMap ip_tunnels;
|
IPTunnelMap ip_tunnels;
|
||||||
|
|
||||||
analyzer::arp::ARP_Analyzer* arp_analyzer;
|
|
||||||
|
|
||||||
analyzer::stepping_stone::SteppingStoneManager* stp_manager;
|
analyzer::stepping_stone::SteppingStoneManager* stp_manager;
|
||||||
detail::Discarder* discarder;
|
detail::Discarder* discarder;
|
||||||
detail::PacketFilter* packet_filter;
|
detail::PacketFilter* packet_filter;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
|
|
||||||
add_subdirectory(arp)
|
|
||||||
add_subdirectory(ayiya)
|
add_subdirectory(ayiya)
|
||||||
add_subdirectory(bittorrent)
|
add_subdirectory(bittorrent)
|
||||||
add_subdirectory(conn-size)
|
add_subdirectory(conn-size)
|
||||||
|
|
|
@ -1,244 +0,0 @@
|
||||||
// See the file "COPYING" in the main distribution directory for copyright.
|
|
||||||
|
|
||||||
#include "ARP.h"
|
|
||||||
#include "Event.h"
|
|
||||||
#include "Reporter.h"
|
|
||||||
#include "Desc.h"
|
|
||||||
|
|
||||||
#include "events.bif.h"
|
|
||||||
|
|
||||||
namespace zeek::analyzer::arp {
|
|
||||||
|
|
||||||
ARP_Analyzer::ARP_Analyzer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ARP_Analyzer::~ARP_Analyzer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Argh! FreeBSD and Linux have almost completely different net/if_arp.h .
|
|
||||||
// ... and on Solaris we are missing half of the ARPOP codes, so define
|
|
||||||
// them here as necessary:
|
|
||||||
|
|
||||||
#ifndef ARPOP_REQUEST
|
|
||||||
#define ARPOP_REQUEST 1 // ARP request.
|
|
||||||
#endif
|
|
||||||
#ifndef ARPOP_REPLY
|
|
||||||
#define ARPOP_REPLY 2 // ARP reply.
|
|
||||||
#endif
|
|
||||||
#ifndef ARPOP_PREQUEST
|
|
||||||
#define ARPOP_RREQUEST 3 // RARP request.
|
|
||||||
#endif
|
|
||||||
#ifndef ARPOP_RREPLY
|
|
||||||
#define ARPOP_RREPLY 4 // RARP reply.
|
|
||||||
#endif
|
|
||||||
#ifndef ARPOP_InREQUEST
|
|
||||||
#define ARPOP_InREQUEST 8 // InARP request.
|
|
||||||
#endif
|
|
||||||
#ifndef ARPOP_InREPLY
|
|
||||||
#define ARPOP_InREPLY 9 // InARP reply.
|
|
||||||
#endif
|
|
||||||
#ifndef ARPOP_NAK
|
|
||||||
#define ARPOP_NAK 10 // (ATM)ARP NAK.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ar_sha
|
|
||||||
#define ar_sha(ap) ((caddr_t((ap)+1)) + 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ar_spa
|
|
||||||
#define ar_spa(ap) ((caddr_t((ap)+1)) + (ap)->ar_hln)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ar_tha
|
|
||||||
#define ar_tha(ap) ((caddr_t((ap)+1)) + (ap)->ar_hln + (ap)->ar_pln)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ar_tpa
|
|
||||||
#define ar_tpa(ap) ((caddr_t((ap)+1)) + 2*(ap)->ar_hln + (ap)->ar_pln)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ARPOP_REVREQUEST
|
|
||||||
#define ARPOP_REVREQUEST ARPOP_RREQUEST
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ARPOP_REVREPLY
|
|
||||||
#define ARPOP_REVREPLY ARPOP_RREPLY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ARPOP_INVREQUEST
|
|
||||||
#define ARPOP_INVREQUEST ARPOP_InREQUEST
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ARPOP_INVREPLY
|
|
||||||
#define ARPOP_INVREPLY ARPOP_InREPLY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void ARP_Analyzer::NextPacket(double t, const Packet* pkt)
|
|
||||||
{
|
|
||||||
const u_char *data = pkt->data;
|
|
||||||
// Check whether the packet is OK ("inspired" in tcpdump's print-arp.c).
|
|
||||||
const struct arp_pkthdr* ah =
|
|
||||||
(const struct arp_pkthdr*) (data + pkt->hdr_size);
|
|
||||||
|
|
||||||
// Check the size.
|
|
||||||
int min_length = (ar_tpa(ah) - (char*) (data + pkt->hdr_size)) + ah->ar_pln;
|
|
||||||
int real_length = pkt->cap_len - pkt->hdr_size;
|
|
||||||
if ( min_length > real_length )
|
|
||||||
{
|
|
||||||
Corrupted("truncated_ARP");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char errbuf[1024];
|
|
||||||
|
|
||||||
// Check the address description fields.
|
|
||||||
switch ( ntohs(ah->ar_hrd) ) {
|
|
||||||
case ARPHRD_ETHER:
|
|
||||||
if ( ah->ar_hln != 6 )
|
|
||||||
{ // don't know how to handle the opcode
|
|
||||||
snprintf(errbuf, sizeof(errbuf),
|
|
||||||
"corrupt-arp-header (hrd=%i, hln=%i)",
|
|
||||||
ntohs(ah->ar_hrd), ah->ar_hln);
|
|
||||||
BadARP(ah, errbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
{ // don't know how to proceed
|
|
||||||
snprintf(errbuf, sizeof(errbuf),
|
|
||||||
"unknown-arp-hw-address (hrd=%i)", ntohs(ah->ar_hrd));
|
|
||||||
BadARP(ah, errbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ### Note, we don't support IPv6 addresses yet.
|
|
||||||
switch ( ntohs(ah->ar_pro) ) {
|
|
||||||
case ETHERTYPE_IP:
|
|
||||||
if ( ah->ar_pln != 4 )
|
|
||||||
{ // don't know how to handle the opcode
|
|
||||||
snprintf(errbuf, sizeof(errbuf),
|
|
||||||
"corrupt-arp-header (pro=%i, pln=%i)",
|
|
||||||
ntohs(ah->ar_pro), ah->ar_pln);
|
|
||||||
BadARP(ah, errbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
{ // don't know how to proceed
|
|
||||||
snprintf(errbuf, sizeof(errbuf),
|
|
||||||
"unknown-arp-proto-address (pro=%i)",
|
|
||||||
ntohs(ah->ar_pro));
|
|
||||||
BadARP(ah, errbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Check MAC src address = ARP sender MAC address.
|
|
||||||
if ( memcmp(pkt->l2_src, ar_sha(ah), ah->ar_hln) )
|
|
||||||
{
|
|
||||||
BadARP(ah, "weird-arp-sha");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the code is supported.
|
|
||||||
switch ( ntohs(ah->ar_op) ) {
|
|
||||||
case ARPOP_REQUEST:
|
|
||||||
RREvent(arp_request, pkt->l2_src, pkt->l2_dst,
|
|
||||||
ar_spa(ah), ar_sha(ah), ar_tpa(ah), ar_tha(ah));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARPOP_REPLY:
|
|
||||||
RREvent(arp_reply, pkt->l2_src, pkt->l2_dst,
|
|
||||||
ar_spa(ah), ar_sha(ah), ar_tpa(ah), ar_tha(ah));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARPOP_REVREQUEST:
|
|
||||||
case ARPOP_REVREPLY:
|
|
||||||
case ARPOP_INVREQUEST:
|
|
||||||
case ARPOP_INVREPLY:
|
|
||||||
{ // don't know how to handle the opcode
|
|
||||||
snprintf(errbuf, sizeof(errbuf),
|
|
||||||
"unimplemented-arp-opcode (%i)", ntohs(ah->ar_op));
|
|
||||||
BadARP(ah, errbuf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{ // invalid opcode
|
|
||||||
snprintf(errbuf, sizeof(errbuf),
|
|
||||||
"invalid-arp-opcode (opcode=%i)", ntohs(ah->ar_op));
|
|
||||||
BadARP(ah, errbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARP_Analyzer::Describe(ODesc* d) const
|
|
||||||
{
|
|
||||||
d->Add("<ARP analyzer>");
|
|
||||||
d->NL();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARP_Analyzer::BadARP(const struct arp_pkthdr* hdr, const char* msg)
|
|
||||||
{
|
|
||||||
if ( ! bad_arp )
|
|
||||||
return;
|
|
||||||
|
|
||||||
event_mgr.Enqueue(bad_arp,
|
|
||||||
ToAddrVal(ar_spa(hdr)),
|
|
||||||
ToEthAddrStr((const u_char*) ar_sha(hdr)),
|
|
||||||
ToAddrVal(ar_tpa(hdr)),
|
|
||||||
ToEthAddrStr((const u_char*) ar_tha(hdr)),
|
|
||||||
make_intrusive<StringVal>(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARP_Analyzer::Corrupted(const char* msg)
|
|
||||||
{
|
|
||||||
reporter->Weird(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARP_Analyzer::RREvent(EventHandlerPtr e,
|
|
||||||
const u_char* src, const u_char *dst,
|
|
||||||
const char* spa, const char* sha,
|
|
||||||
const char* tpa, const char* tha)
|
|
||||||
{
|
|
||||||
if ( ! e )
|
|
||||||
return;
|
|
||||||
|
|
||||||
event_mgr.Enqueue(e,
|
|
||||||
ToEthAddrStr(src),
|
|
||||||
ToEthAddrStr(dst),
|
|
||||||
ToAddrVal(spa),
|
|
||||||
ToEthAddrStr((const u_char*) sha),
|
|
||||||
ToAddrVal(tpa),
|
|
||||||
ToEthAddrStr((const u_char*) tha));
|
|
||||||
}
|
|
||||||
|
|
||||||
AddrVal* ARP_Analyzer::ConstructAddrVal(const void* addr)
|
|
||||||
{ return ToAddrVal(addr).release(); }
|
|
||||||
|
|
||||||
AddrValPtr ARP_Analyzer::ToAddrVal(const void* addr)
|
|
||||||
{
|
|
||||||
// ### For now, we only handle IPv4 addresses.
|
|
||||||
return make_intrusive<AddrVal>(*(const uint32_t*) addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringVal* ARP_Analyzer::EthAddrToStr(const u_char* addr)
|
|
||||||
{ return ToEthAddrStr(addr).release(); }
|
|
||||||
|
|
||||||
StringValPtr ARP_Analyzer::ToEthAddrStr(const u_char* addr)
|
|
||||||
{
|
|
||||||
char buf[1024];
|
|
||||||
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
||||||
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
|
|
||||||
return make_intrusive<StringVal>(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace zeek::analyzer::arp
|
|
|
@ -1,66 +0,0 @@
|
||||||
// See the file "COPYING" in the main distribution directory for copyright.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "zeek-config.h"
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/if_arp.h>
|
|
||||||
#ifdef HAVE_NET_ETHERNET_H
|
|
||||||
#include <net/ethernet.h>
|
|
||||||
#elif defined(HAVE_SYS_ETHERNET_H)
|
|
||||||
#include <sys/ethernet.h>
|
|
||||||
#elif defined(HAVE_NETINET_IF_ETHER_H)
|
|
||||||
#include <netinet/if_ether.h>
|
|
||||||
#elif defined(HAVE_NET_ETHERTYPES_H)
|
|
||||||
#include <net/ethertypes.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef arp_pkthdr
|
|
||||||
#define arp_pkthdr arphdr
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "NetVar.h"
|
|
||||||
|
|
||||||
ZEEK_FORWARD_DECLARE_NAMESPACED(Packet, zeek);
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <pcap.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace zeek::analyzer::arp {
|
|
||||||
|
|
||||||
class ARP_Analyzer : public Obj {
|
|
||||||
public:
|
|
||||||
ARP_Analyzer();
|
|
||||||
~ARP_Analyzer() override;
|
|
||||||
|
|
||||||
void NextPacket(double t, const Packet* pkt);
|
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
|
||||||
void RREvent(EventHandlerPtr e, const u_char* src, const u_char* dst,
|
|
||||||
const char* spa, const char* sha,
|
|
||||||
const char* tpa, const char* tha);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
[[deprecated("Remove in v4.1. Use ToAddrVal().")]]
|
|
||||||
AddrVal* ConstructAddrVal(const void* addr);
|
|
||||||
[[deprecated("Remove in v4.1. Use ToEthAddrStr().")]]
|
|
||||||
StringVal* EthAddrToStr(const u_char* addr);
|
|
||||||
|
|
||||||
AddrValPtr ToAddrVal(const void* addr);
|
|
||||||
StringValPtr ToEthAddrStr(const u_char* addr);
|
|
||||||
void BadARP(const struct arp_pkthdr* hdr, const char* string);
|
|
||||||
void Corrupted(const char* string);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace zeek::analyzer::arp
|
|
||||||
|
|
||||||
namespace analyzer::arp {
|
|
||||||
|
|
||||||
using ARP_Analyzer [[deprecated("Remove in v4.1. Use zeek::analyzer::arp::ARP_Analyzer.")]] = zeek::analyzer::arp::ARP_Analyzer;
|
|
||||||
|
|
||||||
} // namespace analyzer::arp
|
|
|
@ -1,15 +0,0 @@
|
||||||
|
|
||||||
# This is not an actual analyzer, but used by the core. We still
|
|
||||||
# maintain it here along with the other analyzers because conceptually
|
|
||||||
# it's also parsing a protocol just like them. The current structure
|
|
||||||
# is merely a left-over from when this code was written.
|
|
||||||
|
|
||||||
include(ZeekPlugin)
|
|
||||||
|
|
||||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
|
|
||||||
zeek_plugin_begin(Zeek ARP)
|
|
||||||
zeek_plugin_cc(ARP.cc Plugin.cc)
|
|
||||||
zeek_plugin_bif(events.bif)
|
|
||||||
zeek_plugin_end()
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
// See the file in the main distribution directory for copyright.
|
|
||||||
|
|
||||||
#include "plugin/Plugin.h"
|
|
||||||
|
|
||||||
namespace zeek::plugin::detail::Zeek_ARP {
|
|
||||||
|
|
||||||
class Plugin : public zeek::plugin::Plugin {
|
|
||||||
public:
|
|
||||||
zeek::plugin::Configuration Configure() override
|
|
||||||
{
|
|
||||||
zeek::plugin::Configuration config;
|
|
||||||
config.name = "Zeek::ARP";
|
|
||||||
config.description = "ARP Parsing";
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
} plugin;
|
|
||||||
|
|
||||||
} // namespace zeek::plugin::detail::Zeek_ARP
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
include(ZeekSubdir)
|
include(ZeekSubdir)
|
||||||
|
|
||||||
include_directories(BEFORE
|
include_directories(BEFORE
|
||||||
|
|
|
@ -1,6 +1,20 @@
|
||||||
// See the file "COPYING" in the main distribution directory for copyright.
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
#include "ARP.h"
|
#include "ARP.h"
|
||||||
|
#include "Event.h"
|
||||||
|
|
||||||
|
#include "events.bif.h"
|
||||||
|
|
||||||
|
#include "zeek-config.h"
|
||||||
|
#ifdef HAVE_NET_ETHERNET_H
|
||||||
|
#include <net/ethernet.h>
|
||||||
|
#elif defined(HAVE_SYS_ETHERNET_H)
|
||||||
|
#include <sys/ethernet.h>
|
||||||
|
#elif defined(HAVE_NETINET_IF_ETHER_H)
|
||||||
|
#include <netinet/if_ether.h>
|
||||||
|
#elif defined(HAVE_NET_ETHERTYPES_H)
|
||||||
|
#include <net/ethertypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace zeek::packet_analysis::ARP;
|
using namespace zeek::packet_analysis::ARP;
|
||||||
|
|
||||||
|
@ -9,11 +23,202 @@ ARPAnalyzer::ARPAnalyzer()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Argh! FreeBSD and Linux have almost completely different net/if_arp.h .
|
||||||
|
// ... and on Solaris we are missing half of the ARPOP codes, so define
|
||||||
|
// them here as necessary:
|
||||||
|
|
||||||
|
#ifndef ARPOP_REQUEST
|
||||||
|
#define ARPOP_REQUEST 1 // ARP request.
|
||||||
|
#endif
|
||||||
|
#ifndef ARPOP_REPLY
|
||||||
|
#define ARPOP_REPLY 2 // ARP reply.
|
||||||
|
#endif
|
||||||
|
#ifndef ARPOP_PREQUEST
|
||||||
|
#define ARPOP_RREQUEST 3 // RARP request.
|
||||||
|
#endif
|
||||||
|
#ifndef ARPOP_RREPLY
|
||||||
|
#define ARPOP_RREPLY 4 // RARP reply.
|
||||||
|
#endif
|
||||||
|
#ifndef ARPOP_InREQUEST
|
||||||
|
#define ARPOP_InREQUEST 8 // InARP request.
|
||||||
|
#endif
|
||||||
|
#ifndef ARPOP_InREPLY
|
||||||
|
#define ARPOP_InREPLY 9 // InARP reply.
|
||||||
|
#endif
|
||||||
|
#ifndef ARPOP_NAK
|
||||||
|
#define ARPOP_NAK 10 // (ATM)ARP NAK.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ar_sha
|
||||||
|
#define ar_sha(ap) ((caddr_t((ap)+1)) + 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ar_spa
|
||||||
|
#define ar_spa(ap) ((caddr_t((ap)+1)) + (ap)->ar_hln)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ar_tha
|
||||||
|
#define ar_tha(ap) ((caddr_t((ap)+1)) + (ap)->ar_hln + (ap)->ar_pln)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ar_tpa
|
||||||
|
#define ar_tpa(ap) ((caddr_t((ap)+1)) + 2*(ap)->ar_hln + (ap)->ar_pln)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARPOP_REVREQUEST
|
||||||
|
#define ARPOP_REVREQUEST ARPOP_RREQUEST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARPOP_REVREPLY
|
||||||
|
#define ARPOP_REVREPLY ARPOP_RREPLY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARPOP_INVREQUEST
|
||||||
|
#define ARPOP_INVREQUEST ARPOP_InREQUEST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARPOP_INVREPLY
|
||||||
|
#define ARPOP_INVREPLY ARPOP_InREPLY
|
||||||
|
#endif
|
||||||
|
|
||||||
zeek::packet_analysis::AnalyzerResult ARPAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
|
zeek::packet_analysis::AnalyzerResult ARPAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
|
||||||
{
|
{
|
||||||
// TODO: Make ARP analyzer a native packet analyzer
|
|
||||||
packet->l3_proto = L3_ARP;
|
packet->l3_proto = L3_ARP;
|
||||||
|
|
||||||
|
// Check whether the packet is OK ("inspired" in tcpdump's print-arp.c).
|
||||||
|
auto ah = (const struct arp_pkthdr*) data;
|
||||||
|
|
||||||
|
// Check the size.
|
||||||
|
auto min_length = (ar_tpa(ah) - (char*) data) + ah->ar_pln;
|
||||||
|
auto pkt_hdr_len = data - packet->data;
|
||||||
|
auto real_length = packet->cap_len - pkt_hdr_len;
|
||||||
|
if ( min_length > real_length )
|
||||||
|
{
|
||||||
|
packet->Weird("truncated_ARP");
|
||||||
|
return AnalyzerResult::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the address description fields.
|
||||||
|
switch ( ntohs(ah->ar_hrd) ) {
|
||||||
|
case ARPHRD_ETHER:
|
||||||
|
if ( ah->ar_hln != 6 )
|
||||||
|
{
|
||||||
|
// don't know how to handle the opcode
|
||||||
|
BadARPEvent(ah, "corrupt-arp-header (hrd=%i, hln=%i)",
|
||||||
|
ntohs(ah->ar_hrd), ah->ar_hln);
|
||||||
|
return AnalyzerResult::Failed;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// don't know how to proceed
|
||||||
|
BadARPEvent(ah, "unknown-arp-hw-address (hrd=%i)", ntohs(ah->ar_hrd));
|
||||||
|
return AnalyzerResult::Failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: We don't support IPv6 addresses.
|
||||||
|
switch ( ntohs(ah->ar_pro) ) {
|
||||||
|
case ETHERTYPE_IP:
|
||||||
|
if ( ah->ar_pln != 4 )
|
||||||
|
{
|
||||||
|
// don't know how to handle the opcode
|
||||||
|
BadARPEvent(ah,"corrupt-arp-header (pro=%i, pln=%i)",
|
||||||
|
ntohs(ah->ar_pro), ah->ar_pln);
|
||||||
|
return AnalyzerResult::Failed;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// don't know how to proceed
|
||||||
|
BadARPEvent(ah,"unknown-arp-proto-address (pro=%i)", ntohs(ah->ar_pro));
|
||||||
|
return AnalyzerResult::Failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check MAC src address = ARP sender MAC address.
|
||||||
|
if ( memcmp(packet->l2_src, ar_sha(ah), ah->ar_hln) != 0 )
|
||||||
|
{
|
||||||
|
BadARPEvent(ah, "weird-arp-sha");
|
||||||
|
return AnalyzerResult::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the code is supported.
|
||||||
|
switch ( ntohs(ah->ar_op) ) {
|
||||||
|
case ARPOP_REQUEST:
|
||||||
|
RequestReplyEvent(arp_request, packet->l2_src, packet->l2_dst,
|
||||||
|
ar_spa(ah), ar_sha(ah), ar_tpa(ah), ar_tha(ah));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARPOP_REPLY:
|
||||||
|
RequestReplyEvent(arp_reply, packet->l2_src, packet->l2_dst,
|
||||||
|
ar_spa(ah), ar_sha(ah), ar_tpa(ah), ar_tha(ah));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARPOP_REVREQUEST:
|
||||||
|
case ARPOP_REVREPLY:
|
||||||
|
case ARPOP_INVREQUEST:
|
||||||
|
case ARPOP_INVREPLY:
|
||||||
|
{
|
||||||
|
// don't know how to handle the opcode
|
||||||
|
BadARPEvent(ah, "unimplemented-arp-opcode (%i)", ntohs(ah->ar_op));
|
||||||
|
return AnalyzerResult::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// invalid opcode
|
||||||
|
BadARPEvent(ah, "invalid-arp-opcode (opcode=%i)", ntohs(ah->ar_op));
|
||||||
|
return AnalyzerResult::Failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Leave packet analyzer land
|
// Leave packet analyzer land
|
||||||
return AnalyzerResult::Terminate;
|
return AnalyzerResult::Terminate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zeek::AddrValPtr ARPAnalyzer::ToAddrVal(const void* addr)
|
||||||
|
{
|
||||||
|
//Note: We only handle IPv4 addresses.
|
||||||
|
return zeek::make_intrusive<zeek::AddrVal>(*(const uint32_t*) addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
zeek::StringValPtr ARPAnalyzer::ToEthAddrStr(const u_char* addr)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
|
||||||
|
return zeek::make_intrusive<zeek::StringVal>(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARPAnalyzer::BadARPEvent(const struct arp_pkthdr* hdr, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
if ( ! bad_arp )
|
||||||
|
return;
|
||||||
|
|
||||||
|
char msg[1024];
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf(msg, sizeof(msg), fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
event_mgr.Enqueue(bad_arp,
|
||||||
|
ToAddrVal(ar_spa(hdr)), ToEthAddrStr((const u_char*) ar_sha(hdr)),
|
||||||
|
ToAddrVal(ar_tpa(hdr)), ToEthAddrStr((const u_char*) ar_tha(hdr)),
|
||||||
|
zeek::make_intrusive<zeek::StringVal>(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARPAnalyzer::RequestReplyEvent(EventHandlerPtr e, const u_char *src, const u_char *dst,
|
||||||
|
const char *spa, const char *sha, const char *tpa, const char *tha)
|
||||||
|
{
|
||||||
|
if ( ! e )
|
||||||
|
return;
|
||||||
|
|
||||||
|
event_mgr.Enqueue(e, ToEthAddrStr(src), ToEthAddrStr(dst),
|
||||||
|
ToAddrVal(spa), ToEthAddrStr((const u_char*) sha),
|
||||||
|
ToAddrVal(tpa), ToEthAddrStr((const u_char*) tha));
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,12 @@
|
||||||
#include <packet_analysis/Analyzer.h>
|
#include <packet_analysis/Analyzer.h>
|
||||||
#include <packet_analysis/Component.h>
|
#include <packet_analysis/Component.h>
|
||||||
|
|
||||||
|
#include <net/if_arp.h>
|
||||||
|
|
||||||
|
#ifndef arp_pkthdr
|
||||||
|
#define arp_pkthdr arphdr
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace zeek::packet_analysis::ARP {
|
namespace zeek::packet_analysis::ARP {
|
||||||
|
|
||||||
class ARPAnalyzer : public Analyzer {
|
class ARPAnalyzer : public Analyzer {
|
||||||
|
@ -18,6 +24,15 @@ public:
|
||||||
{
|
{
|
||||||
return std::make_shared<ARPAnalyzer>();
|
return std::make_shared<ARPAnalyzer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
zeek::AddrValPtr ToAddrVal(const void* addr);
|
||||||
|
zeek::StringValPtr ToEthAddrStr(const u_char* addr);
|
||||||
|
|
||||||
|
void BadARPEvent(const struct arp_pkthdr* hdr, const char* fmt, ...)
|
||||||
|
__attribute__((format(printf, 3, 4)));
|
||||||
|
void RequestReplyEvent(EventHandlerPtr e, const u_char* src, const u_char* dst,
|
||||||
|
const char* spa, const char* sha, const char* tpa, const char* tha);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
|
||||||
include(ZeekPlugin)
|
include(ZeekPlugin)
|
||||||
|
|
||||||
include_directories(BEFORE $ {CMAKE_CURRENT_SOURCE_DIR} $ {CMAKE_CURRENT_BINARY_DIR})
|
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
zeek_plugin_begin(PacketAnalyzer ARP)
|
zeek_plugin_begin(Zeek ARP)
|
||||||
zeek_plugin_cc(ARP.cc Plugin.cc)
|
zeek_plugin_cc(ARP.cc Plugin.cc)
|
||||||
|
zeek_plugin_bif(events.bif)
|
||||||
zeek_plugin_end()
|
zeek_plugin_end()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
include(ZeekPlugin)
|
include(ZeekPlugin)
|
||||||
|
|
||||||
include_directories(BEFORE $ {CMAKE_CURRENT_SOURCE_DIR} $ {CMAKE_CURRENT_BINARY_DIR})
|
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
zeek_plugin_begin(PacketAnalyzer IPv6)
|
zeek_plugin_begin(PacketAnalyzer IPv6)
|
||||||
zeek_plugin_cc(IPv6.cc Plugin.cc)
|
zeek_plugin_cc(IPv6.cc Plugin.cc)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
include(ZeekPlugin)
|
include(ZeekPlugin)
|
||||||
|
|
||||||
include_directories(BEFORE $ {CMAKE_CURRENT_SOURCE_DIR} $ {CMAKE_CURRENT_BINARY_DIR})
|
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
zeek_plugin_begin(PacketAnalyzer LinuxSLL)
|
zeek_plugin_begin(PacketAnalyzer LinuxSLL)
|
||||||
zeek_plugin_cc(LinuxSLL.cc Plugin.cc)
|
zeek_plugin_cc(LinuxSLL.cc Plugin.cc)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
include(ZeekPlugin)
|
include(ZeekPlugin)
|
||||||
|
|
||||||
include_directories(BEFORE $ {CMAKE_CURRENT_SOURCE_DIR} $ {CMAKE_CURRENT_BINARY_DIR})
|
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
zeek_plugin_begin(PacketAnalyzer Null)
|
zeek_plugin_begin(PacketAnalyzer Null)
|
||||||
zeek_plugin_cc(Null.cc Plugin.cc)
|
zeek_plugin_cc(Null.cc Plugin.cc)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#empty_field (empty)
|
#empty_field (empty)
|
||||||
#unset_field -
|
#unset_field -
|
||||||
#path loaded_scripts
|
#path loaded_scripts
|
||||||
#open 2020-08-26-12-08-09
|
#open 2020-08-28-14-19-59
|
||||||
#fields name
|
#fields name
|
||||||
#types string
|
#types string
|
||||||
scripts/base/init-bare.zeek
|
scripts/base/init-bare.zeek
|
||||||
|
@ -91,7 +91,6 @@ scripts/base/init-frameworks-and-bifs.zeek
|
||||||
build/scripts/base/bif/cardinality-counter.bif.zeek
|
build/scripts/base/bif/cardinality-counter.bif.zeek
|
||||||
build/scripts/base/bif/top-k.bif.zeek
|
build/scripts/base/bif/top-k.bif.zeek
|
||||||
build/scripts/base/bif/plugins/__load__.zeek
|
build/scripts/base/bif/plugins/__load__.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek
|
|
||||||
build/scripts/base/bif/plugins/Zeek_BitTorrent.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_BitTorrent.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_ConnSize.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_ConnSize.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_ConnSize.functions.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_ConnSize.functions.bif.zeek
|
||||||
|
@ -190,6 +189,7 @@ scripts/base/init-frameworks-and-bifs.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_UDP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_UDP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_VXLAN.events.bif.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_XMPP.events.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_FileEntropy.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.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_FileExtract.functions.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_FileExtract.functions.bif.zeek
|
||||||
|
@ -212,4 +212,4 @@ scripts/base/init-frameworks-and-bifs.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_SQLiteWriter.sqlite.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_SQLiteWriter.sqlite.bif.zeek
|
||||||
scripts/policy/misc/loaded-scripts.zeek
|
scripts/policy/misc/loaded-scripts.zeek
|
||||||
scripts/base/utils/paths.zeek
|
scripts/base/utils/paths.zeek
|
||||||
#close 2020-08-26-12-08-09
|
#close 2020-08-28-14-19-59
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#empty_field (empty)
|
#empty_field (empty)
|
||||||
#unset_field -
|
#unset_field -
|
||||||
#path loaded_scripts
|
#path loaded_scripts
|
||||||
#open 2020-09-22-16-59-24
|
#open 2020-09-22-17-05-35
|
||||||
#fields name
|
#fields name
|
||||||
#types string
|
#types string
|
||||||
scripts/base/init-bare.zeek
|
scripts/base/init-bare.zeek
|
||||||
|
@ -91,7 +91,6 @@ scripts/base/init-frameworks-and-bifs.zeek
|
||||||
build/scripts/base/bif/cardinality-counter.bif.zeek
|
build/scripts/base/bif/cardinality-counter.bif.zeek
|
||||||
build/scripts/base/bif/top-k.bif.zeek
|
build/scripts/base/bif/top-k.bif.zeek
|
||||||
build/scripts/base/bif/plugins/__load__.zeek
|
build/scripts/base/bif/plugins/__load__.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek
|
|
||||||
build/scripts/base/bif/plugins/Zeek_BitTorrent.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_BitTorrent.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_ConnSize.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_ConnSize.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_ConnSize.functions.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_ConnSize.functions.bif.zeek
|
||||||
|
@ -190,6 +189,7 @@ scripts/base/init-frameworks-and-bifs.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_UDP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_UDP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_VXLAN.events.bif.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_XMPP.events.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_FileEntropy.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.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_FileExtract.functions.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_FileExtract.functions.bif.zeek
|
||||||
|
@ -408,4 +408,4 @@ scripts/base/init-default.zeek
|
||||||
scripts/base/misc/find-filtered-trace.zeek
|
scripts/base/misc/find-filtered-trace.zeek
|
||||||
scripts/base/misc/version.zeek
|
scripts/base/misc/version.zeek
|
||||||
scripts/policy/misc/loaded-scripts.zeek
|
scripts/policy/misc/loaded-scripts.zeek
|
||||||
#close 2020-09-22-16-59-24
|
#close 2020-09-22-17-05-36
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue