Removing legacy binpac analyzer for DNS and HTTP.

This commit is contained in:
Robin Sommer 2013-04-03 13:38:08 -07:00
parent e0c4bd1a82
commit bfda42b9e9
13 changed files with 5 additions and 866 deletions

View file

@ -117,19 +117,13 @@ redef capture_filters += {
["netbios-ns"] = "udp port 137",
};
const dns_udp_ports = { 53/udp, 137/udp, 5353/udp, 5355/udp };
const dns_tcp_ports = { 53/tcp };
redef likely_server_ports += { dns_udp_ports, dns_tcp_ports };
const ports = { 53/udp, 53/tcp, 137/udp, 5353/udp, 5355/udp };
redef likely_server_ports += { ports };
event bro_init() &priority=5
{
Log::create_stream(DNS::LOG, [$columns=Info, $ev=log_dns]);
Analyzer::register_for_ports(Analyzer::ANALYZER_DNS, dns_tcp_ports);
Analyzer::register_for_ports(Analyzer::ANALYZER_DNS, dns_udp_ports);
Analyzer::register_for_ports(Analyzer::ANALYZER_DNS_TCP_BINPAC, dns_tcp_ports);
Analyzer::register_for_ports(Analyzer::ANALYZER_DNS_UDP_BINPAC, dns_udp_ports);
Analyzer::register_for_ports(Analyzer::ANALYZER_DNS, ports);
}
function new_session(c: connection, trans_id: count): Info

View file

@ -144,14 +144,8 @@ binpac_target(dce_rpc_simple.pac
dce_rpc-protocol.pac epmapper.pac)
binpac_target(dhcp.pac
dhcp-protocol.pac dhcp-analyzer.pac)
binpac_target(dns.pac
dns-protocol.pac dns-analyzer.pac)
binpac_target(dns_tcp.pac
dns.pac)
binpac_target(gtpv1.pac
gtpv1-protocol.pac gtpv1-analyzer.pac)
# binpac_target(http.pac
# http-protocol.pac http-analyzer.pac)
binpac_target(ncp.pac)
binpac_target(netflow.pac
netflow-protocol.pac netflow-analyzer.pac)
@ -159,8 +153,6 @@ binpac_target(smb.pac
smb-protocol.pac smb-pipe.pac smb-mailslot.pac)
binpac_target(socks.pac
socks-protocol.pac socks-analyzer.pac)
# binpac_target(ssl.pac
# ssl-defs.pac ssl-protocol.pac ssl-analyzer.pac)
binpac_target(syslog.pac
syslog-protocol.pac syslog-analyzer.pac)
binpac_target(modbus.pac
@ -258,7 +250,6 @@ set(bro_SRCS
DFA.cc
DHCP-binpac.cc
DNS.cc
DNS-binpac.cc
DNS_Mgr.cc
DbgBreakpoint.cc
DbgHelp.cc

View file

@ -1,90 +0,0 @@
#include "DNS-binpac.h"
#include "TCP_Reassembler.h"
DNS_UDP_Analyzer_binpac::DNS_UDP_Analyzer_binpac(Connection* conn)
: Analyzer("DNS_UDP_BINPAC", conn)
{
interp = new binpac::DNS::DNS_Conn(this);
did_session_done = 0;
ADD_ANALYZER_TIMER(&DNS_UDP_Analyzer_binpac::ExpireTimer,
network_time + dns_session_timeout, 1, TIMER_DNS_EXPIRE);
}
DNS_UDP_Analyzer_binpac::~DNS_UDP_Analyzer_binpac()
{
delete interp;
}
void DNS_UDP_Analyzer_binpac::Done()
{
Analyzer::Done();
if ( ! did_session_done )
Event(udp_session_done);
}
void DNS_UDP_Analyzer_binpac::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen)
{
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
interp->NewData(orig, data, data + len);
}
void DNS_UDP_Analyzer_binpac::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() >= dns_session_timeout - 1.0 || terminating )
{
Event(connection_timeout);
sessions->Remove(Conn());
}
else
ADD_ANALYZER_TIMER(&DNS_UDP_Analyzer_binpac::ExpireTimer,
t + dns_session_timeout, 1, TIMER_DNS_EXPIRE);
}
DNS_TCP_Analyzer_binpac::DNS_TCP_Analyzer_binpac(Connection* conn)
: TCP_ApplicationAnalyzer("DNS_TCP_BINPAC", conn)
{
interp = new binpac::DNS_on_TCP::DNS_TCP_Conn(this);
}
DNS_TCP_Analyzer_binpac::~DNS_TCP_Analyzer_binpac()
{
delete interp;
}
void DNS_TCP_Analyzer_binpac::Done()
{
TCP_ApplicationAnalyzer::Done();
interp->FlowEOF(true);
interp->FlowEOF(false);
}
void DNS_TCP_Analyzer_binpac::EndpointEOF(bool is_orig)
{
TCP_ApplicationAnalyzer::EndpointEOF(is_orig);
interp->FlowEOF(is_orig);
}
void DNS_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 DNS_TCP_Analyzer_binpac::Undelivered(int seq, int len, bool orig)
{
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
interp->NewGap(orig, len);
}

View file

@ -1,60 +0,0 @@
#ifndef dns_binpac_h
#define dns_binpac_h
#include "UDP.h"
#include "TCP.h"
#include "dns_pac.h"
// FIXME: As the binpac analyer for DNS-TCP and DNS-UDP are currently
// structured, we cannot directly combine them into one analyzer. Can we
// change that easily? (Ideally, the TCP preprocessing would become a
// support-analyzer as it is done for the traditional DNS analyzer.)
class DNS_UDP_Analyzer_binpac : public analyzer::Analyzer {
public:
DNS_UDP_Analyzer_binpac(Connection* conn);
virtual ~DNS_UDP_Analyzer_binpac();
virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new DNS_UDP_Analyzer_binpac(conn); }
static bool Available()
{ return (dns_request || dns_full_request) && FLAGS_use_binpac; }
protected:
friend class AnalyzerTimer;
void ExpireTimer(double t);
int did_session_done;
binpac::DNS::DNS_Conn* interp;
};
#include "dns_tcp_pac.h"
class DNS_TCP_Analyzer_binpac : public TCP_ApplicationAnalyzer {
public:
DNS_TCP_Analyzer_binpac(Connection* conn);
virtual ~DNS_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(bool is_orig);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new DNS_TCP_Analyzer_binpac(conn); }
static bool Available()
{ return (dns_request || dns_full_request) && FLAGS_use_binpac; }
protected:
binpac::DNS_on_TCP::DNS_TCP_Conn* interp;
};
#endif

View file

@ -19,8 +19,6 @@
#include "ICMP.h"
#include "UDP.h"
#include "DNS-binpac.h"
#include "SteppingStone.h"
#include "BackDoor.h"
#include "InterConn.h"

View file

@ -1,343 +0,0 @@
%extern{
#include <set>
%}
%code{
int add_to_name_buffer(DNS_name* name, char* buf, const int buf_n, int buf_i)
{
for ( int i = 0; i < int(name->labels()->size()); ++i )
{
DNS_label* label = (*name->labels())[i];
if ( label->label_type() == 0 )
{
bytestring const &label_str = label->label();
if ( buf_i > 0 && buf_i < buf_n )
buf[buf_i++] = '.';
BINPAC_ASSERT(buf_i + label_str.length() <= buf_n);
memcpy(buf + buf_i, label_str.begin(),
label_str.length());
buf_i += label_str.length();
}
else if ( label->label_type() == 3 )
{
return add_to_name_buffer(label->ptr(), buf,
buf_n, buf_i);
}
}
return buf_i;
}
StringVal* name_to_val(DNS_name* name)
{
char name_buf[520];
int n = add_to_name_buffer(name, name_buf, sizeof(name_buf), 0);
if ( n > 0 )
--n; // remove the trailing '.'
BINPAC_ASSERT(n < int(sizeof(name_buf)));
name_buf[n] = 0;
for ( int i = 0; i < n; ++i )
if ( isupper(name_buf[i]) )
name_buf[i] = tolower(name_buf[i]);
return new StringVal(name_buf);
}
%}
connection DNS_Conn(bro_analyzer: BroAnalyzer)
{
upflow = DNS_Flow;
downflow = DNS_Flow;
};
flow DNS_Flow
{
datagram = DNS_message withcontext(connection, this);
%member{
set<int> pointer_set;
BroVal dns_msg_val_;
%}
%init{
dns_msg_val_ = 0;
%}
%cleanup{
Unref(dns_msg_val_);
dns_msg_val_ = 0;
%}
# Return a byte segment starting at <offset> in the original message.
function get_pointer(msgdata: const_bytestring,
offset: int): const_bytestring
%{
if ( offset < 0 || offset >= msgdata.length() )
return const_bytestring(0, 0);
if ( pointer_set.find(offset) != pointer_set.end() )
throw Exception("DNS pointer loop!");
pointer_set.insert(offset);
return const_bytestring(msgdata.begin() + offset, msgdata.end());
%}
function reset_pointer_set(): bool
%{
pointer_set.clear();
return true;
%}
function process_dns_header(hdr: DNS_header): bool
%{
Unref(dns_msg_val_);
RecordVal* r = new RecordVal(dns_msg);
r->Assign(0, new Val(${hdr.id}, TYPE_COUNT));
r->Assign(1, new Val(${hdr.opcode}, TYPE_COUNT));
r->Assign(2, new Val(${hdr.rcode}, TYPE_COUNT));
r->Assign(3, new Val(${hdr.qr}, TYPE_BOOL));
r->Assign(4, new Val(${hdr.aa}, TYPE_BOOL));
r->Assign(5, new Val(${hdr.tc}, TYPE_BOOL));
r->Assign(6, new Val(${hdr.rd}, TYPE_BOOL));
r->Assign(7, new Val(${hdr.ra}, TYPE_BOOL));
r->Assign(8, new Val(${hdr.z}, TYPE_COUNT));
r->Assign(9, new Val(${hdr.qdcount}, TYPE_COUNT));
r->Assign(10, new Val(${hdr.ancount}, TYPE_COUNT));
r->Assign(11, new Val(${hdr.nscount}, TYPE_COUNT));
r->Assign(12, new Val(${hdr.arcount}, TYPE_COUNT));
dns_msg_val_ = r;
return true;
%}
function process_dns_question(question: DNS_question): bool
%{
DNS_message* msg = question->msg();
if ( msg->header()->qr() == 0 )
{
BifEvent::generate_dns_request(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dns_msg_val_->Ref(),
name_to_val(question->qname()),
question->qtype(),
question->qclass());
}
else if ( msg->header()->ancount() == 0 &&
msg->header()->nscount() == 0 &&
msg->header()->arcount() == 0 )
{
BifEvent::generate_dns_rejected(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dns_msg_val_->Ref(),
name_to_val(question->qname()),
question->qtype(),
question->qclass());
}
return true;
%}
function build_dns_answer(rr: DNS_rr): BroVal
%{
RecordVal* r = new RecordVal(dns_answer);
r->Assign(0, new Val(rr->answer_type(), TYPE_COUNT));
r->Assign(1, name_to_val(rr->rr_name()));
r->Assign(2, new Val(rr->rr_type(), TYPE_COUNT));
r->Assign(3, new Val(rr->rr_class(), TYPE_COUNT));
r->Assign(4, new IntervalVal(double(rr->rr_ttl()), Seconds));
return r;
%}
function build_dns_soa(soa: DNS_rdata_SOA): BroVal
%{
RecordVal* r = new RecordVal(dns_soa);
r->Assign(0, name_to_val(soa->mname()));
r->Assign(1, name_to_val(soa->rname()));
r->Assign(2, new Val(soa->serial(), TYPE_COUNT));
r->Assign(3, new IntervalVal(double(soa->refresh()), Seconds));
r->Assign(4, new IntervalVal(double(soa->retry()), Seconds));
r->Assign(5, new IntervalVal(double(soa->expire()), Seconds));
r->Assign(6, new IntervalVal(double(soa->minimum()), Seconds));
return r;
%}
function build_edns_additional(rr: DNS_rr): BroVal
%{
// We have to treat the additional record type in EDNS
// differently than a regular resource record.
RecordVal* r = new RecordVal(dns_edns_additional);
r->Assign(0, new Val(int(rr->answer_type()), TYPE_COUNT));
r->Assign(1, name_to_val(rr->rr_name()));
// Type = 0x29 or 41 = EDNS
r->Assign(2, new Val(rr->rr_type(), TYPE_COUNT));
// Sender's UDP payload size, per RFC 2671 4.3
r->Assign(3, new Val(rr->rr_class(), TYPE_COUNT));
// Need to break the TTL field into three components:
// initial: [------------- ttl (32) ---------------------]
// after: [DO][ ext rcode (7)][ver # (8)][ Z field (16)]
unsigned int ercode = (rr->rr_ttl() & 0xff000000) >> 24;
unsigned int version = (rr->rr_ttl() & 0x00ff0000) >> 16;
unsigned int z = (rr->rr_ttl() & 0x0000ffff);
int rcode = rr->msg()->header()->rcode();
unsigned int return_error = (ercode << 8) | rcode;
r->Assign(4, new Val(return_error, TYPE_COUNT));
r->Assign(5, new Val(version, TYPE_COUNT));
r->Assign(6, new Val(z, TYPE_COUNT));
r->Assign(7, new IntervalVal(double(rr->rr_ttl()), Seconds));
r->Assign(8, new Val(rr->msg()->header()->qr() == 0, TYPE_COUNT));
return r;
%}
function process_dns_rr(rr: DNS_rr): bool
%{
const DNS_rdata* rd = rr->rr_rdata();
switch ( rr->rr_type() ) {
case TYPE_A:
if ( dns_A_reply )
{
::uint32 addr = rd->type_a();
BifEvent::generate_dns_A_reply(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dns_msg_val_->Ref(), build_dns_answer(rr),
new AddrVal(htonl(addr)));
}
break;
case TYPE_A6:
if ( dns_A6_reply )
{
::uint32 addr[4];
for ( unsigned int i = 0; i < 4; ++i )
addr[i] = htonl((*rd->type_aaaa())[i]);
BifEvent::generate_dns_A6_reply(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dns_msg_val_->Ref(), build_dns_answer(rr),
new AddrVal(addr));
}
break;
case TYPE_AAAA:
if ( dns_AAAA_reply )
{
::uint32 addr[4];
for ( unsigned int i = 0; i < 4; ++i )
addr[i] = htonl((*rd->type_aaaa())[i]);
BifEvent::generate_dns_AAAA_reply(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dns_msg_val_->Ref(), build_dns_answer(rr),
new AddrVal(addr));
}
break;
case TYPE_NS:
if ( dns_NS_reply )
{
BifEvent::generate_dns_NS_reply(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dns_msg_val_->Ref(),
build_dns_answer(rr),
name_to_val(rr->rr_rdata()->type_ns()));
}
break;
case TYPE_CNAME:
if ( dns_CNAME_reply )
{
BifEvent::generate_dns_CNAME_reply(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dns_msg_val_->Ref(),
build_dns_answer(rr),
name_to_val(rr->rr_rdata()->type_cname()));
}
break;
case TYPE_SOA:
if ( dns_SOA_reply )
{
BifEvent::generate_dns_SOA_reply(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dns_msg_val_->Ref(),
build_dns_answer(rr),
build_dns_soa(rr->rr_rdata()->type_soa()));
}
break;
case TYPE_PTR:
if ( dns_PTR_reply )
{
BifEvent::generate_dns_PTR_reply(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dns_msg_val_->Ref(),
build_dns_answer(rr),
name_to_val(rr->rr_rdata()->type_ptr()));
}
break;
case TYPE_MX:
if ( dns_MX_reply )
{
BifEvent::generate_dns_MX_reply(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dns_msg_val_->Ref(),
build_dns_answer(rr),
name_to_val(rr->rr_rdata()->type_mx()->name()),
rr->rr_rdata()->type_mx()->preference());
}
break;
case TYPE_EDNS:
if ( dns_EDNS_addl )
{
BifEvent::generate_dns_EDNS_addl(
connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dns_msg_val_->Ref(),
build_edns_additional(rr));
}
break;
}
return true;
%}
};
refine typeattr DNS_header += &let {
proc_dns_header = $context.flow.process_dns_header(this);
};
refine typeattr DNS_question += &let {
proc_dns_question = $context.flow.process_dns_question(this);
};
refine typeattr DNS_rr += &let {
proc_dns_rr = $context.flow.process_dns_rr(this);
};

View file

@ -1,215 +0,0 @@
enum DNS_answer_type {
DNS_QUESTION,
DNS_ANSWER,
DNS_AUTHORITY,
DNS_ADDITIONAL,
};
enum DNS_rdata_type {
TYPE_A = 1,
TYPE_NS = 2,
TYPE_MD = 3,
TYPE_MF = 4,
TYPE_CNAME = 5,
TYPE_SOA = 6,
TYPE_MB = 7,
TYPE_MG = 8,
TYPE_MR = 9,
TYPE_NULL = 10,
TYPE_WKS = 11,
TYPE_PTR = 12,
TYPE_HINFO = 13,
TYPE_MINFO = 14,
TYPE_MX = 15,
TYPE_TXT = 16,
TYPE_AAAA = 28, # IPv6 (RFC 1886)
TYPE_NBS = 32, # Netbios name (RFC 1002)
TYPE_A6 = 38, # IPv6 with indirection (RFC 2874)
TYPE_EDNS = 41, # < OPT pseudo-RR (RFC 2671)
};
# 1 1 1 1 1 1
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | ID |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | QDCOUNT |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | ANCOUNT |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | NSCOUNT |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | ARCOUNT |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
type DNS_header = record {
id : uint16;
qrop : uint16;
qdcount : uint16;
ancount : uint16;
nscount : uint16;
arcount : uint16;
} &let {
qr: bool = qrop >> 15;
opcode: uint8 = (qrop >> 11) & 0xf;
aa: bool = (qrop >> 10) & 0x1;
tc: bool = (qrop >> 9) & 0x1;
rd: bool = (qrop >> 8) & 0x1;
ra: bool = (qrop >> 7) & 0x1;
z: uint8 = (qrop >> 4) & 0x7;
rcode: uint8 = qrop & 0xf;
};
type DNS_label(msg: DNS_message) = record {
length: uint8;
data: case label_type of {
0 -> label: bytestring &length = length;
3 -> ptr_lo: uint8;
};
} &let {
label_type: uint8 = length >> 6;
last: bool = (length == 0) || (label_type == 3);
# A name pointer.
ptr: DNS_name(msg)
withinput $context.flow.get_pointer(msg.sourcedata,
((length & 0x3f) << 8) | ptr_lo)
&if(label_type == 3);
clear_pointer_set: bool = $context.flow.reset_pointer_set()
&if(last);
};
type DNS_name(msg: DNS_message) = record {
labels: DNS_label(msg)[] &until($element.last);
};
type DNS_char_string = record {
length: uint8;
data: bytestring &length = length;
};
# 1 1 1 1 1 1
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | |
# / QNAME /
# / /
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | QTYPE |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | QCLASS |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
type DNS_question(msg: DNS_message) = record {
qname: DNS_name(msg);
qtype: uint16;
qclass: uint16;
};
type DNS_rdata_MX(msg: DNS_message) = record {
preference: uint16;
name: DNS_name(msg);
};
type DNS_rdata_SOA(msg: DNS_message) = record {
mname: DNS_name(msg);
rname: DNS_name(msg);
serial: uint32;
refresh: uint32;
retry: uint32;
expire: uint32;
minimum: uint32;
};
type DNS_rdata_WKS = record {
address: uint32;
protocol: uint8;
bitmap: bytestring &restofdata;
};
type DNS_rdata_HINFO = record {
cpu: DNS_char_string;
os: DNS_char_string;
};
type DNS_rdata(msg: DNS_message,
rr_type: uint16,
rr_class: uint16) = case rr_type of {
TYPE_A -> type_a: uint32 &check(rr_class == CLASS_IN);
TYPE_NS -> type_ns: DNS_name(msg);
TYPE_CNAME -> type_cname: DNS_name(msg);
TYPE_SOA -> type_soa: DNS_rdata_SOA(msg);
TYPE_PTR -> type_ptr: DNS_name(msg);
TYPE_MX -> type_mx: DNS_rdata_MX(msg);
TYPE_AAAA, TYPE_A6
-> type_aaaa: uint32[4];
# TYPE_WKS -> type_wks: DNS_rdata_WKS;
# TYPE_HINFO -> type_hinfo: DNS_rdata_HINFO;
# TYPE_TXT -> type_txt: bytestring &restofdata;
# 3 -> type_md: DNS_rdata_MD;
# 4 -> type_mf: DNS_rdata_MF;
# 7 -> type_mb: DNS_rdata_MB;
# 8 -> type_mg: DNS_rdata_MG;
# 9 -> type_mr: DNS_rdata_MR;
# 10 -> type_null: DNS_rdata_NULL;
# 14 -> type_minfo: DNS_rdata_MINFO;
# 32 -> type_nbs: DNS_rdata_NBS;
default -> unknown: bytestring &restofdata;
};
# 1 1 1 1 1 1
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | |
# / /
# / NAME /
# | |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | TYPE |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | CLASS |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | TTL |
# | |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | RDLENGTH |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
# / RDATA /
# / /
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
type DNS_rr(msg: DNS_message, answer_type: DNS_answer_type) = record {
rr_name: DNS_name(msg);
rr_type: uint16;
rr_class: uint16;
rr_ttl: uint32;
rr_rdlength: uint16;
rr_rdata: DNS_rdata(msg, rr_type, rr_class) &length = rr_rdlength;
};
# +---------------------+
# | Header |
# +---------------------+
# | Question | the question for the name server
# +---------------------+
# | Answer | RRs answering the question
# +---------------------+
# | Authority | RRs pointing toward an authority
# +---------------------+
# | Additional | RRs holding additional information
# +---------------------+
type DNS_message = record {
header: DNS_header;
question: DNS_question(this)[header.qdcount];
answer: DNS_rr(this, DNS_ANSWER)[header.ancount];
authority: DNS_rr(this, DNS_AUTHORITY)[header.nscount];
additional: DNS_rr(this, DNS_ADDITIONAL)[header.arcount];
} &byteorder = bigendian, &exportsourcedata;

View file

@ -1,9 +0,0 @@
%include bro.pac
analyzer DNS withcontext {
connection: DNS_Conn;
flow: DNS_Flow;
};
%include dns-protocol.pac
%include dns-analyzer.pac

View file

@ -1,45 +0,0 @@
%extern{
#include "dns_pac.h" // for DNS_Conn
%}
%include bro.pac
analyzer DNS_on_TCP withcontext {
connection: DNS_TCP_Conn;
flow: DNS_TCP_Flow;
};
type DNS_TCP_PDU(is_orig: bool) = record {
msglen: uint16;
msg: bytestring &length = msglen;
} &byteorder = bigendian, &length = 2 + msglen, &let {
deliver: bool = $context.connection.deliver_dns_message(is_orig, msg);
};
connection DNS_TCP_Conn(bro_analyzer: BroAnalyzer) {
upflow = DNS_TCP_Flow(true);
downflow = DNS_TCP_Flow(false);
%member{
DNS::DNS_Conn *abstract_dns_connection_;
%}
%init{
abstract_dns_connection_ = new DNS::DNS_Conn(bro_analyzer);
%}
%cleanup{
delete abstract_dns_connection_;
abstract_dns_connection_ = 0;
%}
function deliver_dns_message(is_orig: bool, msg: const_bytestring): bool
%{
abstract_dns_connection_->NewData(is_orig, msg.begin(), msg.end());
return true;
%}
};
flow DNS_TCP_Flow(is_orig: bool) {
flowunit = DNS_TCP_PDU(is_orig) withcontext(connection, this);
};

View file

@ -21,7 +21,6 @@
#include "FTP.h"
#include "FileAnalyzer.h"
#include "DNS.h"
#include "DNS-binpac.h"
#include "DHCP-binpac.h"
#include "Telnet.h"
#include "Rlogin.h"
@ -50,11 +49,6 @@ BuiltinAnalyzers builtin_analyzers;
#define DEFINE_ANALYZER(name, factory) \
AddComponent(new Component(name, factory))
#define DEFINE_ANALYZER_VERSION_BINPAC(name, factory) \
AddComponent(new Component(name, factory, 0, FLAGS_use_binpac))
#define DEFINE_ANALYZER_VERSION_NON_BINPAC(name, factory) \
AddComponent(new Component(name, factory, 0, ! FLAGS_use_binpac))
void BuiltinAnalyzers::Init()
{
plugin::Description desc;
@ -74,7 +68,7 @@ void BuiltinAnalyzers::Init()
DEFINE_ANALYZER("BITTORRENT", BitTorrent_Analyzer::InstantiateAnalyzer);
DEFINE_ANALYZER("BITTORRENTTRACKER", BitTorrentTracker_Analyzer::InstantiateAnalyzer);
DEFINE_ANALYZER("DCE_RPC", DCE_RPC_Analyzer::InstantiateAnalyzer);
DEFINE_ANALYZER_VERSION_NON_BINPAC("DNS", DNS_Analyzer::InstantiateAnalyzer);
DEFINE_ANALYZER("DNS", DNS_Analyzer::InstantiateAnalyzer);
DEFINE_ANALYZER("FINGER", Finger_Analyzer::InstantiateAnalyzer);
DEFINE_ANALYZER("FTP", FTP_Analyzer::InstantiateAnalyzer);
DEFINE_ANALYZER("GNUTELLA", Gnutella_Analyzer::InstantiateAnalyzer);
@ -96,8 +90,6 @@ void BuiltinAnalyzers::Init()
DEFINE_ANALYZER("TELNET", Telnet_Analyzer::InstantiateAnalyzer);
DEFINE_ANALYZER("DHCP_BINPAC", DHCP_Analyzer_binpac::InstantiateAnalyzer);
DEFINE_ANALYZER_VERSION_BINPAC("DNS_TCP_BINPAC", DNS_TCP_Analyzer_binpac::InstantiateAnalyzer);
DEFINE_ANALYZER_VERSION_BINPAC("DNS_UDP_BINPAC", DNS_UDP_Analyzer_binpac::InstantiateAnalyzer);
DEFINE_ANALYZER("SYSLOG_BINPAC", Syslog_Analyzer_binpac::InstantiateAnalyzer);
DEFINE_ANALYZER("MODBUS", ModbusTCP_Analyzer::InstantiateAnalyzer);

View file

@ -183,7 +183,7 @@ public:
{ return (http_request || http_reply || http_header ||
http_all_headers || http_begin_entity || http_end_entity ||
http_content_type || http_entity_data || http_message_done ||
http_event || http_stats) && !FLAGS_use_binpac; }
http_event || http_stats); }
protected:
void GenStats();

View file

@ -1,46 +0,0 @@
#include "HTTP-binpac.h"
#include "TCP_Reassembler.h"
HTTP_Analyzer_binpac::HTTP_Analyzer_binpac(Connection *c)
: TCP_ApplicationAnalyzer("HTTP_BINPAC", c)
{
interp = new binpac::HTTP::HTTP_Conn(this);
}
HTTP_Analyzer_binpac::~HTTP_Analyzer_binpac()
{
delete interp;
}
void HTTP_Analyzer_binpac::Done()
{
TCP_ApplicationAnalyzer::Done();
interp->FlowEOF(true);
interp->FlowEOF(false);
}
void HTTP_Analyzer_binpac::EndpointEOF(bool is_orig)
{
TCP_ApplicationAnalyzer::EndpointEOF(is_orig);
interp->FlowEOF(is_orig);
}
void HTTP_Analyzer_binpac::DeliverStream(int len, const u_char* data, bool orig)
{
TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
assert(TCP());
if ( TCP()->IsPartial() )
// punt on partial.
return;
interp->NewData(orig, data, data + len);
}
void HTTP_Analyzer_binpac::Undelivered(int seq, int len, bool orig)
{
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
interp->NewGap(orig, len);
}

View file

@ -1,28 +0,0 @@
#ifndef http_binpac_h
#define http_binpac_h
#include "TCP.h"
#include "http_pac.h"
class HTTP_Analyzer_binpac : public TCP_ApplicationAnalyzer {
public:
HTTP_Analyzer_binpac(Connection* conn);
virtual ~HTTP_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(bool is_orig);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new HTTP_Analyzer_binpac(conn); }
static bool Available()
{ return (http_request || http_reply) && FLAGS_use_binpac; }
protected:
binpac::HTTP::HTTP_Conn* interp;
};
#endif