mirror of
https://github.com/zeek/zeek.git
synced 2025-10-06 16:48:19 +00:00
Tunnel decapsulation bugfix when FlipRoles is called.
If FlipRoles() is called the conn_val in Conn.cc gets Unref'ed and thus my tunnel_partent RecordVal was lost. Fixing this.
This commit is contained in:
parent
ae1eb5379b
commit
08dc84a250
5 changed files with 64 additions and 37 deletions
|
@ -15,6 +15,7 @@
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "PIA.h"
|
#include "PIA.h"
|
||||||
#include "binpac.h"
|
#include "binpac.h"
|
||||||
|
#include "TunnelHandler.h"
|
||||||
|
|
||||||
HashKey* ConnID::BuildConnKey() const
|
HashKey* ConnID::BuildConnKey() const
|
||||||
{
|
{
|
||||||
|
@ -139,7 +140,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, RecordVal *arg_tunnel_parent)
|
Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, TunnelParent* arg_tunnel_parent)
|
||||||
{
|
{
|
||||||
sessions = s;
|
sessions = s;
|
||||||
key = k;
|
key = k;
|
||||||
|
@ -209,6 +210,9 @@ Connection::~Connection()
|
||||||
Unref(conn_val);
|
Unref(conn_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( tunnel_parent )
|
||||||
|
delete tunnel_parent;
|
||||||
|
|
||||||
delete key;
|
delete key;
|
||||||
delete root_analyzer;
|
delete root_analyzer;
|
||||||
delete conn_timer_mgr;
|
delete conn_timer_mgr;
|
||||||
|
@ -372,7 +376,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)));
|
||||||
conn_val->Assign(10, tunnel_parent);
|
if ( tunnel_parent )
|
||||||
|
conn_val->Assign(10, tunnel_parent->GetRecordVal());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( root_analyzer )
|
if ( root_analyzer )
|
||||||
|
|
|
@ -23,6 +23,7 @@ class RuleHdrTest;
|
||||||
class Specific_RE_Matcher;
|
class Specific_RE_Matcher;
|
||||||
class TransportLayerAnalyzer;
|
class TransportLayerAnalyzer;
|
||||||
class RuleEndpointState;
|
class RuleEndpointState;
|
||||||
|
class TunnelParent;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NUL_IN_LINE,
|
NUL_IN_LINE,
|
||||||
|
@ -86,7 +87,7 @@ class Analyzer;
|
||||||
|
|
||||||
class Connection : public BroObj {
|
class Connection : public BroObj {
|
||||||
public:
|
public:
|
||||||
Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, RecordVal *arg_tunnel_parent);
|
Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, TunnelParent *arg_tunnel_parent);
|
||||||
virtual ~Connection();
|
virtual ~Connection();
|
||||||
|
|
||||||
// Invoked when connection is about to be removed. Use Ref(this)
|
// Invoked when connection is about to be removed. Use Ref(this)
|
||||||
|
@ -335,7 +336,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
|
||||||
RecordVal* tunnel_parent; // nil if not tunneled
|
TunnelParent* tunnel_parent; // nil if not tunneled
|
||||||
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;
|
||||||
|
|
|
@ -1018,11 +1018,8 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
|
||||||
int src_h = ntohs(id->src_port);
|
int src_h = ntohs(id->src_port);
|
||||||
int dst_h = ntohs(id->dst_port);
|
int dst_h = ntohs(id->dst_port);
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
RecordVal *tunnel_parent = 0;
|
TunnelParent *tunnel_parent = 0;
|
||||||
|
|
||||||
if ( tunnel_info )
|
|
||||||
tunnel_parent = tunnel_info->GetRecordVal();
|
|
||||||
|
|
||||||
// Hmm... This is not great.
|
// Hmm... This is not great.
|
||||||
TransportProto tproto;
|
TransportProto tproto;
|
||||||
switch ( proto ) {
|
switch ( proto ) {
|
||||||
|
@ -1068,6 +1065,9 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
|
||||||
id = &flip_id;
|
id = &flip_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( tunnel_info )
|
||||||
|
tunnel_parent = new TunnelParent(&(tunnel_info->parent));
|
||||||
|
|
||||||
Connection* conn = new Connection(this, k, t, id, tunnel_parent);
|
Connection* conn = new Connection(this, k, t, id, tunnel_parent);
|
||||||
conn->SetTransport(tproto);
|
conn->SetTransport(tproto);
|
||||||
dpm->BuildInitialAnalyzerTree(tproto, conn, data);
|
dpm->BuildInitialAnalyzerTree(tproto, conn, data);
|
||||||
|
|
|
@ -54,7 +54,7 @@ TunnelInfo* TunnelHandler::DecapsulateTunnel(const IP_Hdr *ip_hdr, int len, int
|
||||||
// TODO: check if IP6 header makes sense
|
// TODO: check if IP6 header makes sense
|
||||||
tunnel_info = new TunnelInfo();
|
tunnel_info = new TunnelInfo();
|
||||||
tunnel_info->child = new IP_Hdr((const struct ip6_hdr*)ip_hdr->Payload());
|
tunnel_info->child = new IP_Hdr((const struct ip6_hdr*)ip_hdr->Payload());
|
||||||
tunnel_info->tunneltype = BifEnum::Tunnel::IP6_IN_IP;
|
tunnel_info->parent.tunneltype = BifEnum::Tunnel::IP6_IN_IP;
|
||||||
tunnel_info->hdr_len = tunnel_info->child->HdrLen();
|
tunnel_info->hdr_len = tunnel_info->child->HdrLen();
|
||||||
tunnel_info->SetParentIPs(ip_hdr);
|
tunnel_info->SetParentIPs(ip_hdr);
|
||||||
return tunnel_info;
|
return tunnel_info;
|
||||||
|
@ -137,7 +137,7 @@ TunnelInfo* TunnelHandler::HandleUDP(const IP_Hdr *ip_hdr, int len, int caplen)
|
||||||
{
|
{
|
||||||
TunnelInfo *tunnel_info = new TunnelInfo();
|
TunnelInfo *tunnel_info = new TunnelInfo();
|
||||||
tunnel_info->child = cand_ip_hdr;
|
tunnel_info->child = cand_ip_hdr;
|
||||||
tunnel_info->tunneltype = tunneltype;
|
tunnel_info->parent.tunneltype = tunneltype;
|
||||||
tunnel_info->SetParentIPs(ip_hdr);
|
tunnel_info->SetParentIPs(ip_hdr);
|
||||||
tunnel_info->SetParentPorts(uh);
|
tunnel_info->SetParentPorts(uh);
|
||||||
tunnel_info->hdr_len = hdr_len + cand_ip_hdr->HdrLen();
|
tunnel_info->hdr_len = hdr_len + cand_ip_hdr->HdrLen();
|
||||||
|
|
|
@ -4,37 +4,29 @@
|
||||||
#define tunnelhandler_h
|
#define tunnelhandler_h
|
||||||
|
|
||||||
#include <netinet/udp.h>
|
#include <netinet/udp.h>
|
||||||
|
#include "net_util.h"
|
||||||
#include "IP.h"
|
#include "IP.h"
|
||||||
#include "Conn.h"
|
#include "Conn.h"
|
||||||
#include "Sessions.h"
|
#include "Sessions.h"
|
||||||
#include "Val.h"
|
#include "Val.h"
|
||||||
|
|
||||||
|
class TunnelParent {
|
||||||
class TunnelInfo {
|
|
||||||
public:
|
public:
|
||||||
TunnelInfo()
|
TunnelParent()
|
||||||
{
|
{
|
||||||
child = 0;
|
|
||||||
tunneltype = BifEnum::Tunnel::NONE;
|
tunneltype = BifEnum::Tunnel::NONE;
|
||||||
hdr_len = 0;
|
src_port = dst_port = 0;
|
||||||
parent.src_addr = parent.dst_addr = 0;
|
for (int i=0; i<NUM_ADDR_WORDS; i++)
|
||||||
parent.src_port = parent.dst_port = 0;
|
src_addr[i] = dst_addr[i] = 0;
|
||||||
parent.is_one_way = 0;
|
|
||||||
}
|
|
||||||
~TunnelInfo()
|
|
||||||
{
|
|
||||||
if (child) delete child;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetParentIPs(const IP_Hdr *ip_hdr)
|
TunnelParent (TunnelParent *other)
|
||||||
{
|
{
|
||||||
parent.src_addr = ip_hdr->SrcAddr();
|
tunneltype = other->tunneltype;
|
||||||
parent.dst_addr = ip_hdr->DstAddr();
|
copy_addr(other->src_addr, src_addr);
|
||||||
}
|
copy_addr(other->dst_addr, dst_addr);
|
||||||
void SetParentPorts(const struct udphdr *uh)
|
src_port = other->src_port;
|
||||||
{
|
dst_port = other->dst_port;
|
||||||
parent.src_port = uh->uh_sport;
|
|
||||||
parent.dst_port = uh->uh_dport;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordVal* GetRecordVal() const
|
RecordVal* GetRecordVal() const
|
||||||
|
@ -51,21 +43,50 @@ public:
|
||||||
} // end switch
|
} // end switch
|
||||||
|
|
||||||
RecordVal* id_val = new RecordVal(conn_id);
|
RecordVal* id_val = new RecordVal(conn_id);
|
||||||
id_val->Assign(0, new AddrVal(parent.src_addr));
|
id_val->Assign(0, new AddrVal(src_addr));
|
||||||
id_val->Assign(1, new PortVal(ntohs(parent.src_port), tproto));
|
id_val->Assign(1, new PortVal(ntohs(src_port), tproto));
|
||||||
id_val->Assign(2, new AddrVal(parent.dst_addr));
|
id_val->Assign(2, new AddrVal(dst_addr));
|
||||||
id_val->Assign(3, new PortVal(ntohs(parent.dst_port), tproto));
|
id_val->Assign(3, new PortVal(ntohs(dst_port), tproto));
|
||||||
rv->Assign(0, id_val);
|
rv->Assign(0, id_val);
|
||||||
rv->Assign(1, new EnumVal(tunneltype, BifType::Enum::Tunnel::Tunneltype));
|
rv->Assign(1, new EnumVal(tunneltype, BifType::Enum::Tunnel::Tunneltype));
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_Hdr *child;
|
uint32 src_addr[NUM_ADDR_WORDS];
|
||||||
ConnID parent;
|
uint32 dst_addr[NUM_ADDR_WORDS];
|
||||||
int hdr_len;
|
uint16 src_port;
|
||||||
|
uint16 dst_port;
|
||||||
BifEnum::Tunnel::Tunneltype tunneltype;
|
BifEnum::Tunnel::Tunneltype tunneltype;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TunnelInfo {
|
||||||
|
public:
|
||||||
|
TunnelInfo()
|
||||||
|
{
|
||||||
|
child = 0;
|
||||||
|
hdr_len = 0;
|
||||||
|
}
|
||||||
|
~TunnelInfo()
|
||||||
|
{
|
||||||
|
if (child) delete child;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetParentIPs(const IP_Hdr *ip_hdr)
|
||||||
|
{
|
||||||
|
copy_addr(ip_hdr->SrcAddr(), parent.src_addr);
|
||||||
|
copy_addr(ip_hdr->DstAddr(), parent.dst_addr);
|
||||||
|
}
|
||||||
|
void SetParentPorts(const struct udphdr *uh)
|
||||||
|
{
|
||||||
|
parent.src_port = uh->uh_sport;
|
||||||
|
parent.dst_port = uh->uh_dport;
|
||||||
|
}
|
||||||
|
|
||||||
|
IP_Hdr *child;
|
||||||
|
TunnelParent parent;
|
||||||
|
int hdr_len;
|
||||||
|
};
|
||||||
|
|
||||||
class TunnelHandler {
|
class TunnelHandler {
|
||||||
public:
|
public:
|
||||||
TunnelHandler(NetSessions *arg_s);
|
TunnelHandler(NetSessions *arg_s);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue