Merge remote-tracking branch 'origin/master' into topic/dnthayer/bif-tests

This commit is contained in:
Daniel Thayer 2012-05-25 11:46:44 -05:00
commit 1f53193685
50 changed files with 1131 additions and 375 deletions

View file

@ -1,4 +1,8 @@
2.0-377 | 2012-05-24 16:46:06 -0700
* Documentation fixes. (Jon Siwek and Daniel Thayer)
2.0-372 | 2012-05-17 13:59:45 -0700
* Fix compile errors. (Jon Siwek)

View file

@ -1 +1 @@
2.0-372
2.0-377

@ -1 +1 @@
Subproject commit 95c93494d7192f69d30f208c4caa3bd38adda6fd
Subproject commit 07866915a1450ddd25b888917f494b4824b0cc3f

@ -1 +1 @@
Subproject commit ba9e1aa2f2159deac0cf96863f54405643764df0
Subproject commit 892b60edb967bb456872638f22ba994e84530137

@ -1 +1 @@
Subproject commit e0da8d0e284bbebbaef711c91c1b961580f225d2
Subproject commit 3ee8d4b3232d74ed7bd475819193ad3a4055e2f5

View file

@ -6,8 +6,8 @@ Binary Output with DataSeries
.. rst-class:: opening
Bro's default ASCII log format is not exactly the most efficient
way for storing large volumes of data. An an alternative, Bro comes
with experimental support for `DataSeries
way for storing and searching large volumes of data. An an
alternative, Bro comes with experimental support for `DataSeries
<http://www.hpl.hp.com/techreports/2009/HPL-2009-323.html>`_
output, an efficient binary format for recording structured bulk
data. DataSeries is developed and maintained at HP Labs.
@ -35,9 +35,12 @@ To build and install the two into ``<prefix>``, do::
Please refer to the packages' documentation for more information about
the installation process. In particular, there's more information on
required and optional `dependencies for Lintel
<https://raw.github.com/eric-anderson/Lintel/master/doc/dependencies.txt>`_
<https://raw.github.com/dataseries/Lintel/master/doc/dependencies.txt>`_
and `dependencies for DataSeries
<https://raw.github.com/eric-anderson/DataSeries/master/doc/dependencies.txt>`_
<https://raw.github.com/dataseries/DataSeries/master/doc/dependencies.txt>`_.
For users on RedHat-style systems, you'll need the following::
yum install libxml2-devel boost-devel
Compiling Bro with DataSeries Support
-------------------------------------
@ -166,3 +169,18 @@ with the output files.
The ``man`` pages for these tool show further options, and their
``-h`` option gives some more information (either can be a bit cryptic
unfortunately though).
Deficiencies
------------
Due to limitations of the DataSeries format, one cannot inspect its
files before they have been fully written. In other words, when using
DataSeries, it's currently it's not possible to inspect the live log
files inside the spool directory before they are rotated to their
final location. It seems that this could be fixed with some effort,
and we will work with DataSeries development team on that if the
format gains traction among Bro users.
Likewise, we're considering writing custom command line tools for
interacting with DataSeries files, making that a bit more convenient
than what the standard utilities provide.

View file

@ -77,6 +77,9 @@ export {
node_type: NodeType;
## The IP address of the cluster node.
ip: addr;
## If the *ip* field is a non-global IPv6 address, this field
## can specify a particular :rfc:`4007` ``zone_id``.
zone_id: string &default="";
## The port to which the this local node can connect when
## establishing communication.
p: port;

View file

@ -19,23 +19,26 @@ event bro_init() &priority=9
# Connections from the control node for runtime control and update events.
# Every node in a cluster is eligible for control from this host.
if ( n$node_type == CONTROL )
Communication::nodes["control"] = [$host=n$ip, $connect=F,
$class="control", $events=control_events];
Communication::nodes["control"] = [$host=n$ip, $zone_id=n$zone_id,
$connect=F, $class="control",
$events=control_events];
if ( me$node_type == MANAGER )
{
if ( n$node_type == WORKER && n$manager == node )
Communication::nodes[i] =
[$host=n$ip, $connect=F,
[$host=n$ip, $zone_id=n$zone_id, $connect=F,
$class=i, $events=worker2manager_events, $request_logs=T];
if ( n$node_type == PROXY && n$manager == node )
Communication::nodes[i] =
[$host=n$ip, $connect=F,
[$host=n$ip, $zone_id=n$zone_id, $connect=F,
$class=i, $events=proxy2manager_events, $request_logs=T];
if ( n$node_type == TIME_MACHINE && me?$time_machine && me$time_machine == i )
Communication::nodes["time-machine"] = [$host=nodes[i]$ip, $p=nodes[i]$p,
Communication::nodes["time-machine"] = [$host=nodes[i]$ip,
$zone_id=nodes[i]$zone_id,
$p=nodes[i]$p,
$connect=T, $retry=1min,
$events=tm2manager_events];
}
@ -44,7 +47,8 @@ event bro_init() &priority=9
{
if ( n$node_type == WORKER && n$proxy == node )
Communication::nodes[i] =
[$host=n$ip, $connect=F, $class=i, $sync=T, $auth=T, $events=worker2proxy_events];
[$host=n$ip, $zone_id=n$zone_id, $connect=F, $class=i,
$sync=T, $auth=T, $events=worker2proxy_events];
# accepts connections from the previous one.
# (This is not ideal for setups with many proxies)
@ -53,16 +57,18 @@ event bro_init() &priority=9
{
if ( n?$proxy )
Communication::nodes[i]
= [$host=n$ip, $p=n$p,
= [$host=n$ip, $zone_id=n$zone_id, $p=n$p,
$connect=T, $auth=F, $sync=T, $retry=1mins];
else if ( me?$proxy && me$proxy == i )
Communication::nodes[me$proxy]
= [$host=nodes[i]$ip, $connect=F, $auth=T, $sync=T];
= [$host=nodes[i]$ip, $zone_id=nodes[i]$zone_id,
$connect=F, $auth=T, $sync=T];
}
# Finally the manager, to send it status updates.
if ( n$node_type == MANAGER && me$manager == i )
Communication::nodes["manager"] = [$host=nodes[i]$ip,
$zone_id=nodes[i]$zone_id,
$p=nodes[i]$p,
$connect=T, $retry=1mins,
$class=node,
@ -72,6 +78,7 @@ event bro_init() &priority=9
{
if ( n$node_type == MANAGER && me$manager == i )
Communication::nodes["manager"] = [$host=nodes[i]$ip,
$zone_id=nodes[i]$zone_id,
$p=nodes[i]$p,
$connect=T, $retry=1mins,
$class=node,
@ -79,6 +86,7 @@ event bro_init() &priority=9
if ( n$node_type == PROXY && me$proxy == i )
Communication::nodes["proxy"] = [$host=nodes[i]$ip,
$zone_id=nodes[i]$zone_id,
$p=nodes[i]$p,
$connect=T, $retry=1mins,
$sync=T, $class=node,
@ -87,6 +95,7 @@ event bro_init() &priority=9
if ( n$node_type == TIME_MACHINE &&
me?$time_machine && me$time_machine == i )
Communication::nodes["time-machine"] = [$host=nodes[i]$ip,
$zone_id=nodes[i]$zone_id,
$p=nodes[i]$p,
$connect=T,
$retry=1min,

View file

@ -2,6 +2,7 @@
##! and/or transfer events.
@load base/frameworks/packet-filter
@load base/utils/addrs
module Communication;
@ -10,7 +11,7 @@ export {
## The communication logging stream identifier.
redef enum Log::ID += { LOG };
## Which interface to listen on (0.0.0.0 for any interface).
## Which interface to listen on (``0.0.0.0`` or ``[::]`` are wildcards).
const listen_interface = 0.0.0.0 &redef;
## Which port to listen on.
@ -19,6 +20,19 @@ export {
## This defines if a listening socket should use SSL.
const listen_ssl = F &redef;
## Defines if a listening socket can bind to IPv6 addresses.
const listen_ipv6 = F &redef;
## If :bro:id:`Communication::listen_interface` is a non-global
## IPv6 address and requires a specific :rfc:`4007` ``zone_id``,
## it can be specified here.
const listen_ipv6_zone_id = "" &redef;
## Defines the interval at which to retry binding to
## :bro:id:`Communication::listen_interface` on
## :bro:id:`Communication::listen_port` if it's already in use.
const listen_retry = 30 secs &redef;
## Default compression level. Compression level is 0-9, with 0 = no
## compression.
global compression_level = 0 &redef;
@ -52,6 +66,10 @@ export {
## Remote address.
host: addr;
## If the *host* field is a non-global IPv6 address, this field
## can specify a particular :rfc:`4007` ``zone_id``.
zone_id: string &optional;
## Port of the remote Bro communication endpoint if we are initiating
## the connection based on the :bro:id:`connect` field.
p: port &optional;
@ -160,7 +178,7 @@ event remote_log(level: count, src: count, msg: string)
# This is a core generated event.
event remote_log_peer(p: event_peer, level: count, src: count, msg: string)
{
local rmsg = fmt("[#%d/%s:%d] %s", p$id, p$host, p$p, msg);
local rmsg = fmt("[#%d/%s:%d] %s", p$id, addr_to_uri(p$host), p$p, msg);
do_script_log_common(level, src, rmsg);
}
@ -178,7 +196,8 @@ function connect_peer(peer: string)
p = node$p;
local class = node?$class ? node$class : "";
local id = connect(node$host, p, class, node$retry, node$ssl);
local zone_id = node?$zone_id ? node$zone_id : "";
local id = connect(node$host, zone_id, p, class, node$retry, node$ssl);
if ( id == PEER_ID_NONE )
Log::write(Communication::LOG, [$ts = network_time(),

View file

@ -11,6 +11,10 @@ export {
## The port of the host that will be controlled.
const host_port = 0/tcp &redef;
## If :bro:id:`Control::host` is a non-global IPv6 address and
## requires a specific :rfc:`4007` ``zone_id``, it can be set here.
const zone_id = "" &redef;
## The command that is being done. It's typically set on the
## command line.
const cmd = "" &redef;

View file

@ -10,7 +10,7 @@ export {
## 'lzo' -- LZO compression. Very fast decompression times.
## 'gz' -- GZIP compression. Slower than LZF, but also produces smaller output.
## 'bz2' -- BZIP2 compression. Slower than GZIP, but also produces smaller output.
const compression = "lzo" &redef;
const compression = "gz" &redef;
## The extent buffer size.
## Larger values here lead to better compression and more efficient writes, but

View file

@ -178,9 +178,9 @@ type endpoint_stats: record {
## use ``count``. That should be changed.
type AnalyzerID: count;
## Statistics about an endpoint.
## Statistics about a :bro:type:`connection` endpoint.
##
## todo::Where is this used?
## .. bro:see:: connection
type endpoint: record {
size: count; ##< Logical size of data sent (for TCP: derived from sequence numbers).
## Endpoint state. For TCP connection, one of the constants:
@ -194,6 +194,9 @@ type endpoint: record {
## Number of IP-level bytes sent. Only set if :bro:id:`use_conn_size_analyzer` is
## true.
num_bytes_ip: count &optional;
## The current IPv6 flow label that the connection endpoint is using.
## Always 0 if the connection is over IPv4.
flow_label: count;
};
# A connection. This is Bro's basic connection type describing IP- and
@ -219,7 +222,7 @@ type connection: record {
service: set[string];
addl: string; ##< Deprecated.
hot: count; ##< Deprecated.
history: string; ##< State history of TCP connections. See *history* in :bro:see:`Conn::Info`.
history: string; ##< State history of connections. See *history* in :bro:see:`Conn::Info`.
## A globally unique connection identifier. For each connection, Bro creates an ID
## that is very likely unique across independent Bro runs. These IDs can thus be
## used to tag and locate information associated with that connection.
@ -967,7 +970,7 @@ const IPPROTO_MOBILITY = 135; ##< IPv6 mobility header.
## Values extracted from an IPv6 extension header's (e.g. hop-by-hop or
## destination option headers) option field.
##
## .. bro:see:: ip6_hdr ip6_hdr_chain ip6_hopopts ip6_dstopts
## .. bro:see:: ip6_hdr ip6_ext_hdr ip6_hopopts ip6_dstopts
type ip6_option: record {
otype: count; ##< Option type.
len: count; ##< Option data length.
@ -976,7 +979,7 @@ type ip6_option: record {
## Values extracted from an IPv6 Hop-by-Hop options extension header.
##
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain ip6_option
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_ext_hdr ip6_option
type ip6_hopopts: record {
## Protocol number of the next header (RFC 1700 et seq., IANA assigned
## number), e.g. :bro:id:`IPPROTO_ICMP`.
@ -989,7 +992,7 @@ type ip6_hopopts: record {
## Values extracted from an IPv6 Destination options extension header.
##
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain ip6_option
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_ext_hdr ip6_option
type ip6_dstopts: record {
## Protocol number of the next header (RFC 1700 et seq., IANA assigned
## number), e.g. :bro:id:`IPPROTO_ICMP`.
@ -1002,7 +1005,7 @@ type ip6_dstopts: record {
## Values extracted from an IPv6 Routing extension header.
##
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_ext_hdr
type ip6_routing: record {
## Protocol number of the next header (RFC 1700 et seq., IANA assigned
## number), e.g. :bro:id:`IPPROTO_ICMP`.
@ -1019,7 +1022,7 @@ type ip6_routing: record {
## Values extracted from an IPv6 Fragment extension header.
##
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_ext_hdr
type ip6_fragment: record {
## Protocol number of the next header (RFC 1700 et seq., IANA assigned
## number), e.g. :bro:id:`IPPROTO_ICMP`.
@ -1038,7 +1041,7 @@ type ip6_fragment: record {
## Values extracted from an IPv6 Authentication extension header.
##
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_ext_hdr
type ip6_ah: record {
## Protocol number of the next header (RFC 1700 et seq., IANA assigned
## number), e.g. :bro:id:`IPPROTO_ICMP`.
@ -1057,7 +1060,7 @@ type ip6_ah: record {
## Values extracted from an IPv6 ESP extension header.
##
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_ext_hdr
type ip6_esp: record {
## Security Parameters Index.
spi: count;
@ -1067,7 +1070,7 @@ type ip6_esp: record {
## Values extracted from an IPv6 Mobility Binding Refresh Request message.
##
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_ext_hdr ip6_mobility_msg
type ip6_mobility_brr: record {
## Reserved.
rsv: count;
@ -1077,7 +1080,7 @@ type ip6_mobility_brr: record {
## Values extracted from an IPv6 Mobility Home Test Init message.
##
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_ext_hdr ip6_mobility_msg
type ip6_mobility_hoti: record {
## Reserved.
rsv: count;
@ -1089,7 +1092,7 @@ type ip6_mobility_hoti: record {
## Values extracted from an IPv6 Mobility Care-of Test Init message.
##
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_ext_hdr ip6_mobility_msg
type ip6_mobility_coti: record {
## Reserved.
rsv: count;
@ -1101,7 +1104,7 @@ type ip6_mobility_coti: record {
## Values extracted from an IPv6 Mobility Home Test message.
##
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_ext_hdr ip6_mobility_msg
type ip6_mobility_hot: record {
## Home Nonce Index.
nonce_idx: count;
@ -1115,7 +1118,7 @@ type ip6_mobility_hot: record {
## Values extracted from an IPv6 Mobility Care-of Test message.
##
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_ext_hdr ip6_mobility_msg
type ip6_mobility_cot: record {
## Care-of Nonce Index.
nonce_idx: count;
@ -1129,7 +1132,7 @@ type ip6_mobility_cot: record {
## Values extracted from an IPv6 Mobility Binding Update message.
##
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_ext_hdr ip6_mobility_msg
type ip6_mobility_bu: record {
## Sequence number.
seq: count;
@ -1149,7 +1152,7 @@ type ip6_mobility_bu: record {
## Values extracted from an IPv6 Mobility Binding Acknowledgement message.
##
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_ext_hdr ip6_mobility_msg
type ip6_mobility_back: record {
## Status.
status: count;
@ -1165,7 +1168,7 @@ type ip6_mobility_back: record {
## Values extracted from an IPv6 Mobility Binding Error message.
##
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain ip6_mobility_msg
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_ext_hdr ip6_mobility_msg
type ip6_mobility_be: record {
## Status.
status: count;
@ -1177,7 +1180,7 @@ type ip6_mobility_be: record {
## Values extracted from an IPv6 Mobility header's message data.
##
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_hdr_chain
## .. bro:see:: ip6_mobility_hdr ip6_hdr ip6_ext_hdr
type ip6_mobility_msg: record {
## The type of message from the header's MH Type field.
id: count;
@ -1201,7 +1204,7 @@ type ip6_mobility_msg: record {
## Values extracted from an IPv6 Mobility header.
##
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_hdr_chain
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_ext_hdr
type ip6_mobility_hdr: record {
## Protocol number of the next header (RFC 1700 et seq., IANA assigned
## number), e.g. :bro:id:`IPPROTO_ICMP`.
@ -1244,7 +1247,7 @@ type ip6_ext_hdr: record {
## Values extracted from an IPv6 header.
##
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr_chain ip6_hopopts ip6_dstopts
## .. bro:see:: pkt_hdr ip4_hdr ip6_ext_hdr ip6_hopopts ip6_dstopts
## ip6_routing ip6_fragment ip6_ah ip6_esp
type ip6_hdr: record {
class: count; ##< Traffic class.

View file

@ -68,7 +68,7 @@ export {
missed_bytes: count &log &default=0;
## Records the state history of connections as a string of letters.
## For TCP connections the meaning of those letters is:
## The meaning of those letters is:
##
## ====== ====================================================
## Letter Meaning

View file

@ -8,5 +8,6 @@ module Communication;
event bro_init() &priority=-10
{
enable_communication();
listen(listen_interface, listen_port, listen_ssl);
listen(listen_interface, listen_port, listen_ssl, listen_ipv6,
listen_ipv6_zone_id, listen_retry);
}

View file

@ -25,8 +25,8 @@ event bro_init() &priority=5
# Establish the communication configuration and only request response
# messages.
Communication::nodes["control"] = [$host=host, $p=host_port,
$sync=F, $connect=T,
Communication::nodes["control"] = [$host=host, $zone_id=zone_id,
$p=host_port, $sync=F, $connect=T,
$class="control", $events=Control::controllee_events];
}

View file

@ -111,7 +111,8 @@ unsigned int Connection::external_connections = 0;
IMPLEMENT_SERIAL(Connection, SER_CONNECTION);
Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id)
Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
uint32 flow)
{
sessions = s;
key = k;
@ -122,6 +123,10 @@ Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id)
orig_port = id->src_port;
resp_port = id->dst_port;
proto = TRANSPORT_UNKNOWN;
orig_flow_label = flow;
resp_flow_label = 0;
saw_first_orig_packet = 1;
saw_first_resp_packet = 0;
conn_val = 0;
login_conn = 0;
@ -323,10 +328,12 @@ RecordVal* Connection::BuildConnVal()
RecordVal *orig_endp = new RecordVal(endpoint);
orig_endp->Assign(0, new Val(0, TYPE_COUNT));
orig_endp->Assign(1, new Val(0, TYPE_COUNT));
orig_endp->Assign(4, new Val(orig_flow_label, TYPE_COUNT));
RecordVal *resp_endp = new RecordVal(endpoint);
resp_endp->Assign(0, new Val(0, TYPE_COUNT));
resp_endp->Assign(1, new Val(0, TYPE_COUNT));
resp_endp->Assign(4, new Val(resp_flow_label, TYPE_COUNT));
conn_val->Assign(0, id_val);
conn_val->Assign(1, orig_endp);
@ -675,6 +682,14 @@ void Connection::FlipRoles()
resp_port = orig_port;
orig_port = tmp_port;
bool tmp_bool = saw_first_resp_packet;
saw_first_resp_packet = saw_first_orig_packet;
saw_first_orig_packet = tmp_bool;
uint32 tmp_flow = resp_flow_label;
resp_flow_label = orig_flow_label;
orig_flow_label = tmp_flow;
Unref(conn_val);
conn_val = 0;
@ -882,3 +897,35 @@ void Connection::SetRootAnalyzer(TransportLayerAnalyzer* analyzer, PIA* pia)
root_analyzer = analyzer;
primary_PIA = pia;
}
void Connection::CheckFlowLabel(bool is_orig, uint32 flow_label)
{
uint32& my_flow_label = is_orig ? orig_flow_label : resp_flow_label;
if ( my_flow_label != flow_label )
{
if ( conn_val )
{
RecordVal *endp = conn_val->Lookup(is_orig ? 1 : 2)->AsRecordVal();
endp->Assign(4, new Val(flow_label, TYPE_COUNT));
}
if ( connection_flow_label_changed &&
(is_orig ? saw_first_orig_packet : saw_first_resp_packet) )
{
val_list* vl = new val_list(4);
vl->append(BuildConnVal());
vl->append(new Val(is_orig, TYPE_BOOL));
vl->append(new Val(my_flow_label, TYPE_COUNT));
vl->append(new Val(flow_label, TYPE_COUNT));
ConnectionEvent(connection_flow_label_changed, 0, vl);
}
my_flow_label = flow_label;
}
if ( is_orig )
saw_first_orig_packet = 1;
else
saw_first_resp_packet = 1;
}

View file

@ -50,7 +50,8 @@ class Analyzer;
class Connection : public BroObj {
public:
Connection(NetSessions* s, HashKey* k, double t, const ConnID* id);
Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
uint32 flow);
virtual ~Connection();
// Invoked when connection is about to be removed. Use Ref(this)
@ -241,6 +242,8 @@ public:
void SetUID(uint64 arg_uid) { uid = arg_uid; }
void CheckFlowLabel(bool is_orig, uint32 flow_label);
protected:
Connection() { persistent = 0; }
@ -271,6 +274,7 @@ protected:
IPAddr resp_addr;
uint32 orig_port, resp_port; // in network order
TransportProto proto;
uint32 orig_flow_label, resp_flow_label; // most recent IPv6 flow labels
double start_time, last_time;
double inactivity_timeout;
RecordVal* conn_val;
@ -286,6 +290,7 @@ protected:
unsigned int record_packets:1, record_contents:1;
unsigned int persistent:1;
unsigned int record_current_packet:1, record_current_content:1;
unsigned int saw_first_orig_packet:1, saw_first_resp_packet:1;
// Count number of connections.
static unsigned int total_connections;

View file

@ -524,6 +524,12 @@ public:
int DF() const
{ return ip4 ? ((ntohs(ip4->ip_off) & 0x4000) != 0) : 0; }
/**
* Returns value of an IPv6 header's flow label field or 0 if it's IPv4.
*/
uint32 FlowLabel() const
{ return ip4 ? 0 : (ntohl(ip6->ip6_flow) & 0x000fffff); }
/**
* Returns number of IP headers in packet (includes IPv6 extension headers).
*/

View file

@ -188,11 +188,20 @@ public:
* IPv4 to IPv6 address mapping to return a full 16 bytes.
*
* @param bytes The pointer to a memory location in which the
* raw bytes of the address are to be copied in network byte-order.
* raw bytes of the address are to be copied.
*
* @param order The byte-order in which the returned raw bytes are copied.
* The default is network order.
*/
void CopyIPv6(uint32_t* bytes) const
void CopyIPv6(uint32_t* bytes, ByteOrder order = Network) const
{
memcpy(bytes, in6.s6_addr, sizeof(in6.s6_addr));
if ( order == Host )
{
for ( unsigned int i = 0; i < 4; ++i )
bytes[i] = ntohl(bytes[i]);
}
}
/**
@ -280,6 +289,19 @@ public:
*/
string AsString() const;
/**
* Returns a string representation of the address suitable for inclusion
* in an URI. For IPv4 addresses, this is the same as AsString(), but
* IPv6 addresses are encased in square brackets.
*/
string AsURIString() const
{
if ( GetFamily() == IPv4 )
return AsString();
else
return string("[") + AsString() + "]";
}
/**
* Returns a host-order, plain hex string representation of the address.
*/

View file

@ -147,6 +147,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <unistd.h>
@ -172,6 +173,9 @@
#include <sys/resource.h>
#include <algorithm>
#include <string>
#include <sstream>
#include <vector>
#include "RemoteSerializer.h"
#include "Func.h"
@ -322,6 +326,18 @@ static const char* msgToStr(int msg)
}
}
static vector<string> tokenize(const string& s, char delim)
{
vector<string> tokens;
stringstream ss(s);
string token;
while ( std::getline(ss, token, delim) )
tokens.push_back(token);
return tokens;
}
// Start of every message between two processes. We do the low-level work
// ourselves to make this 64-bit safe. (The actual layout is an artifact of
// an earlier design that depended on how a 32-bit GCC lays out its structs ...)
@ -458,17 +474,6 @@ static inline char* fmt_uint32s(int nargs, va_list ap)
}
#endif
static inline const char* ip2a(uint32 ip)
{
static char buffer[32];
struct in_addr addr;
addr.s_addr = htonl(ip);
return bro_inet_ntop(AF_INET, &addr, buffer, 32);
}
static pid_t child_pid = 0;
// Return true if message type is sent by a peer (rather than the child
@ -675,7 +680,8 @@ void RemoteSerializer::Fork()
}
RemoteSerializer::PeerID RemoteSerializer::Connect(const IPAddr& ip,
uint16 port, const char* our_class, double retry, bool use_ssl)
const string& zone_id, uint16 port, const char* our_class, double retry,
bool use_ssl)
{
if ( ! using_communication )
return true;
@ -683,24 +689,22 @@ RemoteSerializer::PeerID RemoteSerializer::Connect(const IPAddr& ip,
if ( ! initialized )
reporter->InternalError("remote serializer not initialized");
if ( ip.GetFamily() == IPv6 )
Error("inter-Bro communication not supported over IPv6");
const uint32* bytes;
ip.GetBytes(&bytes);
uint32 ip4 = ntohl(*bytes);
if ( ! child_pid )
Fork();
Peer* p = AddPeer(ip4, port);
Peer* p = AddPeer(ip, port);
p->orig = true;
if ( our_class )
p->our_class = our_class;
if ( ! SendToChild(MSG_CONNECT_TO, p, 5, p->id,
ip4, port, uint32(retry), use_ssl) )
const size_t BUFSIZE = 1024;
char* data = new char[BUFSIZE];
snprintf(data, BUFSIZE, "%"PRIu64",%s,%s,%"PRIu16",%"PRIu32",%d", p->id,
ip.AsString().c_str(), zone_id.c_str(), port, uint32(retry),
use_ssl);
if ( ! SendToChild(MSG_CONNECT_TO, p, data) )
{
RemovePeer(p);
return false;
@ -1232,7 +1236,8 @@ bool RemoteSerializer::SendCapabilities(Peer* peer)
return caps ? SendToChild(MSG_CAPS, peer, 3, caps, 0, 0) : true;
}
bool RemoteSerializer::Listen(const IPAddr& ip, uint16 port, bool expect_ssl)
bool RemoteSerializer::Listen(const IPAddr& ip, uint16 port, bool expect_ssl,
bool ipv6, const string& zone_id, double retry)
{
if ( ! using_communication )
return true;
@ -1240,14 +1245,18 @@ bool RemoteSerializer::Listen(const IPAddr& ip, uint16 port, bool expect_ssl)
if ( ! initialized )
reporter->InternalError("remote serializer not initialized");
if ( ip.GetFamily() == IPv6 )
Error("inter-Bro communication not supported over IPv6");
if ( ! ipv6 && ip.GetFamily() == IPv6 &&
ip != IPAddr("0.0.0.0") && ip != IPAddr("::") )
reporter->FatalError("Attempt to listen on address %s, but IPv6 "
"communication disabled", ip.AsString().c_str());
const uint32* bytes;
ip.GetBytes(&bytes);
uint32 ip4 = ntohl(*bytes);
const size_t BUFSIZE = 1024;
char* data = new char[BUFSIZE];
snprintf(data, BUFSIZE, "%s,%"PRIu16",%d,%d,%s,%"PRIu32,
ip.AsString().c_str(), port, expect_ssl, ipv6, zone_id.c_str(),
(uint32) retry);
if ( ! SendToChild(MSG_LISTEN, 0, 3, ip4, port, expect_ssl) )
if ( ! SendToChild(MSG_LISTEN, 0, data) )
return false;
listening = true;
@ -1784,7 +1793,7 @@ RecordVal* RemoteSerializer::MakePeerVal(Peer* peer)
RecordVal* v = new RecordVal(::peer);
v->Assign(0, new Val(uint32(peer->id), TYPE_COUNT));
// Sic! Network order for AddrVal, host order for PortVal.
v->Assign(1, new AddrVal(htonl(peer->ip)));
v->Assign(1, new AddrVal(peer->ip));
v->Assign(2, new PortVal(peer->port, TRANSPORT_TCP));
v->Assign(3, new Val(false, TYPE_BOOL));
v->Assign(4, new StringVal("")); // set when received
@ -1793,8 +1802,8 @@ RecordVal* RemoteSerializer::MakePeerVal(Peer* peer)
return v;
}
RemoteSerializer::Peer* RemoteSerializer::AddPeer(uint32 ip, uint16 port,
PeerID id)
RemoteSerializer::Peer* RemoteSerializer::AddPeer(const IPAddr& ip, uint16 port,
PeerID id)
{
Peer* peer = new Peer;
peer->id = id != PEER_NONE ? id : id_counter++;
@ -1959,9 +1968,22 @@ bool RemoteSerializer::EnterPhaseRunning(Peer* peer)
bool RemoteSerializer::ProcessConnected()
{
// IP and port follow.
uint32* args = (uint32*) current_args->data;
uint32 host = ntohl(args[0]); // ### Fix: only works for IPv4
uint16 port = (uint16) ntohl(args[1]);
vector<string> args = tokenize(current_args->data, ',');
if ( args.size() != 2 )
{
InternalCommError("ProcessConnected() bad number of arguments");
return false;
}
IPAddr host = IPAddr(args[0]);
uint16 port;
if ( ! atoi_n(args[1].size(), args[1].c_str(), 0, 10, port) )
{
InternalCommError("ProcessConnected() bad peer port string");
return false;
}
if ( ! current_peer )
{
@ -2980,7 +3002,8 @@ void RemoteSerializer::Log(LogLevel level, const char* msg, Peer* peer,
if ( peer )
len += snprintf(buffer + len, sizeof(buffer) - len, "[#%d/%s:%d] ",
int(peer->id), ip2a(peer->ip), peer->port);
int(peer->id), peer->ip.AsURIString().c_str(),
peer->port);
len += safe_snprintf(buffer + len, sizeof(buffer) - len, "%s", msg);
@ -3266,8 +3289,10 @@ SocketComm::SocketComm()
terminating = false;
killing = false;
listen_fd_clear = -1;
listen_fd_ssl = -1;
listen_port = 0;
listen_ssl = false;
enable_ipv6 = false;
bind_retry_interval = 0;
listen_next_try = 0;
// We don't want to use the signal handlers of our parent.
@ -3290,8 +3315,7 @@ SocketComm::~SocketComm()
delete peers[i]->io;
delete io;
close(listen_fd_clear);
close(listen_fd_ssl);
CloseListenFDs();
}
static unsigned int first_rtime = 0;
@ -3340,20 +3364,13 @@ void SocketComm::Run()
}
if ( listen_next_try && time(0) > listen_next_try )
Listen(listen_if, listen_port, listen_ssl);
Listen();
if ( listen_fd_clear >= 0 )
for ( size_t i = 0; i < listen_fds.size(); ++i )
{
FD_SET(listen_fd_clear, &fd_read);
if ( listen_fd_clear > max_fd )
max_fd = listen_fd_clear;
}
if ( listen_fd_ssl >= 0 )
{
FD_SET(listen_fd_ssl, &fd_read);
if ( listen_fd_ssl > max_fd )
max_fd = listen_fd_ssl;
FD_SET(listen_fds[i], &fd_read);
if ( listen_fds[i] > max_fd )
max_fd = listen_fds[i];
}
if ( io->IsFillingUp() && ! shutting_conns_down )
@ -3442,12 +3459,9 @@ void SocketComm::Run()
}
}
if ( listen_fd_clear >= 0 &&
FD_ISSET(listen_fd_clear, &fd_read) )
AcceptConnection(listen_fd_clear);
if ( listen_fd_ssl >= 0 && FD_ISSET(listen_fd_ssl, &fd_read) )
AcceptConnection(listen_fd_ssl);
for ( size_t i = 0; i < listen_fds.size(); ++i )
if ( FD_ISSET(listen_fds[i], &fd_read) )
AcceptConnection(listen_fds[i]);
// Hack to display CPU usage of the child, triggered via
// SIGPROF.
@ -3571,13 +3585,8 @@ bool SocketComm::DoParentMessage()
case MSG_LISTEN_STOP:
{
if ( listen_fd_ssl >= 0 )
close(listen_fd_ssl);
CloseListenFDs();
if ( listen_fd_clear >= 0 )
close(listen_fd_clear);
listen_fd_clear = listen_fd_ssl = -1;
Log("stopped listening");
return true;
@ -3717,14 +3726,43 @@ bool SocketComm::ForwardChunkToPeer()
bool SocketComm::ProcessConnectTo()
{
assert(parent_args);
uint32* args = (uint32*) parent_args->data;
vector<string> args = tokenize(parent_args->data, ',');
if ( args.size() != 6 )
{
Error(fmt("ProcessConnectTo() bad number of arguments"));
return false;
}
Peer* peer = new Peer;
peer->id = ntohl(args[0]);
peer->ip = ntohl(args[1]);
peer->port = ntohl(args[2]);
peer->retry = ntohl(args[3]);
peer->ssl = ntohl(args[4]);
if ( ! atoi_n(args[0].size(), args[0].c_str(), 0, 10, peer->id) )
{
Error(fmt("ProccessConnectTo() bad peer id string"));
delete peer;
return false;
}
peer->ip = IPAddr(args[1]);
peer->zone_id = args[2];
if ( ! atoi_n(args[3].size(), args[3].c_str(), 0, 10, peer->port) )
{
Error(fmt("ProcessConnectTo() bad peer port string"));
delete peer;
return false;
}
if ( ! atoi_n(args[4].size(), args[4].c_str(), 0, 10, peer->retry) )
{
Error(fmt("ProcessConnectTo() bad peer retry string"));
delete peer;
return false;
}
peer->ssl = false;
if ( args[5] != "0" )
peer->ssl = true;
return Connect(peer);
}
@ -3732,13 +3770,39 @@ bool SocketComm::ProcessConnectTo()
bool SocketComm::ProcessListen()
{
assert(parent_args);
uint32* args = (uint32*) parent_args->data;
vector<string> args = tokenize(parent_args->data, ',');
uint32 addr = ntohl(args[0]);
uint16 port = uint16(ntohl(args[1]));
uint32 ssl = ntohl(args[2]);
if ( args.size() != 6 )
{
Error(fmt("ProcessListen() bad number of arguments"));
return false;
}
return Listen(addr, port, ssl);
listen_if = args[0];
if ( ! atoi_n(args[1].size(), args[1].c_str(), 0, 10, listen_port) )
{
Error(fmt("ProcessListen() bad peer port string"));
return false;
}
listen_ssl = false;
if ( args[2] != "0" )
listen_ssl = true;
enable_ipv6 = false;
if ( args[3] != "0" )
enable_ipv6 = true;
listen_zone_id = args[4];
if ( ! atoi_n(args[5].size(), args[5].c_str(), 0, 10, bind_retry_interval) )
{
Error(fmt("ProcessListen() bad peer port string"));
return false;
}
return Listen();
}
bool SocketComm::ProcessParentCompress()
@ -3900,29 +3964,54 @@ bool SocketComm::ProcessPeerCompress(Peer* peer)
bool SocketComm::Connect(Peer* peer)
{
struct sockaddr_in server;
int status;
addrinfo hints, *res, *res0;
bzero(&hints, sizeof(hints));
int sockfd = socket(PF_INET, SOCK_STREAM, 0);
if ( sockfd < 0 )
hints.ai_family = PF_UNSPEC;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICHOST;
char port_str[16];
modp_uitoa10(peer->port, port_str);
string gaihostname(peer->ip.AsString());
if ( peer->zone_id != "" )
gaihostname.append("%").append(peer->zone_id);
status = getaddrinfo(gaihostname.c_str(), port_str, &hints, &res0);
if ( status != 0 )
{
Error(fmt("can't create socket, %s", strerror(errno)));
Error(fmt("getaddrinfo error: %s", gai_strerror(status)));
return false;
}
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(peer->port);
server.sin_addr.s_addr = htonl(peer->ip);
bool connected = true;
if ( connect(sockfd, (sockaddr*) &server, sizeof(server)) < 0 )
int sockfd = -1;
for ( res = res0; res; res = res->ai_next )
{
Error(fmt("connect failed: %s", strerror(errno)), peer);
close(sockfd);
connected = false;
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if ( sockfd < 0 )
{
Error(fmt("can't create connect socket, %s", strerror(errno)));
continue;
}
if ( connect(sockfd, res->ai_addr, res->ai_addrlen) < 0 )
{
Error(fmt("connect failed: %s", strerror(errno)), peer);
close(sockfd);
sockfd = -1;
continue;
}
break;
}
freeaddrinfo(res0);
bool connected = sockfd != -1;
if ( ! (connected || peer->retry) )
{
CloseConnection(peer, false);
@ -3947,9 +4036,7 @@ bool SocketComm::Connect(Peer* peer)
if ( connected )
{
if ( peer->ssl )
{
peer->io = new ChunkedIOSSL(sockfd, false);
}
else
peer->io = new ChunkedIOFd(sockfd, "child->peer");
@ -3964,7 +4051,13 @@ bool SocketComm::Connect(Peer* peer)
if ( connected )
{
Log("connected", peer);
if ( ! SendToParent(MSG_CONNECTED, peer, 2, peer->ip, peer->port) )
const size_t BUFSIZE = 1024;
char* data = new char[BUFSIZE];
snprintf(data, BUFSIZE, "%s,%"PRIu32, peer->ip.AsString().c_str(),
peer->port);
if ( ! SendToParent(MSG_CONNECTED, peer, data) )
return false;
}
@ -4001,86 +4094,148 @@ bool SocketComm::CloseConnection(Peer* peer, bool reconnect)
return true;
}
bool SocketComm::Listen(uint32 ip, uint16 port, bool expect_ssl)
bool SocketComm::Listen()
{
int* listen_fd = expect_ssl ? &listen_fd_ssl : &listen_fd_clear;
int status, on = 1;
addrinfo hints, *res, *res0;
bzero(&hints, sizeof(hints));
if ( *listen_fd >= 0 )
close(*listen_fd);
IPAddr listen_ip(listen_if);
struct sockaddr_in server;
*listen_fd = socket(PF_INET, SOCK_STREAM, 0);
if ( *listen_fd < 0 )
if ( enable_ipv6 )
{
Error(fmt("can't create listen socket, %s",
strerror(errno)));
if ( listen_ip == IPAddr("0.0.0.0") || listen_ip == IPAddr("::") )
hints.ai_family = PF_UNSPEC;
else
hints.ai_family = (listen_ip.GetFamily() == IPv4 ? PF_INET : PF_INET6);
}
else
hints.ai_family = PF_INET;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
char port_str[16];
modp_uitoa10(listen_port, port_str);
string scoped_addr(listen_if);
if ( listen_zone_id != "" )
scoped_addr.append("%").append(listen_zone_id);
const char* addr_str = 0;
if ( listen_ip != IPAddr("0.0.0.0") && listen_ip != IPAddr("::") )
addr_str = scoped_addr.c_str();
CloseListenFDs();
if ( (status = getaddrinfo(addr_str, port_str, &hints, &res0)) != 0 )
{
Error(fmt("getaddrinfo error: %s", gai_strerror(status)));
return false;
}
// Set SO_REUSEADDR.
int turn_on = 1;
if ( setsockopt(*listen_fd, SOL_SOCKET, SO_REUSEADDR,
&turn_on, sizeof(turn_on)) < 0 )
for ( res = res0; res; res = res->ai_next )
{
Error(fmt("can't set SO_REUSEADDR, %s",
strerror(errno)));
return false;
}
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = htonl(ip);
if ( bind(*listen_fd, (sockaddr*) &server, sizeof(server)) < 0 )
{
Error(fmt("can't bind to port %d, %s", port, strerror(errno)));
close(*listen_fd);
*listen_fd = -1;
if ( errno == EADDRINUSE )
if ( res->ai_family != AF_INET && res->ai_family != AF_INET6 )
{
listen_if = ip;
listen_port = port;
listen_ssl = expect_ssl;
// FIXME: Make this timeout configurable.
listen_next_try = time(0) + 30;
Error(fmt("can't create listen socket: unknown address family, %d",
res->ai_family));
continue;
}
return false;
IPAddr a = (res->ai_family == AF_INET) ?
IPAddr(((sockaddr_in*)res->ai_addr)->sin_addr) :
IPAddr(((sockaddr_in6*)res->ai_addr)->sin6_addr);
string l_addr_str(a.AsURIString());
if ( listen_zone_id != "")
l_addr_str.append("%").append(listen_zone_id);
int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if ( fd < 0 )
{
Error(fmt("can't create listen socket, %s", strerror(errno)));
continue;
}
if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0 )
Error(fmt("can't set SO_REUSEADDR, %s", strerror(errno)));
// For IPv6 listening sockets, we don't want do dual binding to also
// get IPv4-mapped addresses because that's not as portable. e.g.
// many BSDs don't allow that.
if ( res->ai_family == AF_INET6 &&
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0 )
Error(fmt("can't set IPV6_V6ONLY, %s", strerror(errno)));
if ( bind(fd, res->ai_addr, res->ai_addrlen) < 0 )
{
Error(fmt("can't bind to %s:%s, %s", l_addr_str.c_str(),
port_str, strerror(errno)));
close(fd);
if ( errno == EADDRINUSE )
{
// Abandon completely this attempt to set up listening sockets,
// try again later.
CloseListenFDs();
listen_next_try = time(0) + bind_retry_interval;
return false;
}
continue;
}
if ( listen(fd, 50) < 0 )
{
Error(fmt("can't listen on %s:%s, %s", l_addr_str.c_str(),
port_str, strerror(errno)));
close(fd);
continue;
}
listen_fds.push_back(fd);
Log(fmt("listening on %s:%s (%s)", l_addr_str.c_str(), port_str,
listen_ssl ? "ssl" : "clear"));
}
if ( listen(*listen_fd, 50) < 0 )
{
Error(fmt("can't listen, %s", strerror(errno)));
return false;
}
freeaddrinfo(res0);
listen_next_try = 0;
Log(fmt("listening on %s:%d (%s)",
ip2a(ip), port, expect_ssl ? "ssl" : "clear"));
return true;
return listen_fds.size() > 0;
}
bool SocketComm::AcceptConnection(int fd)
{
sockaddr_in client;
sockaddr_storage client;
socklen_t len = sizeof(client);
int clientfd = accept(fd, (sockaddr*) &client, &len);
if ( clientfd < 0 )
{
Error(fmt("accept failed, %s %d",
strerror(errno), errno));
Error(fmt("accept failed, %s %d", strerror(errno), errno));
return false;
}
if ( client.ss_family != AF_INET && client.ss_family != AF_INET6 )
{
Error(fmt("accept fail, unknown address family %d", client.ss_family));
close(clientfd);
return false;
}
Peer* peer = new Peer;
peer->id = id_counter++;
peer->ip = ntohl(client.sin_addr.s_addr);
peer->port = ntohs(client.sin_port);
peer->ip = client.ss_family == AF_INET ?
IPAddr(((sockaddr_in*)&client)->sin_addr) :
IPAddr(((sockaddr_in6*)&client)->sin6_addr);
peer->port = client.ss_family == AF_INET ?
ntohs(((sockaddr_in*)&client)->sin_port) :
ntohs(((sockaddr_in6*)&client)->sin6_port);
peer->connected = true;
peer->ssl = (fd == listen_fd_ssl);
peer->ssl = listen_ssl;
peer->compressor = false;
if ( peer->ssl )
@ -4090,8 +4245,7 @@ bool SocketComm::AcceptConnection(int fd)
if ( ! peer->io->Init() )
{
Error(fmt("can't init peer io: %s",
peer->io->Error()), false);
Error(fmt("can't init peer io: %s", peer->io->Error()), false);
return false;
}
@ -4099,7 +4253,12 @@ bool SocketComm::AcceptConnection(int fd)
Log(fmt("accepted %s connection", peer->ssl ? "SSL" : "clear"), peer);
if ( ! SendToParent(MSG_CONNECTED, peer, 2, peer->ip, peer->port) )
const size_t BUFSIZE = 1024;
char* data = new char[BUFSIZE];
snprintf(data, BUFSIZE, "%s,%"PRIu32, peer->ip.AsString().c_str(),
peer->port);
if ( ! SendToParent(MSG_CONNECTED, peer, data) )
return false;
return true;
@ -4116,13 +4275,27 @@ const char* SocketComm::MakeLogString(const char* msg, Peer* peer)
int len = 0;
if ( peer )
{
string scoped_addr(peer->ip.AsURIString());
if ( peer->zone_id != "" )
scoped_addr.append("%").append(peer->zone_id);
len = snprintf(buffer, BUFSIZE, "[#%d/%s:%d] ", int(peer->id),
ip2a(peer->ip), peer->port);
scoped_addr.c_str(), peer->port);
}
len += safe_snprintf(buffer + len, BUFSIZE - len, "%s", msg);
return buffer;
}
void SocketComm::CloseListenFDs()
{
for ( size_t i = 0; i < listen_fds.size(); ++i )
close(listen_fds[i]);
listen_fds.clear();
}
void SocketComm::Error(const char* msg, bool kill_me)
{
if ( kill_me )
@ -4165,7 +4338,7 @@ void SocketComm::Log(const char* msg, Peer* peer)
void SocketComm::InternalError(const char* msg)
{
fprintf(stderr, "interal error in child: %s\n", msg);
fprintf(stderr, "internal error in child: %s\n", msg);
Kill();
}
@ -4180,8 +4353,7 @@ void SocketComm::Kill()
LogProf();
Log("terminating");
close(listen_fd_clear);
close(listen_fd_ssl);
CloseListenFDs();
kill(getpid(), SIGTERM);

View file

@ -10,8 +10,8 @@
#include "Stats.h"
#include "File.h"
// All IP arguments are in host byte-order.
// FIXME: Change this to network byte order
#include <vector>
#include <string>
class IncrementalSendTimer;
@ -35,7 +35,8 @@ public:
static const PeerID PEER_NONE = SOURCE_LOCAL;
// Connect to host (returns PEER_NONE on error).
PeerID Connect(const IPAddr& ip, uint16 port, const char* our_class, double retry, bool use_ssl);
PeerID Connect(const IPAddr& ip, const string& zone_id, uint16 port,
const char* our_class, double retry, bool use_ssl);
// Close connection to host.
bool CloseConnection(PeerID peer);
@ -63,7 +64,8 @@ public:
bool CompleteHandshake(PeerID peer);
// Start to listen.
bool Listen(const IPAddr& ip, uint16 port, bool expect_ssl);
bool Listen(const IPAddr& ip, uint16 port, bool expect_ssl, bool ipv6,
const string& zone_id, double retry);
// Stop it.
bool StopListening();
@ -179,9 +181,7 @@ protected:
struct Peer {
PeerID id; // Unique ID (non-zero) per peer.
// ### Fix: currently, we only work for IPv4.
// addr_type ip;
uint32 ip;
IPAddr ip;
uint16 port;
handler_list handlers;
@ -277,7 +277,7 @@ protected:
bool ProcessLogWrite();
bool ProcessRequestLogs();
Peer* AddPeer(uint32 ip, uint16 port, PeerID id = PEER_NONE);
Peer* AddPeer(const IPAddr& ip, uint16 port, PeerID id = PEER_NONE);
Peer* LookupPeer(PeerID id, bool only_if_connected);
void RemovePeer(Peer* peer);
bool IsConnectedPeer(PeerID id);
@ -412,7 +412,6 @@ protected:
{
id = 0;
io = 0;
ip = 0;
port = 0;
state = 0;
connected = false;
@ -424,7 +423,8 @@ protected:
RemoteSerializer::PeerID id;
ChunkedIO* io;
uint32 ip;
IPAddr ip;
string zone_id;
uint16 port;
char state;
bool connected;
@ -437,7 +437,7 @@ protected:
bool compressor;
};
bool Listen(uint32 ip, uint16 port, bool expect_ssl);
bool Listen();
bool AcceptConnection(int listen_fd);
bool Connect(Peer* peer);
bool CloseConnection(Peer* peer, bool reconnect);
@ -482,6 +482,9 @@ protected:
bool ForwardChunkToPeer();
const char* MakeLogString(const char* msg, Peer *peer);
// Closes all file descriptors associated with listening sockets.
void CloseListenFDs();
// Peers we are communicating with:
declare(PList, Peer);
typedef PList(Peer) peer_list;
@ -498,15 +501,17 @@ protected:
char parent_msgtype;
ChunkedIO::Chunk* parent_args;
int listen_fd_clear;
int listen_fd_ssl;
vector<int> listen_fds;
// If the port we're trying to bind to is already in use, we will retry
// it regularly.
uint32 listen_if; // Fix: only supports IPv4
string listen_if;
string listen_zone_id; // RFC 4007 IPv6 zone_id
uint16 listen_port;
bool listen_ssl;
time_t listen_next_try;
bool listen_ssl; // use SSL for IO
bool enable_ipv6; // allow IPv6 listen sockets
uint32 bind_retry_interval; // retry interval for already-in-use sockets
time_t listen_next_try; // time at which to try another bind
bool shutting_conns_down;
bool terminating;
bool killing;

View file

@ -602,7 +602,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
conn = (Connection*) d->Lookup(h);
if ( ! conn )
{
conn = NewConn(h, t, &id, data, proto);
conn = NewConn(h, t, &id, data, proto, ip_hdr->FlowLabel());
if ( conn )
d->Insert(h, conn);
}
@ -623,7 +623,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
conn->Event(connection_reused, 0);
Remove(conn);
conn = NewConn(h, t, &id, data, proto);
conn = NewConn(h, t, &id, data, proto, ip_hdr->FlowLabel());
if ( conn )
d->Insert(h, conn);
}
@ -644,6 +644,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
int is_orig = (id.src_addr == conn->OrigAddr()) &&
(id.src_port == conn->OrigPort());
conn->CheckFlowLabel(is_orig, ip_hdr->FlowLabel());
Val* pkt_hdr_val = 0;
if ( ipv6_ext_headers && ip_hdr->NumHeaders() > 1 )
@ -1002,7 +1004,7 @@ void NetSessions::GetStats(SessionStats& s) const
}
Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
const u_char* data, int proto)
const u_char* data, int proto, uint32 flow_label)
{
// FIXME: This should be cleaned up a bit, it's too protocol-specific.
// But I'm not yet sure what the right abstraction for these things is.
@ -1058,7 +1060,7 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
id = &flip_id;
}
Connection* conn = new Connection(this, k, t, id);
Connection* conn = new Connection(this, k, t, id, flow_label);
conn->SetTransport(tproto);
dpm->BuildInitialAnalyzerTree(tproto, conn, data);

View file

@ -142,7 +142,7 @@ protected:
friend class TimerMgrExpireTimer;
Connection* NewConn(HashKey* k, double t, const ConnID* id,
const u_char* data, int proto);
const u_char* data, int proto, uint32 flow_label);
// Check whether the tag of the current packet is consistent with
// the given connection. Returns:

View file

@ -963,7 +963,7 @@ function sha256_hash_finish%(index: any%): string
## Generates a random number.
##
## max: The maximum value the random number.
## max: The maximum value of the random number.
##
## Returns: a random positive integer in the interval *[0, max)*.
##
@ -1020,7 +1020,7 @@ extern "C" {
## data: The data to find the MIME type for.
##
## return_mime: If true, the function returns a short MIME type string (e.g.,
## ``text/plain`` instead of a more elaborate textual description.
## ``text/plain`` instead of a more elaborate textual description).
##
## Returns: The MIME type of *data*.
function identify_data%(data: string, return_mime: bool%): string
@ -1241,8 +1241,6 @@ function unique_id_from%(pool: int, prefix: string%) : string
## Removes all elements from a set or table.
##
## v: The set or table
##
## Returns: The cleared set/table or 0 if *v* is not a set/table type.
function clear_table%(v: any%): any
%{
if ( v->Type()->Tag() == TYPE_TABLE )
@ -1290,7 +1288,7 @@ function same_object%(o1: any, o2: any%): bool
return new Val(o1 == o2, TYPE_BOOL);
%}
## Returns the number bytes that a value occupies in memory.
## Returns the number of bytes that a value occupies in memory.
##
## v: The value
##
@ -1306,7 +1304,7 @@ function val_size%(v: any%): count
##
## newsize: The new size of *aggr*.
##
## Returns: The old size of *aggr* and 0 if *aggr* is not a :bro:type:`vector`.
## Returns: The old size of *aggr*, or 0 if *aggr* is not a :bro:type:`vector`.
function resize%(aggr: any, newsize: count%) : count
%{
if ( aggr->Type()->Tag() != TYPE_VECTOR )
@ -1423,7 +1421,7 @@ bool indirect_int_sort_function(int a, int b)
%%}
## Sorts a vector in place. The second argument is a comparison function that
## takes two arguments: if the vector type is \verb|vector of T|, then the
## takes two arguments: if the vector type is ``vector of T``, then the
## comparison function must be ``function(a: T, b: T): bool``, which returns
## ``a < b`` for some type-specific notion of the less-than operator.
##
@ -1599,7 +1597,7 @@ function cat%(...%): string
## given argument. If any of the variable arguments is an empty string it is
## replaced by a given default string instead.
##
## sep: The separator to place betwen each argument.
## sep: The separator to place between each argument.
##
## def: The default string to use when an argument is the empty string.
##
@ -1657,7 +1655,7 @@ function cat_sep%(sep: string, def: string, ...%): string
##
## - ``[DT]``: ISO timestamp with microsecond precision
##
## - ``d``: Signed/Unsigned integer (using C-style ``%lld|``/``%llu``
## - ``d``: Signed/Unsigned integer (using C-style ``%lld``/``%llu``
## for ``int``/``count``)
##
## - ``x``: Unsigned hexadecimal (using C-style ``%llx``);
@ -1782,7 +1780,7 @@ function log10%(d: double%): double
# ===========================================================================
## Determines whether *c* has been received externally. For example,
## Broccoli or the Time Machine can send packets to Bro via a mechanism that
## Broccoli or the Time Machine can send packets to Bro via a mechanism that is
## one step lower than sending events. This function checks whether the packets
## of a connection stem from one of these external *packet sources*.
##
@ -1796,7 +1794,7 @@ function is_external_connection%(c: connection%) : bool
## Returns the ID of the analyzer which raised the current event.
##
## Returns: The ID of the analyzer which raised hte current event, or 0 if
## Returns: The ID of the analyzer which raised the current event, or 0 if
## none.
function current_analyzer%(%) : count
%{
@ -2053,7 +2051,7 @@ function get_gap_summary%(%): gap_info
%}
## Generates a table of the size of all global variables. The table index is
## the variable name and the value the variable size in bytes.
## the variable name and the value is the variable size in bytes.
##
## Returns: A table that maps variable names to their sizes.
##
@ -2138,7 +2136,7 @@ function lookup_ID%(id: string%) : any
return i->ID_Val()->Ref();
%}
## Generates meta data about a record fields. The returned information
## Generates metadata about a record's fields. The returned information
## includes the field name, whether it is logged, its value (if it has one),
## and its default value (if specified).
##
@ -2269,11 +2267,11 @@ function dump_rule_stats%(f: file%): bool
return new Val(1, TYPE_BOOL);
%}
## Checks wheter Bro is terminating.
## Checks if Bro is terminating.
##
## Returns: True if Bro is in the process of shutting down.
##
## .. bro:see: terminate
## .. bro:see:: terminate
function bro_is_terminating%(%): bool
%{
return new Val(terminating, TYPE_BOOL);
@ -2354,7 +2352,7 @@ function routing0_data_to_addrs%(s: string%): addr_vec
return rval;
%}
## Converts a :bro:type:`addr` to a :bro:type:`index_vec`.
## Converts an :bro:type:`addr` to an :bro:type:`index_vec`.
##
## a: The address to convert into a vector of counts.
##
@ -2374,7 +2372,7 @@ function addr_to_counts%(a: addr%): index_vec
return rval;
%}
## Converts a :bro:type:`index_vec` to a :bro:type:`addr`.
## Converts an :bro:type:`index_vec` to an :bro:type:`addr`.
##
## v: The vector containing host-order IP address representation,
## one element for IPv4 addresses, four elements for IPv6 addresses.
@ -2404,7 +2402,7 @@ function counts_to_addr%(v: index_vec%): addr
}
%}
## Converts a :bro:type:`string` to a :bro:type:`int`.
## Converts a :bro:type:`string` to an :bro:type:`int`.
##
## str: The :bro:type:`string` to convert.
##
@ -2434,7 +2432,7 @@ function to_int%(str: string%): int
##
## n: The :bro:type:`int` to convert.
##
## Returns: The :bro:type:`int` *n* as unsigned integer or 0 if *n* < 0.
## Returns: The :bro:type:`int` *n* as unsigned integer, or 0 if *n* < 0.
function int_to_count%(n: int%): count
%{
if ( n < 0 )
@ -2449,7 +2447,7 @@ function int_to_count%(n: int%): count
##
## d: The :bro:type:`double` to convert.
##
## Returns: The :bro:type:`double` *d* as unsigned integer or 0 if *d* < 0.0.
## Returns: The :bro:type:`double` *d* as unsigned integer, or 0 if *d* < 0.0.
##
## .. bro:see:: double_to_time
function double_to_count%(d: double%): count
@ -2464,8 +2462,8 @@ function double_to_count%(d: double%): count
##
## str: The :bro:type:`string` to convert.
##
## Returns: The :bro:type:`string` *str* as unsigned integer or if in invalid
## format.
## Returns: The :bro:type:`string` *str* as unsigned integer, or 0 if *str* has
## an invalid format.
##
## .. bro:see:: to_addr to_int to_port to_subnet
function to_count%(str: string%): count
@ -2498,7 +2496,7 @@ function interval_to_double%(i: interval%): double
## Converts a :bro:type:`time` value to a :bro:type:`double`.
##
## t: The :bro:type:`interval` to convert.
## t: The :bro:type:`time` to convert.
##
## Returns: The :bro:type:`time` value *t* as :bro:type:`double`.
##
@ -2508,11 +2506,11 @@ function time_to_double%(t: time%): double
return new Val(t, TYPE_DOUBLE);
%}
## Converts a :bro:type:`time` value to a :bro:type:`double`.
## Converts a :bro:type:`double` value to a :bro:type:`time`.
##
## t: The :bro:type:`interval` to convert.
## d: The :bro:type:`double` to convert.
##
## Returns: The :bro:type:`time` value *t* as :bro:type:`double`.
## Returns: The :bro:type:`double` value *d* as :bro:type:`time`.
##
## .. bro:see:: time_to_double double_to_count
function double_to_time%(d: double%): time
@ -2550,7 +2548,7 @@ function port_to_count%(p: port%): count
##
## proto: The transport protocol.
##
## Returns: The :bro:type:`count` *c* as :bro:type:`port`.
## Returns: The :bro:type:`count` *num* as :bro:type:`port`.
##
## .. bro:see:: port_to_count
function count_to_port%(num: count, proto: transport_proto%): port
@ -2562,7 +2560,7 @@ function count_to_port%(num: count, proto: transport_proto%): port
##
## ip: The :bro:type:`string` to convert.
##
## Returns: The :bro:type:`string` *ip* as :bro:type:`addr` or the unspecified
## Returns: The :bro:type:`string` *ip* as :bro:type:`addr`, or the unspecified
## address ``::`` if the input string does not parse correctly.
##
## .. bro:see:: to_count to_int to_port count_to_v4_addr raw_bytes_to_v4_addr
@ -2579,7 +2577,7 @@ function to_addr%(ip: string%): addr
##
## sn: The subnet to convert.
##
## Returns: The *sn* string as a :bro:type:`subnet` or the unspecified subnet
## Returns: The *sn* string as a :bro:type:`subnet`, or the unspecified subnet
## ``::/0`` if the input string does not parse correctly.
##
## .. bro:see:: to_count to_int to_port count_to_v4_addr raw_bytes_to_v4_addr
@ -2616,7 +2614,7 @@ function count_to_v4_addr%(ip: count%): addr
##
## b: The raw bytes (:bro:type:`string`) to convert.
##
## Returns: The byte :bro:type:`string` *ip* as :bro:type:`addr`.
## Returns: The byte :bro:type:`string` *b* as :bro:type:`addr`.
##
## .. bro:see:: raw_bytes_to_v4_addr to_addr to_subnet
function raw_bytes_to_v4_addr%(b: string%): addr
@ -2635,7 +2633,7 @@ function raw_bytes_to_v4_addr%(b: string%): addr
return new AddrVal(htonl(a));
%}
## Converts a :bro:type:`string` to an :bro:type:`port`.
## Converts a :bro:type:`string` to a :bro:type:`port`.
##
## s: The :bro:type:`string` to convert.
##
@ -2885,7 +2883,7 @@ function parse_ftp_port%(s: string%): ftp_port
%}
## Converts a string representation of the FTP EPRT command to an ``ftp_port``.
## (see `RFC 2428 <http://tools.ietf.org/html/rfc2428>`_).
## See `RFC 2428 <http://tools.ietf.org/html/rfc2428>`_.
## The format is ``EPRT<space><d><net-prt><d><net-addr><d><tcp-port><d>``,
## where ``<d>`` is a delimiter in the ASCII range 33-126 (usually ``|``).
##
@ -2976,7 +2974,7 @@ function fmt_ftp_port%(a: addr, p: port%): string
## Decode a NetBIOS name. See http://support.microsoft.com/kb/194203.
##
## name: The encoded NetBIOS name, e.g., ``"FEEIEFCAEOEFFEECEJEPFDCAEOEBENEF:``.
## name: The encoded NetBIOS name, e.g., ``"FEEIEFCAEOEFFEECEJEPFDCAEOEBENEF"``.
##
## Returns: The decoded NetBIOS name, e.g., ``"THE NETBIOS NAME"``.
##
@ -3009,7 +3007,7 @@ function decode_netbios_name%(name: string%): string
return new StringVal(i, result);
%}
## Converts a NetBIOS name type to its corresonding numeric value.
## Converts a NetBIOS name type to its corresponding numeric value.
## See http://support.microsoft.com/kb/163409.
##
## name: The NetBIOS name type.
@ -3029,7 +3027,7 @@ function decode_netbios_name_type%(name: string%): count
##
## bytestring: The string of bytes.
##
## Returns: The hexadecimal reprsentation of *bytestring*.
## Returns: The hexadecimal representation of *bytestring*.
##
## .. bro:see:: hexdump
function bytestring_to_hexstr%(bytestring: string%): string
@ -3069,7 +3067,7 @@ function decode_base64%(s: string%): string
## s: The Base64-encoded string.
##
## a: The custom alphabet. The empty string indicates the default alphabet. The
## lengh of *a* must bt 64. For example, a custom alphabet could be
## length of *a* must be 64. For example, a custom alphabet could be
## ``"!#$%&/(),-.:;<>@[]^ `_{|}~abcdefghijklmnopqrstuvwxyz0123456789+?"``.
##
## Returns: The decoded version of *s*.
@ -3138,7 +3136,7 @@ function uuid_to_string%(uuid: string%): string
##
## p2: The second pattern.
##
## Returns: The compiled pattern of the concatentation of *p1* and *p2*.
## Returns: The compiled pattern of the concatenation of *p1* and *p2*.
##
## .. bro:see:: convert_for_pattern string_to_pattern
##
@ -3277,7 +3275,7 @@ function strftime%(fmt: string, d: time%) : string
## a: The address to mask.
##
## top_bits_to_keep: The number of top bits to keep in *a*; must be greater
## than 0 and less than 33.
## than 0 and less than 33 for IPv4, or 129 for IPv6.
##
## Returns: The address *a* masked down to *top_bits_to_keep* bits.
##
@ -3341,7 +3339,7 @@ function is_udp_port%(p: port%): bool
##
## p: The :bro:type:`port` to check.
##
## Returns: True iff *p* is a ICMP port.
## Returns: True iff *p* is an ICMP port.
##
## .. bro:see:: is_tcp_port is_udp_port
function is_icmp_port%(p: port%): bool
@ -3383,7 +3381,7 @@ EnumVal* map_conn_type(TransportProto tp)
##
## cid: The connection identifier.
##
## Returns: The transport protocol of the connection identified by *id*.
## Returns: The transport protocol of the connection identified by *cid*.
##
## .. bro:see:: get_port_transport_proto
## get_orig_seq get_resp_seq
@ -3497,7 +3495,7 @@ const char* conn_id_string(Val* c)
##
## c: The HTTP connection.
##
## is_orig: If true, the client data is skipped and the server data otherwise.
## is_orig: If true, the client data is skipped, and the server data otherwise.
##
## .. bro:see:: skip_smtp_data
function skip_http_entity_data%(c: connection, is_orig: bool%): any
@ -3572,7 +3570,7 @@ function dump_current_packet%(file_name: string%) : bool
## Returns the currently processed PCAP packet.
##
## Returns: The currently processed packet, which is as a record
## Returns: The currently processed packet, which is a record
## containing the timestamp, ``snaplen``, and packet data.
##
## .. bro:see:: dump_current_packet dump_packet send_current_packet
@ -3730,7 +3728,7 @@ function lookup_addr%(host: addr%) : string
##
## host: The hostname to lookup.
##
## Returns: A set of DNS A records associated with *host*.
## Returns: A set of DNS A and AAAA records associated with *host*.
##
## .. bro:see:: lookup_addr
function lookup_hostname%(host: string%) : addr_set
@ -3897,6 +3895,7 @@ function lookup_location%(a: addr%) : geo_location
%}
## Performs an AS lookup of an IP address.
## Requires Bro to be built with ``libgeoip``.
##
## a: The IP address to lookup.
##
@ -4096,7 +4095,7 @@ function x509_err2str%(err_num: count%): string
## Converts UNIX file permissions given by a mode to an ASCII string.
##
## mode: The permisssions, e.g., 644 or 755.
## mode: The permissions (an octal number like 0644 converted to decimal).
##
## Returns: A string representation of *mode* in the format
## ``rw[xsS]rw[xsS]rw[xtT]``.
@ -4273,7 +4272,7 @@ function analyzer_name%(aid: count%) : string
##
## cid: The connection ID.
##
## Returns: False if *id* does not point to an active connection and true
## Returns: False if *cid* does not point to an active connection, and true
## otherwise.
##
## .. note::
@ -4295,10 +4294,10 @@ function skip_further_processing%(cid: conn_id%): bool
##
## cid: The connection identifier.
##
## do_record: True to enable packet contens and false to disable for the
## do_record: True to enable packet contents, and false to disable for the
## connection identified by *cid*.
##
## Returns: False if *id* does not point to an active connection and true
## Returns: False if *cid* does not point to an active connection, and true
## otherwise.
##
## .. bro:see:: skip_further_processing
@ -4309,7 +4308,7 @@ function skip_further_processing%(cid: conn_id%): bool
## connection, which is controlled separately by
## :bro:id:`skip_further_processing`.
##
## .. bro:see: get_contents_file set_contents_file
## .. bro:see:: get_contents_file set_contents_file
function set_record_packets%(cid: conn_id, do_record: bool%): bool
%{
Connection* c = sessions->FindConnection(cid);
@ -4326,7 +4325,7 @@ function set_record_packets%(cid: conn_id, do_record: bool%): bool
## cid: The connection ID.
##
## direction: Controls what sides of the connection to record. The argument can
## take one the four values:
## take one of the four values:
##
## - ``CONTENTS_NONE``: Stop recording the connection's content.
## - ``CONTENTS_ORIG``: Record the data sent by the connection
@ -4340,7 +4339,7 @@ function set_record_packets%(cid: conn_id, do_record: bool%): bool
##
## f: The file handle of the file to write the contents to.
##
## Returns: Returns false if *id* does not point to an active connection and
## Returns: Returns false if *cid* does not point to an active connection, and
## true otherwise.
##
## .. note::
@ -4351,7 +4350,7 @@ function set_record_packets%(cid: conn_id, do_record: bool%): bool
## missing data; this can happen, e.g., due to an
## :bro:id:`ack_above_hole` event.
##
## .. bro:see: get_contents_file set_record_packets
## .. bro:see:: get_contents_file set_record_packets
function set_contents_file%(cid: conn_id, direction: count, f: file%): bool
%{
Connection* c = sessions->FindConnection(cid);
@ -4366,15 +4365,15 @@ function set_contents_file%(cid: conn_id, direction: count, f: file%): bool
##
## cid: The connection ID.
##
## direction: Controls what sides of the connection to record. SEe
## direction: Controls what sides of the connection to record. See
## :bro:id:`set_contents_file` for possible values.
##
## Returns: The :bro:type:`file` handle for the contentents file of the
## Returns: The :bro:type:`file` handle for the contents file of the
## connection identified by *cid*. If the connection exists
## but no contents file for *direction*, the function generates a
## error and returns a file handle to ``stderr``.
## but there is no contents file for *direction*, then the function
## generates an error and returns a file handle to ``stderr``.
##
## .. bro:see: set_contents_file set_record_packets
## .. bro:see:: set_contents_file set_record_packets
function get_contents_file%(cid: conn_id, direction: count%): file
%{
Connection* c = sessions->FindConnection(cid);
@ -4425,7 +4424,7 @@ function set_inactivity_timeout%(cid: conn_id, t: interval%): interval
##
## - ``LOGIN_STATE_AUTHENTICATE``: The connection is in its
## initial authentication dialog.
## - ``OGIN_STATE_LOGGED_IN``: The analyzer believes the user has
## - ``LOGIN_STATE_LOGGED_IN``: The analyzer believes the user has
## successfully authenticated.
## - ``LOGIN_STATE_SKIP``: The analyzer has skipped any further
## processing of the connection.
@ -4433,7 +4432,7 @@ function set_inactivity_timeout%(cid: conn_id, t: interval%): interval
## does not correctly know the state of the connection, and/or
## the username associated with it.
##
## .. bro:see: set_login_state
## .. bro:see:: set_login_state
function get_login_state%(cid: conn_id%): count
%{
Connection* c = sessions->FindConnection(cid);
@ -4456,9 +4455,9 @@ function get_login_state%(cid: conn_id%): count
## :bro:id:`get_login_state` for possible values.
##
## Returns: Returns false if *cid* is not an active connection
## or does not tagged as login analyzer, and true otherwise.
## or is not tagged as a login analyzer, and true otherwise.
##
## .. bro:see: get_login_state
## .. bro:see:: get_login_state
function set_login_state%(cid: conn_id, new_state: count%): bool
%{
Connection* c = sessions->FindConnection(cid);
@ -4590,9 +4589,9 @@ function disable_event_group%(group: string%) : any
##
## f: The path to the file.
##
## Returns: A :bro:type:`file` handle for subsequent operations.
## Returns: A :bro:type:`file` handle for subsequent operations.
##
## .. bro:see;: active_file open_for_append close write_file
## .. bro:see:: active_file open_for_append close write_file
## get_file_name set_buf flush_all mkdir enable_raw_output
function open%(f: string%): file
%{
@ -4609,9 +4608,9 @@ function open%(f: string%): file
##
## f: The path to the file.
##
## Returns: A :bro:type:`file` handle for subsequent operations.
## Returns: A :bro:type:`file` handle for subsequent operations.
##
## .. bro:see;: active_file open close write_file
## .. bro:see:: active_file open close write_file
## get_file_name set_buf flush_all mkdir enable_raw_output
function open_for_append%(f: string%): file
%{
@ -4619,13 +4618,12 @@ function open_for_append%(f: string%): file
%}
## Closes an open file and flushes any buffered content.
## exists, this function appends to it (as opposed to :bro:id:`open`).
##
## f: A :bro:type:`file` handle to an open file.
##
## Returns: True on success.
## Returns: True on success.
##
## .. bro:see;: active_file open open_for_append write_file
## .. bro:see:: active_file open open_for_append write_file
## get_file_name set_buf flush_all mkdir enable_raw_output
function close%(f: file%): bool
%{
@ -4638,9 +4636,9 @@ function close%(f: file%): bool
##
## data: The data to write to *f*.
##
## Returns: True on success.
## Returns: True on success.
##
## .. bro:see;: active_file open open_for_append close
## .. bro:see:: active_file open open_for_append close
## get_file_name set_buf flush_all mkdir enable_raw_output
function write_file%(f: file, data: string%): bool
%{
@ -4656,11 +4654,11 @@ function write_file%(f: file, data: string%): bool
## f: A :bro:type:`file` handle to an open file.
##
## buffered: When true, *f* is fully buffered, i.e., bytes are saved in a
## buffered until the block size has been reached. When
## buffer until the block size has been reached. When
## false, *f* is line buffered, i.e., bytes are saved up until a
## newline occurs.
##
## .. bro:see;: active_file open open_for_append close
## .. bro:see:: active_file open open_for_append close
## get_file_name write_file flush_all mkdir enable_raw_output
function set_buf%(f: file, buffered: bool%): any
%{
@ -4670,9 +4668,9 @@ function set_buf%(f: file, buffered: bool%): any
## Flushes all open files to disk.
##
## Returns: True on success.
## Returns: True on success.
##
## .. bro:see;: active_file open open_for_append close
## .. bro:see:: active_file open open_for_append close
## get_file_name write_file set_buf mkdir enable_raw_output
function flush_all%(%): bool
%{
@ -4683,10 +4681,10 @@ function flush_all%(%): bool
##
## f: The directory name.
##
## Returns: Returns true if the operation succeeds and false if the
## Returns: Returns true if the operation succeeds, or false if the
## creation fails or if *f* exists already.
##
## .. bro:see;: active_file open_for_append close write_file
## .. bro:see:: active_file open_for_append close write_file
## get_file_name set_buf flush_all enable_raw_output
function mkdir%(f: string%): bool
%{
@ -4731,7 +4729,7 @@ function get_file_name%(f: file%): string
##
## f: An open file handle.
##
## Returns: Rotations statistics which include the original file name, the name
## Returns: Rotation statistics which include the original file name, the name
## after the rotation, and the time when *f* was opened/closed.
##
## .. bro:see:: rotate_file_by_name calc_next_rotate
@ -4755,7 +4753,7 @@ function rotate_file%(f: file%): rotate_info
##
## f: The name of the file to rotate
##
## Returns: Rotations statistics which include the original file name, the name
## Returns: Rotation statistics which include the original file name, the name
## after the rotation, and the time when *f* was opened/closed.
##
## .. bro:see:: rotate_file calc_next_rotate
@ -4851,7 +4849,7 @@ function disable_print_hook%(f: file%): any
return 0;
%}
## Prevents escaping of non-ASCII character when writing to a file.
## Prevents escaping of non-ASCII characters when writing to a file.
## This function is equivalent to :bro:attr:`&disable_print_hook`.
##
## f: The file to disable raw output for.
@ -5213,9 +5211,9 @@ function checkpoint_state%(%) : bool
return new Val(persistence_serializer->WriteState(true), TYPE_BOOL);
%}
## Reads persistent state from the \texttt{.state} directory and populates the
## in-memory data structures accordingly. This function is the dual to
## :bro:id:`checkpoint_state`.
## Reads persistent state and populates the in-memory data structures
## accordingly. Persistent state is read from the ``.state`` directory.
## This function is the dual to :bro:id:`checkpoint_state`.
##
## Returns: True on success.
##
@ -5267,16 +5265,20 @@ function capture_state_updates%(filename: string%) : bool
##
## ip: The IP address of the remote peer.
##
## port: The port of the remote peer.
## zone_id: If *ip* is a non-global IPv6 address, a particular :rfc:`4007`
## ``zone_id`` can given here. An empty string, ``""``, means
## not to add any ``zone_id``.
##
## our_class: If an non-empty string, the remote (listening) peer checks it
## p: The port of the remote peer.
##
## our_class: If a non-empty string, then the remote (listening) peer checks it
## against its class name in its peer table and terminates the
## connection if they don't match.
##
## retry: If the connection fails, try to reconnect with the peer after this
## time interval.
##
## ssl: If true, uses SSL to encrypt the session.
## ssl: If true, use SSL to encrypt the session.
##
## Returns: A locally unique ID of the new peer.
##
@ -5290,16 +5292,17 @@ function capture_state_updates%(filename: string%) : bool
## set_compression_level
## send_state
## send_id
function connect%(ip: addr, p: port, our_class: string, retry: interval, ssl: bool%) : count
function connect%(ip: addr, zone_id: string, p: port, our_class: string, retry: interval, ssl: bool%) : count
%{
return new Val(uint32(remote_serializer->Connect(ip->AsAddr(), p->Port(),
our_class->CheckString(), retry, ssl)),
return new Val(uint32(remote_serializer->Connect(ip->AsAddr(),
zone_id->CheckString(), p->Port(), our_class->CheckString(),
retry, ssl)),
TYPE_COUNT);
%}
## Terminate the connection with a peer.
##
## p: The peer ID return from :bro:id:`connect`.
## p: The peer ID returned from :bro:id:`connect`.
##
## Returns: True on success.
##
@ -5313,7 +5316,7 @@ function disconnect%(p: event_peer%) : bool
## Subscribes to all events from a remote peer whose names match a given
## pattern.
##
## p: The peer ID return from :bro:id:`connect`.
## p: The peer ID returned from :bro:id:`connect`.
##
## handlers: The pattern describing the events to request from peer *p*.
##
@ -5331,7 +5334,7 @@ function request_remote_events%(p: event_peer, handlers: pattern%) : bool
## Requests synchronization of IDs with a remote peer.
##
## p: The peer ID return from :bro:id:`connect`.
## p: The peer ID returned from :bro:id:`connect`.
##
## auth: If true, the local instance considers its current state authoritative
## and sends it to *p* right after the handshake.
@ -5349,7 +5352,7 @@ function request_remote_sync%(p: event_peer, auth: bool%) : bool
## Requests logs from a remote peer.
##
## p: The peer ID return from :bro:id:`connect`.
## p: The peer ID returned from :bro:id:`connect`.
##
## Returns: True on success.
##
@ -5361,9 +5364,11 @@ function request_remote_logs%(p: event_peer%) : bool
return new Val(remote_serializer->RequestLogs(id), TYPE_BOOL);
%}
## Sets a boolean flag whether Bro accepts state from a remote peer.
## Sets a boolean flag indicating whether Bro accepts state from a remote peer.
##
## p: The peer ID return from :bro:id:`connect`.
## p: The peer ID returned from :bro:id:`connect`.
##
## accept: True if Bro accepts state from peer *p*, or false otherwise.
##
## Returns: True on success.
##
@ -5379,7 +5384,7 @@ function set_accept_state%(p: event_peer, accept: bool%) : bool
## Sets the compression level of the session with a remote peer.
##
## p: The peer ID return from :bro:id:`connect`.
## p: The peer ID returned from :bro:id:`connect`.
##
## level: Allowed values are in the range *[0, 9]*, where 0 is the default and
## means no compression.
@ -5394,20 +5399,29 @@ function set_compression_level%(p: event_peer, level: count%) : bool
TYPE_BOOL);
%}
## Listens on address a given IP address and port for remote connections.
## Listens on a given IP address and port for remote connections.
##
## ip: The IP address to bind to.
##
## p: The TCP port to listen to.
## p: The TCP port to listen on.
##
## ssl: If true, Bro uses SSL to encrypt the session.
##
## ipv6: If true, enable listening on IPv6 addresses.
##
## zone_id: If *ip* is a non-global IPv6 address, a particular :rfc:`4007`
## ``zone_id`` can given here. An empty string, ``""``, means
## not to add any ``zone_id``.
##
## retry_interval: If address *ip* is found to be already in use, this is
## the interval at which to automatically retry binding.
##
## Returns: True on success.
##
## .. bro:see:: connect disconnect
function listen%(ip: addr, p: port, ssl: bool %) : bool
function listen%(ip: addr, p: port, ssl: bool, ipv6: bool, zone_id: string, retry_interval: interval%) : bool
%{
return new Val(remote_serializer->Listen(ip->AsAddr(), p->Port(), ssl), TYPE_BOOL);
return new Val(remote_serializer->Listen(ip->AsAddr(), p->Port(), ssl, ipv6, zone_id->CheckString(), retry_interval), TYPE_BOOL);
%}
## Checks whether the last raised event came from a remote peer.
@ -5420,7 +5434,7 @@ function is_remote_event%(%) : bool
## Sends all persistent state to a remote peer.
##
## p: The peer ID return from :bro:id:`connect`.
## p: The peer ID returned from :bro:id:`connect`.
##
## Returns: True on success.
##
@ -5431,10 +5445,10 @@ function send_state%(p: event_peer%) : bool
return new Val(persistence_serializer->SendState(id, true), TYPE_BOOL);
%}
## Sends a global identifier to a remote peer, which them might install it
## Sends a global identifier to a remote peer, which then might install it
## locally.
##
## p: The peer ID return from :bro:id:`connect`.
## p: The peer ID returned from :bro:id:`connect`.
##
## id: The identifier to send.
##
@ -5468,7 +5482,7 @@ function terminate_communication%(%) : bool
## Signals a remote peer that the local Bro instance finished the initial
## handshake.
##
## p: The peer ID return from :bro:id:`connect`.
## p: The peer ID returned from :bro:id:`connect`.
##
## Returns: True on success.
function complete_handshake%(p: event_peer%) : bool
@ -5481,7 +5495,7 @@ function complete_handshake%(p: event_peer%) : bool
## for :bro:id:`remote_pong`, this function can be used to measure latency
## between two peers.
##
## p: The peer ID return from :bro:id:`connect`.
## p: The peer ID returned from :bro:id:`connect`.
##
## seq: A sequence number (also included by :bro:id:`remote_pong`).
##
@ -5496,7 +5510,7 @@ function send_ping%(p: event_peer, seq: count%) : bool
## Sends the currently processed packet to a remote peer.
##
## p: The peer ID return from :bro:id:`connect`.
## p: The peer ID returned from :bro:id:`connect`.
##
## Returns: True if sending the packet succeeds.
##
@ -5522,7 +5536,7 @@ function send_current_packet%(p: event_peer%) : bool
## Returns the peer who generated the last event.
##
## Returns: The ID of the peer who genereated the last event.
## Returns: The ID of the peer who generated the last event.
##
## .. bro:see:: get_local_event_peer
function get_event_peer%(%) : event_peer
@ -5565,7 +5579,7 @@ function get_local_event_peer%(%) : event_peer
## Sends a capture filter to a remote peer.
##
## p: The peer ID return from :bro:id:`connect`.
## p: The peer ID returned from :bro:id:`connect`.
##
## s: The capture filter.
##
@ -5582,7 +5596,7 @@ function send_capture_filter%(p: event_peer, s: string%) : bool
## distributed trace processing with communication enabled
## (*pseudo-realtime* mode).
##
## .. bro:see: continue_processing suspend_state_updates resume_state_updates
## .. bro:see:: continue_processing suspend_state_updates resume_state_updates
function suspend_processing%(%) : any
%{
net_suspend_processing();
@ -5591,7 +5605,7 @@ function suspend_processing%(%) : any
## Resumes Bro's packet processing.
##
## .. bro:see: suspend_processing suspend_state_updates resume_state_updates
## .. bro:see:: suspend_processing suspend_state_updates resume_state_updates
function continue_processing%(%) : any
%{
net_continue_processing();
@ -5600,7 +5614,7 @@ function continue_processing%(%) : any
## Stops propagating :bro:attr:`&synchronized` accesses.
##
## .. bro:see: suspend_processing continue_processing resume_state_updates
## .. bro:see:: suspend_processing continue_processing resume_state_updates
function suspend_state_updates%(%) : any
%{
if ( remote_serializer )
@ -5610,7 +5624,7 @@ function suspend_state_updates%(%) : any
## Resumes propagating :bro:attr:`&synchronized` accesses.
##
## .. bro:see: suspend_processing continue_processing suspend_state_updates
## .. bro:see:: suspend_processing continue_processing suspend_state_updates
function resume_state_updates%(%) : any
%{
if ( remote_serializer )

View file

@ -171,8 +171,11 @@ event new_connection_contents%(c: connection%);
## new_connection new_connection_contents partial_connection
event connection_attempt%(c: connection%);
## Generated for an established TCP connection. The event is raised when the
## initial 3-way TCP handshake has successfully finished for a connection.
## Generated when a SYN-ACK packet is seen in response to SYN a packet during
## a TCP handshake. The final ACK of the handshake in response to SYN-ACK may
## or may not occur later, one way to tell is to check the *history* field of
## :bro:type:`connection` to see if the originator sent an ACK, indicated by
## 'A' in the history string.
##
## c: The connection.
##
@ -335,8 +338,6 @@ event connection_SYN_packet%(c: connection, pkt: SYN_packet%);
##
## c: The connection.
##
## pkt: Information extracted from the SYN packet.
##
## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt
## connection_established connection_external connection_finished
## connection_half_finished connection_partial_close connection_pending
@ -401,6 +402,20 @@ event connection_reused%(c: connection%);
## new_connection new_connection_contents partial_connection
event connection_status_update%(c: connection%);
## Generated for a connection over IPv6 when one direction has changed
## the flow label that it's using.
##
## c: The connection.
##
## is_orig: True if the event is raised for the originator side.
##
## old_label: The old flow label that the endpoint was using.
##
## new_label: The new flow label that the endpoint is using.
##
## .. bro:see:: connection_established new_connection
event connection_flow_label_changed%(c: connection, is_orig: bool, old_label: count, new_label: count%);
## Generated at the end of reassembled TCP connections. The TCP reassembler
## raised the event once for each endpoint of a connection when it finished
## reassembling the corresponding side of the communication.

View file

@ -11,8 +11,8 @@ using namespace std;
%%}
## Concates all arguments into a single string. The function takes a variable
## number of arguments of type string and stiches them together.
## Concatenates all arguments into a single string. The function takes a
## variable number of arguments of type string and stitches them together.
##
## Returns: The concatenation of all (string) arguments.
##
@ -157,9 +157,9 @@ function join_string_array%(sep: string, a: string_array%): string
##
## sep: The separator to place between each element.
##
## a: The :bro:type:`string_vec` (``vector of string``).
## vec: The :bro:type:`string_vec` (``vector of string``).
##
## Returns: The concatenation of all elements in *a*, with *sep* placed
## Returns: The concatenation of all elements in *vec*, with *sep* placed
## between each element.
##
## .. bro:see:: cat cat_sep string_cat cat_string_array cat_string_array_n
@ -219,7 +219,7 @@ function sort_string_array%(a: string_array%): string_array
## Returns an edited version of a string that applies a special
## "backspace character" (usually ``\x08`` for backspace or ``\x7f`` for DEL).
## For ## example, ``edit("hello there", "e")`` returns ``"llo t"``.
## For example, ``edit("hello there", "e")`` returns ``"llo t"``.
##
## arg_s: The string to edit.
##
@ -229,7 +229,7 @@ function sort_string_array%(a: string_array%): string_array
## the string.
##
## Returns: An edited version of *arg_s* where *arg_edit_char* triggers the
## deletetion of the last character.
## deletion of the last character.
##
## .. bro:see:: clean
## to_string_literal
@ -278,7 +278,7 @@ function byte_len%(s: string%): count
return new Val(s->Len(), TYPE_COUNT);
%}
## Get a substring of from a string, given a starting position length.
## Get a substring from a string, given a starting position and length.
##
## s: The string to obtain a substring from.
##
@ -486,10 +486,10 @@ function split%(str: string, re: pattern%): string_array
return do_split(str, re, 0, 0, 0);
%}
## Splits a string *once* into a a two-element array of strings according to a
## pattern. This function is the same as :bro:id:`split`, but * is only split
## once (if possible) at the earliest position and an array of two strings is
## returned.
## Splits a string *once* into a two-element array of strings according to a
## pattern. This function is the same as :bro:id:`split`, but *str* is only
## split once (if possible) at the earliest position and an array of two strings
## is returned.
##
## str: The string to split.
##
@ -518,7 +518,7 @@ function split1%(str: string, re: pattern%): string_array
##
## Returns: An array of strings where each two successive elements correspond
## to a substring in *str* of the part not matching *re* (odd-indexed)
## and thei part that matches *re* (even-indexed).
## and the part that matches *re* (even-indexed).
##
## .. bro:see:: split split1 split_n str_split
function split_all%(str: string, re: pattern%): string_array
@ -568,7 +568,7 @@ function split_complete%(str: string,
##
## re: The pattern being replaced with *repl*.
##
## repl: The string that replacs *re*.
## repl: The string that replaces *re*.
##
## Returns: A copy of *str* with the first occurence of *re* replaced with
## *repl*.
@ -579,16 +579,16 @@ function sub%(str: string, re: pattern, repl: string%): string
return do_sub(str, re, repl, 0);
%}
## Substitutes a given replacement string for the all occurrences of a pattern
## Substitutes a given replacement string for all occurrences of a pattern
## in a given string.
##
## str: The string to perform the substitution in.
##
## re: The pattern being replaced with *repl*.
##
## repl: The string that replacs *re*.
## repl: The string that replaces *re*.
##
## Returns: A copy of *str* with all occurences of *re* replaced with *repl*.
## Returns: A copy of *str* with all occurrences of *re* replaced with *repl*.
##
## .. bro:see:: sub subst_string
function gsub%(str: string, re: pattern, repl: string%): string
@ -597,7 +597,7 @@ function gsub%(str: string, re: pattern, repl: string%): string
%}
## Lexicographically compares two string.
## Lexicographically compares two strings.
##
## s1: The first string.
##
@ -616,7 +616,7 @@ function strcmp%(s1: string, s2: string%): int
##
## little: The (smaller) string to find inside *big*.
##
## Returns: The location of *little* in *big* or 0 if *little* is not found in
## Returns: The location of *little* in *big*, or 0 if *little* is not found in
## *big*.
##
## .. bro:see:: find_all find_last
@ -685,7 +685,7 @@ function subst_string%(s: string, from: string, to: string%): string
## str: The string to convert to lowercase letters.
##
## Returns: A copy of the given string with the uppercase letters (as indicated
## by ``isascii`` and \verb|isupper|``) folded to lowercase
## by ``isascii`` and ``isupper``) folded to lowercase
## (via ``tolower``).
##
## .. bro:see:: to_upper is_ascii
@ -714,7 +714,7 @@ function to_lower%(str: string%): string
## str: The string to convert to uppercase letters.
##
## Returns: A copy of the given string with the lowercase letters (as indicated
## by ``isascii`` and \verb|islower|``) folded to uppercase
## by ``isascii`` and ``islower``) folded to uppercase
## (via ``toupper``).
##
## .. bro:see:: to_lower is_ascii
@ -744,7 +744,7 @@ function to_upper%(str: string%): string
## - ``NUL`` to ``\0``
## - ``DEL`` to ``^?``
## - values <= 26 to ``^[A-Z]``
## - values not in *[32, 126]** to ``%XX``
## - values not in *[32, 126]* to ``%XX``
##
## If the string does not yet have a trailing NUL, one is added.
##
@ -765,7 +765,7 @@ function clean%(str: string%): string
## - ``NUL`` to ``\0``
## - ``DEL`` to ``^?``
## - values <= 26 to ``^[A-Z]``
## - values not in *[32, 126]** to ``%XX``
## - values not in *[32, 126]* to ``%XX``
##
## str: The string to escape.
##
@ -831,14 +831,16 @@ function string_to_ascii_hex%(s: string%): string
return new StringVal(new BroString(1, (u_char*) x, s->Len() * 2));
%}
## Uses the Smith Waterman algorithm to find similar/overlapping substrings.
## Uses the Smith-Waterman algorithm to find similar/overlapping substrings.
## See `Wikipedia <http://en.wikipedia.org/wiki/Smith%E2%80%93Waterman_algorithm>`_.
##
## s1: The first string.
##
## s2: The second string.
##
## Returns: The result of the Smit Waterman algorithm calculation.
## params: Parameters for the Smith-Waterman algorithm.
##
## Returns: The result of the Smith-Waterman algorithm calculation.
function str_smith_waterman%(s1: string, s2: string, params: sw_params%) : sw_substring_vec
%{
SWParams sw_params(params->AsRecordVal()->Lookup(0)->AsCount(),

View file

@ -376,6 +376,8 @@ template<class T> int atoi_n(int len, const char* s, const char** end, int base,
// Instantiate the ones we need.
template int atoi_n<int>(int len, const char* s, const char** end, int base, int& result);
template int atoi_n<uint16_t>(int len, const char* s, const char** end, int base, uint16_t& result);
template int atoi_n<uint32_t>(int len, const char* s, const char** end, int base, uint32_t& result);
template int atoi_n<int64_t>(int len, const char* s, const char** end, int base, int64_t& result);
template int atoi_n<uint64_t>(int len, const char* s, const char** end, int base, uint64_t& result);

View file

@ -6,13 +6,13 @@ all: make-verbose coverage
brief: make-brief coverage
make-verbose:
@for repo in $(DIRS); do (cd $$repo && make ); done
@for repo in $(DIRS); do (cd $$repo && make -s ); done
make-brief:
@for repo in $(DIRS); do (cd $$repo && make brief ); done
@for repo in $(DIRS); do (cd $$repo && make -s brief ); done
coverage:
@for repo in $(DIRS); do (cd $$repo && echo "Coverage for '$$repo' dir:" && make coverage); done
@for repo in $(DIRS); do (cd $$repo && echo "Coverage for '$$repo' dir:" && make -s coverage); done
@test -f btest/coverage.log && cp btest/coverage.log `mktemp brocov.tmp.XXX` || true
@for f in external/*/coverage.log; do test -f $$f && cp $$f `mktemp brocov.tmp.XXX` || true; done
@echo "Complete test suite code coverage:"

View file

@ -0,0 +1,74 @@
new_connection: [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49185/tcp, resp_h=2001:470:4867:99::21, resp_p=21/tcp]
orig_flow 0
resp_flow 0
connection_established: [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49185/tcp, resp_h=2001:470:4867:99::21, resp_p=21/tcp]
orig_flow 0
resp_flow 0
connection_flow_label_changed(resp): [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49185/tcp, resp_h=2001:470:4867:99::21, resp_p=21/tcp]
orig_flow 0
resp_flow 7407
old_label 0
new_label 7407
new_connection: [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49186/tcp, resp_h=2001:470:4867:99::21, resp_p=57086/tcp]
orig_flow 0
resp_flow 0
connection_established: [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49186/tcp, resp_h=2001:470:4867:99::21, resp_p=57086/tcp]
orig_flow 0
resp_flow 0
connection_flow_label_changed(resp): [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49186/tcp, resp_h=2001:470:4867:99::21, resp_p=57086/tcp]
orig_flow 0
resp_flow 176012
old_label 0
new_label 176012
new_connection: [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49187/tcp, resp_h=2001:470:4867:99::21, resp_p=57087/tcp]
orig_flow 0
resp_flow 0
connection_established: [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49187/tcp, resp_h=2001:470:4867:99::21, resp_p=57087/tcp]
orig_flow 0
resp_flow 0
connection_flow_label_changed(resp): [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49187/tcp, resp_h=2001:470:4867:99::21, resp_p=57087/tcp]
orig_flow 0
resp_flow 390927
old_label 0
new_label 390927
new_connection: [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49188/tcp, resp_h=2001:470:4867:99::21, resp_p=57088/tcp]
orig_flow 0
resp_flow 0
connection_established: [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49188/tcp, resp_h=2001:470:4867:99::21, resp_p=57088/tcp]
orig_flow 0
resp_flow 0
connection_flow_label_changed(resp): [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49188/tcp, resp_h=2001:470:4867:99::21, resp_p=57088/tcp]
orig_flow 0
resp_flow 364705
old_label 0
new_label 364705
connection_state_remove: [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49186/tcp, resp_h=2001:470:4867:99::21, resp_p=57086/tcp]
orig_flow 0
resp_flow 176012
connection_state_remove: [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49187/tcp, resp_h=2001:470:4867:99::21, resp_p=57087/tcp]
orig_flow 0
resp_flow 390927
connection_state_remove: [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49188/tcp, resp_h=2001:470:4867:99::21, resp_p=57088/tcp]
orig_flow 0
resp_flow 364705
new_connection: [orig_h=2001:470:4867:99::21, orig_p=55785/tcp, resp_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, resp_p=49189/tcp]
orig_flow 267377
resp_flow 0
connection_established: [orig_h=2001:470:4867:99::21, orig_p=55785/tcp, resp_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, resp_p=49189/tcp]
orig_flow 267377
resp_flow 126027
new_connection: [orig_h=2001:470:4867:99::21, orig_p=55647/tcp, resp_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, resp_p=49190/tcp]
orig_flow 355265
resp_flow 0
connection_established: [orig_h=2001:470:4867:99::21, orig_p=55647/tcp, resp_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, resp_p=49190/tcp]
orig_flow 355265
resp_flow 126028
connection_state_remove: [orig_h=2001:470:4867:99::21, orig_p=55785/tcp, resp_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, resp_p=49189/tcp]
orig_flow 267377
resp_flow 126027
connection_state_remove: [orig_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, orig_p=49185/tcp, resp_h=2001:470:4867:99::21, resp_p=21/tcp]
orig_flow 0
resp_flow 7407
connection_state_remove: [orig_h=2001:470:4867:99::21, orig_p=55647/tcp, resp_h=2001:470:1f11:81f:c999:d94:aa7c:2e3e, resp_p=49190/tcp]
orig_flow 355265
resp_flow 126028

View file

@ -0,0 +1 @@
handshake done with peer: ::1

View file

@ -0,0 +1,2 @@
handshake done with peer: ::1
my_event: hello world

View file

@ -0,0 +1,9 @@
handshake done with peer
bro_addr(1.2.3.4)
bro_subnet(10.0.0.0/16)
bro_addr(2607:f8b0:4009:802::1014)
bro_subnet(2607:f8b0::/32)
broccoli_addr(1.2.3.4)
broccoli_subnet(10.0.0.0/16)
broccoli_addr(2607:f8b0:4009:802::1014)
broccoli_subnet(2607:f8b0::/32)

View file

@ -0,0 +1,6 @@
Connected to Bro instance at: ::1:47757
Received bro_addr(1.2.3.4)
Received bro_subnet(10.0.0.0/16)
Received bro_addr(2607:f8b0:4009:802::1014)
Received bro_subnet(2607:f8b0::/32)
Terminating

View file

@ -0,0 +1,9 @@
handshake done with peer
bro_addr(1.2.3.4)
bro_subnet(10.0.0.0/16)
bro_addr(2607:f8b0:4009:802::1014)
bro_subnet(2607:f8b0::/32)
broccoli_addr(1.2.3.4)
broccoli_subnet(10.0.0.0/16)
broccoli_addr(2607:f8b0:4009:802::1014)
broccoli_subnet(2607:f8b0::/32)

View file

@ -0,0 +1,6 @@
Connected to Bro instance at: localhost:47757
Received bro_addr(1.2.3.4)
Received bro_subnet(10.0.0.0/16)
Received bro_addr(2607:f8b0:4009:802::1014)
Received bro_subnet(2607:f8b0::/32)
Terminating

View file

@ -0,0 +1,33 @@
http_request
http_begin_entity
http_header
http_header
http_header
http_header
http_all_headers
http_content_type
http_end_entity
http_message_done
http_signature_found
http_reply
http_begin_entity
http_header
http_header
http_header
http_header
http_header
http_header
http_header
http_header
http_header
http_all_headers
http_content_type
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_end_entity
http_message_done

View file

@ -0,0 +1,33 @@
http_request
http_begin_entity
http_header
http_header
http_header
http_header
http_all_headers
http_content_type
http_end_entity
http_message_done
http_signature_found
http_reply
http_begin_entity
http_header
http_header
http_header
http_header
http_header
http_header
http_header
http_header
http_header
http_all_headers
http_content_type
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_end_entity
http_message_done

View file

@ -5,4 +5,4 @@
#path http
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file
#types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file
1324314406.995958 arKYeMETxOg 141.42.64.125 56730 125.190.109.199 80 1 GET www.icir.org / - Wget/1.10 0 9130 200 OK - - - (empty) - - - text/html - -
1336588614.060989 arKYeMETxOg 141.42.64.125 56730 125.190.109.199 80 1 GET www.icir.org / - Wget/1.10 0 9130 200 OK - - - (empty) - - - text/html - -

View file

@ -5,4 +5,4 @@
#path http
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file
#types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file
1324314406.995958 arKYeMETxOg 141.42.64.125 56730 125.190.109.199 80 1 GET www.icir.org / - Wget/1.10 0 9130 200 OK - - - (empty) - - - text/html - -
1336588614.060989 arKYeMETxOg 141.42.64.125 56730 125.190.109.199 80 1 GET www.icir.org / - Wget/1.10 0 9130 200 OK - - - (empty) - - - text/html - -

View file

@ -0,0 +1,33 @@
http_request
http_begin_entity
http_header
http_header
http_header
http_header
http_all_headers
http_content_type
http_end_entity
http_message_done
http_signature_found
http_reply
http_begin_entity
http_header
http_header
http_header
http_header
http_header
http_header
http_header
http_header
http_header
http_all_headers
http_content_type
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_end_entity
http_message_done

View file

@ -0,0 +1,33 @@
http_request
http_begin_entity
http_header
http_header
http_header
http_header
http_all_headers
http_content_type
http_end_entity
http_message_done
http_signature_found
http_reply
http_begin_entity
http_header
http_header
http_header
http_header
http_header
http_header
http_header
http_header
http_header
http_all_headers
http_content_type
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_entity_data
http_end_entity
http_message_done

View file

@ -5,4 +5,4 @@
#path http
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file
#types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file
1324314415.616486 arKYeMETxOg 141.42.64.125 56730 125.190.109.199 80 1 GET www.icir.org / - Wget/1.10 0 9130 200 OK - - - (empty) - - - text/html - -
1336587178.164598 arKYeMETxOg 141.42.64.125 56730 125.190.109.199 80 1 GET www.icir.org / - Wget/1.10 0 9130 200 OK - - - (empty) - - - text/html - -

View file

@ -5,4 +5,4 @@
#path http
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file
#types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file
1324314415.616486 arKYeMETxOg 141.42.64.125 56730 125.190.109.199 80 1 GET www.icir.org / - Wget/1.10 0 9130 200 OK - - - (empty) - - - text/html - -
1336587178.164598 arKYeMETxOg 141.42.64.125 56730 125.190.109.199 80 1 GET www.icir.org / - Wget/1.10 0 9130 200 OK - - - (empty) - - - text/html - -

View file

@ -0,0 +1,32 @@
# @TEST-EXEC: bro -b -r $TRACES/ipv6-ftp.trace %INPUT >output
# @TEST-EXEC: btest-diff output
function print_connection(c: connection, event_name: string)
{
print fmt("%s: %s", event_name, c$id);
print fmt(" orig_flow %d", c$orig$flow_label);
print fmt(" resp_flow %d", c$resp$flow_label);
}
event new_connection(c: connection)
{
print_connection(c, "new_connection");
}
event connection_established(c: connection)
{
print_connection(c, "connection_established");
}
event connection_state_remove(c: connection)
{
print_connection(c, "connection_state_remove");
}
event connection_flow_label_changed(c: connection, is_orig: bool,
old_label: count, new_label: count)
{
print_connection(c, fmt("connection_flow_label_changed(%s)", is_orig ? "orig" : "resp"));
print fmt(" old_label %d", old_label);
print fmt(" new_label %d", new_label);
}

View file

@ -0,0 +1,56 @@
# @TEST-GROUP: comm
#
# @TEST-REQUIRES: ifconfig | grep -q -E "inet6 ::1|inet6 addr: ::1"
#
# @TEST-EXEC: btest-bg-run recv bro -b ../recv.bro
# @TEST-EXEC: btest-bg-run send bro -b ../send.bro
# @TEST-EXEC: btest-bg-wait -k 20
#
# @TEST-EXEC: btest-diff recv/.stdout
# @TEST-EXEC: btest-diff send/.stdout
@TEST-START-FILE send.bro
@load base/frameworks/communication
redef Communication::nodes += {
["foo"] = [$host=[::1], $connect=T, $events=/my_event/]
};
global my_event: event(s: string);
event remote_connection_handshake_done(p: event_peer)
{
print fmt("handshake done with peer: %s", p$host);
}
event my_event(s: string)
{
print fmt("my_event: %s", s);
terminate();
}
@TEST-END-FILE
#############
@TEST-START-FILE recv.bro
@load frameworks/communication/listen
redef Communication::listen_ipv6=T;
global my_event: event(s: string);
event remote_connection_handshake_done(p: event_peer)
{
print fmt("handshake done with peer: %s", p$host);
event my_event("hello world");
}
event remote_connection_closed(p: event_peer)
{
terminate();
}
@TEST-END-FILE

View file

@ -0,0 +1,10 @@
# @TEST-GROUP: comm
#
# @TEST-REQUIRES: test -e $BUILD/aux/broccoli/src/libbroccoli.so || test -e $BUILD/aux/broccoli/src/libbroccoli.dylib
# @TEST-REQUIRES: ifconfig | grep -q -E "inet6 ::1|inet6 addr: ::1"
#
# @TEST-EXEC: btest-bg-run bro bro $DIST/aux/broccoli/test/broccoli-v6addrs.bro "Communication::listen_ipv6=T"
# @TEST-EXEC: btest-bg-run broccoli $BUILD/aux/broccoli/test/broccoli-v6addrs -6 ::1
# @TEST-EXEC: btest-bg-wait -k 20
# @TEST-EXEC: btest-diff bro/.stdout
# @TEST-EXEC: btest-diff broccoli/.stdout

View file

@ -2,14 +2,8 @@
#
# @TEST-REQUIRES: test -e $BUILD/aux/broccoli/src/libbroccoli.so || test -e $BUILD/aux/broccoli/src/libbroccoli.dylib
#
# @TEST-EXEC: btest-bg-run bro bro %INPUT $DIST/aux/broccoli/test/broccoli-v6addrs.bro
# @TEST-EXEC: btest-bg-run bro bro $DIST/aux/broccoli/test/broccoli-v6addrs.bro
# @TEST-EXEC: btest-bg-run broccoli $BUILD/aux/broccoli/test/broccoli-v6addrs
# @TEST-EXEC: btest-bg-wait -k 20
# @TEST-EXEC: btest-diff bro/.stdout
# @TEST-EXEC: btest-diff broccoli/.stdout
event remote_connection_closed(p: event_peer)
{
terminate();
}

View file

@ -0,0 +1,68 @@
# @TEST-GROUP: comm
#
# @TEST-REQUIRES: test -e $BUILD/aux/broccoli/src/libbroccoli.so || test -e $BUILD/aux/broccoli/src/libbroccoli.dylib
#
# @TEST-EXEC: chmod 600 broccoli.conf
# @TEST-EXEC: btest-bg-run bro bro $DIST/aux/broccoli/test/broccoli-v6addrs.bro "Communication::listen_ssl=T" "ssl_ca_certificate=../ca_cert.pem" "ssl_private_key=../bro.pem"
# @TEST-EXEC: btest-bg-run broccoli BROCCOLI_CONFIG_FILE=../broccoli.conf $BUILD/aux/broccoli/test/broccoli-v6addrs
# @TEST-EXEC: btest-bg-wait -k 20
# @TEST-EXEC: btest-diff bro/.stdout
# @TEST-EXEC: btest-diff broccoli/.stdout
@TEST-START-FILE broccoli.conf
/broccoli/use_ssl yes
/broccoli/ca_cert ../ca_cert.pem
/broccoli/host_cert ../bro.pem
/broccoli/host_key ../bro.pem
@TEST-END-FILE
@TEST-START-FILE bro.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQD17FE8UVaO224Y8UL2bH1okCYxr5dVytTQ93uE5J9caGADzPZe
qYPuvtPt9ivhBtf2L9odK7unQU60v6RsO3bb9bQktQbEdh0FEjnso2UHe/nLreYn
VyLCEp9Sh1OFQnMhJNYuzNwVzWOqH/TYNy3ODueZTS4YBsRyEkpEfgeoaQIDAQAB
AoGAJ/S1Xi94+Mz+Hl9UmeUWmx6QlhIJbI7/9NPA5d6fZcwvjW6HuOmh3fBzTn5o
sq8B96Xesk6gtpQNzaA1fsBKlzDSpGRDVg2odN9vIT3jd0Dub2F47JHdFCqtMUIV
rCsO+fpGtavv1zJ/rzlJz7rx4cRP+/Gwd5YlH0q5cFuHhAECQQD9q328Ye4A7o2e
cLOhzuWUZszqdIY7ZTgDtk06F57VrjLVERrZjrtAwbs77m+ybw4pDKKU7H5inhQQ
03PU40ARAkEA+C6cCM6E4hRwuR+QyIqpNC4CzgPaKlF+VONZLYYvHEwFvx2/EPtX
zOZdE4HdJwnXBYx7+AGFeq8uHhrN2Tq62QJBAMory2JAinejqKsGF6R2SPMlm1ug
0vqziRksShBqkuSqmUjHASczYnoR7S+usMb9S8PblhgrA++FHWjrnf2lwIECQQCj
+/AfpY2J8GWW/HNm/q/UiX5S75qskZI+tsXK3bmtIdI+OIJxzxFxktj3NbyRud+4
i92xvhebO7rmK2HOYg7pAkEA2wrwY1E237twoYXuUInv9F9kShKLQs19nup/dfmF
xfoVqYjJwidzPfgngowJZij7SoTaIBKv/fKp5Tq6xW3AEg==
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICZDCCAc2gAwIBAgIJAKoxR9yFGsk8MA0GCSqGSIb3DQEBBQUAMCsxKTAnBgNV
BAMTIEJybyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MCAXDTExMDYxNTIx
MjgxNVoYDzIxMTEwNTIyMjEyODE1WjArMSkwJwYDVQQDEyBCcm8gUm9vdCBDZXJ0
aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
9exRPFFWjttuGPFC9mx9aJAmMa+XVcrU0Pd7hOSfXGhgA8z2XqmD7r7T7fYr4QbX
9i/aHSu7p0FOtL+kbDt22/W0JLUGxHYdBRI57KNlB3v5y63mJ1ciwhKfUodThUJz
ISTWLszcFc1jqh/02Dctzg7nmU0uGAbEchJKRH4HqGkCAwEAAaOBjTCBijAdBgNV
HQ4EFgQU2vIsKYuGhHP8c7GeJLfWAjbKCFgwWwYDVR0jBFQwUoAU2vIsKYuGhHP8
c7GeJLfWAjbKCFihL6QtMCsxKTAnBgNVBAMTIEJybyBSb290IENlcnRpZmljYXRp
b24gQXV0aG9yaXR5ggkAqjFH3IUayTwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B
AQUFAAOBgQAF2oceL61dA7WxA9lxcxsA/Fccr7+J6sO+pLXoZtx5tpknEuIUebkm
UfMGAiyYIenHi8u0Sia8KrIfuCDc2dG3DYmfX7/faCEbtSx8KtNQFIs3aXr1zhsw
3sX9fLS0gp/qHoPMuhbhlvTlMFSE/Mih3KDsZEGcifzI6ooLF0YP5A==
-----END CERTIFICATE-----
@TEST-END-FILE
@TEST-START-FILE ca_cert.pem
-----BEGIN CERTIFICATE-----
MIICZDCCAc2gAwIBAgIJAKoxR9yFGsk8MA0GCSqGSIb3DQEBBQUAMCsxKTAnBgNV
BAMTIEJybyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MCAXDTExMDYxNTIx
MjgxNVoYDzIxMTEwNTIyMjEyODE1WjArMSkwJwYDVQQDEyBCcm8gUm9vdCBDZXJ0
aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
9exRPFFWjttuGPFC9mx9aJAmMa+XVcrU0Pd7hOSfXGhgA8z2XqmD7r7T7fYr4QbX
9i/aHSu7p0FOtL+kbDt22/W0JLUGxHYdBRI57KNlB3v5y63mJ1ciwhKfUodThUJz
ISTWLszcFc1jqh/02Dctzg7nmU0uGAbEchJKRH4HqGkCAwEAAaOBjTCBijAdBgNV
HQ4EFgQU2vIsKYuGhHP8c7GeJLfWAjbKCFgwWwYDVR0jBFQwUoAU2vIsKYuGhHP8
c7GeJLfWAjbKCFihL6QtMCsxKTAnBgNVBAMTIEJybyBSb290IENlcnRpZmljYXRp
b24gQXV0aG9yaXR5ggkAqjFH3IUayTwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B
AQUFAAOBgQAF2oceL61dA7WxA9lxcxsA/Fccr7+J6sO+pLXoZtx5tpknEuIUebkm
UfMGAiyYIenHi8u0Sia8KrIfuCDc2dG3DYmfX7/faCEbtSx8KtNQFIs3aXr1zhsw
3sX9fLS0gp/qHoPMuhbhlvTlMFSE/Mih3KDsZEGcifzI6ooLF0YP5A==
-----END CERTIFICATE-----
@TEST-END-FILE

View file

@ -8,8 +8,10 @@
# @TEST-EXEC: btest-diff receiver/http.log
# @TEST-EXEC: cmp sender/http.log receiver/http.log
#
# @TEST-EXEC: bro -x sender/events.bst http/base | sed 's/^Event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' >events.snd.log
# @TEST-EXEC: bro -x receiver/events.bst http/base | sed 's/^Event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' >events.rec.log
# @TEST-EXEC: bro -x sender/events.bst | sed 's/^Event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' >events.snd.log
# @TEST-EXEC: bro -x receiver/events.bst | sed 's/^Event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' >events.rec.log
# @TEST-EXEC: btest-diff events.rec.log
# @TEST-EXEC: btest-diff events.snd.log
# @TEST-EXEC: cmp events.rec.log events.snd.log
#
# We don't compare the transmitted event paramerters anymore. With the dynamic

View file

@ -10,6 +10,8 @@
#
# @TEST-EXEC: bro -x sender/events.bst | sed 's/^Event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' >events.snd.log
# @TEST-EXEC: bro -x receiver/events.bst | sed 's/^Event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' >events.rec.log
# @TEST-EXEC: btest-diff events.rec.log
# @TEST-EXEC: btest-diff events.snd.log
# @TEST-EXEC: cmp events.rec.log events.snd.log
#
# We don't compare the transmitted event paramerters anymore. With the dynamic