mirror of
https://github.com/zeek/zeek.git
synced 2025-10-03 23:28:20 +00:00
Adding support to de-capsulate tunnels.
Checkpoint. Decapsulation happens after IP Defragmentation. The "identity" of the enclosing tunnel (the "parent") is added to the connection record of the child (tunneled) connection as an optional field $tunnel_parent.
This commit is contained in:
parent
6c806b0bce
commit
9c388a1809
10 changed files with 183 additions and 17 deletions
|
@ -33,6 +33,7 @@
|
|||
#include "DPM.h"
|
||||
|
||||
#include "PacketSort.h"
|
||||
#include "TunnelHandler.h"
|
||||
|
||||
// These represent NetBIOS services on ephemeral ports. They're numbered
|
||||
// so that we can use a single int to hold either an actual TCP/UDP server
|
||||
|
@ -128,6 +129,12 @@ NetSessions::NetSessions()
|
|||
arp_analyzer = new ARP_Analyzer();
|
||||
else
|
||||
arp_analyzer = 0;
|
||||
|
||||
|
||||
if ( 1 )
|
||||
tunnel_handler = new TunnelHandler(this);
|
||||
else
|
||||
tunnel_handler = 0;
|
||||
}
|
||||
|
||||
NetSessions::~NetSessions()
|
||||
|
@ -433,14 +440,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
if ( discarder && discarder->NextPacket(ip_hdr, len, caplen) )
|
||||
return;
|
||||
|
||||
int proto = ip_hdr->NextProto();
|
||||
if ( proto != IPPROTO_TCP && proto != IPPROTO_UDP &&
|
||||
proto != IPPROTO_ICMP )
|
||||
{
|
||||
dump_this_packet = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
FragReassembler* f = 0;
|
||||
uint32 frag_field = ip_hdr->FragField();
|
||||
|
||||
|
@ -474,6 +473,23 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
}
|
||||
}
|
||||
|
||||
TunnelInfo *tunnel_info = tunnel_handler->DecapsulateTunnel(ip_hdr, len, caplen, hdr, pkt);
|
||||
if (tunnel_info)
|
||||
{
|
||||
ip4 = tunnel_info->child->IP4_Hdr();
|
||||
ip_hdr = tunnel_info->child;
|
||||
len -= tunnel_info->hdr_len;
|
||||
caplen -= tunnel_info->hdr_len;
|
||||
}
|
||||
|
||||
int proto = ip_hdr->NextProto();
|
||||
if ( proto != IPPROTO_TCP && proto != IPPROTO_UDP &&
|
||||
proto != IPPROTO_ICMP )
|
||||
{
|
||||
dump_this_packet = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
len -= ip_hdr_len; // remove IP header
|
||||
caplen -= ip_hdr_len;
|
||||
|
||||
|
@ -561,7 +577,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
conn = (Connection*) d->Lookup(h);
|
||||
if ( ! conn )
|
||||
{
|
||||
conn = NewConn(h, t, &id, data, proto);
|
||||
conn = NewConn(h, t, &id, data, proto, tunnel_info);
|
||||
if ( conn )
|
||||
d->Insert(h, conn);
|
||||
}
|
||||
|
@ -581,7 +597,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
conn->Event(connection_reused, 0);
|
||||
|
||||
Remove(conn);
|
||||
conn = NewConn(h, t, &id, data, proto);
|
||||
conn = NewConn(h, t, &id, data, proto, tunnel_info);
|
||||
if ( conn )
|
||||
d->Insert(h, conn);
|
||||
}
|
||||
|
@ -609,6 +625,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
record_packet, record_content,
|
||||
hdr, pkt, hdr_size);
|
||||
|
||||
if ( tunnel_info )
|
||||
delete tunnel_info;
|
||||
if ( f )
|
||||
{
|
||||
// Above we already recorded the fragment in its entirety.
|
||||
|
@ -1045,13 +1063,17 @@ void NetSessions::GetStats(SessionStats& s) const
|
|||
}
|
||||
|
||||
Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
|
||||
const u_char* data, int proto)
|
||||
const u_char* data, int proto, TunnelInfo* tunnel_info)
|
||||
{
|
||||
// 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.
|
||||
int src_h = ntohs(id->src_port);
|
||||
int dst_h = ntohs(id->dst_port);
|
||||
int flags = 0;
|
||||
RecordVal *tunnel_parent = 0;
|
||||
|
||||
if ( tunnel_info )
|
||||
tunnel_parent = tunnel_info->GetRecordVal();
|
||||
|
||||
// Hmm... This is not great.
|
||||
TransportProto tproto;
|
||||
|
@ -1098,7 +1120,7 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
|
|||
id = &flip_id;
|
||||
}
|
||||
|
||||
Connection* conn = new Connection(this, k, t, id);
|
||||
Connection* conn = new Connection(this, k, t, id, tunnel_parent);
|
||||
conn->SetTransport(tproto);
|
||||
dpm->BuildInitialAnalyzerTree(tproto, conn, data);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue