Another tunneling checkpoint.

- AYIYA works.
  - AYIYA analyzed connections are still labelled wrong in conn.log (logged as syslog)
- Some clean up for left over code.
- Small refactoring to pass packets back from analyzers to core.
- $uid is now optional in conn logs since ip-in-ip tunnel parent's
  won't have an actual connection.
This commit is contained in:
Seth Hall 2012-04-24 01:05:35 -04:00
parent ae96314196
commit 2a79fe95ec
12 changed files with 53 additions and 122 deletions

View file

@ -10,7 +10,7 @@ export {
type Info: record {
ts: time &log;
uid: string &log;
uid: string &log &optional;
id: conn_id &log;
action: Action &log;
tunnel_type: string &log;

View file

@ -2631,21 +2631,7 @@ module Tunnel;
export {
## Whether to decapsulate IP tunnels (IPinIP, 6in4, 6to4)
const decapsulate_ip = T &redef;
## Whether to decapsulate UDP tunnels (e.g., Teredo, IPv4 in UDP)
const decapsulate_udp = F &redef;
## If decapsulating UDP: the set of ports for which to do so.
## Can be overridden by :bro:id:`Tunnel::udp_tunnel_allports`
const udp_tunnel_ports: set[port] = {
3544/udp, # Teredo
5072/udp, # AYIAY
} &redef;
## If udp_tunnel_allports is T :bro:id:`udp_tunnel_ports` is ignored and we
## check every UDP packet for tunnels.
const udp_tunnel_allports = F &redef;
## The maximum depth of a tunnel to decapsulate until giving up.
const max_depth: count = 2 &redef;
} # end export

View file

@ -101,6 +101,9 @@ export {
resp_pkts: count &log &optional;
## Number IP level bytes the responder sent. See ``orig_pkts``.
resp_ip_bytes: count &log &optional;
## If this connection was over a tunnel, indicate the
## `uid` value for the parent connection or connections.
parents: vector of string &log &optional;
};
## Event that can be handled to access the :bro:type:`Conn::Info`
@ -190,6 +193,15 @@ function set_conn(c: connection, eoc: bool)
c$conn$ts=c$start_time;
c$conn$uid=c$uid;
c$conn$id=c$id;
if ( ! c$conn?$parents && c?$tunnel )
{
c$conn$parents = vector();
for ( i in c$tunnel )
{
# TODO: maybe we should be storing uid's in the $tunnel field?
#c$conn$parents[|c$conn$parents|] = lookup_connection(c$tunnel[i]$cid)$uid;
}
}
c$conn$proto=get_port_transport_proto(c$id$resp_p);
if( |Site::local_nets| > 0 )
c$conn$local_orig=Site::is_local_addr(c$id$orig_h);

View file

@ -1,13 +1,10 @@
#include "AYIYA.h"
#include "TCP_Reassembler.h"
AYIYA_Analyzer::AYIYA_Analyzer(Connection* conn)
: Analyzer(AnalyzerTag::SYSLOG_BINPAC, conn)
{
interp = new binpac::AYIYA::AYIYA_Conn(this);
did_session_done = 0;
//ADD_ANALYZER_TIMER(&AYIYA_Analyzer::ExpireTimer,
// network_time + Syslog_session_timeout, 1, TIMER_Syslog_EXPIRE);
}
AYIYA_Analyzer::~AYIYA_Analyzer()
@ -28,63 +25,3 @@ void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int s
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
interp->NewData(orig, data, data + len);
}
//void AYIYA_Analyzer::ExpireTimer(double t)
// {
// // The - 1.0 in the following is to allow 1 second for the
// // common case of a single request followed by a single reply,
// // so we don't needlessly set the timer twice in that case.
// if ( t - Conn()->LastTime() >= Syslog_session_timeout - 1.0 || terminating )
// {
// Event(connection_timeout);
// sessions->Remove(Conn());
// }
// else
// ADD_ANALYZER_TIMER(&AYIYA_Analyzer::ExpireTimer,
// t + Syslog_session_timeout, 1, TIMER_Syslog_EXPIRE);
// }
//Syslog_TCP_Analyzer_binpac::Syslog_TCP_Analyzer_binpac(Connection* conn)
//: TCP_ApplicationAnalyzer(AnalyzerTag::Syslog_TCP_BINPAC, conn)
// {
// interp = new binpac::Syslog_on_TCP::Syslog_TCP_Conn(this);
// }
//Syslog_TCP_Analyzer_binpac::~Syslog_TCP_Analyzer_binpac()
// {
// delete interp;
// }
//void Syslog_TCP_Analyzer_binpac::Done()
// {
// TCP_ApplicationAnalyzer::Done();
//
// interp->FlowEOF(true);
// interp->FlowEOF(false);
// }
//void Syslog_TCP_Analyzer_binpac::EndpointEOF(TCP_Reassembler* endp)
// {
// TCP_ApplicationAnalyzer::EndpointEOF(endp);
// interp->FlowEOF(endp->IsOrig());
// }
//void Syslog_TCP_Analyzer_binpac::DeliverStream(int len, const u_char* data,
// bool orig)
// {
// TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
//
// assert(TCP());
//
// if ( TCP()->IsPartial() || TCP()->HadGap(orig) )
// // punt-on-partial or stop-on-gap.
// return;
//
// interp->NewData(orig, data, data + len);
// }
//void Syslog_TCP_Analyzer_binpac::Undelivered(int seq, int len, bool orig)
// {
// TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
// interp->NewGap(orig, len);
// }

View file

@ -1,9 +1,6 @@
#ifndef AYIYA_h
#define AYIYA_h
#include "UDP.h"
#include "TCP.h"
#include "ayiya_pac.h"
class AYIYA_Analyzer : public Analyzer {
@ -19,7 +16,7 @@ public:
{ return new AYIYA_Analyzer(conn); }
static bool Available()
{ return true; }
{ return BifConst::Tunnel::decapsulate_ip; }
protected:
friend class AnalyzerTimer;
@ -30,26 +27,4 @@ protected:
binpac::AYIYA::AYIYA_Conn* interp;
};
// #include "Syslog_tcp_pac.h"
//
//class Syslog_TCP_Analyzer_binpac : public TCP_ApplicationAnalyzer {
//public:
// Syslog_TCP_Analyzer_binpac(Connection* conn);
// virtual ~Syslog_TCP_Analyzer_binpac();
//
// virtual void Done();
// virtual void DeliverStream(int len, const u_char* data, bool orig);
// virtual void Undelivered(int seq, int len, bool orig);
// virtual void EndpointEOF(TCP_Reassembler* endp);
//
// static Analyzer* InstantiateAnalyzer(Connection* conn)
// { return new Syslog_TCP_Analyzer_binpac(conn); }
//
// static bool Available()
// { return (Syslog_request || Syslog_full_request) && FLAGS_use_binpac; }
//
//protected:
// binpac::Syslog_on_TCP::Syslog_TCP_Conn* interp;
//};
//
#endif

View file

@ -129,9 +129,6 @@ const Analyzer::Config Analyzer::analyzer_configs[] = {
Syslog_Analyzer_binpac::InstantiateAnalyzer,
Syslog_Analyzer_binpac::Available, 0, false },
//{ AnalyzerTag::6to4, "6to4",
// 6to4_Analyzer::InstantiateAnalyzer,
// 6to4_Anylzer::Available, 0, false },
{ AnalyzerTag::AYIYA, "AYIYA",
AYIYA_Analyzer::InstantiateAnalyzer,
AYIYA_Analyzer::Available, 0, false },

View file

@ -34,7 +34,6 @@ namespace AnalyzerTag {
HTTP_BINPAC, SSL, SYSLOG_BINPAC,
// Decapsulation Analyzers
//6to4,
AYIYA,
SOCKS,
//Teredo,

View file

@ -245,7 +245,9 @@ public:
void SetTransport(TransportProto arg_proto) { proto = arg_proto; }
void SetUID(uint64 arg_uid) { uid = arg_uid; }
Encapsulation* GetEncapsulation() { return &encapsulation; }
protected:
Connection() { persistent = 0; }

View file

@ -131,6 +131,10 @@ public:
return tcp_conns.Length() + udp_conns.Length() +
icmp_conns.Length();
}
void DoNextPacket(double t, const struct pcap_pkthdr* hdr,
const IP_Hdr* ip_hdr, const u_char* const pkt,
int hdr_size, Encapsulation& encapsulation);
unsigned int ConnectionMemoryUsage();
unsigned int ConnectionMemoryUsageConnVals();
@ -174,10 +178,6 @@ protected:
const u_char* const pkt, int hdr_size,
PacketSortElement* pkt_elem);
void DoNextPacket(double t, const struct pcap_pkthdr* hdr,
const IP_Hdr* ip_hdr, const u_char* const pkt,
int hdr_size, Encapsulation& encapsulation);
void NextPacketSecondary(double t, const struct pcap_pkthdr* hdr,
const u_char* const pkt, int hdr_size,
const PktSrc* src_ps);

View file

@ -11,10 +11,37 @@ flow AYIYA_Flow
function process_ayiya(pdu: PDU): bool
%{
connection()->bro_analyzer()->ProtocolConfirmation();
Connection *c = connection()->bro_analyzer()->Conn();
// Not sure what to do here.
printf("packet: %s\n", ${pdu.packet}.data());
if ( c->GetEncapsulation()->Depth() >= BifConst::Tunnel::max_depth )
{
reporter->Weird(c->OrigAddr(), c->RespAddr(), "tunnel_depth");
// TODO: this should stop this analyzer instance
return false;
}
IP_Hdr* inner_ip;
if ( ${pdu.next_header} == IPPROTO_IPV6 )
inner_ip = new IP_Hdr((const struct ip6_hdr*) ${pdu.packet}.data(), false, ${pdu.packet}.length());
else
inner_ip = new IP_Hdr((const struct ip*) ${pdu.packet}.data(), false);
if ( inner_ip != 0)
connection()->bro_analyzer()->ProtocolConfirmation();
else
connection()->bro_analyzer()->ProtocolViolation("ayiya_tunnel_non_ip");
struct pcap_pkthdr fake_hdr;
fake_hdr.caplen = fake_hdr.len = ${pdu.packet}.length();
// Not sure what to do with this timestamp.
//fake_hdr.ts = network_time();
EncapsulatingConn ec(c->OrigAddr(), c->RespAddr(), BifEnum::Tunnel::AYIYA);
c->GetEncapsulation()->Add(ec);
sessions->DoNextPacket(network_time(), &fake_hdr, inner_ip, ${pdu.packet}.data(), 0, *c->GetEncapsulation());
delete inner_ip;
return true;
%}

View file

@ -12,7 +12,4 @@ const NFS3::return_data_max: count;
const NFS3::return_data_first_only: bool;
const Tunnel::decapsulate_ip: bool;
const Tunnel::decapsulate_udp: bool;
const Tunnel::udp_tunnel_ports: any;
const Tunnel::udp_tunnel_allports: bool;
const Tunnel::max_depth: count;

View file

@ -178,8 +178,7 @@ enum Type %{
IP4_IN_IP6,
IP6_IN_UDP,
IP4_IN_UDP,
IP6_IN_AYIAY,
IP4_IN_AYIAY,
AYIYA,
%}
type EncapsulatingConn: record;