Merge branch 'master' into topic/jsiwek/pybroccoli-fixes

This commit is contained in:
Jon Siwek 2011-06-27 16:00:50 -05:00
commit 1c30ce7e23
30 changed files with 387 additions and 416 deletions

View file

@ -63,6 +63,7 @@ public:
protected:
char* host; // if non-nil, this is a host request
uint32 addr;
uint32 ttl;
int request_pending;
};
@ -82,8 +83,8 @@ int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns)
class DNS_Mapping {
public:
DNS_Mapping(const char* host, struct hostent* h);
DNS_Mapping(uint32 addr, struct hostent* h);
DNS_Mapping(const char* host, struct hostent* h, uint32 ttl);
DNS_Mapping(uint32 addr, struct hostent* h, uint32 ttl);
DNS_Mapping(FILE* f);
int NoMapping() const { return no_mapping; }
@ -108,6 +109,9 @@ public:
int Failed() const { return failed; }
int Valid() const { return ! failed; }
bool Expired() const
{ return current_time() > (creation_time + req_ttl); }
protected:
friend class DNS_Mgr;
@ -119,6 +123,7 @@ protected:
char* req_host;
uint32 req_addr;
uint32 req_ttl;
int num_names;
char** names;
@ -146,21 +151,23 @@ static TableVal* empty_addr_set()
return new TableVal(s);
}
DNS_Mapping::DNS_Mapping(const char* host, struct hostent* h)
DNS_Mapping::DNS_Mapping(const char* host, struct hostent* h, uint32 ttl)
{
Init(h);
req_host = copy_string(host);
req_addr = 0;
req_ttl = ttl;
if ( names && ! names[0] )
names[0] = copy_string(host);
}
DNS_Mapping::DNS_Mapping(uint32 addr, struct hostent* h)
DNS_Mapping::DNS_Mapping(uint32 addr, struct hostent* h, uint32 ttl)
{
Init(h);
req_addr = addr;
req_host = 0;
req_ttl = ttl;
}
DNS_Mapping::DNS_Mapping(FILE* f)
@ -663,6 +670,7 @@ Val* DNS_Mgr::BuildMappingVal(DNS_Mapping* dm)
void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r)
{
struct hostent* h = (r && r->host_errno == 0) ? r->hostent : 0;
u_int32_t ttl = r->ttl;
DNS_Mapping* new_dm;
DNS_Mapping* prev_dm;
@ -670,7 +678,7 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r)
if ( dr->ReqHost() )
{
new_dm = new DNS_Mapping(dr->ReqHost(), h);
new_dm = new DNS_Mapping(dr->ReqHost(), h, ttl);
prev_dm = host_mappings.Insert(dr->ReqHost(), new_dm);
if ( new_dm->Failed() && prev_dm && prev_dm->Valid() )
@ -683,7 +691,7 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r)
}
else
{
new_dm = new DNS_Mapping(dr->ReqAddr(), h);
new_dm = new DNS_Mapping(dr->ReqAddr(), h, ttl);
uint32 tmp_addr = dr->ReqAddr();
HashKey k(&tmp_addr, 1);
prev_dm = addr_mappings.Insert(&k, new_dm);
@ -833,9 +841,16 @@ const char* DNS_Mgr::LookupAddrInCache(dns_mgr_addr_type addr)
{
HashKey h(&addr, 1);
DNS_Mapping* d = dns_mgr->addr_mappings.Lookup(&h);
if ( ! d )
return 0;
if ( d->Expired() )
{
dns_mgr->addr_mappings.Remove(&h);
return 0;
}
// The escapes in the following strings are to avoid having it
// interpreted as a trigraph sequence.
return d->names ? d->names[0] : "<\?\?\?>";
@ -844,9 +859,17 @@ const char* DNS_Mgr::LookupAddrInCache(dns_mgr_addr_type addr)
TableVal* DNS_Mgr::LookupNameInCache(string name)
{
DNS_Mapping* d = dns_mgr->host_mappings.Lookup(name.c_str());
if ( ! d || ! d->names )
return 0;
if ( d->Expired() )
{
HashKey h(name.c_str());
dns_mgr->host_mappings.Remove(&h);
return 0;
}
return d->AddrsSet();
}

View file

@ -519,6 +519,7 @@ void init_builtin_funcs()
{
ftp_port = internal_type("ftp_port")->AsRecordType();
bro_resources = internal_type("bro_resources")->AsRecordType();
net_stats = internal_type("NetStats")->AsRecordType();
matcher_stats = internal_type("matcher_stats")->AsRecordType();
var_sizes = internal_type("var_sizes")->AsTableType();
gap_info = internal_type("gap_info")->AsRecordType();

View file

@ -744,13 +744,14 @@ bool LogMgr::AddFilter(EnumVal* id, RecordVal* fval)
else
{
// If no path is given, use the Stream ID's namespace as the default
// if it has one, and it ID itself otherwise.
// If no path is given, use the Stream ID as the default but
// strip the namespace.
const char* s = stream->name.c_str();
const char* e = strstr(s, "::");
const char* e = s + strlen(s);
if ( ! e )
e = s + strlen(s);
const char* t = strstr(s, "::");
if ( t )
s = t + 2;
string path(s, e);
std::transform(path.begin(), path.end(), path.begin(), ::tolower);

View file

@ -20,10 +20,7 @@ EnumType* transport_proto;
TableType* string_set;
TableType* count_set;
RecordType* net_stats;
int watchdog_interval;
double heartbeat_interval;
int max_timer_expires;
int max_remote_events_processed;
@ -404,10 +401,7 @@ void init_net_var()
ntp_session_timeout = opt_internal_double("ntp_session_timeout");
rpc_timeout = opt_internal_double("rpc_timeout");
net_stats = internal_type("net_stats")->AsRecordType();
watchdog_interval = int(opt_internal_double("watchdog_interval"));
heartbeat_interval = opt_internal_double("heartbeat_interval");
max_timer_expires = opt_internal_int("max_timer_expires");
max_remote_events_processed =

View file

@ -23,10 +23,7 @@ extern EnumType* transport_proto;
extern TableType* string_set;
extern TableType* count_set;
extern RecordType* net_stats;
extern int watchdog_interval;
extern double heartbeat_interval;
extern int max_timer_expires;
extern int max_remote_events_processed;

View file

@ -43,27 +43,6 @@ enum NetBIOS_Service {
NetSessions* sessions;
class NetworkTimer : public Timer {
public:
NetworkTimer(NetSessions* arg_sess, double arg_t)
: Timer(arg_t, TIMER_NETWORK)
{ sess = arg_sess; }
void Dispatch(double t, int is_expire);
protected:
NetSessions* sess;
};
void NetworkTimer::Dispatch(double t, int is_expire)
{
if ( is_expire )
return;
sess->HeartBeat(t);
}
void TimerMgrExpireTimer::Dispatch(double t, int is_expire)
{
if ( mgr->LastAdvance() + timer_mgr_inactivity_timeout < timer_mgr->Time() )
@ -105,9 +84,6 @@ NetSessions::NetSessions()
udp_conns.SetDeleteFunc(bro_obj_delete_func);
fragments.SetDeleteFunc(bro_obj_delete_func);
if ( (reading_live || pseudo_realtime) && net_stats_update )
timer_mgr->Add(new NetworkTimer(this, 1.0));
if ( stp_correlate_pair )
stp_manager = new SteppingStoneManager();
else
@ -1049,39 +1025,6 @@ void NetSessions::Drain()
ExpireTimerMgrs();
}
void NetSessions::HeartBeat(double t)
{
unsigned int recv = 0;
unsigned int drop = 0;
unsigned int link = 0;
loop_over_list(pkt_srcs, i)
{
PktSrc* ps = pkt_srcs[i];
struct PktSrc::Stats stat;
ps->Statistics(&stat);
recv += stat.received;
drop += stat.dropped;
link += stat.link;
}
val_list* vl = new val_list;
vl->append(new Val(t, TYPE_TIME));
RecordVal* ns = new RecordVal(net_stats);
ns->Assign(0, new Val(recv, TYPE_COUNT));
ns->Assign(1, new Val(drop, TYPE_COUNT));
ns->Assign(2, new Val(link, TYPE_COUNT));
vl->append(ns);
mgr.QueueEvent(net_stats_update, vl);
timer_mgr->Add(new NetworkTimer(this, t + heartbeat_interval));
}
void NetSessions::GetStats(SessionStats& s) const
{
s.num_TCP_conns = tcp_conns.Length();

View file

@ -75,7 +75,7 @@ public:
void DispatchPacket(double t, const struct pcap_pkthdr* hdr,
const u_char* const pkt, int hdr_size,
PktSrc* src_ps, PacketSortElement* pkt_elem);
void Done(); // call to drain events before destructing
// Returns a reassembled packet, or nil if there are still
@ -105,9 +105,6 @@ public:
// that are still active.
void Drain();
// Called periodically to generate statistics reports.
void HeartBeat(double t);
void GetStats(SessionStats& s) const;
void Weird(const char* name,
@ -177,7 +174,7 @@ protected:
void NextPacket(double t, const struct pcap_pkthdr* hdr,
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);
@ -185,7 +182,7 @@ protected:
void NextPacketSecondary(double t, const struct pcap_pkthdr* hdr,
const u_char* const pkt, int hdr_size,
const PktSrc* src_ps);
// Record the given packet (if a dumper is active). If len=0
// then the whole packet is recorded, otherwise just the first
// len bytes.

View file

@ -14,6 +14,7 @@
using namespace std;
RecordType* ftp_port;
RecordType* net_stats;
RecordType* bro_resources;
RecordType* matcher_stats;
TableType* var_sizes;
@ -1471,6 +1472,31 @@ function bytestring_to_hexstr%(bytestring: string%): string
extern const char* bro_version();
%%}
function net_stats%(%): NetStats
%{
unsigned int recv = 0;
unsigned int drop = 0;
unsigned int link = 0;
loop_over_list(pkt_srcs, i)
{
PktSrc* ps = pkt_srcs[i];
struct PktSrc::Stats stat;
ps->Statistics(&stat);
recv += stat.received;
drop += stat.dropped;
link += stat.link;
}
RecordVal* ns = new RecordVal(net_stats);
ns->Assign(0, new Val(recv, TYPE_COUNT));
ns->Assign(1, new Val(drop, TYPE_COUNT));
ns->Assign(2, new Val(link, TYPE_COUNT));
return ns;
%}
function resource_usage%(%): bro_resources
%{
struct rusage r;

View file

@ -53,7 +53,6 @@ event icmp_echo_reply%(c: connection, icmp: icmp_conn, id: count, seq: count, pa
event icmp_unreachable%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
event icmp_time_exceeded%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
event icmp_redirect%(c: connection, icmp: icmp_conn, a: addr%);
event net_stats_update%(t: time, ns: net_stats%);
event conn_stats%(c: connection, os: endpoint_stats, rs: endpoint_stats%);
event conn_weird%(name: string, c: connection%);
event conn_weird_addl%(name: string, c: connection, addl: string%);

View file

@ -888,7 +888,8 @@ int main(int argc, char** argv)
UnserialInfo info(&s);
info.print = stdout;
info.install_uniques = true;
s.Read(&info, bst_file);
if ( ! s.Read(&info, bst_file) )
error("Failed to read events from %s\n", bst_file);
}
exit(0);

View file

@ -438,6 +438,7 @@ nb_dns_activity(struct nb_dns_info *nd, struct nb_dns_result *nr, char *errstr)
register char **ap, **hap;
register u_int16_t id;
register const u_char *rdata;
register u_int32_t rttl;
register struct hostent *he;
register size_t rdlen;
ns_msg handle;
@ -557,6 +558,7 @@ nb_dns_activity(struct nb_dns_info *nd, struct nb_dns_result *nr, char *errstr)
rdata = ns_rr_rdata(rr);
rdlen = ns_rr_rdlen(rr);
rttl = ns_rr_ttl(rr);
switch (atype) {
case T_A:
@ -603,10 +605,12 @@ nb_dns_activity(struct nb_dns_info *nd, struct nb_dns_result *nr, char *errstr)
/* "Find first satisfactory answer" */
nr->hostent = he;
nr->ttl = rttl;
return (1);
}
}
nr->hostent = he;
nr->ttl = rttl;
return (1);
}

View file

@ -11,6 +11,7 @@ struct nb_dns_result {
void *cookie;
int host_errno;
struct hostent *hostent;
uint32_t ttl;
};
typedef unsigned int nb_uint32_t;

View file

@ -8,6 +8,7 @@
#include <list>
#include <string>
#include <algorithm>
#include <sys/stat.h>
#include "input.h"
#include "util.h"
@ -54,8 +55,9 @@ char last_tok[128];
if ( ((result = fread(buf, 1, max_size, yyin)) == 0) && ferror(yyin) ) \
error(fmt("read failed with \"%s\"", strerror(errno)));
// Files we have already scanned (or are in the process of scanning).
static PList(char) files_scanned;
// Files we have already scanned (or are in the process of scanning). They
// are tracked by inode number.
static std::list<ino_t> files_scanned;
// reST documents that we've created (or have at least opened so far).
std::list<BroDoc*> docs_generated;
@ -84,6 +86,19 @@ static const char* canon_doc_comment(const char* comment)
return ( comment[0] == ' ' ) ? comment + 1 : comment;
}
static ino_t get_inode_num(FILE* f, const char* filename)
{
struct stat b;
if ( fstat(fileno(f), &b) )
{
error("failed to fstat fd of %s\n", filename);
exit(1);
}
return b.st_ino;
}
class FileInfo {
public:
FileInfo(string restore_module = "");
@ -332,7 +347,18 @@ when return TOK_WHEN;
const char* new_file = skip_whitespace(yytext + 7);
// All we have to do is pretend we've already scanned it.
files_scanned.append(copy_string(new_file));
const char* full_filename;
FILE* f = search_for_file(new_file, "bro", &full_filename, true);
if ( f )
{
ino_t i = get_inode_num(f, full_filename);
fclose(f);
delete [] full_filename;
files_scanned.push_back(i);
}
else
error("failed find file associated with @unload %s", new_file);
}
@prefixes{WS}("+"?)={WS}{PREFIX} {
@ -499,33 +525,10 @@ YYLTYPE GetCurrentLocation()
static int load_files_with_prefix(const char* orig_file)
{
loop_over_list(files_scanned, j)
{
if ( streq(files_scanned[j], orig_file) )
return 0;
}
// Be sure to copy "orig_file", since it could be an alias
// for yytext, which is ephemeral and will be zapped
// if we do a yy_switch_to_buffer() below.
char* file = copy_string(orig_file);
// Whether we pushed on a FileInfo that will restore the
// current module after the final file has been scanned.
bool did_module_restore = false;
files_scanned.append(file);
// If the file has a .bro extension, add a second version to the list
// of known files which has it stripped.
char* ext = strrchr(file, '.');
if ( ext && streq(ext, ".bro") )
{
char* s = copy_string(file);
s[ext - file] = '\0';
files_scanned.append(s);
}
// Note, we need to loop through the prefixes backwards, since
// we push them onto a stack, with the last one we push on the
// stack being the first one we will scan.
@ -536,7 +539,7 @@ static int load_files_with_prefix(const char* orig_file)
const char* full_filename = "<internal error>";
FILE* f;
if ( streq(file, "-") )
if ( streq(orig_file, "-") )
{
f = stdin;
full_filename = "<stdin>";
@ -550,13 +553,13 @@ static int load_files_with_prefix(const char* orig_file)
else
{
int n = strlen(prefix) + strlen(file) + 2;
int n = strlen(prefix) + strlen(orig_file) + 2;
char* new_filename = new char[n];
if ( prefix[0] )
sprintf(new_filename, "%s.%s", prefix, file);
sprintf(new_filename, "%s.%s", prefix, orig_file);
else
strcpy(new_filename, file);
strcpy(new_filename, orig_file);
f = search_for_file(new_filename, "bro", &full_filename, true);
delete [] new_filename;
@ -564,6 +567,21 @@ static int load_files_with_prefix(const char* orig_file)
if ( f )
{
ino_t i = get_inode_num(f, full_filename);
std::list<ino_t>::const_iterator it;
for ( it = files_scanned.begin(); it != files_scanned.end(); ++it )
{
if ( *it == i )
{
fclose(f);
delete [] full_filename;
return 0;
}
}
files_scanned.push_back(i);
if ( g_policy_debug )
{
// Add the filename to the file mapping