Move SessionManager::ParseIPPacket to IP analyzer's namespace

This commit is contained in:
Tim Wojtulewicz 2021-04-09 15:46:19 -07:00
parent 0c3e3069d0
commit 3e1692676d
10 changed files with 78 additions and 91 deletions

View file

@ -10,6 +10,7 @@
#include "zeek/Frag.h"
#include "zeek/Event.h"
#include "zeek/TunnelEncapsulation.h"
#include "zeek/IPAddr.h"
using namespace zeek::packet_analysis::IP;
@ -260,3 +261,40 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
return return_val;
}
int zeek::packet_analysis::IP::ParsePacket(int caplen, const u_char* const pkt, int proto,
std::unique_ptr<zeek::IP_Hdr>& inner)
{
if ( proto == IPPROTO_IPV6 )
{
if ( caplen < (int)sizeof(struct ip6_hdr) )
return -1;
const struct ip6_hdr* ip6 = (const struct ip6_hdr*) pkt;
inner = std::make_unique<zeek::IP_Hdr>(ip6, false, caplen);
if ( ( ip6->ip6_ctlun.ip6_un2_vfc & 0xF0 ) != 0x60 )
return -2;
}
else if ( proto == IPPROTO_IPV4 )
{
if ( caplen < (int)sizeof(struct ip) )
return -1;
const struct ip* ip4 = (const struct ip*) pkt;
inner = std::make_unique<zeek::IP_Hdr>(ip4, false);
if ( ip4->ip_v != 4 )
return -2;
}
else
{
zeek::reporter->InternalWarning("Bad IP protocol version in IP::ParsePacket");
return -1;
}
if ( (uint32_t)caplen != inner->TotalLen() )
return (uint32_t)caplen < inner->TotalLen() ? -1 : 1;
return 0;
}

View file

@ -32,4 +32,28 @@ private:
zeek::detail::Discarder* discarder = nullptr;
};
/**
* Returns a wrapper IP_Hdr object if \a pkt appears to be a valid IPv4
* or IPv6 header based on whether it's long enough to contain such a header,
* if version given in the header matches the proto argument, and also checks
* that the payload length field of that header matches the actual
* length of \a pkt given by \a caplen.
*
* @param caplen The length of \a pkt in bytes.
* @param pkt The inner IP packet data.
* @param proto Either IPPROTO_IPV6 or IPPROTO_IPV4 to indicate which IP
* protocol \a pkt corresponds to.
* @param inner The inner IP packet wrapper pointer to be allocated/assigned
* if \a pkt looks like a valid IP packet or at least long enough
* to hold an IP header.
* @return 0 If the inner IP packet appeared valid, else -1 if \a caplen
* is greater than the supposed IP packet's payload length field, -2
* if the version of the inner header does not match proto or
* 1 if \a caplen is less than the supposed packet's payload length.
* In the -1 case, \a inner may still be non-null if \a caplen was
* long enough to be an IP header, and \a inner is always non-null
* for other return values.
*/
int ParsePacket(int caplen, const u_char* const pkt, int proto,
std::unique_ptr<IP_Hdr>& inner);
}

View file

@ -4,10 +4,10 @@
#include <pcap.h> // For DLT_ constants
#include "zeek/session/Manager.h"
#include "zeek/RunState.h"
#include "zeek/IP.h"
#include "zeek/TunnelEncapsulation.h"
#include "zeek/packet_analysis/protocol/ip/IP.h"
namespace zeek::packet_analysis::IPTunnel {
@ -45,12 +45,12 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa
BifEnum::Tunnel::Type tunnel_type = packet->tunnel_type;
int gre_link_type = packet->gre_link_type;
IP_Hdr* inner = nullptr;
std::unique_ptr<IP_Hdr> inner = nullptr;
if ( gre_version != 0 )
{
// Check for a valid inner packet first.
int result = session_mgr->ParseIPPacket(len, data, proto, inner);
int result = packet_analysis::IP::ParsePacket(len, data, proto, inner);
if ( result == -2 )
Weird("invalid_inner_IP_version", packet);
else if ( result < 0 )
@ -59,10 +59,7 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa
Weird("inner_IP_payload_length_mismatch", packet);
if ( result != 0 )
{
delete inner;
return false;
}
}
// Look up to see if we've already seen this IP tunnel, identified
@ -100,7 +97,7 @@ bool IPTunnelAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pa
* Handles a packet that contains an IP header directly after the tunnel header.
*/
bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt,
const IP_Hdr* inner,
const std::unique_ptr<IP_Hdr>& inner,
std::shared_ptr<EncapsulationStack> prev,
const EncapsulatingConn& ec)
{
@ -138,8 +135,6 @@ bool IPTunnelAnalyzer::ProcessEncapsulatedPacket(double t, const Packet* pkt,
// Forward the packet back to the IP analyzer.
bool return_val = ForwardPacket(len, data, &p);
delete inner;
return return_val;
}

View file

@ -40,7 +40,7 @@ public:
* @param ec The most-recently found depth of encapsulation.
*/
bool ProcessEncapsulatedPacket(double t, const Packet *pkt,
const IP_Hdr* inner,
const std::unique_ptr<IP_Hdr>& inner,
std::shared_ptr<EncapsulationStack> prev,
const EncapsulatingConn& ec);