zeek/policy.old/time-machine/time-machine.bro
2011-03-01 10:51:44 -05:00

278 lines
7.3 KiB
Text

# $Id: time-machine.bro,v 1.1.2.8 2006/01/06 01:51:37 sommer Exp $
#
# Low-level time-machine interface.
@load notice
module TimeMachine;
export {
# Request to send us a connection. Automatically subscribes
# and suspends cut-off.
#
# start : time where to start searching (0 for as early as possible).
# in_mem: only scan TM's memory-buffer but not any on-disk data.
# descr: description to be written to log file to identify the query
#
# Returns tag of this query.
global request_connection:
function(c: connection, in_mem: bool, descr: string) : string;
# id$orig_p = 0/tcp acts as wildcard.
global request_connection_id:
function(id: conn_id, start: time, in_mem: bool, descr: string)
: string;
# Request to save connection to file in TM host. Automatically
# suspends cut-off.
#
# filename: destination file on TM host.
# start : time where to start searching (0 = as early as possible).
# in_mem : only scan TM's memory-buffer, but not any on-disk data.
global capture_connection:
function(filename: string, c: connection, in_mem: bool,
descr: string);
# id$orig_p = 0/tcp acts as wildcard.
global capture_connection_id:
function(filename: string, id: conn_id, start: time,
in_mem: bool, descr: string);
# Request to send everything involving a certain host to us.
# Always searches mem and disk buffers.
#
# host : address of host
# start: time where to start searching (0 for as early as possible).
#
# Returns tag of this query.
global request_addr: function(host: addr, start: time,
in_mem: bool, descr: string) : string;
# Don't issue duplicate queries. Should be on for normal use;
# only need to turn off for benchmarking.
global filter_duplicates = T &redef;
# Automatically issue suspend_cutoff as specified above.
# Should be on for normal use; off only used for benchmarking.
global auto_suspend_cutoff = T &redef;
# Automatically subscribe as specified above.
# Should be on for normal use; off only used for benchmarking.
global auto_subscribe = F &redef;
# Automatically set start time for query.
# Should be on for normal use; off only used for benchmarking.
global auto_set_start = T &redef;
# Request to save everything involving a certain host.
# Always searches mem and disk buffers.
#
# filename: destination file on TM host.
# host : address of host
# start: time where to start searching (0 for as early as possible).
#
global capture_addr: function(filename: string, host: addr,
start: time, in_mem: bool,
descr: string);
# Prevent the TM from cutting the connection off.
global suspend_cut_off: function(c: connection, descr: string);
# id$orig_p = 0/tcp acts as wildcard.
global suspend_cut_off_id: function(id: conn_id, descr: string);
type Direction: enum {
ORIG, # connections originating from host
RESP, # connections responded to by host
BOTH # independent of direction
};
# Change the TM class for given IP.
global set_class: function(host: addr, class: string, dir: Direction,
descr: string);
# Revoke class assignment for IP.
global unset_class: function(host: addr, descr: string);
# ID of this Bro instance for TM queries. Automatically set.
global feed_id = "";
}
global tag = 0;
global cmds: table[string] of string &read_expire = 1 day;
global command: event(cmd: string);
global descrs: table[string] of string;
global profile: file;
global logfile = open_log_file("tm");
function id2str(id: conn_id, include_index: bool) : string
{
local index = "";
if ( include_index )
index = id$orig_p != 0/tcp ? "connection4 " : "connection3 ";
if ( id$orig_p != 0/tcp)
return fmt("%s\"%s %s:%d %s:%d\"", index,
get_port_transport_proto(id$resp_p),
id$orig_h, id$orig_p,
id$resp_h, id$resp_p);
else
return fmt("%s\"%s %s %s:%d\"", index,
get_port_transport_proto(id$resp_p),
id$orig_h,
id$resp_h, id$resp_p);
}
function issue_query(result: string, add_tag: bool, cmd: string,
start: time, in_mem: bool, sub: bool, descr: string) : string
{
local key = fmt("%s %s", result, cmd);
local qtag = "";
if ( key in cmds && filter_duplicates )
return cmds[key];
if ( add_tag )
{
qtag = fmt("t%x", ++tag);
result = fmt("%s tag %s", result, qtag);
}
local range = "";
if ( time_to_double(start) > 0.0 && auto_set_start )
{ # We subtract a few seconds to allow for clock skew.
start = start - 2 secs;
range += fmt("start %.6f end 9876543210 ", start);
}
if ( in_mem )
range += "mem_only ";
if ( sub )
range += "subscribe ";
local c = fmt("query %s %s %s", result, cmd, range);
descrs[c] = descr;
if ( time_machine_profiling )
print profile, fmt("%.6f %s %s", current_time(),
(qtag != "" ? qtag : "-"), c);
event TimeMachine::command(c);
cmds[key] = qtag;
return qtag;
}
function issue_command(cmd: string, descr: string)
{
if ( cmd in cmds && filter_duplicates )
return;
descrs[cmd] = descr;
event TimeMachine::command(cmd);
cmds[cmd] = "";
}
function request_connection(c: connection, in_mem: bool, descr: string) : string
{
return request_connection_id(c$id, c$start_time, in_mem, descr);
}
function request_connection_id(id: conn_id, start: time, in_mem: bool,
descr: string) : string
{
if ( auto_suspend_cutoff )
suspend_cut_off_id(id, descr);
return issue_query(fmt("feed %s", feed_id), T,
fmt("index %s", id2str(id, T)), start, in_mem,
auto_subscribe, descr);
}
function capture_connection(filename: string, c: connection,
in_mem: bool, descr: string)
{
capture_connection_id(filename, c$id, c$start_time, in_mem, descr);
}
function capture_connection_id(filename: string, id: conn_id, start: time,
in_mem: bool, descr: string)
{
if ( auto_suspend_cutoff )
suspend_cut_off_id(id, descr);
issue_query(fmt("to_file \"%s\"", filename), F,
fmt("index %s", id2str(id, T)),
start, in_mem, auto_subscribe, descr);
}
function request_addr(host: addr, start: time, in_mem: bool, descr: string)
: string
{
return issue_query(fmt("feed %s", feed_id), T,
fmt("index ip \"%s\"", host), start, in_mem, F, descr);
}
function capture_addr(filename: string, host: addr, start: time,
in_mem: bool, descr: string)
{
issue_query(fmt("to_file \"%s\"", filename), F,
fmt("index ip \"%s\"", host), start, in_mem, F, descr);
}
function suspend_cut_off(c: connection, descr: string)
{
suspend_cut_off_id(c$id, descr);
}
function suspend_cut_off_id(id: conn_id, descr: string)
{
issue_command(fmt("suspend_cutoff %s", id2str(id, F)), descr);
}
function set_class(host: addr, class: string, dir: Direction, descr: string)
{
local d = "";
if ( dir == ORIG )
d = " orig";
else if ( dir == RESP )
d = " resp";
issue_command(fmt("set_dyn_class %s %s%s", host, class, d), descr);
}
function unset_class(host: addr, descr: string)
{
issue_command(fmt("unset_dyn_class %s", host), descr);
}
event command(cmd: string)
{
# We might not know the command if we're just relaying the event
# from external.
if ( cmd in descrs )
{
local descr = descrs[cmd];
delete descrs[cmd];
print logfile, fmt("%.6f %.6f [%s] %s", network_time(), current_time(), descr, cmd);
}
}
event bro_init()
{
set_buf(logfile, F);
# Create a feed ID that's unique across restarts w/ high probability.
feed_id = fmt("%s-%d-%d", gethostname(), getpid(), rand(100));
if ( time_machine_profiling )
profile = open_log_file("tm-prof.queries");
}