mirror of
https://github.com/zeek/zeek.git
synced 2025-10-07 09:08:20 +00:00
Tunnel support performance optimization.
Looks better to allocate Encapsulation objects on-demand when tunnels are discovered rather than always have an automatic, empty one for every packet.
This commit is contained in:
parent
47c2fda88e
commit
9851591317
7 changed files with 110 additions and 65 deletions
37
src/Conn.cc
37
src/Conn.cc
|
@ -113,7 +113,7 @@ unsigned int Connection::external_connections = 0;
|
||||||
IMPLEMENT_SERIAL(Connection, SER_CONNECTION);
|
IMPLEMENT_SERIAL(Connection, SER_CONNECTION);
|
||||||
|
|
||||||
Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
|
Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
|
||||||
uint32 flow, const Encapsulation& arg_encap)
|
uint32 flow, const Encapsulation* arg_encap)
|
||||||
{
|
{
|
||||||
sessions = s;
|
sessions = s;
|
||||||
key = k;
|
key = k;
|
||||||
|
@ -161,7 +161,10 @@ Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
|
||||||
|
|
||||||
uid = 0; // Will set later.
|
uid = 0; // Will set later.
|
||||||
|
|
||||||
encapsulation = arg_encap;
|
if ( arg_encap )
|
||||||
|
encapsulation = new Encapsulation(arg_encap);
|
||||||
|
else
|
||||||
|
encapsulation = 0;
|
||||||
|
|
||||||
if ( conn_timer_mgr )
|
if ( conn_timer_mgr )
|
||||||
{
|
{
|
||||||
|
@ -190,12 +193,38 @@ Connection::~Connection()
|
||||||
delete key;
|
delete key;
|
||||||
delete root_analyzer;
|
delete root_analyzer;
|
||||||
delete conn_timer_mgr;
|
delete conn_timer_mgr;
|
||||||
|
delete encapsulation;
|
||||||
|
|
||||||
--current_connections;
|
--current_connections;
|
||||||
if ( conn_timer_mgr )
|
if ( conn_timer_mgr )
|
||||||
--external_connections;
|
--external_connections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Connection::CheckEncapsulation(const Encapsulation* arg_encap)
|
||||||
|
{
|
||||||
|
if ( encapsulation && arg_encap )
|
||||||
|
{
|
||||||
|
if ( *encapsulation != *arg_encap )
|
||||||
|
{
|
||||||
|
Event(tunnel_changed, 0, arg_encap->GetVectorVal());
|
||||||
|
delete encapsulation;
|
||||||
|
encapsulation = new Encapsulation(arg_encap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( encapsulation )
|
||||||
|
{
|
||||||
|
Encapsulation empty;
|
||||||
|
Event(tunnel_changed, 0, empty.GetVectorVal());
|
||||||
|
delete encapsulation;
|
||||||
|
encapsulation = new Encapsulation(arg_encap);
|
||||||
|
}
|
||||||
|
else if ( arg_encap )
|
||||||
|
{
|
||||||
|
Event(tunnel_changed, 0, arg_encap->GetVectorVal());
|
||||||
|
encapsulation = new Encapsulation(arg_encap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Connection::Done()
|
void Connection::Done()
|
||||||
{
|
{
|
||||||
finished = 1;
|
finished = 1;
|
||||||
|
@ -352,8 +381,8 @@ RecordVal* Connection::BuildConnVal()
|
||||||
|
|
||||||
char tmp[20];
|
char tmp[20];
|
||||||
conn_val->Assign(9, new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62)));
|
conn_val->Assign(9, new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62)));
|
||||||
if ( encapsulation.Depth() > 0 )
|
if ( encapsulation && encapsulation->Depth() > 0 )
|
||||||
conn_val->Assign(10, encapsulation.GetVectorVal());
|
conn_val->Assign(10, encapsulation->GetVectorVal());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( root_analyzer )
|
if ( root_analyzer )
|
||||||
|
|
15
src/Conn.h
15
src/Conn.h
|
@ -52,17 +52,10 @@ class Analyzer;
|
||||||
class Connection : public BroObj {
|
class Connection : public BroObj {
|
||||||
public:
|
public:
|
||||||
Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
|
Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
|
||||||
uint32 flow, const Encapsulation& arg_encap);
|
uint32 flow, const Encapsulation* arg_encap);
|
||||||
virtual ~Connection();
|
virtual ~Connection();
|
||||||
|
|
||||||
void CheckEncapsulation(const Encapsulation& arg_encap)
|
void CheckEncapsulation(const Encapsulation* arg_encap);
|
||||||
{
|
|
||||||
if ( encapsulation != arg_encap )
|
|
||||||
{
|
|
||||||
Event(tunnel_changed, 0, arg_encap.GetVectorVal());
|
|
||||||
encapsulation = arg_encap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoked when connection is about to be removed. Use Ref(this)
|
// Invoked when connection is about to be removed. Use Ref(this)
|
||||||
// inside Done to keep the connection object around (though it'll
|
// inside Done to keep the connection object around (though it'll
|
||||||
|
@ -254,7 +247,7 @@ public:
|
||||||
|
|
||||||
uint64 GetUID() const { return uid; }
|
uint64 GetUID() const { return uid; }
|
||||||
|
|
||||||
const Encapsulation& GetEncapsulation() const
|
const Encapsulation* GetEncapsulation() const
|
||||||
{ return encapsulation; }
|
{ return encapsulation; }
|
||||||
|
|
||||||
void CheckFlowLabel(bool is_orig, uint32 flow_label);
|
void CheckFlowLabel(bool is_orig, uint32 flow_label);
|
||||||
|
@ -294,7 +287,7 @@ protected:
|
||||||
double inactivity_timeout;
|
double inactivity_timeout;
|
||||||
RecordVal* conn_val;
|
RecordVal* conn_val;
|
||||||
LoginConn* login_conn; // either nil, or this
|
LoginConn* login_conn; // either nil, or this
|
||||||
Encapsulation encapsulation; // tunnels
|
const Encapsulation* encapsulation; // tunnels
|
||||||
int suppress_event; // suppress certain events to once per conn.
|
int suppress_event; // suppress certain events to once per conn.
|
||||||
|
|
||||||
unsigned int installed_status_timer:1;
|
unsigned int installed_status_timer:1;
|
||||||
|
|
|
@ -179,8 +179,6 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
if ( record_all_packets )
|
if ( record_all_packets )
|
||||||
DumpPacket(hdr, pkt);
|
DumpPacket(hdr, pkt);
|
||||||
|
|
||||||
Encapsulation encapsulation;
|
|
||||||
|
|
||||||
if ( pkt_elem && pkt_elem->IPHdr() )
|
if ( pkt_elem && pkt_elem->IPHdr() )
|
||||||
// Fast path for "normal" IP packets if an IP_Hdr is
|
// Fast path for "normal" IP packets if an IP_Hdr is
|
||||||
// already extracted when doing PacketSort. Otherwise
|
// already extracted when doing PacketSort. Otherwise
|
||||||
|
@ -188,7 +186,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
// difference here is that header extraction in
|
// difference here is that header extraction in
|
||||||
// PacketSort does not generate Weird events.
|
// PacketSort does not generate Weird events.
|
||||||
|
|
||||||
DoNextPacket(t, hdr, pkt_elem->IPHdr(), pkt, hdr_size, encapsulation);
|
DoNextPacket(t, hdr, pkt_elem->IPHdr(), pkt, hdr_size, 0);
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -213,7 +211,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
if ( ip->ip_v == 4 )
|
if ( ip->ip_v == 4 )
|
||||||
{
|
{
|
||||||
IP_Hdr ip_hdr(ip, false);
|
IP_Hdr ip_hdr(ip, false);
|
||||||
DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size, encapsulation);
|
DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( ip->ip_v == 6 )
|
else if ( ip->ip_v == 6 )
|
||||||
|
@ -225,7 +223,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size), false, caplen);
|
IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size), false, caplen);
|
||||||
DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size, encapsulation);
|
DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( ARP_Analyzer::IsARP(pkt, hdr_size) )
|
else if ( ARP_Analyzer::IsARP(pkt, hdr_size) )
|
||||||
|
@ -347,7 +345,7 @@ int NetSessions::CheckConnectionTag(Connection* conn)
|
||||||
|
|
||||||
void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
const IP_Hdr* ip_hdr, const u_char* const pkt,
|
const IP_Hdr* ip_hdr, const u_char* const pkt,
|
||||||
int hdr_size, Encapsulation& encapsulation)
|
int hdr_size, const Encapsulation* encapsulation)
|
||||||
{
|
{
|
||||||
uint32 caplen = hdr->caplen - hdr_size;
|
uint32 caplen = hdr->caplen - hdr_size;
|
||||||
const struct ip* ip4 = ip_hdr->IP4_Hdr();
|
const struct ip* ip4 = ip_hdr->IP4_Hdr();
|
||||||
|
@ -525,23 +523,19 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
case IPPROTO_IPV4:
|
case IPPROTO_IPV4:
|
||||||
case IPPROTO_IPV6:
|
case IPPROTO_IPV6:
|
||||||
{
|
{
|
||||||
if ( encapsulation.Depth() >= BifConst::Tunnel::max_depth )
|
if ( encapsulation &&
|
||||||
|
encapsulation->Depth() >= BifConst::Tunnel::max_depth )
|
||||||
{
|
{
|
||||||
reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), "tunnel_depth");
|
reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), "tunnel_depth");
|
||||||
Remove(f);
|
Remove(f);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_Hdr* inner_ip;
|
Encapsulation* outer = new Encapsulation(encapsulation);
|
||||||
if ( proto == IPPROTO_IPV6 )
|
|
||||||
inner_ip = new IP_Hdr((const struct ip6_hdr*) data, false, caplen);
|
|
||||||
else
|
|
||||||
inner_ip = new IP_Hdr((const struct ip*) data, false);
|
|
||||||
|
|
||||||
struct pcap_pkthdr fake_hdr;
|
|
||||||
fake_hdr.caplen = fake_hdr.len = caplen;
|
|
||||||
fake_hdr.ts = hdr->ts;
|
|
||||||
|
|
||||||
|
// Look up to see if we've already seen this IP tunnel, identified
|
||||||
|
// by the pair of IP addresses, so that we can always associate the
|
||||||
|
// same UID with it.
|
||||||
IPPair tunnel_idx;
|
IPPair tunnel_idx;
|
||||||
if ( ip_hdr->SrcAddr() < ip_hdr->DstAddr() )
|
if ( ip_hdr->SrcAddr() < ip_hdr->DstAddr() )
|
||||||
tunnel_idx = IPPair(ip_hdr->SrcAddr(), ip_hdr->DstAddr());
|
tunnel_idx = IPPair(ip_hdr->SrcAddr(), ip_hdr->DstAddr());
|
||||||
|
@ -555,21 +549,22 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr(),
|
EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr(),
|
||||||
BifEnum::Tunnel::IP);
|
BifEnum::Tunnel::IP);
|
||||||
ip_tunnels[tunnel_idx] = ec;
|
ip_tunnels[tunnel_idx] = ec;
|
||||||
encapsulation.Add(ec);
|
outer->Add(ec);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
encapsulation.Add(it->second);
|
outer->Add(it->second);
|
||||||
|
|
||||||
DoNextPacket(t, &fake_hdr, inner_ip, data, 0, encapsulation);
|
DoNextInnerPacket(t, hdr, caplen, data, proto, outer);
|
||||||
|
|
||||||
delete inner_ip;
|
delete outer;
|
||||||
Remove(f);
|
Remove(f);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPPROTO_NONE:
|
case IPPROTO_NONE:
|
||||||
{
|
{
|
||||||
if ( encapsulation.LastType() == BifEnum::Tunnel::TEREDO )
|
if ( encapsulation &&
|
||||||
|
encapsulation->LastType() == BifEnum::Tunnel::TEREDO )
|
||||||
{
|
{
|
||||||
// TODO: raise bubble packet event
|
// TODO: raise bubble packet event
|
||||||
}
|
}
|
||||||
|
@ -680,6 +675,31 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
|
int caplen, const u_char* pkt, int proto,
|
||||||
|
const Encapsulation* outer_encap)
|
||||||
|
{
|
||||||
|
IP_Hdr* inner_ip = 0;
|
||||||
|
|
||||||
|
if ( proto == IPPROTO_IPV6 )
|
||||||
|
inner_ip = new IP_Hdr((const struct ip6_hdr*) pkt, false, caplen);
|
||||||
|
else if ( proto == IPPROTO_IPV4 )
|
||||||
|
inner_ip = new IP_Hdr((const struct ip*) pkt, false);
|
||||||
|
else
|
||||||
|
reporter->InternalError("Bad IP protocol version in DoNextInnerPacket");
|
||||||
|
|
||||||
|
struct pcap_pkthdr fake_hdr;
|
||||||
|
fake_hdr.caplen = fake_hdr.len = caplen;
|
||||||
|
if ( hdr )
|
||||||
|
fake_hdr.ts = hdr->ts;
|
||||||
|
else
|
||||||
|
fake_hdr.ts.tv_sec = fake_hdr.ts.tv_usec = 0;
|
||||||
|
|
||||||
|
DoNextPacket(t, &fake_hdr, inner_ip, pkt, 0, outer_encap);
|
||||||
|
|
||||||
|
delete inner_ip;
|
||||||
|
}
|
||||||
|
|
||||||
bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen,
|
bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen,
|
||||||
const struct pcap_pkthdr* h, const u_char* p)
|
const struct pcap_pkthdr* h, const u_char* p)
|
||||||
{
|
{
|
||||||
|
@ -1013,7 +1033,7 @@ void NetSessions::GetStats(SessionStats& s) const
|
||||||
|
|
||||||
Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
|
Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
|
||||||
const u_char* data, int proto, uint32 flow_label,
|
const u_char* data, int proto, uint32 flow_label,
|
||||||
const Encapsulation& encapsulation)
|
const Encapsulation* encapsulation)
|
||||||
{
|
{
|
||||||
// FIXME: This should be cleaned up a bit, it's too protocol-specific.
|
// FIXME: This should be cleaned up a bit, it's too protocol-specific.
|
||||||
// But I'm not yet sure what the right abstraction for these things is.
|
// But I'm not yet sure what the right abstraction for these things is.
|
||||||
|
|
|
@ -136,7 +136,10 @@ public:
|
||||||
|
|
||||||
void DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
void DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
const IP_Hdr* ip_hdr, const u_char* const pkt,
|
const IP_Hdr* ip_hdr, const u_char* const pkt,
|
||||||
int hdr_size, Encapsulation& encapsulation);
|
int hdr_size, const Encapsulation* encapsulation);
|
||||||
|
|
||||||
|
void DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, int caplen,
|
||||||
|
const u_char* pkt, int proto, const Encapsulation* outer_encap);
|
||||||
|
|
||||||
unsigned int ConnectionMemoryUsage();
|
unsigned int ConnectionMemoryUsage();
|
||||||
unsigned int ConnectionMemoryUsageConnVals();
|
unsigned int ConnectionMemoryUsageConnVals();
|
||||||
|
@ -150,7 +153,7 @@ protected:
|
||||||
|
|
||||||
Connection* NewConn(HashKey* k, double t, const ConnID* id,
|
Connection* NewConn(HashKey* k, double t, const ConnID* id,
|
||||||
const u_char* data, int proto, uint32 flow_lable,
|
const u_char* data, int proto, uint32 flow_lable,
|
||||||
const Encapsulation& encapsulation);
|
const Encapsulation* encapsulation);
|
||||||
|
|
||||||
// Check whether the tag of the current packet is consistent with
|
// Check whether the tag of the current packet is consistent with
|
||||||
// the given connection. Returns:
|
// the given connection. Returns:
|
||||||
|
|
|
@ -92,7 +92,9 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
|
||||||
{
|
{
|
||||||
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
|
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
|
||||||
|
|
||||||
if ( Conn()->GetEncapsulation().Depth() >= BifConst::Tunnel::max_depth )
|
const Encapsulation* e = Conn()->GetEncapsulation();
|
||||||
|
|
||||||
|
if ( e && e->Depth() >= BifConst::Tunnel::max_depth )
|
||||||
{
|
{
|
||||||
reporter->Weird(Conn(), "tunnel_depth");
|
reporter->Weird(Conn(), "tunnel_depth");
|
||||||
return;
|
return;
|
||||||
|
@ -107,20 +109,15 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_Hdr inner_ip((const struct ip6_hdr*) te.InnerIP(), false, len);
|
|
||||||
|
|
||||||
ProtocolConfirmation();
|
ProtocolConfirmation();
|
||||||
|
|
||||||
// TODO: raise Teredo-specific events
|
// TODO: raise Teredo-specific events
|
||||||
|
|
||||||
struct pcap_pkthdr fake_hdr;
|
Encapsulation* outer = new Encapsulation(e);
|
||||||
fake_hdr.caplen = fake_hdr.len = len;
|
|
||||||
fake_hdr.ts.tv_sec = fake_hdr.ts.tv_usec = 0;
|
|
||||||
|
|
||||||
Encapsulation encap(Conn()->GetEncapsulation());
|
|
||||||
EncapsulatingConn ec(Conn(), BifEnum::Tunnel::TEREDO);
|
EncapsulatingConn ec(Conn(), BifEnum::Tunnel::TEREDO);
|
||||||
encap.Add(ec);
|
outer->Add(ec);
|
||||||
|
|
||||||
sessions->DoNextPacket(network_time, &fake_hdr, &inner_ip, te.InnerIP(), 0,
|
sessions->DoNextInnerPacket(network_time, 0, len, te.InnerIP(),
|
||||||
encap);
|
IPPROTO_IPV6, outer);
|
||||||
|
delete outer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,14 @@ public:
|
||||||
conns = 0;
|
conns = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Encapsulation(const Encapsulation* other)
|
||||||
|
{
|
||||||
|
if ( other && other->conns )
|
||||||
|
conns = new vector<EncapsulatingConn>(*(other->conns));
|
||||||
|
else
|
||||||
|
conns = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Encapsulation& operator=(const Encapsulation& other)
|
Encapsulation& operator=(const Encapsulation& other)
|
||||||
{
|
{
|
||||||
if ( this == &other ) return *this;
|
if ( this == &other ) return *this;
|
||||||
|
|
|
@ -12,8 +12,9 @@ flow AYIYA_Flow
|
||||||
function process_ayiya(pdu: PDU): bool
|
function process_ayiya(pdu: PDU): bool
|
||||||
%{
|
%{
|
||||||
Connection *c = connection()->bro_analyzer()->Conn();
|
Connection *c = connection()->bro_analyzer()->Conn();
|
||||||
|
const Encapsulation* e = c->GetEncapsulation();
|
||||||
|
|
||||||
if ( c->GetEncapsulation().Depth() >= BifConst::Tunnel::max_depth )
|
if ( e && e->Depth() >= BifConst::Tunnel::max_depth )
|
||||||
{
|
{
|
||||||
reporter->Weird(c, "tunnel_depth");
|
reporter->Weird(c, "tunnel_depth");
|
||||||
return false;
|
return false;
|
||||||
|
@ -25,12 +26,8 @@ flow AYIYA_Flow
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_Hdr* inner_ip;
|
if ( ${pdu.next_header} != IPPROTO_IPV6 &&
|
||||||
if ( ${pdu.next_header} == IPPROTO_IPV6 )
|
${pdu.next_header} != IPPROTO_IPV4 )
|
||||||
inner_ip = new IP_Hdr((const struct ip6_hdr*) ${pdu.packet}.data(), false, ${pdu.packet}.length());
|
|
||||||
else if ( ${pdu.next_header} == IPPROTO_IPV4 )
|
|
||||||
inner_ip = new IP_Hdr((const struct ip*) ${pdu.packet}.data(), false);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
reporter->Weird(c, "ayiya_tunnel_non_ip");
|
reporter->Weird(c, "ayiya_tunnel_non_ip");
|
||||||
return false;
|
return false;
|
||||||
|
@ -38,17 +35,15 @@ flow AYIYA_Flow
|
||||||
|
|
||||||
connection()->bro_analyzer()->ProtocolConfirmation();
|
connection()->bro_analyzer()->ProtocolConfirmation();
|
||||||
|
|
||||||
struct pcap_pkthdr fake_hdr;
|
Encapsulation* outer = new Encapsulation(e);
|
||||||
fake_hdr.caplen = fake_hdr.len = ${pdu.packet}.length();
|
|
||||||
fake_hdr.ts.tv_sec = fake_hdr.ts.tv_usec = 0;
|
|
||||||
|
|
||||||
Encapsulation encap(c->GetEncapsulation());
|
|
||||||
EncapsulatingConn ec(c, BifEnum::Tunnel::AYIYA);
|
EncapsulatingConn ec(c, BifEnum::Tunnel::AYIYA);
|
||||||
encap.Add(ec);
|
outer->Add(ec);
|
||||||
|
|
||||||
sessions->DoNextPacket(network_time(), &fake_hdr, inner_ip, ${pdu.packet}.data(), 0, encap);
|
sessions->DoNextInnerPacket(network_time(), 0, ${pdu.packet}.length(),
|
||||||
|
${pdu.packet}.data(), ${pdu.next_header},
|
||||||
|
outer);
|
||||||
|
|
||||||
delete inner_ip;
|
delete outer;
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue