mirror of
https://github.com/zeek/zeek.git
synced 2025-10-11 11:08:20 +00:00
Store the ip header in the packet after processing, reuse other places
This commit is contained in:
parent
7d2c35174f
commit
665d0d9814
5 changed files with 51 additions and 58 deletions
|
@ -71,7 +71,6 @@ FragReassembler::~FragReassembler()
|
||||||
{
|
{
|
||||||
DeleteTimer();
|
DeleteTimer();
|
||||||
delete [] proto_hdr;
|
delete [] proto_hdr;
|
||||||
delete reassembled_pkt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
|
void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
|
||||||
|
|
|
@ -95,23 +95,8 @@ void VXLAN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
|
||||||
len -= pkt.hdr_size;
|
len -= pkt.hdr_size;
|
||||||
caplen -= pkt.hdr_size;
|
caplen -= pkt.hdr_size;
|
||||||
|
|
||||||
IP_Hdr* inner_hdr = nullptr;
|
if ( ! pkt.ip_hdr )
|
||||||
int res = 0;
|
|
||||||
|
|
||||||
switch ( pkt.l3_proto ) {
|
|
||||||
case L3_IPV4:
|
|
||||||
res = sessions->ParseIPPacket(len, data, IPPROTO_IPV4, inner_hdr);
|
|
||||||
break;
|
|
||||||
case L3_IPV6:
|
|
||||||
res = sessions->ParseIPPacket(len, data, IPPROTO_IPV6, inner_hdr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( res < 0 )
|
|
||||||
{
|
{
|
||||||
delete inner_hdr;
|
|
||||||
if ( delete_outer )
|
if ( delete_outer )
|
||||||
delete outer;
|
delete outer;
|
||||||
|
|
||||||
|
@ -124,7 +109,7 @@ void VXLAN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
|
||||||
|
|
||||||
if ( vxlan_packet )
|
if ( vxlan_packet )
|
||||||
Conn()->EnqueueEvent(vxlan_packet, nullptr, ConnVal(),
|
Conn()->EnqueueEvent(vxlan_packet, nullptr, ConnVal(),
|
||||||
inner_hdr->ToPktHdrVal(), val_mgr->Count(vni));
|
pkt.ip_hdr->ToPktHdrVal(), val_mgr->Count(vni));
|
||||||
|
|
||||||
if ( delete_outer )
|
if ( delete_outer )
|
||||||
delete outer;
|
delete outer;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "iosource/Manager.h"
|
#include "iosource/Manager.h"
|
||||||
#include "packet_analysis/Manager.h"
|
#include "packet_analysis/Manager.h"
|
||||||
#include "Var.h"
|
#include "Var.h"
|
||||||
|
#include "TunnelEncapsulation.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <pcap.h>
|
#include <pcap.h>
|
||||||
|
@ -61,6 +62,16 @@ void Packet::Init(int arg_link_type, pkt_timeval *arg_ts, uint32_t arg_caplen,
|
||||||
l3_proto = L3_UNKNOWN;
|
l3_proto = L3_UNKNOWN;
|
||||||
l3_checksummed = false;
|
l3_checksummed = false;
|
||||||
|
|
||||||
|
delete encap;
|
||||||
|
encap = nullptr;
|
||||||
|
delete ip_hdr;
|
||||||
|
ip_hdr = nullptr;
|
||||||
|
|
||||||
|
proto = -1;
|
||||||
|
tunnel_type = BifEnum::Tunnel::IP;
|
||||||
|
gre_version = -1;
|
||||||
|
gre_link_type = DLT_RAW;
|
||||||
|
|
||||||
if ( data )
|
if ( data )
|
||||||
{
|
{
|
||||||
// From here we assume that layer 2 is valid. If the packet analysis fails,
|
// From here we assume that layer 2 is valid. If the packet analysis fails,
|
||||||
|
@ -69,6 +80,14 @@ void Packet::Init(int arg_link_type, pkt_timeval *arg_ts, uint32_t arg_caplen,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Packet::~Packet()
|
||||||
|
{
|
||||||
|
if ( copy )
|
||||||
|
delete [] data;
|
||||||
|
|
||||||
|
delete ip_hdr;
|
||||||
|
}
|
||||||
|
|
||||||
const IP_Hdr Packet::IP() const
|
const IP_Hdr Packet::IP() const
|
||||||
{
|
{
|
||||||
return IP_Hdr((struct ip *) (data + hdr_size), false);
|
return IP_Hdr((struct ip *) (data + hdr_size), false);
|
||||||
|
@ -141,18 +160,10 @@ RecordValPtr Packet::ToRawPktHdrVal() const
|
||||||
|
|
||||||
pkt_hdr->Assign(0, std::move(l2_hdr));
|
pkt_hdr->Assign(0, std::move(l2_hdr));
|
||||||
|
|
||||||
if ( l3_proto == L3_IPV4 )
|
if ( l3_proto == L3_IPV4 || l3_proto == L3_IPV6 )
|
||||||
{
|
// Packet analysis will have stored the IP header in the packet, so we can use
|
||||||
IP_Hdr ip_hdr((const struct ip*)(data + hdr_size), false);
|
// that to build the output.
|
||||||
return ip_hdr.ToPktHdrVal(std::move(pkt_hdr), 1);
|
return ip_hdr->ToPktHdrVal(std::move(pkt_hdr), 1);
|
||||||
}
|
|
||||||
|
|
||||||
else if ( l3_proto == L3_IPV6 )
|
|
||||||
{
|
|
||||||
IP_Hdr ip6_hdr((const struct ip6_hdr*)(data + hdr_size), false, cap_len);
|
|
||||||
return ip6_hdr.ToPktHdrVal(std::move(pkt_hdr), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else
|
||||||
return pkt_hdr;
|
return pkt_hdr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,11 +88,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Destructor.
|
* Destructor.
|
||||||
*/
|
*/
|
||||||
~Packet()
|
~Packet();
|
||||||
{
|
|
||||||
if ( copy )
|
|
||||||
delete [] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (Re-)initialize from packet data.
|
* (Re-)initialize from packet data.
|
||||||
|
@ -135,6 +131,9 @@ public:
|
||||||
[[deprecated("Remove in v4.1. Use ToRawPktHdrval() instead.")]]
|
[[deprecated("Remove in v4.1. Use ToRawPktHdrval() instead.")]]
|
||||||
RecordVal* BuildPktHdrVal() const;
|
RecordVal* BuildPktHdrVal() const;
|
||||||
|
|
||||||
|
// Wrapper to generate a packet-level weird. Has to be public for llanalyzers to use it.
|
||||||
|
void Weird(const char* name, const EncapsulationStack* encap = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximal length of a layer 2 address.
|
* Maximal length of a layer 2 address.
|
||||||
*/
|
*/
|
||||||
|
@ -227,9 +226,6 @@ public:
|
||||||
int gre_version = -1;
|
int gre_version = -1;
|
||||||
int gre_link_type = DLT_RAW;
|
int gre_link_type = DLT_RAW;
|
||||||
|
|
||||||
// Wrapper to generate a packet-level weird. Has to be public for llanalyzers to use it.
|
|
||||||
void Weird(const char* name, const EncapsulationStack* encap = nullptr);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Renders an MAC address into its ASCII representation.
|
// Renders an MAC address into its ASCII representation.
|
||||||
ValPtr FmtEUI48(const u_char* mac) const;
|
ValPtr FmtEUI48(const u_char* mac) const;
|
||||||
|
|
|
@ -51,10 +51,10 @@ 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.
|
||||||
std::unique_ptr<IP_Hdr> ip_hdr = nullptr;
|
IP_Hdr* ip_hdr = nullptr;
|
||||||
if ( protocol == 4 )
|
if ( protocol == 4 )
|
||||||
{
|
{
|
||||||
ip_hdr = std::make_unique<IP_Hdr>(ip, false);
|
ip_hdr = new IP_Hdr(ip, false);
|
||||||
packet->l3_proto = L3_IPV4;
|
packet->l3_proto = L3_IPV4;
|
||||||
}
|
}
|
||||||
else if ( protocol == 6 )
|
else if ( protocol == 6 )
|
||||||
|
@ -65,7 +65,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip_hdr = std::make_unique<IP_Hdr>((const struct ip6_hdr*) data, false, len);
|
ip_hdr = new IP_Hdr((const struct ip6_hdr*) data, false, len);
|
||||||
packet->l3_proto = L3_IPV6;
|
packet->l3_proto = L3_IPV6;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -74,6 +74,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
|
||||||
|
// 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();
|
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
|
||||||
|
@ -98,13 +102,13 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
uint16_t ip_hdr_len = ip_hdr->HdrLen();
|
uint16_t ip_hdr_len = ip_hdr->HdrLen();
|
||||||
if ( ip_hdr_len > total_len )
|
if ( ip_hdr_len > total_len )
|
||||||
{
|
{
|
||||||
sessions->Weird("invalid_IP_header_size", ip_hdr.get(), encapsulation);
|
sessions->Weird("invalid_IP_header_size", ip_hdr, encapsulation);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ip_hdr_len > len )
|
if ( ip_hdr_len > len )
|
||||||
{
|
{
|
||||||
sessions->Weird("internally_truncated_header", ip_hdr.get(), encapsulation);
|
sessions->Weird("internally_truncated_header", ip_hdr, encapsulation);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +131,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.get(), total_len, len) )
|
if ( packet_filter && packet_filter->Match(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 &&
|
||||||
|
@ -137,7 +141,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( discarder && discarder->NextPacket(ip_hdr.get(), total_len, len) )
|
if ( discarder && discarder->NextPacket(ip_hdr, total_len, len) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
detail::FragReassembler* f = nullptr;
|
detail::FragReassembler* f = nullptr;
|
||||||
|
@ -148,7 +152,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
|
|
||||||
if ( len < total_len )
|
if ( len < total_len )
|
||||||
{
|
{
|
||||||
sessions->Weird("incompletely_captured_fragment", ip_hdr.get(), encapsulation);
|
sessions->Weird("incompletely_captured_fragment", ip_hdr, encapsulation);
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -158,7 +162,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
f = detail::fragment_mgr->NextFragment(run_state::processing_start_time, ip_hdr.get(), packet->data + packet->hdr_size);
|
f = detail::fragment_mgr->NextFragment(run_state::processing_start_time, ip_hdr, packet->data + packet->hdr_size);
|
||||||
IP_Hdr* ih = f->ReassembledPkt();
|
IP_Hdr* ih = f->ReassembledPkt();
|
||||||
if ( ! ih )
|
if ( ! ih )
|
||||||
// It didn't reassemble into anything yet.
|
// It didn't reassemble into anything yet.
|
||||||
|
@ -166,16 +170,19 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
|
|
||||||
ip4 = ih->IP4_Hdr();
|
ip4 = ih->IP4_Hdr();
|
||||||
|
|
||||||
// Delete the old ip_hdr and replace it with this one.
|
// Switch the stored ip header over to the one from the
|
||||||
ip_hdr.reset(ih);
|
// fragmented packet.
|
||||||
|
delete ip_hdr;
|
||||||
|
ip_hdr = ih;
|
||||||
|
|
||||||
len = total_len = ip_hdr->TotalLen();
|
len = total_len = ip_hdr->TotalLen();
|
||||||
ip_hdr_len = ip_hdr->HdrLen();
|
ip_hdr_len = 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.get(), encapsulation);
|
sessions->Weird("invalid_IP_header_size", ip_hdr, encapsulation);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,12 +239,14 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
bool return_val = true;
|
bool return_val = true;
|
||||||
int proto = ip_hdr->NextProto();
|
int proto = ip_hdr->NextProto();
|
||||||
|
|
||||||
|
packet->proto = proto;
|
||||||
|
|
||||||
switch ( proto ) {
|
switch ( proto ) {
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP:
|
||||||
case IPPROTO_ICMP:
|
case IPPROTO_ICMP:
|
||||||
case IPPROTO_ICMPV6:
|
case IPPROTO_ICMPV6:
|
||||||
sessions->DoNextPacket(run_state::processing_start_time, packet, ip_hdr.get(), encapsulation);
|
sessions->DoNextPacket(run_state::processing_start_time, packet, ip_hdr, encapsulation);
|
||||||
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
|
||||||
|
@ -251,8 +260,6 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// The tunnel analyzer needs this data.
|
|
||||||
packet->ip_hdr = ip_hdr.get();
|
|
||||||
packet->proto = proto;
|
packet->proto = proto;
|
||||||
|
|
||||||
// For everything else, pass it on to another analyzer. If there's no one to handle that,
|
// For everything else, pass it on to another analyzer. If there's no one to handle that,
|
||||||
|
@ -262,12 +269,7 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( f )
|
if ( f )
|
||||||
{
|
|
||||||
// If this was a fragment, we need to release the pointer here so that it doesn't get
|
|
||||||
// deleted. Deleting this one will be the responsibility of the fragment tracker.
|
|
||||||
ip_hdr.release();
|
|
||||||
f->DeleteTimer();
|
f->DeleteTimer();
|
||||||
}
|
|
||||||
|
|
||||||
return return_val;
|
return return_val;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue