Fix for IP tunnel UID persistence.

This commit is contained in:
Jon Siwek 2012-04-27 10:28:46 -05:00
parent 8791ac7337
commit 064c5dddb8
9 changed files with 102 additions and 6 deletions

View file

@ -27,7 +27,7 @@ export {
ts: time &log;
## The unique identifier for the tunnel, which may correspond
## to a :bro:type:`connection`'s *uid* field for non-IP-in-IP tunnels.
uid: string &log &optional;
uid: string &log;
## The tunnel "connection" 4-tuple of endpoint addresses/ports.
## For an IP tunnel, the ports will be 0.
id: conn_id &log;

View file

@ -190,7 +190,7 @@ export {
tunnel_type: Tunnel::Type;
## A globally unique identifier that, for non-IP-in-IP tunnels,
## cross-references the *uid* field of :bro:type:`connection`.
uid: string &optional;
uid: string;
} &log;
} # end export
module GLOBAL;

View file

@ -13,6 +13,7 @@
#include "Timer.h"
#include "PIA.h"
#include "binpac.h"
#include "Tunnels.h"
void ConnectionTimer::Init(Connection* arg_conn, timer_func arg_timer,
int arg_do_expire)

View file

@ -542,9 +542,23 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
fake_hdr.caplen = fake_hdr.len = caplen;
fake_hdr.ts = hdr->ts;
EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr(),
BifEnum::Tunnel::IP);
encapsulation.Add(ec);
IPPair tunnel_idx;
if ( ip_hdr->SrcAddr() < ip_hdr->DstAddr() )
tunnel_idx = IPPair(ip_hdr->SrcAddr(), ip_hdr->DstAddr());
else
tunnel_idx = IPPair(ip_hdr->DstAddr(), ip_hdr->SrcAddr());
IPTunnelMap::const_iterator it = ip_tunnels.find(tunnel_idx);
if ( it == ip_tunnels.end() )
{
EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr(),
BifEnum::Tunnel::IP);
ip_tunnels[tunnel_idx] = ec;
encapsulation.Add(ec);
}
else
encapsulation.Add(it->second);
DoNextPacket(t, &fake_hdr, inner_ip, data, 0, encapsulation);

View file

@ -11,6 +11,8 @@
#include "PacketFilter.h"
#include "Stats.h"
#include "NetVar.h"
#include "Tunnels.h"
#include <utility>
struct pcap_pkthdr;
@ -202,6 +204,9 @@ protected:
PDict(Connection) udp_conns;
PDict(Connection) icmp_conns;
PDict(FragReassembler) fragments;
typedef pair<IPAddr, IPAddr> IPPair;
typedef std::map<IPPair, EncapsulatingConn> IPTunnelMap;
IPTunnelMap ip_tunnels;
ARP_Analyzer* arp_analyzer;

View file

@ -13,6 +13,10 @@ class Connection;
class EncapsulatingConn {
public:
EncapsulatingConn()
: src_port(0), dst_port(0), type(BifEnum::Tunnel::NONE), uid(0)
{}
EncapsulatingConn(const IPAddr& s, const IPAddr& d,
BifEnum::Tunnel::Type t)
: src_addr(s), dst_addr(d), src_port(0), dst_port(0), type(t)
@ -36,7 +40,13 @@ public:
friend bool operator==(const EncapsulatingConn& ec1,
const EncapsulatingConn& ec2)
{
return ec1.type == ec2.type && ec1.src_addr == ec2.src_addr &&
if ( ec1.type != ec2.type )
return false;
if ( ec1.type == BifEnum::Tunnel::IP )
return ec1.uid == ec2.uid &&
((ec1.src_addr == ec2.src_addr && ec1.dst_addr == ec2.dst_addr) ||
(ec1.src_addr == ec2.dst_addr && ec1.dst_addr == ec2.src_addr));
return ec1.src_addr == ec2.src_addr && ec1.dst_addr == ec2.dst_addr &&
ec1.src_port == ec2.src_port && ec1.dst_port == ec2.dst_port &&
ec1.uid == ec2.uid;
}

View file

@ -0,0 +1,33 @@
new_connection: tunnel
conn_id: [orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp]
encap: [[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]]
NEW_PACKET:
[orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp]
[[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]]
NEW_PACKET:
[orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp]
[[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]]
NEW_PACKET:
[orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp]
[[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]]
NEW_PACKET:
[orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp]
[[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]]
NEW_PACKET:
[orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp]
[[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]]
NEW_PACKET:
[orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp]
[[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]]
NEW_PACKET:
[orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp]
[[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]]
NEW_PACKET:
[orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp]
[[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]]
NEW_PACKET:
[orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp]
[[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]]
NEW_PACKET:
[orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp]
[[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]]

Binary file not shown.

View file

@ -0,0 +1,33 @@
# @TEST-EXEC: bro -b -r $TRACES/tunnels/ping6-in-ipv4.pcap %INPUT >>output 2>&1
# @TEST-EXEC: btest-diff output
event new_connection(c: connection)
{
if ( c?$tunnel )
{
print "new_connection: tunnel";
print fmt(" conn_id: %s", c$id);
print fmt(" encap: %s", c$tunnel);
}
else
{
print "new_connection: no tunnel";
}
}
event tunnel_changed(c: connection, e: EncapsulatingConnVector)
{
print "tunnel_changed:";
print fmt(" conn_id: %s", c$id);
if ( c?$tunnel )
print fmt(" old: %s", c$tunnel);
print fmt(" new: %s", e);
}
event new_packet(c: connection, p: pkt_hdr)
{
print "NEW_PACKET:";
print fmt(" %s", c$id);
if ( c?$tunnel )
print fmt(" %s", c$tunnel);
}