mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00

Majority of PLists are now created as automatic/stack objects, rather than on heap and initialized either with the known-capacity reserved upfront or directly from an initializer_list (so there's no wasted slack in the memory that gets allocated for lists containing a fixed/known number of elements). Added versions of the ConnectionEvent/QueueEvent methods that take a val_list by value. Added a move ctor/assign-operator to Plists to allow passing them around without having to copy the underlying array of pointers.
161 lines
3.1 KiB
C++
161 lines
3.1 KiB
C++
// See the file "COPYING" in the main distribution directory for copyright.
|
|
|
|
#include <algorithm>
|
|
|
|
#include "bro-config.h"
|
|
|
|
#include "Net.h"
|
|
#include "Var.h"
|
|
#include "Discard.h"
|
|
|
|
Discarder::Discarder()
|
|
{
|
|
check_ip = internal_func("discarder_check_ip");
|
|
check_tcp = internal_func("discarder_check_tcp");
|
|
check_udp = internal_func("discarder_check_udp");
|
|
check_icmp = internal_func("discarder_check_icmp");
|
|
|
|
discarder_maxlen = static_cast<int>(opt_internal_int("discarder_maxlen"));
|
|
}
|
|
|
|
Discarder::~Discarder()
|
|
{
|
|
}
|
|
|
|
int Discarder::IsActive()
|
|
{
|
|
return check_ip || check_tcp || check_udp || check_icmp;
|
|
}
|
|
|
|
int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
|
|
{
|
|
int discard_packet = 0;
|
|
|
|
if ( check_ip )
|
|
{
|
|
val_list args{ip->BuildPktHdrVal()};
|
|
|
|
try
|
|
{
|
|
discard_packet = check_ip->Call(&args)->AsBool();
|
|
}
|
|
|
|
catch ( InterpreterException& e )
|
|
{
|
|
discard_packet = false;
|
|
}
|
|
|
|
if ( discard_packet )
|
|
return discard_packet;
|
|
}
|
|
|
|
int proto = ip->NextProto();
|
|
if ( proto != IPPROTO_TCP && proto != IPPROTO_UDP &&
|
|
proto != IPPROTO_ICMP )
|
|
// This is not a protocol we understand.
|
|
return 0;
|
|
|
|
// XXX shall we only check the first packet???
|
|
if ( ip->IsFragment() )
|
|
// Never check any fragment.
|
|
return 0;
|
|
|
|
int ip_hdr_len = ip->HdrLen();
|
|
len -= ip_hdr_len; // remove IP header
|
|
caplen -= ip_hdr_len;
|
|
|
|
int is_tcp = (proto == IPPROTO_TCP);
|
|
int is_udp = (proto == IPPROTO_UDP);
|
|
int min_hdr_len = is_tcp ?
|
|
sizeof(struct tcphdr) :
|
|
(is_udp ? sizeof(struct udphdr) : sizeof(struct icmp));
|
|
|
|
if ( len < min_hdr_len || caplen < min_hdr_len )
|
|
// we don't have a complete protocol header
|
|
return 0;
|
|
|
|
// Where the data starts - if this is a protocol we know about,
|
|
// this gets advanced past the transport header.
|
|
const u_char* data = ip->Payload();
|
|
|
|
if ( is_tcp )
|
|
{
|
|
if ( check_tcp )
|
|
{
|
|
const struct tcphdr* tp = (const struct tcphdr*) data;
|
|
int th_len = tp->th_off * 4;
|
|
|
|
val_list args{
|
|
ip->BuildPktHdrVal(),
|
|
BuildData(data, th_len, len, caplen),
|
|
};
|
|
|
|
try
|
|
{
|
|
discard_packet = check_tcp->Call(&args)->AsBool();
|
|
}
|
|
|
|
catch ( InterpreterException& e )
|
|
{
|
|
discard_packet = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
else if ( is_udp )
|
|
{
|
|
if ( check_udp )
|
|
{
|
|
const struct udphdr* up = (const struct udphdr*) data;
|
|
int uh_len = sizeof (struct udphdr);
|
|
|
|
val_list args{
|
|
ip->BuildPktHdrVal(),
|
|
BuildData(data, uh_len, len, caplen),
|
|
};
|
|
|
|
try
|
|
{
|
|
discard_packet = check_udp->Call(&args)->AsBool();
|
|
}
|
|
|
|
catch ( InterpreterException& e )
|
|
{
|
|
discard_packet = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
if ( check_icmp )
|
|
{
|
|
const struct icmp* ih = (const struct icmp*) data;
|
|
|
|
val_list args{ip->BuildPktHdrVal()};
|
|
|
|
try
|
|
{
|
|
discard_packet = check_icmp->Call(&args)->AsBool();
|
|
}
|
|
|
|
catch ( InterpreterException& e )
|
|
{
|
|
discard_packet = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return discard_packet;
|
|
}
|
|
|
|
Val* Discarder::BuildData(const u_char* data, int hdrlen, int len, int caplen)
|
|
{
|
|
len -= hdrlen;
|
|
caplen -= hdrlen;
|
|
data += hdrlen;
|
|
|
|
len = max(min(min(len, caplen), discarder_maxlen), 0);
|
|
|
|
return new StringVal(new BroString(data, len, 1));
|
|
}
|