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 2.0-372 | 2012-05-17 13:59:45 -0700
* Fix compile errors. (Jon Siwek) * 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 .. rst-class:: opening
Bro's default ASCII log format is not exactly the most efficient Bro's default ASCII log format is not exactly the most efficient
way for storing large volumes of data. An an alternative, Bro comes way for storing and searching large volumes of data. An an
with experimental support for `DataSeries alternative, Bro comes with experimental support for `DataSeries
<http://www.hpl.hp.com/techreports/2009/HPL-2009-323.html>`_ <http://www.hpl.hp.com/techreports/2009/HPL-2009-323.html>`_
output, an efficient binary format for recording structured bulk output, an efficient binary format for recording structured bulk
data. DataSeries is developed and maintained at HP Labs. 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 Please refer to the packages' documentation for more information about
the installation process. In particular, there's more information on the installation process. In particular, there's more information on
required and optional `dependencies for Lintel 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 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 Compiling Bro with DataSeries Support
------------------------------------- -------------------------------------
@ -166,3 +169,18 @@ with the output files.
The ``man`` pages for these tool show further options, and their The ``man`` pages for these tool show further options, and their
``-h`` option gives some more information (either can be a bit cryptic ``-h`` option gives some more information (either can be a bit cryptic
unfortunately though). 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; node_type: NodeType;
## The IP address of the cluster node. ## The IP address of the cluster node.
ip: addr; 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 ## The port to which the this local node can connect when
## establishing communication. ## establishing communication.
p: port; p: port;

View file

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

View file

@ -2,6 +2,7 @@
##! and/or transfer events. ##! and/or transfer events.
@load base/frameworks/packet-filter @load base/frameworks/packet-filter
@load base/utils/addrs
module Communication; module Communication;
@ -10,7 +11,7 @@ export {
## The communication logging stream identifier. ## The communication logging stream identifier.
redef enum Log::ID += { LOG }; 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; const listen_interface = 0.0.0.0 &redef;
## Which port to listen on. ## Which port to listen on.
@ -19,6 +20,19 @@ export {
## This defines if a listening socket should use SSL. ## This defines if a listening socket should use SSL.
const listen_ssl = F &redef; 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 ## Default compression level. Compression level is 0-9, with 0 = no
## compression. ## compression.
global compression_level = 0 &redef; global compression_level = 0 &redef;
@ -52,6 +66,10 @@ export {
## Remote address. ## Remote address.
host: addr; 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 ## Port of the remote Bro communication endpoint if we are initiating
## the connection based on the :bro:id:`connect` field. ## the connection based on the :bro:id:`connect` field.
p: port &optional; p: port &optional;
@ -160,7 +178,7 @@ event remote_log(level: count, src: count, msg: string)
# This is a core generated event. # This is a core generated event.
event remote_log_peer(p: event_peer, level: count, src: count, msg: string) 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); do_script_log_common(level, src, rmsg);
} }
@ -178,7 +196,8 @@ function connect_peer(peer: string)
p = node$p; p = node$p;
local class = node?$class ? node$class : ""; 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 ) if ( id == PEER_ID_NONE )
Log::write(Communication::LOG, [$ts = network_time(), Log::write(Communication::LOG, [$ts = network_time(),

View file

@ -11,6 +11,10 @@ export {
## The port of the host that will be controlled. ## The port of the host that will be controlled.
const host_port = 0/tcp &redef; 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 ## The command that is being done. It's typically set on the
## command line. ## command line.
const cmd = "" &redef; const cmd = "" &redef;

View file

@ -10,7 +10,7 @@ export {
## 'lzo' -- LZO compression. Very fast decompression times. ## 'lzo' -- LZO compression. Very fast decompression times.
## 'gz' -- GZIP compression. Slower than LZF, but also produces smaller output. ## 'gz' -- GZIP compression. Slower than LZF, but also produces smaller output.
## 'bz2' -- BZIP2 compression. Slower than GZIP, 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. ## The extent buffer size.
## Larger values here lead to better compression and more efficient writes, but ## 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. ## use ``count``. That should be changed.
type AnalyzerID: count; 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 { type endpoint: record {
size: count; ##< Logical size of data sent (for TCP: derived from sequence numbers). size: count; ##< Logical size of data sent (for TCP: derived from sequence numbers).
## Endpoint state. For TCP connection, one of the constants: ## 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 ## Number of IP-level bytes sent. Only set if :bro:id:`use_conn_size_analyzer` is
## true. ## true.
num_bytes_ip: count &optional; 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 # A connection. This is Bro's basic connection type describing IP- and
@ -219,7 +222,7 @@ type connection: record {
service: set[string]; service: set[string];
addl: string; ##< Deprecated. addl: string; ##< Deprecated.
hot: count; ##< 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 ## 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 ## that is very likely unique across independent Bro runs. These IDs can thus be
## used to tag and locate information associated with that connection. ## 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 ## Values extracted from an IPv6 extension header's (e.g. hop-by-hop or
## destination option headers) option field. ## 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 { type ip6_option: record {
otype: count; ##< Option type. otype: count; ##< Option type.
len: count; ##< Option data length. len: count; ##< Option data length.
@ -976,7 +979,7 @@ type ip6_option: record {
## Values extracted from an IPv6 Hop-by-Hop options extension header. ## 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 { type ip6_hopopts: record {
## Protocol number of the next header (RFC 1700 et seq., IANA assigned ## Protocol number of the next header (RFC 1700 et seq., IANA assigned
## number), e.g. :bro:id:`IPPROTO_ICMP`. ## number), e.g. :bro:id:`IPPROTO_ICMP`.
@ -989,7 +992,7 @@ type ip6_hopopts: record {
## Values extracted from an IPv6 Destination options extension header. ## 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 { type ip6_dstopts: record {
## Protocol number of the next header (RFC 1700 et seq., IANA assigned ## Protocol number of the next header (RFC 1700 et seq., IANA assigned
## number), e.g. :bro:id:`IPPROTO_ICMP`. ## number), e.g. :bro:id:`IPPROTO_ICMP`.
@ -1002,7 +1005,7 @@ type ip6_dstopts: record {
## Values extracted from an IPv6 Routing extension header. ## 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 { type ip6_routing: record {
## Protocol number of the next header (RFC 1700 et seq., IANA assigned ## Protocol number of the next header (RFC 1700 et seq., IANA assigned
## number), e.g. :bro:id:`IPPROTO_ICMP`. ## number), e.g. :bro:id:`IPPROTO_ICMP`.
@ -1019,7 +1022,7 @@ type ip6_routing: record {
## Values extracted from an IPv6 Fragment extension header. ## 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 { type ip6_fragment: record {
## Protocol number of the next header (RFC 1700 et seq., IANA assigned ## Protocol number of the next header (RFC 1700 et seq., IANA assigned
## number), e.g. :bro:id:`IPPROTO_ICMP`. ## number), e.g. :bro:id:`IPPROTO_ICMP`.
@ -1038,7 +1041,7 @@ type ip6_fragment: record {
## Values extracted from an IPv6 Authentication extension header. ## 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 { type ip6_ah: record {
## Protocol number of the next header (RFC 1700 et seq., IANA assigned ## Protocol number of the next header (RFC 1700 et seq., IANA assigned
## number), e.g. :bro:id:`IPPROTO_ICMP`. ## number), e.g. :bro:id:`IPPROTO_ICMP`.
@ -1057,7 +1060,7 @@ type ip6_ah: record {
## Values extracted from an IPv6 ESP extension header. ## 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 { type ip6_esp: record {
## Security Parameters Index. ## Security Parameters Index.
spi: count; spi: count;
@ -1067,7 +1070,7 @@ type ip6_esp: record {
## Values extracted from an IPv6 Mobility Binding Refresh Request message. ## 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 { type ip6_mobility_brr: record {
## Reserved. ## Reserved.
rsv: count; rsv: count;
@ -1077,7 +1080,7 @@ type ip6_mobility_brr: record {
## Values extracted from an IPv6 Mobility Home Test Init message. ## 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 { type ip6_mobility_hoti: record {
## Reserved. ## Reserved.
rsv: count; rsv: count;
@ -1089,7 +1092,7 @@ type ip6_mobility_hoti: record {
## Values extracted from an IPv6 Mobility Care-of Test Init message. ## 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 { type ip6_mobility_coti: record {
## Reserved. ## Reserved.
rsv: count; rsv: count;
@ -1101,7 +1104,7 @@ type ip6_mobility_coti: record {
## Values extracted from an IPv6 Mobility Home Test message. ## 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 { type ip6_mobility_hot: record {
## Home Nonce Index. ## Home Nonce Index.
nonce_idx: count; nonce_idx: count;
@ -1115,7 +1118,7 @@ type ip6_mobility_hot: record {
## Values extracted from an IPv6 Mobility Care-of Test message. ## 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 { type ip6_mobility_cot: record {
## Care-of Nonce Index. ## Care-of Nonce Index.
nonce_idx: count; nonce_idx: count;
@ -1129,7 +1132,7 @@ type ip6_mobility_cot: record {
## Values extracted from an IPv6 Mobility Binding Update message. ## 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 { type ip6_mobility_bu: record {
## Sequence number. ## Sequence number.
seq: count; seq: count;
@ -1149,7 +1152,7 @@ type ip6_mobility_bu: record {
## Values extracted from an IPv6 Mobility Binding Acknowledgement message. ## 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 { type ip6_mobility_back: record {
## Status. ## Status.
status: count; status: count;
@ -1165,7 +1168,7 @@ type ip6_mobility_back: record {
## Values extracted from an IPv6 Mobility Binding Error message. ## 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 { type ip6_mobility_be: record {
## Status. ## Status.
status: count; status: count;
@ -1177,7 +1180,7 @@ type ip6_mobility_be: record {
## Values extracted from an IPv6 Mobility header's message data. ## 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 { type ip6_mobility_msg: record {
## The type of message from the header's MH Type field. ## The type of message from the header's MH Type field.
id: count; id: count;
@ -1201,7 +1204,7 @@ type ip6_mobility_msg: record {
## Values extracted from an IPv6 Mobility header. ## 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 { type ip6_mobility_hdr: record {
## Protocol number of the next header (RFC 1700 et seq., IANA assigned ## Protocol number of the next header (RFC 1700 et seq., IANA assigned
## number), e.g. :bro:id:`IPPROTO_ICMP`. ## number), e.g. :bro:id:`IPPROTO_ICMP`.
@ -1244,7 +1247,7 @@ type ip6_ext_hdr: record {
## Values extracted from an IPv6 header. ## 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 ## ip6_routing ip6_fragment ip6_ah ip6_esp
type ip6_hdr: record { type ip6_hdr: record {
class: count; ##< Traffic class. class: count; ##< Traffic class.

View file

@ -68,7 +68,7 @@ export {
missed_bytes: count &log &default=0; missed_bytes: count &log &default=0;
## Records the state history of connections as a string of letters. ## 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 ## Letter Meaning

View file

@ -8,5 +8,6 @@ module Communication;
event bro_init() &priority=-10 event bro_init() &priority=-10
{ {
enable_communication(); 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 # Establish the communication configuration and only request response
# messages. # messages.
Communication::nodes["control"] = [$host=host, $p=host_port, Communication::nodes["control"] = [$host=host, $zone_id=zone_id,
$sync=F, $connect=T, $p=host_port, $sync=F, $connect=T,
$class="control", $events=Control::controllee_events]; $class="control", $events=Control::controllee_events];
} }

View file

@ -111,7 +111,8 @@ unsigned int Connection::external_connections = 0;
IMPLEMENT_SERIAL(Connection, SER_CONNECTION); 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; sessions = s;
key = k; key = k;
@ -122,6 +123,10 @@ Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id)
orig_port = id->src_port; orig_port = id->src_port;
resp_port = id->dst_port; resp_port = id->dst_port;
proto = TRANSPORT_UNKNOWN; proto = TRANSPORT_UNKNOWN;
orig_flow_label = flow;
resp_flow_label = 0;
saw_first_orig_packet = 1;
saw_first_resp_packet = 0;
conn_val = 0; conn_val = 0;
login_conn = 0; login_conn = 0;
@ -323,10 +328,12 @@ RecordVal* Connection::BuildConnVal()
RecordVal *orig_endp = new RecordVal(endpoint); RecordVal *orig_endp = new RecordVal(endpoint);
orig_endp->Assign(0, new Val(0, TYPE_COUNT)); orig_endp->Assign(0, new Val(0, TYPE_COUNT));
orig_endp->Assign(1, 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); RecordVal *resp_endp = new RecordVal(endpoint);
resp_endp->Assign(0, new Val(0, TYPE_COUNT)); resp_endp->Assign(0, new Val(0, TYPE_COUNT));
resp_endp->Assign(1, 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(0, id_val);
conn_val->Assign(1, orig_endp); conn_val->Assign(1, orig_endp);
@ -675,6 +682,14 @@ void Connection::FlipRoles()
resp_port = orig_port; resp_port = orig_port;
orig_port = tmp_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); Unref(conn_val);
conn_val = 0; conn_val = 0;
@ -882,3 +897,35 @@ void Connection::SetRootAnalyzer(TransportLayerAnalyzer* analyzer, PIA* pia)
root_analyzer = analyzer; root_analyzer = analyzer;
primary_PIA = pia; 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 { class Connection : public BroObj {
public: 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(); virtual ~Connection();
// Invoked when connection is about to be removed. Use Ref(this) // 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 SetUID(uint64 arg_uid) { uid = arg_uid; }
void CheckFlowLabel(bool is_orig, uint32 flow_label);
protected: protected:
Connection() { persistent = 0; } Connection() { persistent = 0; }
@ -271,6 +274,7 @@ protected:
IPAddr resp_addr; IPAddr resp_addr;
uint32 orig_port, resp_port; // in network order uint32 orig_port, resp_port; // in network order
TransportProto proto; TransportProto proto;
uint32 orig_flow_label, resp_flow_label; // most recent IPv6 flow labels
double start_time, last_time; double start_time, last_time;
double inactivity_timeout; double inactivity_timeout;
RecordVal* conn_val; RecordVal* conn_val;
@ -286,6 +290,7 @@ protected:
unsigned int record_packets:1, record_contents:1; unsigned int record_packets:1, record_contents:1;
unsigned int persistent:1; unsigned int persistent:1;
unsigned int record_current_packet:1, record_current_content: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. // Count number of connections.
static unsigned int total_connections; static unsigned int total_connections;

View file

@ -524,6 +524,12 @@ public:
int DF() const int DF() const
{ return ip4 ? ((ntohs(ip4->ip_off) & 0x4000) != 0) : 0; } { 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). * 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. * IPv4 to IPv6 address mapping to return a full 16 bytes.
* *
* @param bytes The pointer to a memory location in which the * @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)); 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; 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. * Returns a host-order, plain hex string representation of the address.
*/ */

View file

@ -147,6 +147,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netdb.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <unistd.h> #include <unistd.h>
@ -172,6 +173,9 @@
#include <sys/resource.h> #include <sys/resource.h>
#include <algorithm> #include <algorithm>
#include <string>
#include <sstream>
#include <vector>
#include "RemoteSerializer.h" #include "RemoteSerializer.h"
#include "Func.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 // 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 // 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 ...) // 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 #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; static pid_t child_pid = 0;
// Return true if message type is sent by a peer (rather than the child // 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, 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 ) if ( ! using_communication )
return true; return true;
@ -683,24 +689,22 @@ RemoteSerializer::PeerID RemoteSerializer::Connect(const IPAddr& ip,
if ( ! initialized ) if ( ! initialized )
reporter->InternalError("remote serializer not 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 ) if ( ! child_pid )
Fork(); Fork();
Peer* p = AddPeer(ip4, port); Peer* p = AddPeer(ip, port);
p->orig = true; p->orig = true;
if ( our_class ) if ( our_class )
p->our_class = our_class; p->our_class = our_class;
if ( ! SendToChild(MSG_CONNECT_TO, p, 5, p->id, const size_t BUFSIZE = 1024;
ip4, port, uint32(retry), use_ssl) ) 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); RemovePeer(p);
return false; return false;
@ -1232,7 +1236,8 @@ bool RemoteSerializer::SendCapabilities(Peer* peer)
return caps ? SendToChild(MSG_CAPS, peer, 3, caps, 0, 0) : true; 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 ) if ( ! using_communication )
return true; return true;
@ -1240,14 +1245,18 @@ bool RemoteSerializer::Listen(const IPAddr& ip, uint16 port, bool expect_ssl)
if ( ! initialized ) if ( ! initialized )
reporter->InternalError("remote serializer not initialized"); reporter->InternalError("remote serializer not initialized");
if ( ip.GetFamily() == IPv6 ) if ( ! ipv6 && ip.GetFamily() == IPv6 &&
Error("inter-Bro communication not supported over 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; const size_t BUFSIZE = 1024;
ip.GetBytes(&bytes); char* data = new char[BUFSIZE];
uint32 ip4 = ntohl(*bytes); 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; return false;
listening = true; listening = true;
@ -1784,7 +1793,7 @@ RecordVal* RemoteSerializer::MakePeerVal(Peer* peer)
RecordVal* v = new RecordVal(::peer); RecordVal* v = new RecordVal(::peer);
v->Assign(0, new Val(uint32(peer->id), TYPE_COUNT)); v->Assign(0, new Val(uint32(peer->id), TYPE_COUNT));
// Sic! Network order for AddrVal, host order for PortVal. // 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(2, new PortVal(peer->port, TRANSPORT_TCP));
v->Assign(3, new Val(false, TYPE_BOOL)); v->Assign(3, new Val(false, TYPE_BOOL));
v->Assign(4, new StringVal("")); // set when received v->Assign(4, new StringVal("")); // set when received
@ -1793,7 +1802,7 @@ RecordVal* RemoteSerializer::MakePeerVal(Peer* peer)
return v; return v;
} }
RemoteSerializer::Peer* RemoteSerializer::AddPeer(uint32 ip, uint16 port, RemoteSerializer::Peer* RemoteSerializer::AddPeer(const IPAddr& ip, uint16 port,
PeerID id) PeerID id)
{ {
Peer* peer = new Peer; Peer* peer = new Peer;
@ -1959,9 +1968,22 @@ bool RemoteSerializer::EnterPhaseRunning(Peer* peer)
bool RemoteSerializer::ProcessConnected() bool RemoteSerializer::ProcessConnected()
{ {
// IP and port follow. // IP and port follow.
uint32* args = (uint32*) current_args->data; vector<string> args = tokenize(current_args->data, ',');
uint32 host = ntohl(args[0]); // ### Fix: only works for IPv4
uint16 port = (uint16) ntohl(args[1]); 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 ) if ( ! current_peer )
{ {
@ -2980,7 +3002,8 @@ void RemoteSerializer::Log(LogLevel level, const char* msg, Peer* peer,
if ( peer ) if ( peer )
len += snprintf(buffer + len, sizeof(buffer) - len, "[#%d/%s:%d] ", 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); len += safe_snprintf(buffer + len, sizeof(buffer) - len, "%s", msg);
@ -3266,8 +3289,10 @@ SocketComm::SocketComm()
terminating = false; terminating = false;
killing = false; killing = false;
listen_fd_clear = -1; listen_port = 0;
listen_fd_ssl = -1; listen_ssl = false;
enable_ipv6 = false;
bind_retry_interval = 0;
listen_next_try = 0; listen_next_try = 0;
// We don't want to use the signal handlers of our parent. // We don't want to use the signal handlers of our parent.
@ -3290,8 +3315,7 @@ SocketComm::~SocketComm()
delete peers[i]->io; delete peers[i]->io;
delete io; delete io;
close(listen_fd_clear); CloseListenFDs();
close(listen_fd_ssl);
} }
static unsigned int first_rtime = 0; static unsigned int first_rtime = 0;
@ -3340,20 +3364,13 @@ void SocketComm::Run()
} }
if ( listen_next_try && time(0) > listen_next_try ) 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); FD_SET(listen_fds[i], &fd_read);
if ( listen_fd_clear > max_fd ) if ( listen_fds[i] > max_fd )
max_fd = listen_fd_clear; max_fd = listen_fds[i];
}
if ( listen_fd_ssl >= 0 )
{
FD_SET(listen_fd_ssl, &fd_read);
if ( listen_fd_ssl > max_fd )
max_fd = listen_fd_ssl;
} }
if ( io->IsFillingUp() && ! shutting_conns_down ) if ( io->IsFillingUp() && ! shutting_conns_down )
@ -3442,12 +3459,9 @@ void SocketComm::Run()
} }
} }
if ( listen_fd_clear >= 0 && for ( size_t i = 0; i < listen_fds.size(); ++i )
FD_ISSET(listen_fd_clear, &fd_read) ) if ( FD_ISSET(listen_fds[i], &fd_read) )
AcceptConnection(listen_fd_clear); AcceptConnection(listen_fds[i]);
if ( listen_fd_ssl >= 0 && FD_ISSET(listen_fd_ssl, &fd_read) )
AcceptConnection(listen_fd_ssl);
// Hack to display CPU usage of the child, triggered via // Hack to display CPU usage of the child, triggered via
// SIGPROF. // SIGPROF.
@ -3571,13 +3585,8 @@ bool SocketComm::DoParentMessage()
case MSG_LISTEN_STOP: case MSG_LISTEN_STOP:
{ {
if ( listen_fd_ssl >= 0 ) CloseListenFDs();
close(listen_fd_ssl);
if ( listen_fd_clear >= 0 )
close(listen_fd_clear);
listen_fd_clear = listen_fd_ssl = -1;
Log("stopped listening"); Log("stopped listening");
return true; return true;
@ -3717,14 +3726,43 @@ bool SocketComm::ForwardChunkToPeer()
bool SocketComm::ProcessConnectTo() bool SocketComm::ProcessConnectTo()
{ {
assert(parent_args); 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* peer = new Peer;
peer->id = ntohl(args[0]);
peer->ip = ntohl(args[1]); if ( ! atoi_n(args[0].size(), args[0].c_str(), 0, 10, peer->id) )
peer->port = ntohl(args[2]); {
peer->retry = ntohl(args[3]); Error(fmt("ProccessConnectTo() bad peer id string"));
peer->ssl = ntohl(args[4]); 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); return Connect(peer);
} }
@ -3732,13 +3770,39 @@ bool SocketComm::ProcessConnectTo()
bool SocketComm::ProcessListen() bool SocketComm::ProcessListen()
{ {
assert(parent_args); assert(parent_args);
uint32* args = (uint32*) parent_args->data; vector<string> args = tokenize(parent_args->data, ',');
uint32 addr = ntohl(args[0]); if ( args.size() != 6 )
uint16 port = uint16(ntohl(args[1])); {
uint32 ssl = ntohl(args[2]); 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() bool SocketComm::ProcessParentCompress()
@ -3900,29 +3964,54 @@ bool SocketComm::ProcessPeerCompress(Peer* peer)
bool SocketComm::Connect(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); hints.ai_family = PF_UNSPEC;
if ( sockfd < 0 ) 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; return false;
} }
bzero(&server, sizeof(server)); int sockfd = -1;
server.sin_family = AF_INET; for ( res = res0; res; res = res->ai_next )
server.sin_port = htons(peer->port); {
server.sin_addr.s_addr = htonl(peer->ip); 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;
}
bool connected = true; if ( connect(sockfd, res->ai_addr, res->ai_addrlen) < 0 )
if ( connect(sockfd, (sockaddr*) &server, sizeof(server)) < 0 )
{ {
Error(fmt("connect failed: %s", strerror(errno)), peer); Error(fmt("connect failed: %s", strerror(errno)), peer);
close(sockfd); close(sockfd);
connected = false; sockfd = -1;
continue;
} }
break;
}
freeaddrinfo(res0);
bool connected = sockfd != -1;
if ( ! (connected || peer->retry) ) if ( ! (connected || peer->retry) )
{ {
CloseConnection(peer, false); CloseConnection(peer, false);
@ -3947,9 +4036,7 @@ bool SocketComm::Connect(Peer* peer)
if ( connected ) if ( connected )
{ {
if ( peer->ssl ) if ( peer->ssl )
{
peer->io = new ChunkedIOSSL(sockfd, false); peer->io = new ChunkedIOSSL(sockfd, false);
}
else else
peer->io = new ChunkedIOFd(sockfd, "child->peer"); peer->io = new ChunkedIOFd(sockfd, "child->peer");
@ -3964,7 +4051,13 @@ bool SocketComm::Connect(Peer* peer)
if ( connected ) if ( connected )
{ {
Log("connected", peer); 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; return false;
} }
@ -4001,86 +4094,148 @@ bool SocketComm::CloseConnection(Peer* peer, bool reconnect)
return true; 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 ) IPAddr listen_ip(listen_if);
close(*listen_fd);
struct sockaddr_in server; if ( enable_ipv6 )
*listen_fd = socket(PF_INET, SOCK_STREAM, 0);
if ( *listen_fd < 0 )
{ {
Error(fmt("can't create listen socket, %s", if ( listen_ip == IPAddr("0.0.0.0") || listen_ip == IPAddr("::") )
strerror(errno))); 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; return false;
} }
// Set SO_REUSEADDR. for ( res = res0; res; res = res->ai_next )
int turn_on = 1;
if ( setsockopt(*listen_fd, SOL_SOCKET, SO_REUSEADDR,
&turn_on, sizeof(turn_on)) < 0 )
{ {
Error(fmt("can't set SO_REUSEADDR, %s", if ( res->ai_family != AF_INET && res->ai_family != AF_INET6 )
strerror(errno))); {
return false; Error(fmt("can't create listen socket: unknown address family, %d",
res->ai_family));
continue;
} }
bzero(&server, sizeof(server)); IPAddr a = (res->ai_family == AF_INET) ?
server.sin_family = AF_INET; IPAddr(((sockaddr_in*)res->ai_addr)->sin_addr) :
server.sin_port = htons(port); IPAddr(((sockaddr_in6*)res->ai_addr)->sin6_addr);
server.sin_addr.s_addr = htonl(ip);
if ( bind(*listen_fd, (sockaddr*) &server, sizeof(server)) < 0 ) 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 bind to port %d, %s", port, strerror(errno))); Error(fmt("can't create listen socket, %s", strerror(errno)));
close(*listen_fd); continue;
*listen_fd = -1; }
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 ) if ( errno == EADDRINUSE )
{ {
listen_if = ip; // Abandon completely this attempt to set up listening sockets,
listen_port = port; // try again later.
listen_ssl = expect_ssl; CloseListenFDs();
// FIXME: Make this timeout configurable. listen_next_try = time(0) + bind_retry_interval;
listen_next_try = time(0) + 30;
}
return false; return false;
} }
continue;
}
if ( listen(*listen_fd, 50) < 0 ) if ( listen(fd, 50) < 0 )
{ {
Error(fmt("can't listen, %s", strerror(errno))); Error(fmt("can't listen on %s:%s, %s", l_addr_str.c_str(),
return false; 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"));
}
freeaddrinfo(res0);
listen_next_try = 0; listen_next_try = 0;
Log(fmt("listening on %s:%d (%s)", return listen_fds.size() > 0;
ip2a(ip), port, expect_ssl ? "ssl" : "clear"));
return true;
} }
bool SocketComm::AcceptConnection(int fd) bool SocketComm::AcceptConnection(int fd)
{ {
sockaddr_in client; sockaddr_storage client;
socklen_t len = sizeof(client); socklen_t len = sizeof(client);
int clientfd = accept(fd, (sockaddr*) &client, &len); int clientfd = accept(fd, (sockaddr*) &client, &len);
if ( clientfd < 0 ) if ( clientfd < 0 )
{ {
Error(fmt("accept failed, %s %d", Error(fmt("accept failed, %s %d", strerror(errno), errno));
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; return false;
} }
Peer* peer = new Peer; Peer* peer = new Peer;
peer->id = id_counter++; peer->id = id_counter++;
peer->ip = ntohl(client.sin_addr.s_addr); peer->ip = client.ss_family == AF_INET ?
peer->port = ntohs(client.sin_port); 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->connected = true;
peer->ssl = (fd == listen_fd_ssl); peer->ssl = listen_ssl;
peer->compressor = false; peer->compressor = false;
if ( peer->ssl ) if ( peer->ssl )
@ -4090,8 +4245,7 @@ bool SocketComm::AcceptConnection(int fd)
if ( ! peer->io->Init() ) if ( ! peer->io->Init() )
{ {
Error(fmt("can't init peer io: %s", Error(fmt("can't init peer io: %s", peer->io->Error()), false);
peer->io->Error()), false);
return false; return false;
} }
@ -4099,7 +4253,12 @@ bool SocketComm::AcceptConnection(int fd)
Log(fmt("accepted %s connection", peer->ssl ? "SSL" : "clear"), peer); 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 false;
return true; return true;
@ -4116,13 +4275,27 @@ const char* SocketComm::MakeLogString(const char* msg, Peer* peer)
int len = 0; int len = 0;
if ( peer ) 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), 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); len += safe_snprintf(buffer + len, BUFSIZE - len, "%s", msg);
return buffer; 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) void SocketComm::Error(const char* msg, bool kill_me)
{ {
if ( kill_me ) if ( kill_me )
@ -4165,7 +4338,7 @@ void SocketComm::Log(const char* msg, Peer* peer)
void SocketComm::InternalError(const char* msg) 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(); Kill();
} }
@ -4180,8 +4353,7 @@ void SocketComm::Kill()
LogProf(); LogProf();
Log("terminating"); Log("terminating");
close(listen_fd_clear); CloseListenFDs();
close(listen_fd_ssl);
kill(getpid(), SIGTERM); kill(getpid(), SIGTERM);

View file

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

View file

@ -602,7 +602,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
conn = (Connection*) d->Lookup(h); conn = (Connection*) d->Lookup(h);
if ( ! conn ) if ( ! conn )
{ {
conn = NewConn(h, t, &id, data, proto); conn = NewConn(h, t, &id, data, proto, ip_hdr->FlowLabel());
if ( conn ) if ( conn )
d->Insert(h, conn); d->Insert(h, conn);
} }
@ -623,7 +623,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
conn->Event(connection_reused, 0); conn->Event(connection_reused, 0);
Remove(conn); Remove(conn);
conn = NewConn(h, t, &id, data, proto); conn = NewConn(h, t, &id, data, proto, ip_hdr->FlowLabel());
if ( conn ) if ( conn )
d->Insert(h, 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()) && int is_orig = (id.src_addr == conn->OrigAddr()) &&
(id.src_port == conn->OrigPort()); (id.src_port == conn->OrigPort());
conn->CheckFlowLabel(is_orig, ip_hdr->FlowLabel());
Val* pkt_hdr_val = 0; Val* pkt_hdr_val = 0;
if ( ipv6_ext_headers && ip_hdr->NumHeaders() > 1 ) 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, 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. // 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. // 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; id = &flip_id;
} }
Connection* conn = new Connection(this, k, t, id); Connection* conn = new Connection(this, k, t, id, flow_label);
conn->SetTransport(tproto); conn->SetTransport(tproto);
dpm->BuildInitialAnalyzerTree(tproto, conn, data); dpm->BuildInitialAnalyzerTree(tproto, conn, data);

View file

@ -142,7 +142,7 @@ protected:
friend class TimerMgrExpireTimer; friend class TimerMgrExpireTimer;
Connection* NewConn(HashKey* k, double t, const ConnID* id, 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 // Check whether the tag of the current packet is consistent with
// the given connection. Returns: // the given connection. Returns:

View file

@ -963,7 +963,7 @@ function sha256_hash_finish%(index: any%): string
## Generates a random number. ## 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)*. ## 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. ## data: The data to find the MIME type for.
## ##
## return_mime: If true, the function returns a short MIME type string (e.g., ## 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*. ## Returns: The MIME type of *data*.
function identify_data%(data: string, return_mime: bool%): string 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. ## Removes all elements from a set or table.
## ##
## v: The 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 function clear_table%(v: any%): any
%{ %{
if ( v->Type()->Tag() == TYPE_TABLE ) 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); 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 ## v: The value
## ##
@ -1306,7 +1304,7 @@ function val_size%(v: any%): count
## ##
## newsize: The new size of *aggr*. ## 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 function resize%(aggr: any, newsize: count%) : count
%{ %{
if ( aggr->Type()->Tag() != TYPE_VECTOR ) 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 ## 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 ## comparison function must be ``function(a: T, b: T): bool``, which returns
## ``a < b`` for some type-specific notion of the less-than operator. ## ``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 ## given argument. If any of the variable arguments is an empty string it is
## replaced by a given default string instead. ## 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. ## 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 ## - ``[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``) ## for ``int``/``count``)
## ##
## - ``x``: Unsigned hexadecimal (using C-style ``%llx``); ## - ``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, ## 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 ## one step lower than sending events. This function checks whether the packets
## of a connection stem from one of these external *packet sources*. ## 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 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. ## none.
function current_analyzer%(%) : count 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 ## 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. ## 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(); 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), ## includes the field name, whether it is logged, its value (if it has one),
## and its default value (if specified). ## and its default value (if specified).
## ##
@ -2269,11 +2267,11 @@ function dump_rule_stats%(f: file%): bool
return new Val(1, TYPE_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. ## Returns: True if Bro is in the process of shutting down.
## ##
## .. bro:see: terminate ## .. bro:see:: terminate
function bro_is_terminating%(%): bool function bro_is_terminating%(%): bool
%{ %{
return new Val(terminating, TYPE_BOOL); return new Val(terminating, TYPE_BOOL);
@ -2354,7 +2352,7 @@ function routing0_data_to_addrs%(s: string%): addr_vec
return rval; 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. ## a: The address to convert into a vector of counts.
## ##
@ -2374,7 +2372,7 @@ function addr_to_counts%(a: addr%): index_vec
return rval; 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, ## v: The vector containing host-order IP address representation,
## one element for IPv4 addresses, four elements for IPv6 addresses. ## 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. ## str: The :bro:type:`string` to convert.
## ##
@ -2434,7 +2432,7 @@ function to_int%(str: string%): int
## ##
## n: The :bro:type:`int` to convert. ## 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 function int_to_count%(n: int%): count
%{ %{
if ( n < 0 ) if ( n < 0 )
@ -2449,7 +2447,7 @@ function int_to_count%(n: int%): count
## ##
## d: The :bro:type:`double` to convert. ## 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 ## .. bro:see:: double_to_time
function double_to_count%(d: double%): count 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. ## str: The :bro:type:`string` to convert.
## ##
## Returns: The :bro:type:`string` *str* as unsigned integer or if in invalid ## Returns: The :bro:type:`string` *str* as unsigned integer, or 0 if *str* has
## format. ## an invalid format.
## ##
## .. bro:see:: to_addr to_int to_port to_subnet ## .. bro:see:: to_addr to_int to_port to_subnet
function to_count%(str: string%): count 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`. ## 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`. ## 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); 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 ## .. bro:see:: time_to_double double_to_count
function double_to_time%(d: double%): time function double_to_time%(d: double%): time
@ -2550,7 +2548,7 @@ function port_to_count%(p: port%): count
## ##
## proto: The transport protocol. ## 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 ## .. bro:see:: port_to_count
function count_to_port%(num: count, proto: transport_proto%): port 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. ## 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. ## 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 ## .. 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. ## 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. ## ``::/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 ## .. 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. ## 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 ## .. bro:see:: raw_bytes_to_v4_addr to_addr to_subnet
function raw_bytes_to_v4_addr%(b: string%): addr 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)); 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. ## 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``. ## 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>``, ## 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 ``|``). ## 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. ## 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"``. ## 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); 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. ## See http://support.microsoft.com/kb/163409.
## ##
## name: The NetBIOS name type. ## name: The NetBIOS name type.
@ -3029,7 +3027,7 @@ function decode_netbios_name_type%(name: string%): count
## ##
## bytestring: The string of bytes. ## bytestring: The string of bytes.
## ##
## Returns: The hexadecimal reprsentation of *bytestring*. ## Returns: The hexadecimal representation of *bytestring*.
## ##
## .. bro:see:: hexdump ## .. bro:see:: hexdump
function bytestring_to_hexstr%(bytestring: string%): string function bytestring_to_hexstr%(bytestring: string%): string
@ -3069,7 +3067,7 @@ function decode_base64%(s: string%): string
## s: The Base64-encoded string. ## s: The Base64-encoded string.
## ##
## a: The custom alphabet. The empty string indicates the default alphabet. The ## 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+?"``. ## ``"!#$%&/(),-.:;<>@[]^ `_{|}~abcdefghijklmnopqrstuvwxyz0123456789+?"``.
## ##
## Returns: The decoded version of *s*. ## Returns: The decoded version of *s*.
@ -3138,7 +3136,7 @@ function uuid_to_string%(uuid: string%): string
## ##
## p2: The second pattern. ## 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 ## .. bro:see:: convert_for_pattern string_to_pattern
## ##
@ -3277,7 +3275,7 @@ function strftime%(fmt: string, d: time%) : string
## a: The address to mask. ## a: The address to mask.
## ##
## top_bits_to_keep: The number of top bits to keep in *a*; must be greater ## 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. ## 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. ## 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 ## .. bro:see:: is_tcp_port is_udp_port
function is_icmp_port%(p: port%): bool function is_icmp_port%(p: port%): bool
@ -3383,7 +3381,7 @@ EnumVal* map_conn_type(TransportProto tp)
## ##
## cid: The connection identifier. ## 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 ## .. bro:see:: get_port_transport_proto
## get_orig_seq get_resp_seq ## get_orig_seq get_resp_seq
@ -3497,7 +3495,7 @@ const char* conn_id_string(Val* c)
## ##
## c: The HTTP connection. ## 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 ## .. bro:see:: skip_smtp_data
function skip_http_entity_data%(c: connection, is_orig: bool%): any 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 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. ## containing the timestamp, ``snaplen``, and packet data.
## ##
## .. bro:see:: dump_current_packet dump_packet send_current_packet ## .. 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. ## 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 ## .. bro:see:: lookup_addr
function lookup_hostname%(host: string%) : addr_set 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. ## Performs an AS lookup of an IP address.
## Requires Bro to be built with ``libgeoip``.
## ##
## a: The IP address to lookup. ## 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. ## 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 ## Returns: A string representation of *mode* in the format
## ``rw[xsS]rw[xsS]rw[xtT]``. ## ``rw[xsS]rw[xsS]rw[xtT]``.
@ -4273,7 +4272,7 @@ function analyzer_name%(aid: count%) : string
## ##
## cid: The connection ID. ## 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. ## otherwise.
## ##
## .. note:: ## .. note::
@ -4295,10 +4294,10 @@ function skip_further_processing%(cid: conn_id%): bool
## ##
## cid: The connection identifier. ## 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*. ## 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. ## otherwise.
## ##
## .. bro:see:: skip_further_processing ## .. bro:see:: skip_further_processing
@ -4309,7 +4308,7 @@ function skip_further_processing%(cid: conn_id%): bool
## connection, which is controlled separately by ## connection, which is controlled separately by
## :bro:id:`skip_further_processing`. ## :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 function set_record_packets%(cid: conn_id, do_record: bool%): bool
%{ %{
Connection* c = sessions->FindConnection(cid); Connection* c = sessions->FindConnection(cid);
@ -4326,7 +4325,7 @@ function set_record_packets%(cid: conn_id, do_record: bool%): bool
## cid: The connection ID. ## cid: The connection ID.
## ##
## direction: Controls what sides of the connection to record. The argument can ## 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_NONE``: Stop recording the connection's content.
## - ``CONTENTS_ORIG``: Record the data sent by the connection ## - ``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. ## 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. ## true otherwise.
## ##
## .. note:: ## .. 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 ## missing data; this can happen, e.g., due to an
## :bro:id:`ack_above_hole` event. ## :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 function set_contents_file%(cid: conn_id, direction: count, f: file%): bool
%{ %{
Connection* c = sessions->FindConnection(cid); 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. ## 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. ## :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 ## connection identified by *cid*. If the connection exists
## but no contents file for *direction*, the function generates a ## but there is no contents file for *direction*, then the function
## error and returns a file handle to ``stderr``. ## 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 function get_contents_file%(cid: conn_id, direction: count%): file
%{ %{
Connection* c = sessions->FindConnection(cid); 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 ## - ``LOGIN_STATE_AUTHENTICATE``: The connection is in its
## initial authentication dialog. ## 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. ## successfully authenticated.
## - ``LOGIN_STATE_SKIP``: The analyzer has skipped any further ## - ``LOGIN_STATE_SKIP``: The analyzer has skipped any further
## processing of the connection. ## 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 ## does not correctly know the state of the connection, and/or
## the username associated with it. ## the username associated with it.
## ##
## .. bro:see: set_login_state ## .. bro:see:: set_login_state
function get_login_state%(cid: conn_id%): count function get_login_state%(cid: conn_id%): count
%{ %{
Connection* c = sessions->FindConnection(cid); 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. ## :bro:id:`get_login_state` for possible values.
## ##
## Returns: Returns false if *cid* is not an active connection ## 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 function set_login_state%(cid: conn_id, new_state: count%): bool
%{ %{
Connection* c = sessions->FindConnection(cid); Connection* c = sessions->FindConnection(cid);
@ -4592,7 +4591,7 @@ function disable_event_group%(group: string%) : any
## ##
## 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 ## get_file_name set_buf flush_all mkdir enable_raw_output
function open%(f: string%): file function open%(f: string%): file
%{ %{
@ -4611,7 +4610,7 @@ function open%(f: string%): 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 ## get_file_name set_buf flush_all mkdir enable_raw_output
function open_for_append%(f: string%): file 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. ## 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. ## 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 ## get_file_name set_buf flush_all mkdir enable_raw_output
function close%(f: file%): bool function close%(f: file%): bool
%{ %{
@ -4640,7 +4638,7 @@ function close%(f: file%): bool
## ##
## 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 ## get_file_name set_buf flush_all mkdir enable_raw_output
function write_file%(f: file, data: string%): bool 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. ## 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: 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 ## false, *f* is line buffered, i.e., bytes are saved up until a
## newline occurs. ## 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 ## get_file_name write_file flush_all mkdir enable_raw_output
function set_buf%(f: file, buffered: bool%): any function set_buf%(f: file, buffered: bool%): any
%{ %{
@ -4672,7 +4670,7 @@ function set_buf%(f: file, buffered: bool%): any
## ##
## 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 ## get_file_name write_file set_buf mkdir enable_raw_output
function flush_all%(%): bool function flush_all%(%): bool
%{ %{
@ -4683,10 +4681,10 @@ function flush_all%(%): bool
## ##
## f: The directory name. ## 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. ## 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 ## get_file_name set_buf flush_all enable_raw_output
function mkdir%(f: string%): bool function mkdir%(f: string%): bool
%{ %{
@ -4731,7 +4729,7 @@ function get_file_name%(f: file%): string
## ##
## f: An open file handle. ## 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. ## after the rotation, and the time when *f* was opened/closed.
## ##
## .. bro:see:: rotate_file_by_name calc_next_rotate ## .. 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 ## 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. ## after the rotation, and the time when *f* was opened/closed.
## ##
## .. bro:see:: rotate_file calc_next_rotate ## .. bro:see:: rotate_file calc_next_rotate
@ -4851,7 +4849,7 @@ function disable_print_hook%(f: file%): any
return 0; 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`. ## This function is equivalent to :bro:attr:`&disable_print_hook`.
## ##
## f: The file to disable raw output for. ## 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); return new Val(persistence_serializer->WriteState(true), TYPE_BOOL);
%} %}
## Reads persistent state from the \texttt{.state} directory and populates the ## Reads persistent state and populates the in-memory data structures
## in-memory data structures accordingly. This function is the dual to ## accordingly. Persistent state is read from the ``.state`` directory.
## :bro:id:`checkpoint_state`. ## This function is the dual to :bro:id:`checkpoint_state`.
## ##
## Returns: True on success. ## Returns: True on success.
## ##
@ -5267,16 +5265,20 @@ function capture_state_updates%(filename: string%) : bool
## ##
## ip: The IP address of the remote peer. ## 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 ## against its class name in its peer table and terminates the
## connection if they don't match. ## connection if they don't match.
## ##
## retry: If the connection fails, try to reconnect with the peer after this ## retry: If the connection fails, try to reconnect with the peer after this
## time interval. ## 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. ## Returns: A locally unique ID of the new peer.
## ##
@ -5290,16 +5292,17 @@ function capture_state_updates%(filename: string%) : bool
## set_compression_level ## set_compression_level
## send_state ## send_state
## send_id ## 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(), return new Val(uint32(remote_serializer->Connect(ip->AsAddr(),
our_class->CheckString(), retry, ssl)), zone_id->CheckString(), p->Port(), our_class->CheckString(),
retry, ssl)),
TYPE_COUNT); TYPE_COUNT);
%} %}
## Terminate the connection with a peer. ## 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. ## 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 ## Subscribes to all events from a remote peer whose names match a given
## pattern. ## 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*. ## 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. ## 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 ## auth: If true, the local instance considers its current state authoritative
## and sends it to *p* right after the handshake. ## 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. ## 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. ## 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); 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. ## 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. ## 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 ## level: Allowed values are in the range *[0, 9]*, where 0 is the default and
## means no compression. ## means no compression.
@ -5394,20 +5399,29 @@ function set_compression_level%(p: event_peer, level: count%) : bool
TYPE_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. ## 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. ## 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. ## Returns: True on success.
## ##
## .. bro:see:: connect disconnect ## .. 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. ## 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. ## 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. ## 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); 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. ## locally.
## ##
## p: The peer ID return from :bro:id:`connect`. ## p: The peer ID returned from :bro:id:`connect`.
## ##
## id: The identifier to send. ## 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 ## Signals a remote peer that the local Bro instance finished the initial
## handshake. ## handshake.
## ##
## p: The peer ID return from :bro:id:`connect`. ## p: The peer ID returned from :bro:id:`connect`.
## ##
## Returns: True on success. ## Returns: True on success.
function complete_handshake%(p: event_peer%) : bool 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 ## for :bro:id:`remote_pong`, this function can be used to measure latency
## between two peers. ## 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`). ## 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. ## 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. ## 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 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 ## .. bro:see:: get_local_event_peer
function get_event_peer%(%) : 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. ## 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. ## s: The capture filter.
## ##
@ -5582,7 +5596,7 @@ function send_capture_filter%(p: event_peer, s: string%) : bool
## distributed trace processing with communication enabled ## distributed trace processing with communication enabled
## (*pseudo-realtime* mode). ## (*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 function suspend_processing%(%) : any
%{ %{
net_suspend_processing(); net_suspend_processing();
@ -5591,7 +5605,7 @@ function suspend_processing%(%) : any
## Resumes Bro's packet processing. ## 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 function continue_processing%(%) : any
%{ %{
net_continue_processing(); net_continue_processing();
@ -5600,7 +5614,7 @@ function continue_processing%(%) : any
## Stops propagating :bro:attr:`&synchronized` accesses. ## 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 function suspend_state_updates%(%) : any
%{ %{
if ( remote_serializer ) if ( remote_serializer )
@ -5610,7 +5624,7 @@ function suspend_state_updates%(%) : any
## Resumes propagating :bro:attr:`&synchronized` accesses. ## 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 function resume_state_updates%(%) : any
%{ %{
if ( remote_serializer ) if ( remote_serializer )

View file

@ -171,8 +171,11 @@ event new_connection_contents%(c: connection%);
## new_connection new_connection_contents partial_connection ## new_connection new_connection_contents partial_connection
event connection_attempt%(c: connection%); event connection_attempt%(c: connection%);
## Generated for an established TCP connection. The event is raised when the ## Generated when a SYN-ACK packet is seen in response to SYN a packet during
## initial 3-way TCP handshake has successfully finished for a connection. ## 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. ## c: The connection.
## ##
@ -335,8 +338,6 @@ event connection_SYN_packet%(c: connection, pkt: SYN_packet%);
## ##
## c: The connection. ## c: The connection.
## ##
## pkt: Information extracted from the SYN packet.
##
## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt ## .. bro:see:: connection_EOF connection_SYN_packet connection_attempt
## connection_established connection_external connection_finished ## connection_established connection_external connection_finished
## connection_half_finished connection_partial_close connection_pending ## connection_half_finished connection_partial_close connection_pending
@ -401,6 +402,20 @@ event connection_reused%(c: connection%);
## new_connection new_connection_contents partial_connection ## new_connection new_connection_contents partial_connection
event connection_status_update%(c: 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 ## Generated at the end of reassembled TCP connections. The TCP reassembler
## raised the event once for each endpoint of a connection when it finished ## raised the event once for each endpoint of a connection when it finished
## reassembling the corresponding side of the communication. ## 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 ## Concatenates all arguments into a single string. The function takes a
## number of arguments of type string and stiches them together. ## variable number of arguments of type string and stitches them together.
## ##
## Returns: The concatenation of all (string) arguments. ## 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. ## 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. ## between each element.
## ##
## .. bro:see:: cat cat_sep string_cat cat_string_array cat_string_array_n ## .. 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 ## Returns an edited version of a string that applies a special
## "backspace character" (usually ``\x08`` for backspace or ``\x7f`` for DEL). ## "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. ## arg_s: The string to edit.
## ##
@ -229,7 +229,7 @@ function sort_string_array%(a: string_array%): string_array
## the string. ## the string.
## ##
## Returns: An edited version of *arg_s* where *arg_edit_char* triggers the ## 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 ## .. bro:see:: clean
## to_string_literal ## to_string_literal
@ -278,7 +278,7 @@ function byte_len%(s: string%): count
return new Val(s->Len(), TYPE_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. ## 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); return do_split(str, re, 0, 0, 0);
%} %}
## Splits a string *once* into a a two-element array of strings according to a ## 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 * is only split ## pattern. This function is the same as :bro:id:`split`, but *str* is only
## once (if possible) at the earliest position and an array of two strings is ## split once (if possible) at the earliest position and an array of two strings
## returned. ## is returned.
## ##
## str: The string to split. ## 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 ## Returns: An array of strings where each two successive elements correspond
## to a substring in *str* of the part not matching *re* (odd-indexed) ## 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 ## .. bro:see:: split split1 split_n str_split
function split_all%(str: string, re: pattern%): string_array 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*. ## 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 ## Returns: A copy of *str* with the first occurence of *re* replaced with
## *repl*. ## *repl*.
@ -579,16 +579,16 @@ function sub%(str: string, re: pattern, repl: string%): string
return do_sub(str, re, repl, 0); 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. ## in a given string.
## ##
## str: The string to perform the substitution in. ## str: The string to perform the substitution in.
## ##
## re: The pattern being replaced with *repl*. ## 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 ## .. bro:see:: sub subst_string
function gsub%(str: string, re: pattern, repl: string%): 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. ## s1: The first string.
## ##
@ -616,7 +616,7 @@ function strcmp%(s1: string, s2: string%): int
## ##
## little: The (smaller) string to find inside *big*. ## 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*. ## *big*.
## ##
## .. bro:see:: find_all find_last ## .. 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. ## str: The string to convert to lowercase letters.
## ##
## Returns: A copy of the given string with the uppercase letters (as indicated ## 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``). ## (via ``tolower``).
## ##
## .. bro:see:: to_upper is_ascii ## .. bro:see:: to_upper is_ascii
@ -714,7 +714,7 @@ function to_lower%(str: string%): string
## str: The string to convert to uppercase letters. ## str: The string to convert to uppercase letters.
## ##
## Returns: A copy of the given string with the lowercase letters (as indicated ## 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``). ## (via ``toupper``).
## ##
## .. bro:see:: to_lower is_ascii ## .. bro:see:: to_lower is_ascii
@ -744,7 +744,7 @@ function to_upper%(str: string%): string
## - ``NUL`` to ``\0`` ## - ``NUL`` to ``\0``
## - ``DEL`` to ``^?`` ## - ``DEL`` to ``^?``
## - values <= 26 to ``^[A-Z]`` ## - 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. ## 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`` ## - ``NUL`` to ``\0``
## - ``DEL`` to ``^?`` ## - ``DEL`` to ``^?``
## - values <= 26 to ``^[A-Z]`` ## - values <= 26 to ``^[A-Z]``
## - values not in *[32, 126]** to ``%XX`` ## - values not in *[32, 126]* to ``%XX``
## ##
## str: The string to escape. ## 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)); 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>`_. ## See `Wikipedia <http://en.wikipedia.org/wiki/Smith%E2%80%93Waterman_algorithm>`_.
## ##
## s1: The first string. ## s1: The first string.
## ##
## s2: The second 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 function str_smith_waterman%(s1: string, s2: string, params: sw_params%) : sw_substring_vec
%{ %{
SWParams sw_params(params->AsRecordVal()->Lookup(0)->AsCount(), 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. // 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<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<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); 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 brief: make-brief coverage
make-verbose: make-verbose:
@for repo in $(DIRS); do (cd $$repo && make ); done @for repo in $(DIRS); do (cd $$repo && make -s ); done
make-brief: make-brief:
@for repo in $(DIRS); do (cd $$repo && make brief ); done @for repo in $(DIRS); do (cd $$repo && make -s brief ); done
coverage: 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 @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 @for f in external/*/coverage.log; do test -f $$f && cp $$f `mktemp brocov.tmp.XXX` || true; done
@echo "Complete test suite code coverage:" @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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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-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-run broccoli $BUILD/aux/broccoli/test/broccoli-v6addrs
# @TEST-EXEC: btest-bg-wait -k 20 # @TEST-EXEC: btest-bg-wait -k 20
# @TEST-EXEC: btest-diff bro/.stdout # @TEST-EXEC: btest-diff bro/.stdout
# @TEST-EXEC: btest-diff broccoli/.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: btest-diff receiver/http.log
# @TEST-EXEC: cmp sender/http.log 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 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 http/base | sed 's/^Event \[[-0-9.]*\] //g' | grep '^http_' | grep -v http_stats | sed 's/(.*$//g' >events.rec.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 # @TEST-EXEC: cmp events.rec.log events.snd.log
# #
# We don't compare the transmitted event paramerters anymore. With the dynamic # 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 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: 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 # @TEST-EXEC: cmp events.rec.log events.snd.log
# #
# We don't compare the transmitted event paramerters anymore. With the dynamic # We don't compare the transmitted event paramerters anymore. With the dynamic