mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Store packet's ip header as unique_ptr
This commit is contained in:
parent
2000f89b12
commit
ecd970ffde
13 changed files with 86 additions and 92 deletions
|
@ -35,7 +35,7 @@ bool Discarder::IsActive()
|
||||||
return check_ip || check_tcp || check_udp || check_icmp;
|
return check_ip || check_tcp || check_udp || check_icmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
|
bool Discarder::NextPacket(const std::unique_ptr<IP_Hdr>& ip, int len, int caplen)
|
||||||
{
|
{
|
||||||
bool discard_packet = false;
|
bool discard_packet = false;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <sys/types.h> // for u_char
|
#include <sys/types.h> // for u_char
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "IntrusivePtr.h"
|
#include "IntrusivePtr.h"
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@ public:
|
||||||
|
|
||||||
bool IsActive();
|
bool IsActive();
|
||||||
|
|
||||||
bool NextPacket(const IP_Hdr* ip, int len, int caplen);
|
bool NextPacket(const std::unique_ptr<IP_Hdr>& ip, int len, int caplen);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Val* BuildData(const u_char* data, int hdrlen, int len, int caplen);
|
Val* BuildData(const u_char* data, int hdrlen, int len, int caplen);
|
||||||
|
|
31
src/Frag.cc
31
src/Frag.cc
|
@ -30,7 +30,7 @@ void FragTimer::Dispatch(double t, bool /* is_expire */)
|
||||||
}
|
}
|
||||||
|
|
||||||
FragReassembler::FragReassembler(NetSessions* arg_s,
|
FragReassembler::FragReassembler(NetSessions* arg_s,
|
||||||
const IP_Hdr* ip, const u_char* pkt,
|
const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt,
|
||||||
const FragReassemblerKey& k, double t)
|
const FragReassemblerKey& k, double t)
|
||||||
: Reassembler(0, REASSEM_FRAG)
|
: Reassembler(0, REASSEM_FRAG)
|
||||||
{
|
{
|
||||||
|
@ -73,7 +73,8 @@ FragReassembler::~FragReassembler()
|
||||||
delete [] proto_hdr;
|
delete [] proto_hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
|
void FragReassembler::AddFragment(double t, const std::unique_ptr<IP_Hdr>& ip,
|
||||||
|
const u_char* pkt)
|
||||||
{
|
{
|
||||||
const struct ip* ip4 = ip->IP4_Hdr();
|
const struct ip* ip4 = ip->IP4_Hdr();
|
||||||
|
|
||||||
|
@ -85,19 +86,19 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
|
||||||
// don't check TOS, there's at least one stack that actually
|
// don't check TOS, there's at least one stack that actually
|
||||||
// uses different values, and it's hard to see an associated
|
// uses different values, and it's hard to see an associated
|
||||||
// attack.
|
// attack.
|
||||||
s->Weird("fragment_protocol_inconsistency", ip);
|
s->Weird("fragment_protocol_inconsistency", ip.get());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( ip->NextProto() != next_proto ||
|
if ( ip->NextProto() != next_proto ||
|
||||||
ip->HdrLen() - 8 != proto_hdr_len )
|
ip->HdrLen() - 8 != proto_hdr_len )
|
||||||
s->Weird("fragment_protocol_inconsistency", ip);
|
s->Weird("fragment_protocol_inconsistency", ip.get());
|
||||||
// TODO: more detailed unfrag header consistency checks?
|
// TODO: more detailed unfrag header consistency checks?
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ip->DF() )
|
if ( ip->DF() )
|
||||||
// Linux MTU discovery for UDP can do this, for example.
|
// Linux MTU discovery for UDP can do this, for example.
|
||||||
s->Weird("fragment_with_DF", ip);
|
s->Weird("fragment_with_DF", ip.get());
|
||||||
|
|
||||||
uint16_t offset = ip->FragOffset();
|
uint16_t offset = ip->FragOffset();
|
||||||
uint32_t len = ip->TotalLen();
|
uint32_t len = ip->TotalLen();
|
||||||
|
@ -105,7 +106,7 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
|
||||||
|
|
||||||
if ( len < hdr_len )
|
if ( len < hdr_len )
|
||||||
{
|
{
|
||||||
s->Weird("fragment_protocol_inconsistency", ip);
|
s->Weird("fragment_protocol_inconsistency", ip.get());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +124,7 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
|
||||||
|
|
||||||
else if ( upper_seq != frag_size )
|
else if ( upper_seq != frag_size )
|
||||||
{
|
{
|
||||||
s->Weird("fragment_size_inconsistency", ip);
|
s->Weird("fragment_size_inconsistency", ip.get());
|
||||||
|
|
||||||
if ( upper_seq > frag_size )
|
if ( upper_seq > frag_size )
|
||||||
frag_size = upper_seq;
|
frag_size = upper_seq;
|
||||||
|
@ -131,10 +132,10 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( len < MIN_ACCEPTABLE_FRAG_SIZE )
|
else if ( len < MIN_ACCEPTABLE_FRAG_SIZE )
|
||||||
s->Weird("excessively_small_fragment", ip);
|
s->Weird("excessively_small_fragment", ip.get());
|
||||||
|
|
||||||
if ( upper_seq > MAX_ACCEPTABLE_FRAG_SIZE )
|
if ( upper_seq > MAX_ACCEPTABLE_FRAG_SIZE )
|
||||||
s->Weird("excessively_large_fragment", ip);
|
s->Weird("excessively_large_fragment", ip.get());
|
||||||
|
|
||||||
if ( frag_size && upper_seq > frag_size )
|
if ( frag_size && upper_seq > frag_size )
|
||||||
{
|
{
|
||||||
|
@ -143,7 +144,7 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
|
||||||
// larger than the size we derived from a previously-seen
|
// larger than the size we derived from a previously-seen
|
||||||
// "last fragment".
|
// "last fragment".
|
||||||
|
|
||||||
s->Weird("fragment_size_inconsistency", ip);
|
s->Weird("fragment_size_inconsistency", ip.get());
|
||||||
frag_size = upper_seq;
|
frag_size = upper_seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,8 +287,7 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
|
||||||
memcpy(&pkt[b.seq], b.block, b.upper - b.seq);
|
memcpy(&pkt[b.seq], b.block, b.upper - b.seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete reassembled_pkt;
|
reassembled_pkt.reset();
|
||||||
reassembled_pkt = nullptr;
|
|
||||||
|
|
||||||
unsigned int version = ((const struct ip*)pkt_start)->ip_v;
|
unsigned int version = ((const struct ip*)pkt_start)->ip_v;
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
|
||||||
{
|
{
|
||||||
struct ip* reassem4 = (struct ip*) pkt_start;
|
struct ip* reassem4 = (struct ip*) pkt_start;
|
||||||
reassem4->ip_len = htons(frag_size + proto_hdr_len);
|
reassem4->ip_len = htons(frag_size + proto_hdr_len);
|
||||||
reassembled_pkt = new IP_Hdr(reassem4, true);
|
reassembled_pkt = std::make_unique<IP_Hdr>(reassem4, true);
|
||||||
reassembled_pkt->reassembled = true;
|
reassembled_pkt->reassembled = true;
|
||||||
DeleteTimer();
|
DeleteTimer();
|
||||||
}
|
}
|
||||||
|
@ -305,7 +305,7 @@ void FragReassembler::BlockInserted(DataBlockMap::const_iterator /* it */)
|
||||||
struct ip6_hdr* reassem6 = (struct ip6_hdr*) pkt_start;
|
struct ip6_hdr* reassem6 = (struct ip6_hdr*) pkt_start;
|
||||||
reassem6->ip6_plen = htons(frag_size + proto_hdr_len - 40);
|
reassem6->ip6_plen = htons(frag_size + proto_hdr_len - 40);
|
||||||
const IPv6_Hdr_Chain* chain = new IPv6_Hdr_Chain(reassem6, next_proto, n);
|
const IPv6_Hdr_Chain* chain = new IPv6_Hdr_Chain(reassem6, next_proto, n);
|
||||||
reassembled_pkt = new IP_Hdr(reassem6, true, n, chain);
|
reassembled_pkt = std::make_unique<IP_Hdr>(reassem6, true, n, chain);
|
||||||
reassembled_pkt->reassembled = true;
|
reassembled_pkt->reassembled = true;
|
||||||
DeleteTimer();
|
DeleteTimer();
|
||||||
}
|
}
|
||||||
|
@ -342,7 +342,8 @@ FragmentManager::~FragmentManager()
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
FragReassembler* FragmentManager::NextFragment(double t, const IP_Hdr* ip, const u_char* pkt)
|
FragReassembler* FragmentManager::NextFragment(double t, const std::unique_ptr<IP_Hdr>& ip,
|
||||||
|
const u_char* pkt)
|
||||||
{
|
{
|
||||||
uint32_t frag_id = ip->ID();
|
uint32_t frag_id = ip->ID();
|
||||||
FragReassemblerKey key = std::make_tuple(ip->SrcAddr(), ip->DstAddr(), frag_id);
|
FragReassemblerKey key = std::make_tuple(ip->SrcAddr(), ip->DstAddr(), frag_id);
|
||||||
|
|
11
src/Frag.h
11
src/Frag.h
|
@ -22,17 +22,17 @@ using FragReassemblerKey = std::tuple<IPAddr, IPAddr, bro_uint_t>;
|
||||||
|
|
||||||
class FragReassembler : public Reassembler {
|
class FragReassembler : public Reassembler {
|
||||||
public:
|
public:
|
||||||
FragReassembler(NetSessions* s, const IP_Hdr* ip, const u_char* pkt,
|
FragReassembler(NetSessions* s, const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt,
|
||||||
const FragReassemblerKey& k, double t);
|
const FragReassemblerKey& k, double t);
|
||||||
~FragReassembler() override;
|
~FragReassembler() override;
|
||||||
|
|
||||||
void AddFragment(double t, const IP_Hdr* ip, const u_char* pkt);
|
void AddFragment(double t, const std::unique_ptr<IP_Hdr>& ip, const u_char* pkt);
|
||||||
|
|
||||||
void Expire(double t);
|
void Expire(double t);
|
||||||
void DeleteTimer();
|
void DeleteTimer();
|
||||||
void ClearTimer() { expire_timer = nullptr; }
|
void ClearTimer() { expire_timer = nullptr; }
|
||||||
|
|
||||||
IP_Hdr* ReassembledPkt() { return reassembled_pkt; }
|
std::unique_ptr<IP_Hdr> ReassembledPkt() { return std::move(reassembled_pkt); }
|
||||||
const FragReassemblerKey& Key() const { return key; }
|
const FragReassemblerKey& Key() const { return key; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -41,7 +41,7 @@ protected:
|
||||||
void Weird(const char* name) const;
|
void Weird(const char* name) const;
|
||||||
|
|
||||||
u_char* proto_hdr;
|
u_char* proto_hdr;
|
||||||
IP_Hdr* reassembled_pkt;
|
std::unique_ptr<IP_Hdr> reassembled_pkt;
|
||||||
NetSessions* s;
|
NetSessions* s;
|
||||||
uint64_t frag_size; // size of fully reassembled fragment
|
uint64_t frag_size; // size of fully reassembled fragment
|
||||||
FragReassemblerKey key;
|
FragReassemblerKey key;
|
||||||
|
@ -73,7 +73,8 @@ public:
|
||||||
FragmentManager() = default;
|
FragmentManager() = default;
|
||||||
~FragmentManager();
|
~FragmentManager();
|
||||||
|
|
||||||
FragReassembler* NextFragment(double t, const IP_Hdr* ip, const u_char* pkt);
|
FragReassembler* NextFragment(double t, const std::unique_ptr<IP_Hdr>& ip,
|
||||||
|
const u_char* pkt);
|
||||||
void Clear();
|
void Clear();
|
||||||
void Remove(detail::FragReassembler* f);
|
void Remove(detail::FragReassembler* f);
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ bool PacketFilter::RemoveDst(Val* dst)
|
||||||
return f != nullptr;
|
return f != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PacketFilter::Match(const IP_Hdr* ip, int len, int caplen)
|
bool PacketFilter::Match(const std::unique_ptr<IP_Hdr>& ip, int len, int caplen)
|
||||||
{
|
{
|
||||||
Filter* f = (Filter*) src_filter.Lookup(ip->SrcAddr(), 128);
|
Filter* f = (Filter*) src_filter.Lookup(ip->SrcAddr(), 128);
|
||||||
if ( f )
|
if ( f )
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include "IPAddr.h"
|
#include "IPAddr.h"
|
||||||
#include "PrefixTable.h"
|
#include "PrefixTable.h"
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ public:
|
||||||
bool RemoveDst(Val* dst);
|
bool RemoveDst(Val* dst);
|
||||||
|
|
||||||
// Returns true if packet matches a drop filter
|
// Returns true if packet matches a drop filter
|
||||||
bool Match(const IP_Hdr* ip, int len, int caplen);
|
bool Match(const std::unique_ptr<IP_Hdr>& ip, int len, int caplen);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Filter {
|
struct Filter {
|
||||||
|
|
|
@ -81,8 +81,10 @@ void NetSessions::NextPacket(double t, Packet* pkt)
|
||||||
packet_mgr->ProcessPacket(pkt);
|
packet_mgr->ProcessPacket(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr)
|
void NetSessions::DoNextPacket(double t, const Packet* pkt)
|
||||||
{
|
{
|
||||||
|
const std::unique_ptr<IP_Hdr>& ip_hdr = pkt->ip_hdr;
|
||||||
|
|
||||||
uint32_t caplen = pkt->cap_len - pkt->hdr_size;
|
uint32_t caplen = pkt->cap_len - pkt->hdr_size;
|
||||||
uint32_t len = ip_hdr->TotalLen();
|
uint32_t len = ip_hdr->TotalLen();
|
||||||
uint16_t ip_hdr_len = ip_hdr->HdrLen();
|
uint16_t ip_hdr_len = ip_hdr->HdrLen();
|
||||||
|
@ -218,7 +220,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
|
||||||
conn->EnqueueEvent(new_packet, nullptr, conn->ConnVal(), pkt_hdr_val ?
|
conn->EnqueueEvent(new_packet, nullptr, conn->ConnVal(), pkt_hdr_val ?
|
||||||
std::move(pkt_hdr_val) : ip_hdr->ToPktHdrVal());
|
std::move(pkt_hdr_val) : ip_hdr->ToPktHdrVal());
|
||||||
|
|
||||||
conn->NextPacket(t, is_orig, ip_hdr, len, caplen, data,
|
conn->NextPacket(t, is_orig, ip_hdr.get(), len, caplen, data,
|
||||||
record_packet, record_content, pkt);
|
record_packet, record_content, pkt);
|
||||||
|
|
||||||
// We skip this block for reassembled packets because the pointer
|
// We skip this block for reassembled packets because the pointer
|
||||||
|
|
|
@ -96,7 +96,7 @@ public:
|
||||||
* method is called by the packet analysis manager when after it has processed
|
* method is called by the packet analysis manager when after it has processed
|
||||||
* an IP-based packet, and shouldn't be called directly from other places.
|
* an IP-based packet, and shouldn't be called directly from other places.
|
||||||
*/
|
*/
|
||||||
void DoNextPacket(double t, const Packet *pkt, const IP_Hdr* ip_hdr);
|
void DoNextPacket(double t, const Packet *pkt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a wrapper IP_Hdr object if \a pkt appears to be a valid IPv4
|
* Returns a wrapper IP_Hdr object if \a pkt appears to be a valid IPv4
|
||||||
|
|
|
@ -63,8 +63,7 @@ void Packet::Init(int arg_link_type, pkt_timeval *arg_ts, uint32_t arg_caplen,
|
||||||
l3_checksummed = false;
|
l3_checksummed = false;
|
||||||
|
|
||||||
encap.reset();
|
encap.reset();
|
||||||
delete ip_hdr;
|
ip_hdr.reset();
|
||||||
ip_hdr = nullptr;
|
|
||||||
|
|
||||||
proto = -1;
|
proto = -1;
|
||||||
tunnel_type = BifEnum::Tunnel::IP;
|
tunnel_type = BifEnum::Tunnel::IP;
|
||||||
|
@ -83,8 +82,6 @@ Packet::~Packet()
|
||||||
{
|
{
|
||||||
if ( copy )
|
if ( copy )
|
||||||
delete [] data;
|
delete [] data;
|
||||||
|
|
||||||
delete ip_hdr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const IP_Hdr Packet::IP() const
|
const IP_Hdr Packet::IP() const
|
||||||
|
|
|
@ -16,11 +16,11 @@ typedef struct timeval pkt_timeval;
|
||||||
#include "pcap.h" // For DLT_ constants
|
#include "pcap.h" // For DLT_ constants
|
||||||
#include "zeek/NetVar.h" // For BifEnum::Tunnel
|
#include "zeek/NetVar.h" // For BifEnum::Tunnel
|
||||||
#include "zeek/TunnelEncapsulation.h"
|
#include "zeek/TunnelEncapsulation.h"
|
||||||
|
#include "zeek/IP.h"
|
||||||
|
|
||||||
ZEEK_FORWARD_DECLARE_NAMESPACED(ODesc, zeek);
|
ZEEK_FORWARD_DECLARE_NAMESPACED(ODesc, zeek);
|
||||||
ZEEK_FORWARD_DECLARE_NAMESPACED(Val, zeek);
|
ZEEK_FORWARD_DECLARE_NAMESPACED(Val, zeek);
|
||||||
ZEEK_FORWARD_DECLARE_NAMESPACED(RecordVal, zeek);
|
ZEEK_FORWARD_DECLARE_NAMESPACED(RecordVal, zeek);
|
||||||
ZEEK_FORWARD_DECLARE_NAMESPACED(IP_Hdr, zeek);
|
|
||||||
|
|
||||||
namespace zeek {
|
namespace zeek {
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ public:
|
||||||
* The IP header for this packet. This is filled in by the IP analyzer
|
* The IP header for this packet. This is filled in by the IP analyzer
|
||||||
* during processing if the packet contains an IP header.
|
* during processing if the packet contains an IP header.
|
||||||
*/
|
*/
|
||||||
IP_Hdr* ip_hdr = nullptr;
|
std::unique_ptr<IP_Hdr> ip_hdr = nullptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The protocol of the packet. This is used by the tunnel analyzers to
|
* The protocol of the packet. This is used by the tunnel analyzers to
|
||||||
|
|
|
@ -48,11 +48,9 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_Hdr* ip_hdr = packet->ip_hdr;
|
|
||||||
|
|
||||||
if ( ! BifConst::Tunnel::enable_gre )
|
if ( ! BifConst::Tunnel::enable_gre )
|
||||||
{
|
{
|
||||||
sessions->Weird("GRE_tunnel", ip_hdr, packet->encap);
|
sessions->Weird("GRE_tunnel", packet->ip_hdr.get(), packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +68,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
|
|
||||||
if ( gre_version != 0 && gre_version != 1 )
|
if ( gre_version != 0 && gre_version != 1 )
|
||||||
{
|
{
|
||||||
sessions->Weird("unknown_gre_version", ip_hdr, packet->encap,
|
sessions->Weird("unknown_gre_version", packet->ip_hdr.get(), packet->encap,
|
||||||
util::fmt("%d", gre_version));
|
util::fmt("%d", gre_version));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +86,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sessions->Weird("truncated_GRE", ip_hdr, packet->encap);
|
sessions->Weird("truncated_GRE", packet->ip_hdr.get(), packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +103,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sessions->Weird("truncated_GRE", ip_hdr, packet->encap);
|
sessions->Weird("truncated_GRE", packet->ip_hdr.get(), packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +126,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
erspan_len += 8;
|
erspan_len += 8;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sessions->Weird("truncated_GRE", ip_hdr, packet->encap);
|
sessions->Weird("truncated_GRE", packet->ip_hdr.get(), packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +135,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sessions->Weird("truncated_GRE", ip_hdr, packet->encap);
|
sessions->Weird("truncated_GRE", packet->ip_hdr.get(), packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,7 +146,7 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
if ( proto_typ != 0x880b )
|
if ( proto_typ != 0x880b )
|
||||||
{
|
{
|
||||||
// Enhanced GRE payload must be PPP.
|
// Enhanced GRE payload must be PPP.
|
||||||
sessions->Weird("egre_protocol_type", ip_hdr, packet->encap,
|
sessions->Weird("egre_protocol_type", packet->ip_hdr.get(), packet->encap,
|
||||||
util::fmt("%d", proto_typ));
|
util::fmt("%d", proto_typ));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -159,20 +157,20 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
// RFC 2784 deprecates the variable length routing field
|
// RFC 2784 deprecates the variable length routing field
|
||||||
// specified by RFC 1701. It could be parsed here, but easiest
|
// specified by RFC 1701. It could be parsed here, but easiest
|
||||||
// to just skip for now.
|
// to just skip for now.
|
||||||
sessions->Weird("gre_routing", ip_hdr, packet->encap);
|
sessions->Weird("gre_routing", packet->ip_hdr.get(), packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( flags_ver & 0x0078 )
|
if ( flags_ver & 0x0078 )
|
||||||
{
|
{
|
||||||
// Expect last 4 bits of flags are reserved, undefined.
|
// Expect last 4 bits of flags are reserved, undefined.
|
||||||
sessions->Weird("unknown_gre_flags", ip_hdr, packet->encap);
|
sessions->Weird("unknown_gre_flags", packet->ip_hdr.get(), packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( len < gre_len + ppp_len + eth_len + erspan_len )
|
if ( len < gre_len + ppp_len + eth_len + erspan_len )
|
||||||
{
|
{
|
||||||
sessions->Weird("truncated_GRE", ip_hdr, packet->encap);
|
sessions->Weird("truncated_GRE", packet->ip_hdr.get(), packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +180,8 @@ bool GREAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
|
|
||||||
if ( ppp_proto != 0x0021 && ppp_proto != 0x0057 )
|
if ( ppp_proto != 0x0021 && ppp_proto != 0x0057 )
|
||||||
{
|
{
|
||||||
sessions->Weird("non_ip_packet_in_encap", ip_hdr, packet->encap);
|
sessions->Weird("non_ip_packet_in_encap", packet->ip_hdr.get(),
|
||||||
|
packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,10 +49,9 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
uint32_t protocol = ip->ip_v;
|
uint32_t protocol = ip->ip_v;
|
||||||
|
|
||||||
// This is a unique pointer because of the mass of early returns from this method.
|
// This is a unique pointer because of the mass of early returns from this method.
|
||||||
IP_Hdr* ip_hdr = nullptr;
|
|
||||||
if ( protocol == 4 )
|
if ( protocol == 4 )
|
||||||
{
|
{
|
||||||
ip_hdr = new IP_Hdr(ip, false);
|
packet->ip_hdr = std::make_unique<IP_Hdr>(ip, false);
|
||||||
packet->l3_proto = L3_IPV4;
|
packet->l3_proto = L3_IPV4;
|
||||||
}
|
}
|
||||||
else if ( protocol == 6 )
|
else if ( protocol == 6 )
|
||||||
|
@ -63,7 +62,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip_hdr = new IP_Hdr((const struct ip6_hdr*) data, false, len);
|
packet->ip_hdr = std::make_unique<IP_Hdr>((const struct ip6_hdr*) data, false, len);
|
||||||
packet->l3_proto = L3_IPV6;
|
packet->l3_proto = L3_IPV6;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -72,14 +71,10 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store this with the packet, since it's potentially used in other places
|
const struct ip* ip4 = packet->ip_hdr->IP4_Hdr();
|
||||||
// and it makes sense to not have to parse it out a second time.
|
|
||||||
packet->ip_hdr = ip_hdr;
|
|
||||||
|
|
||||||
const struct ip* ip4 = ip_hdr->IP4_Hdr();
|
|
||||||
|
|
||||||
// total_len is the length of the packet minus all of the headers so far, including IP
|
// total_len is the length of the packet minus all of the headers so far, including IP
|
||||||
uint32_t total_len = ip_hdr->TotalLen();
|
uint32_t total_len = packet->ip_hdr->TotalLen();
|
||||||
if ( total_len == 0 )
|
if ( total_len == 0 )
|
||||||
{
|
{
|
||||||
// TCP segmentation offloading can zero out the ip_len field.
|
// TCP segmentation offloading can zero out the ip_len field.
|
||||||
|
@ -97,20 +92,20 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
|
|
||||||
// For both of these it is safe to pass ip_hdr because the presence
|
// For both of these it is safe to pass ip_hdr because the presence
|
||||||
// is guaranteed for the functions that pass data to us.
|
// is guaranteed for the functions that pass data to us.
|
||||||
uint16_t ip_hdr_len = ip_hdr->HdrLen();
|
uint16_t ip_hdr_len = packet->ip_hdr->HdrLen();
|
||||||
if ( ip_hdr_len > total_len )
|
if ( ip_hdr_len > total_len )
|
||||||
{
|
{
|
||||||
sessions->Weird("invalid_IP_header_size", ip_hdr, packet->encap);
|
sessions->Weird("invalid_IP_header_size", packet->ip_hdr.get(), packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ip_hdr_len > len )
|
if ( ip_hdr_len > len )
|
||||||
{
|
{
|
||||||
sessions->Weird("internally_truncated_header", ip_hdr, packet->encap);
|
sessions->Weird("internally_truncated_header", packet->ip_hdr.get(), packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ip_hdr->IP4_Hdr() )
|
if ( packet->ip_hdr->IP4_Hdr() )
|
||||||
{
|
{
|
||||||
if ( ip_hdr_len < sizeof(struct ip) )
|
if ( ip_hdr_len < sizeof(struct ip) )
|
||||||
{
|
{
|
||||||
|
@ -129,7 +124,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
|
|
||||||
// Ignore if packet matches packet filter.
|
// Ignore if packet matches packet filter.
|
||||||
detail::PacketFilter* packet_filter = sessions->GetPacketFilter(false);
|
detail::PacketFilter* packet_filter = sessions->GetPacketFilter(false);
|
||||||
if ( packet_filter && packet_filter->Match(ip_hdr, total_len, len) )
|
if ( packet_filter && packet_filter->Match(packet->ip_hdr, total_len, len) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( ! packet->l2_checksummed && ! detail::ignore_checksums && ip4 &&
|
if ( ! packet->l2_checksummed && ! detail::ignore_checksums && ip4 &&
|
||||||
|
@ -139,30 +134,31 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( discarder && discarder->NextPacket(ip_hdr, total_len, len) )
|
if ( discarder && discarder->NextPacket(packet->ip_hdr, total_len, len) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
detail::FragReassembler* f = nullptr;
|
detail::FragReassembler* f = nullptr;
|
||||||
|
|
||||||
if ( ip_hdr->IsFragment() )
|
if ( packet->ip_hdr->IsFragment() )
|
||||||
{
|
{
|
||||||
packet->dump_packet = true; // always record fragments
|
packet->dump_packet = true; // always record fragments
|
||||||
|
|
||||||
if ( len < total_len )
|
if ( len < total_len )
|
||||||
{
|
{
|
||||||
sessions->Weird("incompletely_captured_fragment", ip_hdr, packet->encap);
|
sessions->Weird("incompletely_captured_fragment", packet->ip_hdr.get(), packet->encap);
|
||||||
|
|
||||||
// Don't try to reassemble, that's doomed.
|
// Don't try to reassemble, that's doomed.
|
||||||
// Discard all except the first fragment (which
|
// Discard all except the first fragment (which
|
||||||
// is useful in analyzing header-only traces)
|
// is useful in analyzing header-only traces)
|
||||||
if ( ip_hdr->FragOffset() != 0 )
|
if ( packet->ip_hdr->FragOffset() != 0 )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
f = detail::fragment_mgr->NextFragment(run_state::processing_start_time, ip_hdr,
|
f = detail::fragment_mgr->NextFragment(run_state::processing_start_time, packet->ip_hdr,
|
||||||
packet->data + packet->hdr_size);
|
packet->data + packet->hdr_size);
|
||||||
IP_Hdr* ih = f->ReassembledPkt();
|
std::unique_ptr<IP_Hdr> ih = f->ReassembledPkt();
|
||||||
|
|
||||||
if ( ! ih )
|
if ( ! ih )
|
||||||
// It didn't reassemble into anything yet.
|
// It didn't reassemble into anything yet.
|
||||||
return true;
|
return true;
|
||||||
|
@ -171,17 +167,15 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
|
|
||||||
// Switch the stored ip header over to the one from the
|
// Switch the stored ip header over to the one from the
|
||||||
// fragmented packet.
|
// fragmented packet.
|
||||||
delete ip_hdr;
|
packet->ip_hdr = std::move(ih);
|
||||||
ip_hdr = ih;
|
|
||||||
|
|
||||||
len = total_len = ip_hdr->TotalLen();
|
len = total_len = packet->ip_hdr->TotalLen();
|
||||||
ip_hdr_len = ip_hdr->HdrLen();
|
ip_hdr_len = packet->ip_hdr->HdrLen();
|
||||||
packet->cap_len = total_len + packet->hdr_size;
|
packet->cap_len = total_len + packet->hdr_size;
|
||||||
packet->ip_hdr = ih;
|
|
||||||
|
|
||||||
if ( ip_hdr_len > total_len )
|
if ( ip_hdr_len > total_len )
|
||||||
{
|
{
|
||||||
sessions->Weird("invalid_IP_header_size", ip_hdr, packet->encap);
|
sessions->Weird("invalid_IP_header_size", packet->ip_hdr.get(), packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,11 +185,11 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
|
|
||||||
// We stop building the chain when seeing IPPROTO_ESP so if it's
|
// We stop building the chain when seeing IPPROTO_ESP so if it's
|
||||||
// there, it's always the last.
|
// there, it's always the last.
|
||||||
if ( ip_hdr->LastHeader() == IPPROTO_ESP )
|
if ( packet->ip_hdr->LastHeader() == IPPROTO_ESP )
|
||||||
{
|
{
|
||||||
packet->dump_packet = true;
|
packet->dump_packet = true;
|
||||||
if ( esp_packet )
|
if ( esp_packet )
|
||||||
event_mgr.Enqueue(esp_packet, ip_hdr->ToPktHdrVal());
|
event_mgr.Enqueue(esp_packet, packet->ip_hdr->ToPktHdrVal());
|
||||||
|
|
||||||
// Can't do more since upper-layer payloads are going to be encrypted.
|
// Can't do more since upper-layer payloads are going to be encrypted.
|
||||||
return true;
|
return true;
|
||||||
|
@ -204,20 +198,20 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
#ifdef ENABLE_MOBILE_IPV6
|
#ifdef ENABLE_MOBILE_IPV6
|
||||||
// We stop building the chain when seeing IPPROTO_MOBILITY so it's always
|
// We stop building the chain when seeing IPPROTO_MOBILITY so it's always
|
||||||
// last if present.
|
// last if present.
|
||||||
if ( ip_hdr->LastHeader() == IPPROTO_MOBILITY )
|
if ( packet->ip_hdr->LastHeader() == IPPROTO_MOBILITY )
|
||||||
{
|
{
|
||||||
dump_this_packet = true;
|
dump_this_packet = true;
|
||||||
|
|
||||||
if ( ! ignore_checksums && mobility_header_checksum(ip_hdr) != 0xffff )
|
if ( ! ignore_checksums && mobility_header_checksum(packet->ip_hdr) != 0xffff )
|
||||||
{
|
{
|
||||||
sessions->Weird("bad_MH_checksum", packet, packet->encap);
|
sessions->Weird("bad_MH_checksum", packet, packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mobile_ipv6_message )
|
if ( mobile_ipv6_message )
|
||||||
event_mgr.Enqueue(mobile_ipv6_message, ip_hdr->ToPktHdrVal());
|
event_mgr.Enqueue(mobile_ipv6_message, packet->ip_hdr->ToPktHdrVal());
|
||||||
|
|
||||||
if ( ip_hdr->NextProto() != IPPROTO_NONE )
|
if ( packet->ip_hdr->NextProto() != IPPROTO_NONE )
|
||||||
sessions->Weird("mobility_piggyback", packet, packet->encap);
|
sessions->Weird("mobility_piggyback", packet, packet->encap);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -226,7 +220,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
|
|
||||||
// Set the data pointer to match the payload from the IP header. This makes sure that it's also pointing
|
// Set the data pointer to match the payload from the IP header. This makes sure that it's also pointing
|
||||||
// at the reassembled data for a fragmented packet.
|
// at the reassembled data for a fragmented packet.
|
||||||
data = ip_hdr->Payload();
|
data = packet->ip_hdr->Payload();
|
||||||
len -= ip_hdr_len;
|
len -= ip_hdr_len;
|
||||||
|
|
||||||
// Session analysis assumes that the header size stored in the packet does not include the IP header
|
// Session analysis assumes that the header size stored in the packet does not include the IP header
|
||||||
|
@ -236,7 +230,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
// change, but for now we leave it as it is.
|
// change, but for now we leave it as it is.
|
||||||
|
|
||||||
bool return_val = true;
|
bool return_val = true;
|
||||||
int proto = ip_hdr->NextProto();
|
int proto = packet->ip_hdr->NextProto();
|
||||||
|
|
||||||
packet->proto = proto;
|
packet->proto = proto;
|
||||||
|
|
||||||
|
@ -247,7 +241,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
case IPPROTO_ICMPV6:
|
case IPPROTO_ICMPV6:
|
||||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.",
|
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.",
|
||||||
GetAnalyzerName(), proto);
|
GetAnalyzerName(), proto);
|
||||||
sessions->DoNextPacket(run_state::processing_start_time, packet, ip_hdr);
|
sessions->DoNextPacket(run_state::processing_start_time, packet);
|
||||||
break;
|
break;
|
||||||
case IPPROTO_NONE:
|
case IPPROTO_NONE:
|
||||||
// If the packet is encapsulated in Teredo, then it was a bubble and
|
// If the packet is encapsulated in Teredo, then it was a bubble and
|
||||||
|
|
|
@ -26,18 +26,16 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_Hdr* ip_hdr = packet->ip_hdr;
|
|
||||||
|
|
||||||
if ( ! BifConst::Tunnel::enable_ip )
|
if ( ! BifConst::Tunnel::enable_ip )
|
||||||
{
|
{
|
||||||
sessions->Weird("IP_tunnel", ip_hdr, packet->encap);
|
sessions->Weird("IP_tunnel", packet->ip_hdr.get(), packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( packet->encap &&
|
if ( packet->encap &&
|
||||||
packet->encap->Depth() >= BifConst::Tunnel::max_depth )
|
packet->encap->Depth() >= BifConst::Tunnel::max_depth )
|
||||||
{
|
{
|
||||||
sessions->Weird("exceeded_tunnel_max_depth", ip_hdr, packet->encap);
|
sessions->Weird("exceeded_tunnel_max_depth", packet->ip_hdr.get(), packet->encap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,11 +51,11 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa
|
||||||
// Check for a valid inner packet first.
|
// Check for a valid inner packet first.
|
||||||
int result = sessions->ParseIPPacket(len, data, proto, inner);
|
int result = sessions->ParseIPPacket(len, data, proto, inner);
|
||||||
if ( result == -2 )
|
if ( result == -2 )
|
||||||
sessions->Weird("invalid_inner_IP_version", ip_hdr, packet->encap);
|
sessions->Weird("invalid_inner_IP_version", packet->ip_hdr.get(), packet->encap);
|
||||||
else if ( result < 0 )
|
else if ( result < 0 )
|
||||||
sessions->Weird("truncated_inner_IP", ip_hdr, packet->encap);
|
sessions->Weird("truncated_inner_IP", packet->ip_hdr.get(), packet->encap);
|
||||||
else if ( result > 0 )
|
else if ( result > 0 )
|
||||||
sessions->Weird("inner_IP_payload_length_mismatch", ip_hdr, packet->encap);
|
sessions->Weird("inner_IP_payload_length_mismatch", packet->ip_hdr.get(), packet->encap);
|
||||||
|
|
||||||
if ( result != 0 )
|
if ( result != 0 )
|
||||||
{
|
{
|
||||||
|
@ -70,16 +68,16 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa
|
||||||
// by the pair of IP addresses, so that we can always associate the
|
// by the pair of IP addresses, so that we can always associate the
|
||||||
// same UID with it.
|
// same UID with it.
|
||||||
IPPair tunnel_idx;
|
IPPair tunnel_idx;
|
||||||
if ( ip_hdr->SrcAddr() < ip_hdr->DstAddr() )
|
if ( packet->ip_hdr->SrcAddr() < packet->ip_hdr->DstAddr() )
|
||||||
tunnel_idx = IPPair(ip_hdr->SrcAddr(), ip_hdr->DstAddr());
|
tunnel_idx = IPPair(packet->ip_hdr->SrcAddr(), packet->ip_hdr->DstAddr());
|
||||||
else
|
else
|
||||||
tunnel_idx = IPPair(ip_hdr->DstAddr(), ip_hdr->SrcAddr());
|
tunnel_idx = IPPair(packet->ip_hdr->DstAddr(), packet->ip_hdr->SrcAddr());
|
||||||
|
|
||||||
IPTunnelMap::iterator tunnel_it = ip_tunnels.find(tunnel_idx);
|
IPTunnelMap::iterator tunnel_it = ip_tunnels.find(tunnel_idx);
|
||||||
|
|
||||||
if ( tunnel_it == ip_tunnels.end() )
|
if ( tunnel_it == ip_tunnels.end() )
|
||||||
{
|
{
|
||||||
EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr(),
|
EncapsulatingConn ec(packet->ip_hdr->SrcAddr(), packet->ip_hdr->DstAddr(),
|
||||||
tunnel_type);
|
tunnel_type);
|
||||||
ip_tunnels[tunnel_idx] = TunnelActivity(ec, run_state::network_time);
|
ip_tunnels[tunnel_idx] = TunnelActivity(ec, run_state::network_time);
|
||||||
zeek::detail::timer_mgr->Add(new detail::IPTunnelTimer(run_state::network_time, tunnel_idx, this));
|
zeek::detail::timer_mgr->Add(new detail::IPTunnelTimer(run_state::network_time, tunnel_idx, this));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue