mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Merge remote-tracking branch 'origin/topic/dnthayer/langref'
* origin/topic/dnthayer/langref: Minor improvements to script language reference docs Add more script language reference documentation Split the types and attributes reference doc into two docs Wow, this is great! BIT-1269 #merged
This commit is contained in:
commit
175ff9cf2d
7 changed files with 1481 additions and 367 deletions
|
@ -176,6 +176,10 @@ class BroIdentifier(BroGeneric):
|
||||||
def get_index_text(self, objectname, name):
|
def get_index_text(self, objectname, name):
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
class BroKeyword(BroGeneric):
|
||||||
|
def get_index_text(self, objectname, name):
|
||||||
|
return name
|
||||||
|
|
||||||
class BroAttribute(BroGeneric):
|
class BroAttribute(BroGeneric):
|
||||||
def get_index_text(self, objectname, name):
|
def get_index_text(self, objectname, name):
|
||||||
return _('%s (attribute)') % (name)
|
return _('%s (attribute)') % (name)
|
||||||
|
@ -213,6 +217,7 @@ class BroDomain(Domain):
|
||||||
'type': ObjType(l_('type'), 'type'),
|
'type': ObjType(l_('type'), 'type'),
|
||||||
'namespace': ObjType(l_('namespace'), 'namespace'),
|
'namespace': ObjType(l_('namespace'), 'namespace'),
|
||||||
'id': ObjType(l_('id'), 'id'),
|
'id': ObjType(l_('id'), 'id'),
|
||||||
|
'keyword': ObjType(l_('keyword'), 'keyword'),
|
||||||
'enum': ObjType(l_('enum'), 'enum'),
|
'enum': ObjType(l_('enum'), 'enum'),
|
||||||
'attr': ObjType(l_('attr'), 'attr'),
|
'attr': ObjType(l_('attr'), 'attr'),
|
||||||
}
|
}
|
||||||
|
@ -221,6 +226,7 @@ class BroDomain(Domain):
|
||||||
'type': BroGeneric,
|
'type': BroGeneric,
|
||||||
'namespace': BroNamespace,
|
'namespace': BroNamespace,
|
||||||
'id': BroIdentifier,
|
'id': BroIdentifier,
|
||||||
|
'keyword': BroKeyword,
|
||||||
'enum': BroEnum,
|
'enum': BroEnum,
|
||||||
'attr': BroAttribute,
|
'attr': BroAttribute,
|
||||||
}
|
}
|
||||||
|
@ -229,6 +235,7 @@ class BroDomain(Domain):
|
||||||
'type': XRefRole(),
|
'type': XRefRole(),
|
||||||
'namespace': XRefRole(),
|
'namespace': XRefRole(),
|
||||||
'id': XRefRole(),
|
'id': XRefRole(),
|
||||||
|
'keyword': XRefRole(),
|
||||||
'enum': XRefRole(),
|
'enum': XRefRole(),
|
||||||
'attr': XRefRole(),
|
'attr': XRefRole(),
|
||||||
'see': XRefRole(),
|
'see': XRefRole(),
|
||||||
|
|
232
doc/script-reference/attributes.rst
Normal file
232
doc/script-reference/attributes.rst
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
Attributes
|
||||||
|
==========
|
||||||
|
|
||||||
|
The Bro scripting language supports the following attributes.
|
||||||
|
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| Name | Description |
|
||||||
|
+=============================+===============================================+
|
||||||
|
| :bro:attr:`&redef` |Redefine a global constant or extend a type. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&priority` |Specify priority for event handler or hook. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&log` |Mark a record field as to be written to a log. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&optional` |Allow a record field value to be missing. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&default` |Specify a default value. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&add_func` |Specify a function to call for each "redef +=".|
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&delete_func` |Same as "&add_func", except for "redef -=". |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&expire_func` |Specify a function to call when container |
|
||||||
|
| |element expires. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&read_expire` |Specify a read timeout interval. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&write_expire` |Specify a write timeout interval. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&create_expire` |Specify a creation timeout interval. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&synchronized` |Synchronize a variable across nodes. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&persistent` |Make a variable persistent (written to disk). |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&rotate_interval`|Rotate a file after specified interval. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&rotate_size` |Rotate a file after specified file size. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&encrypt` |Encrypt a file when writing to disk. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&raw_output` |Open file in raw mode (chars. are not escaped).|
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&mergeable` |Prefer set union for synchronized state. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&group` |Group event handlers to activate/deactivate. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&error_handler` |Used internally for reporter framework events. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
| :bro:attr:`&type_column` |Used by input framework for "port" type. |
|
||||||
|
+-----------------------------+-----------------------------------------------+
|
||||||
|
|
||||||
|
Here is a more detailed explanation of each attribute:
|
||||||
|
|
||||||
|
.. bro:attr:: &redef
|
||||||
|
|
||||||
|
Allows for redefinition of initial values of global objects declared as
|
||||||
|
constant.
|
||||||
|
|
||||||
|
In this example, the constant (assuming it is global) can be redefined
|
||||||
|
with a :bro:keyword:`redef` at some later point::
|
||||||
|
|
||||||
|
const clever = T &redef;
|
||||||
|
|
||||||
|
.. bro:attr:: &priority
|
||||||
|
|
||||||
|
Specifies the execution priority (as a signed integer) of a hook or
|
||||||
|
event handler. Higher values are executed before lower ones. The
|
||||||
|
default value is 0. Example::
|
||||||
|
|
||||||
|
event bro_init() &priority=10
|
||||||
|
{
|
||||||
|
print "high priority";
|
||||||
|
}
|
||||||
|
|
||||||
|
.. bro:attr:: &log
|
||||||
|
|
||||||
|
Writes a :bro:type:`record` field to the associated log stream.
|
||||||
|
|
||||||
|
.. bro:attr:: &optional
|
||||||
|
|
||||||
|
Allows a record field value to be missing (i.e., neither initialized nor
|
||||||
|
ever assigned a value).
|
||||||
|
|
||||||
|
In this example, the record could be instantiated with either
|
||||||
|
"myrec($a=127.0.0.1)" or "myrec($a=127.0.0.1, $b=80/tcp)"::
|
||||||
|
|
||||||
|
type myrec: record { a: addr; b: port &optional; };
|
||||||
|
|
||||||
|
The ``?$`` operator can be used to check if a record field has a value or
|
||||||
|
not (it returns a ``bool`` value of ``T`` if the field has a value,
|
||||||
|
and ``F`` if not).
|
||||||
|
|
||||||
|
.. bro:attr:: &default
|
||||||
|
|
||||||
|
Specifies a default value for a record field, container element, or a
|
||||||
|
function/hook/event parameter.
|
||||||
|
|
||||||
|
In this example, the record could be instantiated with either
|
||||||
|
"myrec($a=5, $c=3.14)" or "myrec($a=5, $b=53/udp, $c=3.14)"::
|
||||||
|
|
||||||
|
type myrec: record { a: count; b: port &default=80/tcp; c: double; };
|
||||||
|
|
||||||
|
In this example, the table will return the string ``"foo"`` for any
|
||||||
|
attempted access to a non-existing index::
|
||||||
|
|
||||||
|
global mytable: table[count] of string &default="foo";
|
||||||
|
|
||||||
|
When used with function/hook/event parameters, all of the parameters
|
||||||
|
with the "&default" attribute must come after all other parameters.
|
||||||
|
For example, the following function could be called either as "myfunc(5)"
|
||||||
|
or as "myfunc(5, 53/udp)"::
|
||||||
|
|
||||||
|
function myfunc(a: count, b: port &default=80/tcp)
|
||||||
|
{
|
||||||
|
print a, b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.. bro:attr:: &add_func
|
||||||
|
|
||||||
|
Can be applied to an identifier with &redef to specify a function to
|
||||||
|
be called any time a "redef <id> += ..." declaration is parsed. The
|
||||||
|
function takes two arguments of the same type as the identifier, the first
|
||||||
|
being the old value of the variable and the second being the new
|
||||||
|
value given after the "+=" operator in the "redef" declaration. The
|
||||||
|
return value of the function will be the actual new value of the
|
||||||
|
variable after the "redef" declaration is parsed.
|
||||||
|
|
||||||
|
.. bro:attr:: &delete_func
|
||||||
|
|
||||||
|
Same as :bro:attr:`&add_func`, except for :bro:keyword:`redef` declarations
|
||||||
|
that use the "-=" operator.
|
||||||
|
|
||||||
|
.. bro:attr:: &expire_func
|
||||||
|
|
||||||
|
Called right before a container element expires. The function's
|
||||||
|
first parameter is of the same type of the container and the second
|
||||||
|
parameter the same type of the container's index. The return
|
||||||
|
value is an :bro:type:`interval` indicating the amount of additional
|
||||||
|
time to wait before expiring the container element at the given
|
||||||
|
index (which will trigger another execution of this function).
|
||||||
|
|
||||||
|
.. bro:attr:: &read_expire
|
||||||
|
|
||||||
|
Specifies a read expiration timeout for container elements. That is,
|
||||||
|
the element expires after the given amount of time since the last
|
||||||
|
time it has been read. Note that a write also counts as a read.
|
||||||
|
|
||||||
|
.. bro:attr:: &write_expire
|
||||||
|
|
||||||
|
Specifies a write expiration timeout for container elements. That
|
||||||
|
is, the element expires after the given amount of time since the
|
||||||
|
last time it has been written.
|
||||||
|
|
||||||
|
.. bro:attr:: &create_expire
|
||||||
|
|
||||||
|
Specifies a creation expiration timeout for container elements. That
|
||||||
|
is, the element expires after the given amount of time since it has
|
||||||
|
been inserted into the container, regardless of any reads or writes.
|
||||||
|
|
||||||
|
.. bro:attr:: &synchronized
|
||||||
|
|
||||||
|
Synchronizes variable accesses across nodes. The value of a
|
||||||
|
``&synchronized`` variable is automatically propagated to all peers
|
||||||
|
when it changes.
|
||||||
|
|
||||||
|
.. bro:attr:: &persistent
|
||||||
|
|
||||||
|
Makes a variable persistent, i.e., its value is written to disk (per
|
||||||
|
default at shutdown time).
|
||||||
|
|
||||||
|
.. bro:attr:: &rotate_interval
|
||||||
|
|
||||||
|
Rotates a file after a specified interval.
|
||||||
|
|
||||||
|
.. bro:attr:: &rotate_size
|
||||||
|
|
||||||
|
Rotates a file after it has reached a given size in bytes.
|
||||||
|
|
||||||
|
.. bro:attr:: &encrypt
|
||||||
|
|
||||||
|
Encrypts files right before writing them to disk.
|
||||||
|
|
||||||
|
.. bro:attr:: &raw_output
|
||||||
|
|
||||||
|
Opens a file in raw mode, i.e., non-ASCII characters are not
|
||||||
|
escaped.
|
||||||
|
|
||||||
|
.. bro:attr:: &mergeable
|
||||||
|
|
||||||
|
Prefers merging sets on assignment for synchronized state. This
|
||||||
|
attribute is used in conjunction with :bro:attr:`&synchronized`
|
||||||
|
container types: when the same container is updated at two peers
|
||||||
|
with different values, the propagation of the state causes a race
|
||||||
|
condition, where the last update succeeds. This can cause
|
||||||
|
inconsistencies and can be avoided by unifying the two sets, rather
|
||||||
|
than merely overwriting the old value.
|
||||||
|
|
||||||
|
.. bro:attr:: &group
|
||||||
|
|
||||||
|
Groups event handlers such that those in the same group can be
|
||||||
|
jointly activated or deactivated.
|
||||||
|
|
||||||
|
.. bro:attr:: &error_handler
|
||||||
|
|
||||||
|
Internally set on the events that are associated with the reporter
|
||||||
|
framework: :bro:id:`reporter_info`, :bro:id:`reporter_warning`, and
|
||||||
|
:bro:id:`reporter_error`. It prevents any handlers of those events
|
||||||
|
from being able to generate reporter messages that go through any of
|
||||||
|
those events (i.e., it prevents an infinite event recursion). Instead,
|
||||||
|
such nested reporter messages are output to stderr.
|
||||||
|
|
||||||
|
.. bro:attr:: &type_column
|
||||||
|
|
||||||
|
Used by the input framework. It can be used on columns of type
|
||||||
|
:bro:type:`port` (such a column only contains the port number) and
|
||||||
|
specifies the name of an additional column in
|
||||||
|
the input file which specifies the protocol of the port (tcp/udp/icmp).
|
||||||
|
|
||||||
|
In the following example, the input file would contain four columns
|
||||||
|
named "ip", "srcp", "proto", and "msg"::
|
||||||
|
|
||||||
|
type Idx: record {
|
||||||
|
ip: addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
type Val: record {
|
||||||
|
srcp: port &type_column = "proto";
|
||||||
|
msg: string;
|
||||||
|
};
|
||||||
|
|
173
doc/script-reference/directives.rst
Normal file
173
doc/script-reference/directives.rst
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
Directives
|
||||||
|
==========
|
||||||
|
|
||||||
|
The Bro scripting language supports a number of directives that can
|
||||||
|
affect which scripts will be loaded or which lines in a script will be
|
||||||
|
executed. Directives are evaluated before script execution begins.
|
||||||
|
|
||||||
|
.. bro:keyword:: @DEBUG
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
|
||||||
|
.. bro:keyword:: @DIR
|
||||||
|
|
||||||
|
Expands to the directory pathname where the current script is located.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
print "Directory:", @DIR;
|
||||||
|
|
||||||
|
|
||||||
|
.. bro:keyword:: @FILENAME
|
||||||
|
|
||||||
|
Expands to the filename of the current script.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
print "File:", @FILENAME;
|
||||||
|
|
||||||
|
.. bro:keyword:: @load
|
||||||
|
|
||||||
|
Loads the specified Bro script, specified as the relative pathname
|
||||||
|
of the file (relative to one of the directories in Bro's file search path).
|
||||||
|
If the Bro script filename ends with ".bro", then you don't need to
|
||||||
|
specify the file extension. The filename cannot contain any whitespace.
|
||||||
|
|
||||||
|
In this example, Bro will try to load a script
|
||||||
|
"policy/misc/capture-loss.bro" by looking in each directory in the file
|
||||||
|
search path (the file search path can be changed by setting the BROPATH
|
||||||
|
environment variable)::
|
||||||
|
|
||||||
|
@load policy/misc/capture-loss
|
||||||
|
|
||||||
|
If you specify the name of a directory instead of a filename, then
|
||||||
|
Bro will try to load a file in that directory called "__load__.bro"
|
||||||
|
(presumably that file will contain additional "@load" directives).
|
||||||
|
|
||||||
|
In this example, Bro will try to load a file "tuning/defaults/__load__.bro"
|
||||||
|
by looking in each directory in the file search path::
|
||||||
|
|
||||||
|
@load tuning/defaults
|
||||||
|
|
||||||
|
The purpose of this directive is to ensure that all script dependencies
|
||||||
|
are satisfied, and to avoid having to list every needed Bro script
|
||||||
|
on the command-line. Bro keeps track of which scripts have been
|
||||||
|
loaded, so it is not an error to load a script more than once (once
|
||||||
|
a script has been loaded, any subsequent "@load" directives
|
||||||
|
for that script are ignored).
|
||||||
|
|
||||||
|
|
||||||
|
.. bro:keyword:: @load-sigs
|
||||||
|
|
||||||
|
This works similarly to "@load", except that in this case the filename
|
||||||
|
represents a signature file (not a Bro script). If the signature filename
|
||||||
|
ends with ".sig", then you don't need to specify the file extension
|
||||||
|
in the "@load-sigs" directive. The filename cannot contain any
|
||||||
|
whitespace.
|
||||||
|
|
||||||
|
In this example, Bro will try to load a signature file
|
||||||
|
"base/protocols/ssl/dpd.sig"::
|
||||||
|
|
||||||
|
@load-sigs base/protocols/ssl/dpd
|
||||||
|
|
||||||
|
The format for a signature file is explained in the documentation for the
|
||||||
|
`Signature Framework <../frameworks/signatures.html>`_.
|
||||||
|
|
||||||
|
|
||||||
|
.. bro:keyword:: @unload
|
||||||
|
|
||||||
|
This specifies a Bro script that we don't want to load (so a subsequent
|
||||||
|
attempt to load the specified script will be skipped). However,
|
||||||
|
if the specified script has already been loaded, then this directive
|
||||||
|
has no affect.
|
||||||
|
|
||||||
|
In the following example, if the "policy/misc/capture-loss.bro" script
|
||||||
|
has not been loaded yet, then Bro will not load it::
|
||||||
|
|
||||||
|
@unload policy/misc/capture-loss
|
||||||
|
|
||||||
|
|
||||||
|
.. bro:keyword:: @prefixes
|
||||||
|
|
||||||
|
Specifies a filename prefix to use when looking for script files
|
||||||
|
to load automatically. The prefix cannot contain any whitespace.
|
||||||
|
|
||||||
|
In the following example, the prefix "cluster" is used and all prefixes
|
||||||
|
that were previously specified are not used::
|
||||||
|
|
||||||
|
@prefixes = cluster
|
||||||
|
|
||||||
|
In the following example, the prefix "cluster-manager" is used in
|
||||||
|
addition to any previously-specified prefixes::
|
||||||
|
|
||||||
|
@prefixes += cluster-manager
|
||||||
|
|
||||||
|
The way this works is that after Bro parses all script files, then for each
|
||||||
|
loaded script Bro will take the absolute path of the script and then
|
||||||
|
it removes the portion of the directory path that is in Bro's file
|
||||||
|
search path. Then it replaces each "/" character with a period "."
|
||||||
|
and then prepends the prefix (specified in the "@prefixes" directive)
|
||||||
|
followed by a period. The resulting filename is searched for in each
|
||||||
|
directory in Bro's file search path. If a matching file is found, then
|
||||||
|
the file is automatically loaded.
|
||||||
|
|
||||||
|
For example, if a script called "local.bro" has been loaded, and a prefix
|
||||||
|
of "test" was specified, then Bro will look for a file named
|
||||||
|
"test.local.bro" in each directory of Bro's file search path.
|
||||||
|
|
||||||
|
An alternative way to specify prefixes is to use the "-p" Bro
|
||||||
|
command-line option.
|
||||||
|
|
||||||
|
.. bro:keyword:: @if
|
||||||
|
|
||||||
|
The specified expression must evaluate to type :bro:type:`bool`. If the
|
||||||
|
value is true, then the following script lines (up to the next "@else"
|
||||||
|
or "@endif") are available to be executed.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
@if ( ver == 2 )
|
||||||
|
print "version 2 detected";
|
||||||
|
@endif
|
||||||
|
|
||||||
|
.. bro:keyword:: @ifdef
|
||||||
|
|
||||||
|
This works like "@if", except that the result is true if the specified
|
||||||
|
identifier is defined.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
@ifdef ( pi )
|
||||||
|
print "pi is defined";
|
||||||
|
@endif
|
||||||
|
|
||||||
|
.. bro:keyword:: @ifndef
|
||||||
|
|
||||||
|
This works exactly like "@ifdef", except that the result is true if the
|
||||||
|
specified identifier is not defined.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
@ifndef ( pi )
|
||||||
|
print "pi is not defined";
|
||||||
|
@endif
|
||||||
|
|
||||||
|
.. bro:keyword:: @else
|
||||||
|
|
||||||
|
This directive is optional after an "@if", "@ifdef", or
|
||||||
|
"@ifndef". If present, it provides an else clause.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
@ifdef ( pi )
|
||||||
|
print "pi is defined";
|
||||||
|
@else
|
||||||
|
print "pi is not defined";
|
||||||
|
@endif
|
||||||
|
|
||||||
|
.. bro:keyword:: @endif
|
||||||
|
|
||||||
|
This directive is required to terminate each "@if", "@ifdef", or
|
||||||
|
"@ifndef".
|
||||||
|
|
|
@ -5,10 +5,14 @@ Script Reference
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
|
operators
|
||||||
|
types
|
||||||
|
attributes
|
||||||
|
statements
|
||||||
|
directives
|
||||||
notices
|
notices
|
||||||
proto-analyzers
|
proto-analyzers
|
||||||
file-analyzers
|
file-analyzers
|
||||||
builtins
|
|
||||||
packages
|
packages
|
||||||
scripts
|
scripts
|
||||||
Broxygen Example Script </scripts/broxygen/example.bro>
|
Broxygen Example Script </scripts/broxygen/example.bro>
|
||||||
|
|
191
doc/script-reference/operators.rst
Normal file
191
doc/script-reference/operators.rst
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
Operators
|
||||||
|
=========
|
||||||
|
|
||||||
|
The Bro scripting language supports the following operators. Note that
|
||||||
|
each data type only supports a subset of these operators. For more
|
||||||
|
details, see the documentation about the `data types <types.html>`_.
|
||||||
|
|
||||||
|
Relational operators
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
The relational operators evaluate to type :bro:type:`bool`.
|
||||||
|
|
||||||
|
+------------------------------+--------------+
|
||||||
|
| Name | Syntax |
|
||||||
|
+==============================+==============+
|
||||||
|
| Equality | *a* == *b* |
|
||||||
|
+------------------------------+--------------+
|
||||||
|
| Inequality | *a* != *b* |
|
||||||
|
+------------------------------+--------------+
|
||||||
|
| Less than | *a* < *b* |
|
||||||
|
+------------------------------+--------------+
|
||||||
|
| Less than or equal | *a* <= *b* |
|
||||||
|
+------------------------------+--------------+
|
||||||
|
| Greater than | *a* > *b* |
|
||||||
|
+------------------------------+--------------+
|
||||||
|
| Greater than or equal | *a* >= *b* |
|
||||||
|
+------------------------------+--------------+
|
||||||
|
|
||||||
|
|
||||||
|
Logical operators
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The logical operators require operands of type :bro:type:`bool`, and
|
||||||
|
evaluate to type :bro:type:`bool`.
|
||||||
|
|
||||||
|
+------------------------------+--------------+
|
||||||
|
| Name | Syntax |
|
||||||
|
+==============================+==============+
|
||||||
|
| Logical AND | *a* && *b* |
|
||||||
|
+------------------------------+--------------+
|
||||||
|
| Logical OR | *a* \|\| *b* |
|
||||||
|
+------------------------------+--------------+
|
||||||
|
| Logical NOT | ! *a* |
|
||||||
|
+------------------------------+--------------+
|
||||||
|
|
||||||
|
|
||||||
|
Arithmetic operators
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
| Name | Syntax | Notes |
|
||||||
|
+==============================+=============+===============================+
|
||||||
|
| Addition | *a* + *b* | For :bro:type:`string` |
|
||||||
|
| | | operands, this performs |
|
||||||
|
| | | string concatenation. |
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
| Subtraction | *a* - *b* | |
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
| Multiplication | *a* \* *b* | |
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
| Division | *a* / *b* | For :bro:type:`int` or |
|
||||||
|
| | | :bro:type:`count` operands, |
|
||||||
|
| | | the fractional part of the |
|
||||||
|
| | | result is dropped. |
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
| Modulo | *a* % *b* | Operand types cannot be |
|
||||||
|
| | | "double". |
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
| Unary plus | \+ *a* | |
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
| Unary minus | \- *a* | |
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
| Pre-increment | ++ *a* | Operand type cannot be |
|
||||||
|
| | | "double". |
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
| Pre-decrement | ``--`` *a* | Operand type cannot be |
|
||||||
|
| | | "double". |
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
| Absolute value | \| *a* \| | If operand is |
|
||||||
|
| | | :bro:type:`string`, |
|
||||||
|
| | | :bro:type:`set`, |
|
||||||
|
| | | :bro:type:`table`, or |
|
||||||
|
| | | :bro:type:`vector`, this |
|
||||||
|
| | | evaluates to number |
|
||||||
|
| | | of elements. |
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
Assignment operators
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
The assignment operators evaluate to the result of the assignment.
|
||||||
|
|
||||||
|
+------------------------------+-------------+
|
||||||
|
| Name | Syntax |
|
||||||
|
+==============================+=============+
|
||||||
|
| Assignment | *a* = *b* |
|
||||||
|
+------------------------------+-------------+
|
||||||
|
| Addition assignment | *a* += *b* |
|
||||||
|
+------------------------------+-------------+
|
||||||
|
| Subtraction assignment | *a* -= *b* |
|
||||||
|
+------------------------------+-------------+
|
||||||
|
|
||||||
|
|
||||||
|
Record field operators
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
The record field operators take a :bro:type:`record` as the first operand,
|
||||||
|
and a field name as the second operand. For both operators, the specified
|
||||||
|
field name must be in the declaration of the record type.
|
||||||
|
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
| Name | Syntax | Notes |
|
||||||
|
+==============================+=============+===============================+
|
||||||
|
| Field access | *a* $ *b* | |
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
| Field value existence test | *a* ?$ *b* | Evaluates to type |
|
||||||
|
| | | :bro:type:`bool`. |
|
||||||
|
| | | True if the specified field |
|
||||||
|
| | | has been assigned a value, or |
|
||||||
|
| | | false if not. |
|
||||||
|
+------------------------------+-------------+-------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
Other operators
|
||||||
|
---------------
|
||||||
|
|
||||||
|
+--------------------------------+-------------------+------------------------+
|
||||||
|
| Name | Syntax | Notes |
|
||||||
|
+================================+===================+========================+
|
||||||
|
| Membership test | *a* in *b* |Evaluates to type |
|
||||||
|
| | |:bro:type:`bool`. Do not|
|
||||||
|
| | |confuse this use of "in"|
|
||||||
|
| | |with that used in a |
|
||||||
|
| | |:bro:keyword:`for` |
|
||||||
|
| | |statement. |
|
||||||
|
+--------------------------------+-------------------+------------------------+
|
||||||
|
| Non-membership test | *a* !in *b* |This is the logical NOT |
|
||||||
|
| | |of the "in" operator. |
|
||||||
|
| | |For example: "a !in b" |
|
||||||
|
| | |is equivalent to |
|
||||||
|
| | |"!(a in b)". |
|
||||||
|
+--------------------------------+-------------------+------------------------+
|
||||||
|
| Table or vector element access | *a* [ *b* ] |This operator can also |
|
||||||
|
| | |be used with a |
|
||||||
|
| | |:bro:type:`set`, but |
|
||||||
|
| | |only with the |
|
||||||
|
| | |:bro:keyword:`add` or |
|
||||||
|
| | |:bro:keyword:`delete` |
|
||||||
|
| | |statement. |
|
||||||
|
+--------------------------------+-------------------+------------------------+
|
||||||
|
| Substring extraction | *a* [ *b* : *c* ] |See the |
|
||||||
|
| | |:bro:type:`string` type |
|
||||||
|
| | |for more details. |
|
||||||
|
+--------------------------------+-------------------+------------------------+
|
||||||
|
| Create a deep copy | copy ( *a* ) |This is relevant only |
|
||||||
|
| | |for data types that are |
|
||||||
|
| | |assigned by reference, |
|
||||||
|
| | |such as |
|
||||||
|
| | |:bro:type:`vector`, |
|
||||||
|
| | |:bro:type:`set`, |
|
||||||
|
| | |:bro:type:`table`, |
|
||||||
|
| | |and :bro:type:`record`. |
|
||||||
|
+--------------------------------+-------------------+------------------------+
|
||||||
|
| Module namespace access | *a* \:\: *b* |The first operand is the|
|
||||||
|
| | |module name, and the |
|
||||||
|
| | |second operand is an |
|
||||||
|
| | |identifier that refers |
|
||||||
|
| | |to a global variable, |
|
||||||
|
| | |enumeration constant, or|
|
||||||
|
| | |user-defined type that |
|
||||||
|
| | |was exported from the |
|
||||||
|
| | |module. |
|
||||||
|
+--------------------------------+-------------------+------------------------+
|
||||||
|
| Conditional | *a* ? *b* : *c* |The first operand must |
|
||||||
|
| | |evaluate to type |
|
||||||
|
| | |:bro:type:`bool`. |
|
||||||
|
| | |If true, then the |
|
||||||
|
| | |second expression is |
|
||||||
|
| | |evaluated and is the |
|
||||||
|
| | |result of the entire |
|
||||||
|
| | |expression. Otherwise, |
|
||||||
|
| | |the third expression is |
|
||||||
|
| | |evaluated and is the |
|
||||||
|
| | |result of the entire |
|
||||||
|
| | |expression. The types of|
|
||||||
|
| | |the second and third |
|
||||||
|
| | |operands must be |
|
||||||
|
| | |compatible. |
|
||||||
|
+--------------------------------+-------------------+------------------------+
|
||||||
|
|
602
doc/script-reference/statements.rst
Normal file
602
doc/script-reference/statements.rst
Normal file
|
@ -0,0 +1,602 @@
|
||||||
|
Declarations and Statements
|
||||||
|
===========================
|
||||||
|
|
||||||
|
The Bro scripting language supports the following declarations and
|
||||||
|
statements.
|
||||||
|
|
||||||
|
|
||||||
|
Declarations
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
+----------------------------+-----------------------------+
|
||||||
|
| Name | Description |
|
||||||
|
+============================+=============================+
|
||||||
|
| :bro:keyword:`module` | Change the current module |
|
||||||
|
+----------------------------+-----------------------------+
|
||||||
|
| :bro:keyword:`export` | Export identifiers from the |
|
||||||
|
| | current module |
|
||||||
|
+----------------------------+-----------------------------+
|
||||||
|
| :bro:keyword:`global` | Declare a global variable |
|
||||||
|
+----------------------------+-----------------------------+
|
||||||
|
| :bro:keyword:`const` | Declare a constant |
|
||||||
|
+----------------------------+-----------------------------+
|
||||||
|
| :bro:keyword:`type` | Declare a user-defined type |
|
||||||
|
+----------------------------+-----------------------------+
|
||||||
|
| :bro:keyword:`redef` | Redefine a global value or |
|
||||||
|
| | extend a user-defined type |
|
||||||
|
+----------------------------+-----------------------------+
|
||||||
|
| `function/event/hook`_ | Declare a function, event |
|
||||||
|
| | handler, or hook |
|
||||||
|
+----------------------------+-----------------------------+
|
||||||
|
|
||||||
|
Statements
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
+----------------------------+------------------------+
|
||||||
|
| Name | Description |
|
||||||
|
+============================+========================+
|
||||||
|
| :bro:keyword:`local` | Declare a local |
|
||||||
|
| | variable |
|
||||||
|
+----------------------------+------------------------+
|
||||||
|
| :bro:keyword:`add`, | Add or delete |
|
||||||
|
| :bro:keyword:`delete` | elements |
|
||||||
|
+----------------------------+------------------------+
|
||||||
|
| :bro:keyword:`print` | Print to stdout or a |
|
||||||
|
| | file |
|
||||||
|
+----------------------------+------------------------+
|
||||||
|
| :bro:keyword:`for`, | Loop over each |
|
||||||
|
| :bro:keyword:`next`, | element in a container |
|
||||||
|
| :bro:keyword:`break` | object |
|
||||||
|
+----------------------------+------------------------+
|
||||||
|
| :bro:keyword:`if` | Evaluate boolean |
|
||||||
|
| | expression and if true,|
|
||||||
|
| | execute a statement |
|
||||||
|
+----------------------------+------------------------+
|
||||||
|
| :bro:keyword:`switch`, | Evaluate expression |
|
||||||
|
| :bro:keyword:`break`, | and execute statement |
|
||||||
|
| :bro:keyword:`fallthrough` | with a matching value |
|
||||||
|
+----------------------------+------------------------+
|
||||||
|
| :bro:keyword:`when` | Asynchronous execution |
|
||||||
|
+----------------------------+------------------------+
|
||||||
|
| :bro:keyword:`event`, | Invoke or schedule |
|
||||||
|
| :bro:keyword:`schedule` | an event handler |
|
||||||
|
+----------------------------+------------------------+
|
||||||
|
| :bro:keyword:`return` | Return from function, |
|
||||||
|
| | hook, or event handler |
|
||||||
|
+----------------------------+------------------------+
|
||||||
|
|
||||||
|
Declarations
|
||||||
|
------------
|
||||||
|
|
||||||
|
The following global declarations cannot occur within a function, hook, or
|
||||||
|
event handler. Also, these declarations cannot appear after any statements
|
||||||
|
that are outside of a function, hook, or event handler.
|
||||||
|
|
||||||
|
.. bro:keyword:: module
|
||||||
|
|
||||||
|
The "module" keyword is used to change the current module. This
|
||||||
|
affects the scope of any subsequently declared global identifiers.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
module mymodule;
|
||||||
|
|
||||||
|
If a global identifier is declared after a "module" declaration,
|
||||||
|
then its scope ends at the end of the current Bro script or at the
|
||||||
|
next "module" declaration, whichever comes first. However, if a
|
||||||
|
global identifier is declared after a "module" declaration, but inside
|
||||||
|
an :bro:keyword:`export` block, then its scope ends at the end of the
|
||||||
|
last loaded Bro script, but it must be referenced using the namespace
|
||||||
|
operator (``::``) in other modules.
|
||||||
|
|
||||||
|
There can be any number of "module" declarations in a Bro script.
|
||||||
|
The same "module" declaration can appear in any number of different
|
||||||
|
Bro scripts.
|
||||||
|
|
||||||
|
|
||||||
|
.. bro:keyword:: export
|
||||||
|
|
||||||
|
An "export" block contains one or more declarations
|
||||||
|
(no statements are allowed in an "export" block) that the current
|
||||||
|
module is exporting. This enables these global identifiers to be visible
|
||||||
|
in other modules (but not prior to their declaration) via the namespace
|
||||||
|
operator (``::``). See the :bro:keyword:`module` keyword for a more
|
||||||
|
detailed explanation.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
export {
|
||||||
|
redef enum Log::ID += { LOG };
|
||||||
|
|
||||||
|
type Info: record {
|
||||||
|
ts: time &log;
|
||||||
|
uid: string &log;
|
||||||
|
};
|
||||||
|
|
||||||
|
const conntime = 30sec &redef;
|
||||||
|
}
|
||||||
|
|
||||||
|
Note that the braces in an "export" block are always required
|
||||||
|
(they do not indicate a compound statement). Also, no semicolon is
|
||||||
|
needed to terminate an "export" block.
|
||||||
|
|
||||||
|
.. bro:keyword:: global
|
||||||
|
|
||||||
|
Variables declared with the "global" keyword will be global.
|
||||||
|
If a type is not specified, then an initializer is required so that
|
||||||
|
the type can be inferred. Likewise, if an initializer is not supplied,
|
||||||
|
then the type must be specified. Example::
|
||||||
|
|
||||||
|
global pi = 3.14;
|
||||||
|
global hosts: set[addr];
|
||||||
|
global ciphers: table[string] of string = table();
|
||||||
|
|
||||||
|
Variable declarations outside of any function, hook, or event handler are
|
||||||
|
required to use this keyword (unless they are declared with the
|
||||||
|
:bro:keyword:`const` keyword). Definitions of functions, hooks, and
|
||||||
|
event handlers are not allowed to use the "global"
|
||||||
|
keyword (they already have global scope), except function declarations
|
||||||
|
where no function body is supplied use the "global" keyword.
|
||||||
|
|
||||||
|
The scope of a global variable begins where the declaration is located,
|
||||||
|
and extends through all remaining Bro scripts that are loaded (however,
|
||||||
|
see the :bro:keyword:`module` keyword for an explanation of how modules
|
||||||
|
change the visibility of global identifiers).
|
||||||
|
|
||||||
|
|
||||||
|
.. bro:keyword:: const
|
||||||
|
|
||||||
|
A variable declared with the "const" keyword will be constant.
|
||||||
|
Variables declared as constant are required to be initialized at the
|
||||||
|
time of declaration. Example::
|
||||||
|
|
||||||
|
const pi = 3.14;
|
||||||
|
const ssh_port: port = 22/tcp;
|
||||||
|
|
||||||
|
The value of a constant cannot be changed later (the only
|
||||||
|
exception is if the variable is global and has the :bro:attr:`&redef`
|
||||||
|
attribute, then its value can be changed only with a :bro:keyword:`redef`).
|
||||||
|
|
||||||
|
The scope of a constant is local if the declaration is in a
|
||||||
|
function, hook, or event handler, and global otherwise.
|
||||||
|
Note that the "const" keyword cannot be used with either the "local"
|
||||||
|
or "global" keywords (i.e., "const" replaces "local" and "global").
|
||||||
|
|
||||||
|
|
||||||
|
.. bro:keyword:: type
|
||||||
|
|
||||||
|
The "type" keyword is used to declare a user-defined type. The name
|
||||||
|
of this new type has global scope and can be used anywhere a built-in
|
||||||
|
type name can occur.
|
||||||
|
|
||||||
|
The "type" keyword is most commonly used when defining a
|
||||||
|
:bro:type:`record` or an :bro:type:`enum`, but is also useful when
|
||||||
|
dealing with more complex types.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
type mytype: table[count] of table[addr, port] of string;
|
||||||
|
global myvar: mytype;
|
||||||
|
|
||||||
|
.. bro:keyword:: redef
|
||||||
|
|
||||||
|
There are three ways that "redef" can be used: to change the value of
|
||||||
|
a global variable, to extend a record type or enum type, or to specify
|
||||||
|
a new event handler body that replaces all those that were previously
|
||||||
|
defined.
|
||||||
|
|
||||||
|
If you're using "redef" to change a global variable (defined using either
|
||||||
|
:bro:keyword:`const` or :bro:keyword:`global`), then the variable that you
|
||||||
|
want to change must have the :bro:attr:`&redef` attribute. If the variable
|
||||||
|
you're changing is a table, set, or pattern, you can use ``+=`` to add
|
||||||
|
new elements, or you can use ``=`` to specify a new value (all previous
|
||||||
|
contents of the object are removed). If the variable you're changing is a
|
||||||
|
set or table, then you can use the ``-=`` operator to remove the
|
||||||
|
specified elements (nothing happens for specified elements that don't
|
||||||
|
exist). If the variable you are changing is not a table, set, or pattern,
|
||||||
|
then you must use the ``=`` operator.
|
||||||
|
|
||||||
|
Examples::
|
||||||
|
|
||||||
|
redef pi = 3.14;
|
||||||
|
|
||||||
|
If you're using "redef" to extend a record or enum, then you must
|
||||||
|
use the ``+=`` assignment operator.
|
||||||
|
For an enum, you can add more enumeration constants, and for a record
|
||||||
|
you can add more record fields (however, each record field in the "redef"
|
||||||
|
must have either the :bro:attr:`&optional` or :bro:attr:`&default`
|
||||||
|
attribute).
|
||||||
|
|
||||||
|
Examples::
|
||||||
|
|
||||||
|
redef enum color += { Blue, Red };
|
||||||
|
redef record MyRecord += { n2:int &optional; s2:string &optional; };
|
||||||
|
|
||||||
|
If you're using "redef" to specify a new event handler body that
|
||||||
|
replaces all those that were previously defined (i.e., any subsequently
|
||||||
|
defined event handler body will not be affected by this "redef"), then
|
||||||
|
the syntax is the same as a regular event handler definition except for
|
||||||
|
the presence of the "redef" keyword.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
redef event myevent(s:string) { print "Redefined", s; }
|
||||||
|
|
||||||
|
|
||||||
|
.. _function/event/hook:
|
||||||
|
|
||||||
|
**function/event/hook**
|
||||||
|
For details on how to declare a :bro:type:`function`,
|
||||||
|
:bro:type:`event` handler, or :bro:type:`hook`,
|
||||||
|
see the documentation for those types.
|
||||||
|
|
||||||
|
|
||||||
|
Statements
|
||||||
|
----------
|
||||||
|
|
||||||
|
Each statement in a Bro script must be terminated with a semicolon (with a
|
||||||
|
few exceptions noted below). An individual statement can span multiple
|
||||||
|
lines.
|
||||||
|
|
||||||
|
All statements (except those contained within a function, hook, or event
|
||||||
|
handler) must appear after all global declarations.
|
||||||
|
|
||||||
|
Here are the statements that the Bro scripting language supports.
|
||||||
|
|
||||||
|
.. bro:keyword:: add
|
||||||
|
|
||||||
|
The "add" statement is used to add an element to a :bro:type:`set`.
|
||||||
|
Nothing happens if the specified element already exists in the set.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
local myset: set[string];
|
||||||
|
add myset["test"];
|
||||||
|
|
||||||
|
.. bro:keyword:: break
|
||||||
|
|
||||||
|
The "break" statement is used to break out of a :bro:keyword:`switch` or
|
||||||
|
:bro:keyword:`for` statement.
|
||||||
|
|
||||||
|
|
||||||
|
.. bro:keyword:: delete
|
||||||
|
|
||||||
|
The "delete" statement is used to remove an element from a
|
||||||
|
:bro:type:`set` or :bro:type:`table`. Nothing happens if the
|
||||||
|
specified element does not exist in the set or table.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
local myset = set("this", "test");
|
||||||
|
local mytable = table(["key1"] = 80/tcp, ["key2"] = 53/udp);
|
||||||
|
delete myset["test"];
|
||||||
|
delete mytable["key1"];
|
||||||
|
|
||||||
|
.. bro:keyword:: event
|
||||||
|
|
||||||
|
The "event" statement immediately queues invocation of an event handler.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
event myevent("test", 5);
|
||||||
|
|
||||||
|
.. bro:keyword:: fallthrough
|
||||||
|
|
||||||
|
The "fallthrough" statement can be used as the last statement in a
|
||||||
|
"case" block to indicate that execution should continue into the
|
||||||
|
next "case" or "default" label.
|
||||||
|
|
||||||
|
For an example, see the :bro:keyword:`switch` statement.
|
||||||
|
|
||||||
|
.. bro:keyword:: for
|
||||||
|
|
||||||
|
A "for" loop iterates over each element in a string, set, vector, or
|
||||||
|
table and executes a statement for each iteration.
|
||||||
|
|
||||||
|
For each iteration of the loop, a loop variable will be assigned to an
|
||||||
|
element if the expression evaluates to a string or set, or an index if
|
||||||
|
the expression evaluates to a vector or table. Then the statement
|
||||||
|
is executed. However, the statement will not be executed if the expression
|
||||||
|
evaluates to an object with no elements.
|
||||||
|
|
||||||
|
If the expression is a table or a set with more than one index, then the
|
||||||
|
loop variable must be specified as a comma-separated list of different
|
||||||
|
loop variables (one for each index), enclosed in brackets.
|
||||||
|
|
||||||
|
A :bro:keyword:`break` statement can be used at any time to immediately
|
||||||
|
terminate the "for" loop, and a :bro:keyword:`next` statement can be
|
||||||
|
used to skip to the next loop iteration.
|
||||||
|
|
||||||
|
Note that the loop variable in a "for" statement is not allowed to be
|
||||||
|
a global variable, and it does not need to be declared prior to the "for"
|
||||||
|
statement. The type will be inferred from the elements of the
|
||||||
|
expression.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
local myset = set(80/tcp, 81/tcp);
|
||||||
|
local mytable = table([10.0.0.1, 80/tcp]="s1", [10.0.0.2, 81/tcp]="s2");
|
||||||
|
|
||||||
|
for (p in myset)
|
||||||
|
print p;
|
||||||
|
|
||||||
|
for ([i,j] in mytable) {
|
||||||
|
if (mytable[i,j] == "done")
|
||||||
|
break;
|
||||||
|
if (mytable[i,j] == "skip")
|
||||||
|
next;
|
||||||
|
print i,j;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.. bro:keyword:: if
|
||||||
|
|
||||||
|
Evaluates a given expression, which must yield a :bro:type:`bool` value.
|
||||||
|
If true, then a specified statement is executed. If false, then
|
||||||
|
the statement is not executed. Example::
|
||||||
|
|
||||||
|
if ( x == 2 ) print "x is 2";
|
||||||
|
|
||||||
|
|
||||||
|
However, if the expression evaluates to false and if an "else" is
|
||||||
|
provided, then the statement following the "else" is executed. Example::
|
||||||
|
|
||||||
|
if ( x == 2 )
|
||||||
|
print "x is 2";
|
||||||
|
else
|
||||||
|
print "x is not 2";
|
||||||
|
|
||||||
|
.. bro:keyword:: local
|
||||||
|
|
||||||
|
A variable declared with the "local" keyword will be local. If a type
|
||||||
|
is not specified, then an initializer is required so that the type can
|
||||||
|
be inferred. Likewise, if an initializer is not supplied, then the
|
||||||
|
type must be specified.
|
||||||
|
|
||||||
|
Examples::
|
||||||
|
|
||||||
|
local x1 = 5.7;
|
||||||
|
local x2: double;
|
||||||
|
local x3: double = 5.7;
|
||||||
|
|
||||||
|
Variable declarations inside a function, hook, or event handler are
|
||||||
|
required to use this keyword (the only two exceptions are variables
|
||||||
|
declared with :bro:keyword:`const`, and variables implicitly declared in a
|
||||||
|
:bro:keyword:`for` statement).
|
||||||
|
|
||||||
|
The scope of a local variable starts at the location where it is declared
|
||||||
|
and persists to the end of the function, hook,
|
||||||
|
or event handler in which it is declared (this is true even if the
|
||||||
|
local variable was declared within a `compound statement`_ or is the loop
|
||||||
|
variable in a "for" statement).
|
||||||
|
|
||||||
|
|
||||||
|
.. bro:keyword:: next
|
||||||
|
|
||||||
|
The "next" statement can only appear within a :bro:keyword:`for` loop.
|
||||||
|
It causes execution to skip to the next iteration.
|
||||||
|
|
||||||
|
For an example, see the :bro:keyword:`for` statement.
|
||||||
|
|
||||||
|
.. bro:keyword:: print
|
||||||
|
|
||||||
|
The "print" statement takes a comma-separated list of one or more
|
||||||
|
expressions. Each expression in the list is evaluated and then converted
|
||||||
|
to a string. Then each string is printed, with each string separated by
|
||||||
|
a comma in the output.
|
||||||
|
|
||||||
|
Examples::
|
||||||
|
|
||||||
|
print 3.14;
|
||||||
|
print "Results", x, y;
|
||||||
|
|
||||||
|
By default, the "print" statement writes to the standard
|
||||||
|
output (stdout). However, if the first expression is of type
|
||||||
|
:bro:type:`file`, then "print" writes to that file.
|
||||||
|
|
||||||
|
If a string contains non-printable characters (i.e., byte values that are
|
||||||
|
not in the range 32 - 126), then the "print" statement converts each
|
||||||
|
non-printable character to an escape sequence before it is printed.
|
||||||
|
|
||||||
|
For more control over how the strings are formatted, see the :bro:id:`fmt`
|
||||||
|
function.
|
||||||
|
|
||||||
|
.. bro:keyword:: return
|
||||||
|
|
||||||
|
The "return" statement immediately exits the current function, hook, or
|
||||||
|
event handler. For a function, the specified expression (if any) is
|
||||||
|
evaluated and returned. A "return" statement in a hook or event handler
|
||||||
|
cannot return a value because event handlers and hooks do not have
|
||||||
|
return types.
|
||||||
|
|
||||||
|
Examples::
|
||||||
|
|
||||||
|
function my_func(): string
|
||||||
|
{
|
||||||
|
return "done";
|
||||||
|
}
|
||||||
|
|
||||||
|
event my_event(n: count)
|
||||||
|
{
|
||||||
|
if ( n == 0 ) return;
|
||||||
|
|
||||||
|
print n;
|
||||||
|
}
|
||||||
|
|
||||||
|
There is a special form of the "return" statement that is only allowed
|
||||||
|
in functions. Syntactically, it looks like a :bro:keyword:`when` statement
|
||||||
|
immediately preceded by the "return" keyword. This form of the "return"
|
||||||
|
statement is used to specify a function that delays its result (such a
|
||||||
|
function can only be called in the expression of a :bro:keyword:`when`
|
||||||
|
statement). The function returns at the time the "when"
|
||||||
|
statement's condition becomes true, and the function returns the value
|
||||||
|
that the "when" statement's body returns (or if the condition does
|
||||||
|
not become true within the specified timeout interval, then the function
|
||||||
|
returns the value that the "timeout" block returns).
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
global X: table[string] of count;
|
||||||
|
|
||||||
|
function a() : count
|
||||||
|
{
|
||||||
|
# This delays until condition becomes true.
|
||||||
|
return when ( "a" in X )
|
||||||
|
{
|
||||||
|
return X["a"];
|
||||||
|
}
|
||||||
|
timeout 30 sec
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
# Installs a trigger which fires if a() returns 42.
|
||||||
|
when ( a() == 42 )
|
||||||
|
print "expected result";
|
||||||
|
|
||||||
|
print "Waiting for a() to return...";
|
||||||
|
X["a"] = 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.. bro:keyword:: schedule
|
||||||
|
|
||||||
|
The "schedule" statement is used to raise a specified event with
|
||||||
|
specified parameters at a later time specified as an :bro:type:`interval`.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
schedule 30sec { myevent(x, y, z) };
|
||||||
|
|
||||||
|
Note that the braces are always required (they do not indicate a
|
||||||
|
`compound statement`_).
|
||||||
|
|
||||||
|
Note that "schedule" is actually an expression that returns a value
|
||||||
|
of type "timer", but in practice the return value is not used.
|
||||||
|
|
||||||
|
.. bro:keyword:: switch
|
||||||
|
|
||||||
|
A "switch" statement evaluates a given expression and jumps to
|
||||||
|
the first "case" label which contains a matching value (the result of the
|
||||||
|
expression must be type-compatible with all of the values in all of the
|
||||||
|
"case" labels). If there is no matching value, then execution jumps to
|
||||||
|
the "default" label instead, and if there is no "default" label then
|
||||||
|
execution jumps out of the "switch" block.
|
||||||
|
|
||||||
|
Here is an example (assuming that "get_day_of_week" is a
|
||||||
|
function that returns a string)::
|
||||||
|
|
||||||
|
switch get_day_of_week()
|
||||||
|
{
|
||||||
|
case "Sa", "Su":
|
||||||
|
print "weekend";
|
||||||
|
fallthrough;
|
||||||
|
case "Mo", "Tu", "We", "Th", "Fr":
|
||||||
|
print "valid result";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print "invalid result";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
A "switch" block can have any number of "case" labels, and one
|
||||||
|
optional "default" label.
|
||||||
|
|
||||||
|
A "case" label can have a comma-separated list of
|
||||||
|
more than one value. A value in a "case" label can be an expression,
|
||||||
|
but it must be a constant expression (i.e., the expression can consist
|
||||||
|
only of constants).
|
||||||
|
|
||||||
|
Each "case" and the "default" block must
|
||||||
|
end with either a :bro:keyword:`break`, :bro:keyword:`fallthrough`, or
|
||||||
|
:bro:keyword:`return` statement (although "return" is allowed only
|
||||||
|
if the "switch" statement is inside a function, hook, or event handler).
|
||||||
|
If a "case" (or "default") block contain more than one statement, then
|
||||||
|
there is no need to wrap them in braces.
|
||||||
|
|
||||||
|
Note that the braces in a "switch" statement are always required (these
|
||||||
|
do not indicate the presence of a `compound statement`_), and that no
|
||||||
|
semicolon is needed at the end of a "switch" statement.
|
||||||
|
|
||||||
|
|
||||||
|
.. bro:keyword:: when
|
||||||
|
|
||||||
|
Evaluates a given expression, which must result in a value of type
|
||||||
|
:bro:type:`bool`. When the value of the expression becomes available
|
||||||
|
and if the result is true, then a specified statement is executed.
|
||||||
|
|
||||||
|
In the following example, if the expression evaluates to true, then
|
||||||
|
the "print" statement is executed::
|
||||||
|
|
||||||
|
when ( (local x = foo()) && x == 42 )
|
||||||
|
print x;
|
||||||
|
|
||||||
|
However, if a timeout is specified, and if the expression does not
|
||||||
|
evaluate to true within the specified timeout interval, then the
|
||||||
|
statement following the "timeout" keyword is executed::
|
||||||
|
|
||||||
|
when ( (local x = foo()) && x == 42 )
|
||||||
|
print x;
|
||||||
|
timeout 5sec {
|
||||||
|
print "timeout";
|
||||||
|
}
|
||||||
|
|
||||||
|
Note that when a timeout is specified the braces are
|
||||||
|
always required (these do not indicate a `compound statement`_).
|
||||||
|
|
||||||
|
The expression in a "when" statement can contain a declaration of a local
|
||||||
|
variable but only if the declaration is written in the form
|
||||||
|
"local *var* = *init*" (example: "local x = myfunction()"). This form
|
||||||
|
of a local declaration is actually an expression, the result of which
|
||||||
|
is always a boolean true value.
|
||||||
|
|
||||||
|
The expression in a "when" statement can contain an asynchronous function
|
||||||
|
call such as :bro:id:`lookup_hostname` (in fact, this is the only place
|
||||||
|
such a function can be called), but it can also contain an ordinary
|
||||||
|
function call. When an asynchronous function call is in the expression,
|
||||||
|
then Bro will continue processing statements in the script following
|
||||||
|
the "when" statement, and when the result of the function call is available
|
||||||
|
Bro will finish evaluating the expression in the "when" statement.
|
||||||
|
See the :bro:keyword:`return` statement for an explanation of how to
|
||||||
|
create an asynchronous function in a Bro script.
|
||||||
|
|
||||||
|
|
||||||
|
.. _compound statement:
|
||||||
|
|
||||||
|
**compound statement**
|
||||||
|
A compound statement is created by wrapping zero or more statements in
|
||||||
|
braces ``{ }``. Individual statements inside the braces need to be
|
||||||
|
terminated by a semicolon, but a semicolon is not needed at the end
|
||||||
|
(outside of the braces) of a compound statement.
|
||||||
|
|
||||||
|
A compound statement is required in order to execute more than one
|
||||||
|
statement in the body of a :bro:keyword:`for`, :bro:keyword:`if`, or
|
||||||
|
:bro:keyword:`when` statement.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
if ( x == 2 ) {
|
||||||
|
print "x is 2";
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
|
||||||
|
Note that there are other places in the Bro scripting language that use
|
||||||
|
braces, but that do not indicate the presence of a compound
|
||||||
|
statement (these are noted in the documentation).
|
||||||
|
|
||||||
|
.. _null:
|
||||||
|
|
||||||
|
**null statement**
|
||||||
|
The null statement (executing it has no effect) consists of just a
|
||||||
|
semicolon. This might be useful during testing or debugging a Bro script
|
||||||
|
in places where a statement is required, but it is probably not useful
|
||||||
|
otherwise.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
if ( x == 2 )
|
||||||
|
;
|
||||||
|
|
|
@ -1,92 +1,114 @@
|
||||||
Types and Attributes
|
|
||||||
====================
|
|
||||||
|
|
||||||
Types
|
Types
|
||||||
-----
|
=====
|
||||||
|
|
||||||
Every value in a Bro script has a type (see below for a list of all built-in
|
The Bro scripting language supports the following built-in types:
|
||||||
types). Although Bro variables have static types (meaning that their type
|
|
||||||
is fixed), their type is inferred from the value to which they are
|
|
||||||
initially assigned when the variable is declared without an explicit type
|
|
||||||
name.
|
|
||||||
|
|
||||||
Automatic conversions happen when a binary operator has operands of
|
+-----------------------+--------------------+
|
||||||
different types. Automatic conversions are limited to converting between
|
| Name | Description |
|
||||||
numeric types. The numeric types are ``int``, ``count``, and ``double``
|
+=======================+====================+
|
||||||
(``bool`` is not a numeric type).
|
| :bro:type:`bool` | Boolean |
|
||||||
When an automatic conversion occurs, values are promoted to the "highest"
|
+-----------------------+--------------------+
|
||||||
type in the expression. In general, this promotion follows a simple
|
| :bro:type:`count`, | Numeric types |
|
||||||
hierarchy: ``double`` is highest, ``int`` comes next, and ``count`` is
|
| :bro:type:`int`, | |
|
||||||
lowest.
|
| :bro:type:`double` | |
|
||||||
|
+-----------------------+--------------------+
|
||||||
|
| :bro:type:`time`, | Time types |
|
||||||
|
| :bro:type:`interval` | |
|
||||||
|
+-----------------------+--------------------+
|
||||||
|
| :bro:type:`string` | String |
|
||||||
|
+-----------------------+--------------------+
|
||||||
|
| :bro:type:`pattern` | Regular expression |
|
||||||
|
+-----------------------+--------------------+
|
||||||
|
| :bro:type:`port`, | Network types |
|
||||||
|
| :bro:type:`addr`, | |
|
||||||
|
| :bro:type:`subnet` | |
|
||||||
|
+-----------------------+--------------------+
|
||||||
|
| :bro:type:`enum` | Enumeration |
|
||||||
|
| | (user-defined type)|
|
||||||
|
+-----------------------+--------------------+
|
||||||
|
| :bro:type:`table`, | Container types |
|
||||||
|
| :bro:type:`set`, | |
|
||||||
|
| :bro:type:`vector`, | |
|
||||||
|
| :bro:type:`record` | |
|
||||||
|
+-----------------------+--------------------+
|
||||||
|
| :bro:type:`function`, | Executable types |
|
||||||
|
| :bro:type:`event`, | |
|
||||||
|
| :bro:type:`hook` | |
|
||||||
|
+-----------------------+--------------------+
|
||||||
|
| :bro:type:`file` | File type (only |
|
||||||
|
| | for writing) |
|
||||||
|
+-----------------------+--------------------+
|
||||||
|
| :bro:type:`opaque` | Opaque type (for |
|
||||||
|
| | some built-in |
|
||||||
|
| | functions) |
|
||||||
|
+-----------------------+--------------------+
|
||||||
|
| :bro:type:`any` | Any type (for |
|
||||||
|
| | functions or |
|
||||||
|
| | containers) |
|
||||||
|
+-----------------------+--------------------+
|
||||||
|
|
||||||
The Bro scripting language supports the following built-in types.
|
Here is a more detailed description of each type:
|
||||||
|
|
||||||
.. bro:type:: void
|
|
||||||
|
|
||||||
An internal Bro type (i.e., "void" is not a reserved keyword in the Bro
|
|
||||||
scripting language) representing the absence of a return type for a
|
|
||||||
function.
|
|
||||||
|
|
||||||
.. bro:type:: bool
|
.. bro:type:: bool
|
||||||
|
|
||||||
Reflects a value with one of two meanings: true or false. The two
|
Reflects a value with one of two meanings: true or false. The two
|
||||||
``bool`` constants are ``T`` and ``F``.
|
"bool" constants are ``T`` and ``F``.
|
||||||
|
|
||||||
The ``bool`` type supports the following operators: equality/inequality
|
The "bool" type supports the following operators: equality/inequality
|
||||||
(``==``, ``!=``), logical and/or (``&&``, ``||``), logical
|
(``==``, ``!=``), logical and/or (``&&``, ``||``), logical
|
||||||
negation (``!``), and absolute value (where ``|T|`` is 1, and ``|F|`` is 0).
|
negation (``!``), and absolute value (where ``|T|`` is 1, and ``|F|`` is 0,
|
||||||
|
and in both cases the result type is :bro:type:`count`).
|
||||||
|
|
||||||
.. bro:type:: int
|
.. bro:type:: int
|
||||||
|
|
||||||
A numeric type representing a 64-bit signed integer. An ``int`` constant
|
A numeric type representing a 64-bit signed integer. An "int" constant
|
||||||
is a string of digits preceded by a ``+`` or ``-`` sign, e.g.
|
is a string of digits preceded by a "+" or "-" sign, e.g.
|
||||||
``-42`` or ``+5`` (the "+" sign is optional but see note about type
|
``-42`` or ``+5`` (the "+" sign is optional but see note about type
|
||||||
inferencing below). An ``int`` constant can also be written in
|
inferencing below). An "int" constant can also be written in
|
||||||
hexadecimal notation (in which case "0x" must be between the sign and
|
hexadecimal notation (in which case "0x" must be between the sign and
|
||||||
the hex digits), e.g. ``-0xFF`` or ``+0xabc123``.
|
the hex digits), e.g. ``-0xFF`` or ``+0xabc123``.
|
||||||
|
|
||||||
The ``int`` type supports the following operators: arithmetic
|
The "int" type supports the following operators: arithmetic
|
||||||
operators (``+``, ``-``, ``*``, ``/``, ``%``), comparison operators
|
operators (``+``, ``-``, ``*``, ``/``, ``%``), comparison operators
|
||||||
(``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``), assignment operators
|
(``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``), assignment operators
|
||||||
(``=``, ``+=``, ``-=``), pre-increment (``++``), pre-decrement
|
(``=``, ``+=``, ``-=``), pre-increment (``++``), pre-decrement
|
||||||
(``--``), and absolute value (e.g., ``|-3|`` is 3).
|
(``--``), unary plus and minus (``+``, ``-``), and absolute value
|
||||||
|
(e.g., ``|-3|`` is 3, but the result type is :bro:type:`count`).
|
||||||
|
|
||||||
When using type inferencing use care so that the
|
When using type inferencing use care so that the
|
||||||
intended type is inferred, e.g. ``local size_difference = 0`` will
|
intended type is inferred, e.g. "local size_difference = 0" will
|
||||||
infer :bro:type:`count`, while ``local size_difference = +0``
|
infer ":bro:type:`count`", while "local size_difference = +0"
|
||||||
will infer :bro:type:`int`.
|
will infer "int".
|
||||||
|
|
||||||
.. bro:type:: count
|
.. bro:type:: count
|
||||||
|
|
||||||
A numeric type representing a 64-bit unsigned integer. A ``count``
|
A numeric type representing a 64-bit unsigned integer. A "count"
|
||||||
constant is a string of digits, e.g. ``1234`` or ``0``. A ``count``
|
constant is a string of digits, e.g. ``1234`` or ``0``. A "count"
|
||||||
can also be written in hexadecimal notation (in which case "0x" must
|
can also be written in hexadecimal notation (in which case "0x" must
|
||||||
precede the hex digits), e.g. ``0xff`` or ``0xABC123``.
|
precede the hex digits), e.g. ``0xff`` or ``0xABC123``.
|
||||||
|
|
||||||
The ``count`` type supports the same operators as the :bro:type:`int`
|
The "count" type supports the same operators as the ":bro:type:`int`"
|
||||||
type. A unary plus or minus applied to a ``count`` results in an ``int``.
|
type, but a unary plus or minus applied to a "count" results in an
|
||||||
|
"int".
|
||||||
.. bro:type:: counter
|
|
||||||
|
|
||||||
An alias to :bro:type:`count`.
|
|
||||||
|
|
||||||
.. bro:type:: double
|
.. bro:type:: double
|
||||||
|
|
||||||
A numeric type representing a double-precision floating-point
|
A numeric type representing a double-precision floating-point
|
||||||
number. Floating-point constants are written as a string of digits
|
number. Floating-point constants are written as a string of digits
|
||||||
with an optional decimal point, optional scale-factor in scientific
|
with an optional decimal point, optional scale-factor in scientific
|
||||||
notation, and optional ``+`` or ``-`` sign. Examples are ``-1234``,
|
notation, and optional "+" or "-" sign. Examples are ``-1234``,
|
||||||
``-1234e0``, ``3.14159``, and ``.003E-23``.
|
``-1234e0``, ``3.14159``, and ``.003E-23``.
|
||||||
|
|
||||||
The ``double`` type supports the following operators: arithmetic
|
The "double" type supports the following operators: arithmetic
|
||||||
operators (``+``, ``-``, ``*``, ``/``), comparison operators
|
operators (``+``, ``-``, ``*``, ``/``), comparison operators
|
||||||
(``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``), assignment operators
|
(``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``), assignment operators
|
||||||
(``=``, ``+=``, ``-=``), and absolute value (e.g., ``|-3.14|`` is 3.14).
|
(``=``, ``+=``, ``-=``), unary plus and minus (``+``, ``-``), and
|
||||||
|
absolute value (e.g., ``|-3.14|`` is 3.14).
|
||||||
|
|
||||||
When using type inferencing use care so that the
|
When using type inferencing use care so that the
|
||||||
intended type is inferred, e.g. ``local size_difference = 5`` will
|
intended type is inferred, e.g. "local size_difference = 5" will
|
||||||
infer :bro:type:`count`, while ``local size_difference = 5.0``
|
infer ":bro:type:`count`", while "local size_difference = 5.0"
|
||||||
will infer :bro:type:`double`.
|
will infer "double".
|
||||||
|
|
||||||
.. bro:type:: time
|
.. bro:type:: time
|
||||||
|
|
||||||
|
@ -97,10 +119,10 @@ The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
Time values support the comparison operators (``==``, ``!=``, ``<``,
|
Time values support the comparison operators (``==``, ``!=``, ``<``,
|
||||||
``<=``, ``>``, ``>=``). A ``time`` value can be subtracted from
|
``<=``, ``>``, ``>=``). A ``time`` value can be subtracted from
|
||||||
another ``time`` value to produce an ``interval`` value. An ``interval``
|
another ``time`` value to produce an :bro:type:`interval` value. An
|
||||||
value can be added to, or subtracted from, a ``time`` value to produce a
|
``interval`` value can be added to, or subtracted from, a ``time`` value
|
||||||
``time`` value. The absolute value of a ``time`` value is a ``double``
|
to produce a ``time`` value. The absolute value of a ``time`` value is
|
||||||
with the same numeric value.
|
a :bro:type:`double` with the same numeric value.
|
||||||
|
|
||||||
.. bro:type:: interval
|
.. bro:type:: interval
|
||||||
|
|
||||||
|
@ -115,52 +137,58 @@ The Bro scripting language supports the following built-in types.
|
||||||
``3.5mins``. An ``interval`` can also be negated, for example
|
``3.5mins``. An ``interval`` can also be negated, for example
|
||||||
``-12 hr`` represents "twelve hours in the past".
|
``-12 hr`` represents "twelve hours in the past".
|
||||||
|
|
||||||
Intervals support addition and subtraction. Intervals also support
|
Intervals support addition and subtraction, the comparison operators
|
||||||
division (in which case the result is a ``double`` value), the
|
(``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``), the assignment
|
||||||
comparison operators (``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``),
|
operators (``=``, ``+=``, ``-=``), and unary plus and minus (``+``, ``-``).
|
||||||
and the assignment operators (``=``, ``+=``, ``-=``). Also, an
|
|
||||||
``interval`` can be multiplied or divided by an arithmetic type
|
Intervals also support division (in which case the result is a
|
||||||
(``count``, ``int``, or ``double``) to produce an ``interval`` value.
|
:bro:type:`double` value). An ``interval`` can be multiplied or divided
|
||||||
The absolute value of an ``interval`` is a ``double`` value equal to the
|
by an arithmetic type (``count``, ``int``, or ``double``) to produce
|
||||||
number of seconds in the ``interval`` (e.g., ``|-1 min|`` is 60).
|
an ``interval`` value. The absolute value of an ``interval`` is a
|
||||||
|
``double`` value equal to the number of seconds in the ``interval``
|
||||||
|
(e.g., ``|-1 min|`` is 60.0).
|
||||||
|
|
||||||
.. bro:type:: string
|
.. bro:type:: string
|
||||||
|
|
||||||
A type used to hold character-string values which represent text.
|
A type used to hold character-string values which represent text, although
|
||||||
String constants are created by enclosing text in double quotes (")
|
strings in a Bro script can actually contain any arbitrary binary data.
|
||||||
and the backslash character (\\) introduces escape sequences (all of
|
|
||||||
the C-style escape sequences are supported).
|
String constants are created by enclosing text within a pair of double
|
||||||
|
quotes ("). A string constant cannot span multiple lines in a Bro script.
|
||||||
|
The backslash character (\\) introduces escape sequences. The
|
||||||
|
following escape sequences are recognized: ``\n``, ``\t``, ``\v``, ``\b``,
|
||||||
|
``\r``, ``\f``, ``\a``, ``\ooo`` (where each 'o' is an octal digit),
|
||||||
|
``\xhh`` (where each 'h' is a hexadecimal digit). For escape sequences
|
||||||
|
that don't match any of these, Bro will just remove the backslash (so
|
||||||
|
to represent a literal backslash in a string constant, you just use
|
||||||
|
two consecutive backslashes).
|
||||||
|
|
||||||
Strings support concatenation (``+``), and assignment (``=``, ``+=``).
|
Strings support concatenation (``+``), and assignment (``=``, ``+=``).
|
||||||
Strings also support the comparison operators (``==``, ``!=``, ``<``,
|
Strings also support the comparison operators (``==``, ``!=``, ``<``,
|
||||||
``<=``, ``>``, ``>=``). The number of characters in a string can be
|
``<=``, ``>``, ``>=``). The number of characters in a string can be
|
||||||
found by enclosing the string within pipe characters (e.g., ``|"abc"|``
|
found by enclosing the string within pipe characters (e.g., ``|"abc"|``
|
||||||
is 3).
|
is 3). Substring searching can be performed using the "in" or "!in"
|
||||||
|
|
||||||
The subscript operator can extract an individual character or a substring
|
|
||||||
of a string (string indexing is zero-based, but an index of
|
|
||||||
-1 refers to the last character in the string, and -2 refers to the
|
|
||||||
second-to-last character, etc.). When extracting a substring, the
|
|
||||||
starting and ending index values are separated by a colon. For example::
|
|
||||||
|
|
||||||
local orig = "0123456789";
|
|
||||||
local third_char = orig[2];
|
|
||||||
local last_char = orig[-1];
|
|
||||||
local first_three_chars = orig[0:2];
|
|
||||||
|
|
||||||
Substring searching can be performed using the "in" or "!in"
|
|
||||||
operators (e.g., "bar" in "foobar" yields true).
|
operators (e.g., "bar" in "foobar" yields true).
|
||||||
|
|
||||||
Note that Bro represents strings internally as a count and vector of
|
The subscript operator can extract a substring of a string. To do this,
|
||||||
bytes rather than a NUL-terminated byte string (although string
|
specify the starting index to extract (if the starting index is omitted,
|
||||||
constants are also automatically NUL-terminated). This is because
|
then zero is assumed), followed by a colon and index
|
||||||
network traffic can easily introduce NULs into strings either by
|
one past the last character to extract (if the last index is omitted,
|
||||||
nature of an application, inadvertently, or maliciously. And while
|
then the extracted substring will go to the end of the original string).
|
||||||
NULs are allowed in Bro strings, when present in strings passed as
|
However, if both the colon and last index are omitted, then a string of
|
||||||
arguments to many functions, a run-time error can occur as their
|
length one is extracted. String indexing is zero-based, but an index
|
||||||
presence likely indicates a sort of problem. In that case, the
|
of -1 refers to the last character in the string, and -2 refers to the
|
||||||
string will also only be represented to the user as the literal
|
second-to-last character, etc. Here are a few examples::
|
||||||
"<string-with-NUL>" string.
|
|
||||||
|
local orig = "0123456789";
|
||||||
|
local second_char = orig[1];
|
||||||
|
local last_char = orig[-1];
|
||||||
|
local first_two_chars = orig[:2];
|
||||||
|
local last_two_chars = orig[8:];
|
||||||
|
local no_first_and_last = orig[1:9];
|
||||||
|
|
||||||
|
Note that the subscript operator cannot be used to modify a string (i.e.,
|
||||||
|
it cannot be on the left side of an assignment operator).
|
||||||
|
|
||||||
.. bro:type:: pattern
|
.. bro:type:: pattern
|
||||||
|
|
||||||
|
@ -174,7 +202,7 @@ The Bro scripting language supports the following built-in types.
|
||||||
and embedded.
|
and embedded.
|
||||||
|
|
||||||
In exact matching the ``==`` equality relational operator is used
|
In exact matching the ``==`` equality relational operator is used
|
||||||
with one :bro:type:`pattern` operand and one :bro:type:`string`
|
with one "pattern" operand and one ":bro:type:`string`"
|
||||||
operand (order of operands does not matter) to check whether the full
|
operand (order of operands does not matter) to check whether the full
|
||||||
string exactly matches the pattern. In exact matching, the ``^``
|
string exactly matches the pattern. In exact matching, the ``^``
|
||||||
beginning-of-line and ``$`` end-of-line anchors are redundant since
|
beginning-of-line and ``$`` end-of-line anchors are redundant since
|
||||||
|
@ -190,8 +218,8 @@ The Bro scripting language supports the following built-in types.
|
||||||
yields false. The ``!=`` operator would yield the negation of ``==``.
|
yields false. The ``!=`` operator would yield the negation of ``==``.
|
||||||
|
|
||||||
In embedded matching the ``in`` operator is used with one
|
In embedded matching the ``in`` operator is used with one
|
||||||
:bro:type:`pattern` operand (which must be on the left-hand side) and
|
"pattern" operand (which must be on the left-hand side) and
|
||||||
one :bro:type:`string` operand, but tests whether the pattern
|
one ":bro:type:`string`" operand, but tests whether the pattern
|
||||||
appears anywhere within the given string. For example::
|
appears anywhere within the given string. For example::
|
||||||
|
|
||||||
/foo|bar/ in "foobar"
|
/foo|bar/ in "foobar"
|
||||||
|
@ -203,27 +231,12 @@ The Bro scripting language supports the following built-in types.
|
||||||
is false since "oob" does not appear at the start of "foobar". The
|
is false since "oob" does not appear at the start of "foobar". The
|
||||||
``!in`` operator would yield the negation of ``in``.
|
``!in`` operator would yield the negation of ``in``.
|
||||||
|
|
||||||
.. bro:type:: enum
|
|
||||||
|
|
||||||
A type allowing the specification of a set of related values that
|
|
||||||
have no further structure. An example declaration:
|
|
||||||
|
|
||||||
.. code:: bro
|
|
||||||
|
|
||||||
type color: enum { Red, White, Blue, };
|
|
||||||
|
|
||||||
The last comma after ``Blue`` is optional.
|
|
||||||
|
|
||||||
The only operations allowed on enumerations are equality comparisons
|
|
||||||
(``==``, ``!=``) and assignment (``=``).
|
|
||||||
Enumerations do not have associated values or ordering.
|
|
||||||
|
|
||||||
.. bro:type:: port
|
.. bro:type:: port
|
||||||
|
|
||||||
A type representing transport-level port numbers. Besides TCP and
|
A type representing transport-level port numbers (besides TCP and
|
||||||
UDP ports, there is a concept of an ICMP "port" where the source
|
UDP ports, there is a concept of an ICMP "port" where the source
|
||||||
port is the ICMP message type and the destination port the ICMP
|
port is the ICMP message type and the destination port the ICMP
|
||||||
message code. A ``port`` constant is written as an unsigned integer
|
message code). A ``port`` constant is written as an unsigned integer
|
||||||
followed by one of ``/tcp``, ``/udp``, ``/icmp``, or ``/unknown``.
|
followed by one of ``/tcp``, ``/udp``, ``/icmp``, or ``/unknown``.
|
||||||
|
|
||||||
Ports support the comparison operators (``==``, ``!=``, ``<``, ``<=``,
|
Ports support the comparison operators (``==``, ``!=``, ``<``, ``<=``,
|
||||||
|
@ -255,14 +268,6 @@ The Bro scripting language supports the following built-in types.
|
||||||
address) are treated internally as IPv4 addresses (for example,
|
address) are treated internally as IPv4 addresses (for example,
|
||||||
``[::ffff:192.168.1.100]`` is equal to ``192.168.1.100``).
|
``[::ffff:192.168.1.100]`` is equal to ``192.168.1.100``).
|
||||||
|
|
||||||
Hostname constants can also be used, but since a hostname can
|
|
||||||
correspond to multiple IP addresses, the type of such a variable is a
|
|
||||||
:bro:type:`set` of :bro:type:`addr` elements. For example:
|
|
||||||
|
|
||||||
.. code:: bro
|
|
||||||
|
|
||||||
local a = www.google.com;
|
|
||||||
|
|
||||||
Addresses can be compared for equality (``==``, ``!=``),
|
Addresses can be compared for equality (``==``, ``!=``),
|
||||||
and also for ordering (``<``, ``<=``, ``>``, ``>=``). The absolute value
|
and also for ordering (``<``, ``<=``, ``>``, ``>=``). The absolute value
|
||||||
of an address gives the size in bits (32 for IPv4, and 128 for IPv6).
|
of an address gives the size in bits (32 for IPv4, and 128 for IPv6).
|
||||||
|
@ -285,9 +290,17 @@ The Bro scripting language supports the following built-in types.
|
||||||
if ( a in s )
|
if ( a in s )
|
||||||
print "true";
|
print "true";
|
||||||
|
|
||||||
Note that you can check if a given ``addr`` is IPv4 or IPv6 using
|
You can check if a given ``addr`` is IPv4 or IPv6 using
|
||||||
the :bro:id:`is_v4_addr` and :bro:id:`is_v6_addr` built-in functions.
|
the :bro:id:`is_v4_addr` and :bro:id:`is_v6_addr` built-in functions.
|
||||||
|
|
||||||
|
Note that hostname constants can also be used, but since a hostname can
|
||||||
|
correspond to multiple IP addresses, the type of such a variable is
|
||||||
|
"set[addr]". For example:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
local a = www.google.com;
|
||||||
|
|
||||||
.. bro:type:: subnet
|
.. bro:type:: subnet
|
||||||
|
|
||||||
A type representing a block of IP addresses in CIDR notation. A
|
A type representing a block of IP addresses in CIDR notation. A
|
||||||
|
@ -296,13 +309,24 @@ The Bro scripting language supports the following built-in types.
|
||||||
number. For example, ``192.168.0.0/16`` or ``[fe80::]/64``.
|
number. For example, ``192.168.0.0/16`` or ``[fe80::]/64``.
|
||||||
|
|
||||||
Subnets can be compared for equality (``==``, ``!=``). An
|
Subnets can be compared for equality (``==``, ``!=``). An
|
||||||
:bro:type:`addr` can be checked for inclusion in a subnet using
|
"addr" can be checked for inclusion in a subnet using
|
||||||
the "in" or "!in" operators.
|
the ``in`` or ``!in`` operators.
|
||||||
|
|
||||||
.. bro:type:: any
|
.. bro:type:: enum
|
||||||
|
|
||||||
Used to bypass strong typing. For example, a function can take an
|
A type allowing the specification of a set of related values that
|
||||||
argument of type ``any`` when it may be of different types.
|
have no further structure. An example declaration:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
type color: enum { Red, White, Blue, };
|
||||||
|
|
||||||
|
The last comma after ``Blue`` is optional. Both the type name ``color``
|
||||||
|
and the individual values (``Red``, etc.) have global scope.
|
||||||
|
|
||||||
|
Enumerations do not have associated values or ordering.
|
||||||
|
The only operations allowed on enumerations are equality comparisons
|
||||||
|
(``==``, ``!=``) and assignment (``=``).
|
||||||
|
|
||||||
.. bro:type:: table
|
.. bro:type:: table
|
||||||
|
|
||||||
|
@ -316,24 +340,25 @@ The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
table [ type^+ ] of type
|
table [ type^+ ] of type
|
||||||
|
|
||||||
where *type^+* is one or more types, separated by commas. For example:
|
where *type^+* is one or more types, separated by commas.
|
||||||
|
For example:
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
|
||||||
global a: table[count] of string;
|
global a: table[count] of string;
|
||||||
|
|
||||||
declares a table indexed by :bro:type:`count` values and yielding
|
declares a table indexed by "count" values and yielding
|
||||||
:bro:type:`string` values. The yield type can also be more complex:
|
"string" values. The yield type can also be more complex:
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
|
||||||
global a: table[count] of table[addr, port] of string;
|
global a: table[count] of table[addr, port] of string;
|
||||||
|
|
||||||
which declares a table indexed by :bro:type:`count` and yielding
|
which declares a table indexed by "count" and yielding
|
||||||
another :bro:type:`table` which is indexed by an :bro:type:`addr`
|
another "table" which is indexed by an "addr"
|
||||||
and :bro:type:`port` to yield a :bro:type:`string`.
|
and "port" to yield a "string".
|
||||||
|
|
||||||
Initialization of tables occurs by enclosing a set of initializers within
|
One way to initialize a table is by enclosing a set of initializers within
|
||||||
braces, for example:
|
braces, for example:
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
@ -343,18 +368,17 @@ The Bro scripting language supports the following built-in types.
|
||||||
[5] = "five",
|
[5] = "five",
|
||||||
};
|
};
|
||||||
|
|
||||||
A table constructor (equivalent to above example) can also be used
|
A table constructor can also be used to create a table:
|
||||||
to create a table:
|
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
|
||||||
global t2: table[count] of string = table(
|
global t2 = table(
|
||||||
[11] = "eleven",
|
[192.168.0.2, 22/tcp] = "ssh",
|
||||||
[5] = "five"
|
[192.168.0.3, 80/tcp] = "http"
|
||||||
);
|
);
|
||||||
|
|
||||||
Table constructors can also be explicitly named by a type, which is
|
Table constructors can also be explicitly named by a type, which is
|
||||||
useful for when a more complex index type could otherwise be
|
useful when a more complex index type could otherwise be
|
||||||
ambiguous:
|
ambiguous:
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
@ -381,17 +405,7 @@ The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
if ( 13 in t )
|
if ( 13 in t )
|
||||||
...
|
...
|
||||||
|
if ( [192.168.0.2, 22/tcp] in t2 )
|
||||||
Iterate over tables with a ``for`` loop:
|
|
||||||
|
|
||||||
.. code:: bro
|
|
||||||
|
|
||||||
local t: table[count] of string;
|
|
||||||
for ( n in t )
|
|
||||||
...
|
|
||||||
|
|
||||||
local services: table[addr, port] of string;
|
|
||||||
for ( [a, p] in services )
|
|
||||||
...
|
...
|
||||||
|
|
||||||
Add or overwrite individual table elements by assignment:
|
Add or overwrite individual table elements by assignment:
|
||||||
|
@ -400,7 +414,7 @@ The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
t[13] = "thirteen";
|
t[13] = "thirteen";
|
||||||
|
|
||||||
Remove individual table elements with ``delete``:
|
Remove individual table elements with :bro:keyword:`delete`:
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
|
||||||
|
@ -416,6 +430,9 @@ The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
|t|
|
|t|
|
||||||
|
|
||||||
|
See the :bro:keyword:`for` statement for info on how to iterate over
|
||||||
|
the elements in a table.
|
||||||
|
|
||||||
.. bro:type:: set
|
.. bro:type:: set
|
||||||
|
|
||||||
A set is like a :bro:type:`table`, but it is a collection of indices
|
A set is like a :bro:type:`table`, but it is a collection of indices
|
||||||
|
@ -426,25 +443,22 @@ The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
where *type^+* is one or more types separated by commas.
|
where *type^+* is one or more types separated by commas.
|
||||||
|
|
||||||
Sets are initialized by listing elements enclosed by curly braces:
|
Sets can be initialized by listing elements enclosed by curly braces:
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
|
||||||
global s: set[port] = { 21/tcp, 23/tcp, 80/tcp, 443/tcp };
|
global s: set[port] = { 21/tcp, 23/tcp, 80/tcp, 443/tcp };
|
||||||
global s2: set[port, string] = { [21/tcp, "ftp"], [23/tcp, "telnet"] };
|
global s2: set[port, string] = { [21/tcp, "ftp"], [23/tcp, "telnet"] };
|
||||||
|
|
||||||
The types are explicitly shown in the example above, but they could
|
|
||||||
have been left to type inference.
|
|
||||||
|
|
||||||
A set constructor (equivalent to above example) can also be used to
|
A set constructor (equivalent to above example) can also be used to
|
||||||
create a set:
|
create a set:
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
|
||||||
global s3: set[port] = set(21/tcp, 23/tcp, 80/tcp, 443/tcp);
|
global s3 = set(21/tcp, 23/tcp, 80/tcp, 443/tcp);
|
||||||
|
|
||||||
Set constructors can also be explicitly named by a type, which is
|
Set constructors can also be explicitly named by a type, which is
|
||||||
useful for when a more complex index type could otherwise be
|
useful when a more complex index type could otherwise be
|
||||||
ambiguous:
|
ambiguous:
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
@ -465,18 +479,10 @@ The Bro scripting language supports the following built-in types.
|
||||||
if ( 21/tcp in s )
|
if ( 21/tcp in s )
|
||||||
...
|
...
|
||||||
|
|
||||||
if ( 21/tcp !in s )
|
if ( [21/tcp, "ftp"] !in s2 )
|
||||||
...
|
...
|
||||||
|
|
||||||
Iterate over a set with a ``for`` loop:
|
Elements are added with :bro:keyword:`add`:
|
||||||
|
|
||||||
.. code:: bro
|
|
||||||
|
|
||||||
local s: set[port];
|
|
||||||
for ( p in s )
|
|
||||||
...
|
|
||||||
|
|
||||||
Elements are added with ``add``:
|
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
|
||||||
|
@ -485,7 +491,7 @@ The Bro scripting language supports the following built-in types.
|
||||||
Nothing happens if the element with value ``22/tcp`` was already present in
|
Nothing happens if the element with value ``22/tcp`` was already present in
|
||||||
the set.
|
the set.
|
||||||
|
|
||||||
And removed with ``delete``:
|
And removed with :bro:keyword:`delete`:
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
|
||||||
|
@ -501,6 +507,9 @@ The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
|s|
|
|s|
|
||||||
|
|
||||||
|
See the :bro:keyword:`for` statement for info on how to iterate over
|
||||||
|
the elements in a set.
|
||||||
|
|
||||||
.. bro:type:: vector
|
.. bro:type:: vector
|
||||||
|
|
||||||
A vector is like a :bro:type:`table`, except it's always indexed by a
|
A vector is like a :bro:type:`table`, except it's always indexed by a
|
||||||
|
@ -515,7 +524,7 @@ The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
|
||||||
global v: vector of string = vector("one", "two", "three");
|
local v = vector("one", "two", "three");
|
||||||
|
|
||||||
Vector constructors can also be explicitly named by a type, which
|
Vector constructors can also be explicitly named by a type, which
|
||||||
is useful for when a more complex yield type could otherwise be
|
is useful for when a more complex yield type could otherwise be
|
||||||
|
@ -539,14 +548,6 @@ The Bro scripting language supports the following built-in types.
|
||||||
|
|
||||||
print v[2];
|
print v[2];
|
||||||
|
|
||||||
Iterate over a vector with a ``for`` loop:
|
|
||||||
|
|
||||||
.. code:: bro
|
|
||||||
|
|
||||||
local v: vector of string;
|
|
||||||
for ( n in v )
|
|
||||||
...
|
|
||||||
|
|
||||||
An element can be added to a vector by assigning the value (a value
|
An element can be added to a vector by assigning the value (a value
|
||||||
that already exists at that index will be overwritten):
|
that already exists at that index will be overwritten):
|
||||||
|
|
||||||
|
@ -577,11 +578,17 @@ The Bro scripting language supports the following built-in types.
|
||||||
The resulting vector of bool is the logical "and" (or logical "or") of
|
The resulting vector of bool is the logical "and" (or logical "or") of
|
||||||
each element of the operand vectors.
|
each element of the operand vectors.
|
||||||
|
|
||||||
|
See the :bro:keyword:`for` statement for info on how to iterate over
|
||||||
|
the elements in a vector.
|
||||||
|
|
||||||
.. bro:type:: record
|
.. bro:type:: record
|
||||||
|
|
||||||
A ``record`` is a collection of values. Each value has a field name
|
A "record" is a collection of values. Each value has a field name
|
||||||
and a type. Values do not need to have the same type and the types
|
and a type. Values do not need to have the same type and the types
|
||||||
have no restrictions. An example record type definition:
|
have no restrictions. Field names must follow the same syntax as
|
||||||
|
regular variable names (except that field names are allowed to be the
|
||||||
|
same as local or global variables). An example record type
|
||||||
|
definition:
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
|
||||||
|
@ -590,86 +597,45 @@ The Bro scripting language supports the following built-in types.
|
||||||
s: string &optional;
|
s: string &optional;
|
||||||
};
|
};
|
||||||
|
|
||||||
Access to a record field uses the dollar sign (``$``) operator:
|
Records can be initialized or assigned as a whole in three different ways.
|
||||||
|
|
||||||
.. code:: bro
|
|
||||||
|
|
||||||
global r: MyRecordType;
|
|
||||||
r$c = 13;
|
|
||||||
|
|
||||||
Record assignment can be done field by field or as a whole like:
|
|
||||||
|
|
||||||
.. code:: bro
|
|
||||||
|
|
||||||
r = [$c = 13, $s = "thirteen"];
|
|
||||||
|
|
||||||
When assigning a whole record value, all fields that are not
|
When assigning a whole record value, all fields that are not
|
||||||
:bro:attr:`&optional` or have a :bro:attr:`&default` attribute must
|
:bro:attr:`&optional` or have a :bro:attr:`&default` attribute must
|
||||||
be specified.
|
be specified. First, there's a constructor syntax:
|
||||||
|
|
||||||
To test for existence of a field that is :bro:attr:`&optional`, use the
|
.. code:: bro
|
||||||
``?$`` operator:
|
|
||||||
|
local r: MyRecordType = record($c = 7);
|
||||||
|
|
||||||
|
And the constructor can be explicitly named by type, too, which
|
||||||
|
is arguably more readable:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
local r = MyRecordType($c = 42);
|
||||||
|
|
||||||
|
And the third way is like this:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
local r: MyRecordType = [$c = 13, $s = "thirteen"];
|
||||||
|
|
||||||
|
Access to a record field uses the dollar sign (``$``) operator, and
|
||||||
|
record fields can be assigned with this:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
local r: MyRecordType;
|
||||||
|
r$c = 13;
|
||||||
|
|
||||||
|
To test if a field that is :bro:attr:`&optional` has been assigned a
|
||||||
|
value, use the ``?$`` operator (it returns a :bro:type:`bool` value of
|
||||||
|
``T`` if the field has been assigned a value, or ``F`` if not):
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
|
||||||
if ( r ?$ s )
|
if ( r ?$ s )
|
||||||
...
|
...
|
||||||
|
|
||||||
Records can also be created using a constructor syntax:
|
|
||||||
|
|
||||||
.. code:: bro
|
|
||||||
|
|
||||||
global r2: MyRecordType = record($c = 7);
|
|
||||||
|
|
||||||
And the constructor can be explicitly named by type, too, which
|
|
||||||
is arguably more readable code:
|
|
||||||
|
|
||||||
.. code:: bro
|
|
||||||
|
|
||||||
global r3 = MyRecordType($c = 42);
|
|
||||||
|
|
||||||
.. bro:type:: opaque
|
|
||||||
|
|
||||||
A data type whose actual representation/implementation is
|
|
||||||
intentionally hidden, but whose values may be passed to certain
|
|
||||||
functions that can actually access the internal/hidden resources.
|
|
||||||
Opaque types are differentiated from each other by qualifying them
|
|
||||||
like ``opaque of md5`` or ``opaque of sha1``. Any valid identifier
|
|
||||||
can be used as the type qualifier.
|
|
||||||
|
|
||||||
An example use of this type is the set of built-in functions which
|
|
||||||
perform hashing:
|
|
||||||
|
|
||||||
.. code:: bro
|
|
||||||
|
|
||||||
local handle: opaque of md5 = md5_hash_init();
|
|
||||||
md5_hash_update(handle, "test");
|
|
||||||
md5_hash_update(handle, "testing");
|
|
||||||
print md5_hash_finish(handle);
|
|
||||||
|
|
||||||
Here the opaque type is used to provide a handle to a particular
|
|
||||||
resource which is calculating an MD5 checksum incrementally over
|
|
||||||
time, but the details of that resource aren't relevant, it's only
|
|
||||||
necessary to have a handle as a way of identifying it and
|
|
||||||
distinguishing it from other such resources.
|
|
||||||
|
|
||||||
.. bro:type:: file
|
|
||||||
|
|
||||||
Bro supports writing to files, but not reading from them. Files
|
|
||||||
can be opened using either the :bro:id:`open` or :bro:id:`open_for_append`
|
|
||||||
built-in functions, and closed using the :bro:id:`close` built-in
|
|
||||||
function. For example, declare, open, and write to a file
|
|
||||||
and finally close it like:
|
|
||||||
|
|
||||||
.. code:: bro
|
|
||||||
|
|
||||||
global f: file = open("myfile");
|
|
||||||
print f, "hello, world";
|
|
||||||
close(f);
|
|
||||||
|
|
||||||
Writing to files like this for logging usually isn't recommended, for better
|
|
||||||
logging support see :doc:`/frameworks/logging`.
|
|
||||||
|
|
||||||
.. bro:type:: function
|
.. bro:type:: function
|
||||||
|
|
||||||
Function types in Bro are declared using::
|
Function types in Bro are declared using::
|
||||||
|
@ -700,6 +666,16 @@ The Bro scripting language supports the following built-in types.
|
||||||
type, but when it is, the return type and argument list (including the
|
type, but when it is, the return type and argument list (including the
|
||||||
name of each argument) must match exactly.
|
name of each argument) must match exactly.
|
||||||
|
|
||||||
|
Here is an example function that takes no parameters and does not
|
||||||
|
return a value:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
function my_func()
|
||||||
|
{
|
||||||
|
print "my_func";
|
||||||
|
}
|
||||||
|
|
||||||
Function types don't need to have a name and can be assigned anonymously:
|
Function types don't need to have a name and can be assigned anonymously:
|
||||||
|
|
||||||
.. code:: bro
|
.. code:: bro
|
||||||
|
@ -742,9 +718,20 @@ The Bro scripting language supports the following built-in types.
|
||||||
Event handlers are nearly identical in both syntax and semantics to
|
Event handlers are nearly identical in both syntax and semantics to
|
||||||
a :bro:type:`function`, with the two differences being that event
|
a :bro:type:`function`, with the two differences being that event
|
||||||
handlers have no return type since they never return a value, and
|
handlers have no return type since they never return a value, and
|
||||||
you cannot call an event handler. Instead of directly calling an
|
you cannot call an event handler.
|
||||||
event handler from a script, event handler bodies are executed when
|
|
||||||
they are invoked by one of three different methods:
|
Example:
|
||||||
|
|
||||||
|
.. code:: bro
|
||||||
|
|
||||||
|
event my_event(r: bool, s: string)
|
||||||
|
{
|
||||||
|
print "my_event", r, s;
|
||||||
|
}
|
||||||
|
|
||||||
|
Instead of directly calling an event handler from a script, event
|
||||||
|
handler bodies are executed when they are invoked by one of three
|
||||||
|
different methods:
|
||||||
|
|
||||||
- From the event engine
|
- From the event engine
|
||||||
|
|
||||||
|
@ -765,7 +752,7 @@ The Bro scripting language supports the following built-in types.
|
||||||
This assumes that ``password_exposed`` was previously declared
|
This assumes that ``password_exposed`` was previously declared
|
||||||
as an event handler type with compatible arguments.
|
as an event handler type with compatible arguments.
|
||||||
|
|
||||||
- Via the ``schedule`` expression in a script
|
- Via the :bro:keyword:`schedule` expression in a script
|
||||||
|
|
||||||
This delays the invocation of event handlers until some time in
|
This delays the invocation of event handlers until some time in
|
||||||
the future. For example:
|
the future. For example:
|
||||||
|
@ -789,8 +776,8 @@ The Bro scripting language supports the following built-in types.
|
||||||
immediate and they do not get scheduled through an event queue.
|
immediate and they do not get scheduled through an event queue.
|
||||||
Also, a unique feature of a hook is that a given hook handler body
|
Also, a unique feature of a hook is that a given hook handler body
|
||||||
can short-circuit the execution of remaining hook handlers simply by
|
can short-circuit the execution of remaining hook handlers simply by
|
||||||
exiting from the body as a result of a ``break`` statement (as
|
exiting from the body as a result of a :bro:keyword:`break` statement (as
|
||||||
opposed to a ``return`` or just reaching the end of the body).
|
opposed to a :bro:keyword:`return` or just reaching the end of the body).
|
||||||
|
|
||||||
A hook type is declared like::
|
A hook type is declared like::
|
||||||
|
|
||||||
|
@ -859,142 +846,60 @@ The Bro scripting language supports the following built-in types.
|
||||||
executed due to one handler body exiting as a result of a ``break``
|
executed due to one handler body exiting as a result of a ``break``
|
||||||
statement.
|
statement.
|
||||||
|
|
||||||
Attributes
|
.. bro:type:: file
|
||||||
----------
|
|
||||||
|
|
||||||
Attributes occur at the end of type/event declarations and change their
|
Bro supports writing to files, but not reading from them (to read from
|
||||||
behavior. The syntax is ``&key`` or ``&key=val``, e.g., ``type T:
|
files see the :doc:`/frameworks/input`). Files
|
||||||
set[count] &read_expire=5min`` or ``event foo() &priority=-3``. The Bro
|
can be opened using either the :bro:id:`open` or :bro:id:`open_for_append`
|
||||||
scripting language supports the following built-in attributes.
|
built-in functions, and closed using the :bro:id:`close` built-in
|
||||||
|
function. For example, declare, open, and write to a file and finally
|
||||||
|
close it like:
|
||||||
|
|
||||||
.. bro:attr:: &optional
|
.. code:: bro
|
||||||
|
|
||||||
Allows a record field to be missing. For example the type ``record {
|
local f = open("myfile");
|
||||||
a: addr; b: port &optional; }`` could be instantiated both as
|
print f, "hello, world";
|
||||||
singleton ``[$a=127.0.0.1]`` or pair ``[$a=127.0.0.1, $b=80/tcp]``.
|
close(f);
|
||||||
|
|
||||||
.. bro:attr:: &default
|
Writing to files like this for logging usually isn't recommended, for better
|
||||||
|
logging support see :doc:`/frameworks/logging`.
|
||||||
|
|
||||||
Uses a default value for a record field, a function/hook/event
|
.. bro:type:: opaque
|
||||||
parameter, or container elements. For example, ``table[int] of
|
|
||||||
string &default="foo"`` would create a table that returns the
|
|
||||||
:bro:type:`string` ``"foo"`` for any non-existing index.
|
|
||||||
|
|
||||||
.. bro:attr:: &redef
|
A data type whose actual representation/implementation is
|
||||||
|
intentionally hidden, but whose values may be passed to certain
|
||||||
|
built-in functions that can actually access the internal/hidden resources.
|
||||||
|
Opaque types are differentiated from each other by qualifying them
|
||||||
|
like "opaque of md5" or "opaque of sha1".
|
||||||
|
|
||||||
Allows for redefinition of initial object values. This is typically
|
An example use of this type is the set of built-in functions which
|
||||||
used with constants, for example, ``const clever = T &redef;`` would
|
perform hashing:
|
||||||
allow the constant to be redefined at some later point during script
|
|
||||||
execution.
|
|
||||||
|
|
||||||
.. bro:attr:: &rotate_interval
|
.. code:: bro
|
||||||
|
|
||||||
Rotates a file after a specified interval.
|
local handle = md5_hash_init();
|
||||||
|
md5_hash_update(handle, "test");
|
||||||
|
md5_hash_update(handle, "testing");
|
||||||
|
print md5_hash_finish(handle);
|
||||||
|
|
||||||
.. bro:attr:: &rotate_size
|
Here the opaque type is used to provide a handle to a particular
|
||||||
|
resource which is calculating an MD5 hash incrementally over
|
||||||
|
time, but the details of that resource aren't relevant, it's only
|
||||||
|
necessary to have a handle as a way of identifying it and
|
||||||
|
distinguishing it from other such resources.
|
||||||
|
|
||||||
Rotates a file after it has reached a given size in bytes.
|
.. bro:type:: any
|
||||||
|
|
||||||
.. bro:attr:: &add_func
|
Used to bypass strong typing. For example, a function can take an
|
||||||
|
argument of type ``any`` when it may be of different types.
|
||||||
|
The only operation allowed on a variable of type ``any`` is assignment.
|
||||||
|
|
||||||
Can be applied to an identifier with &redef to specify a function to
|
Note that users aren't expected to use this type. It's provided mainly
|
||||||
be called any time a "redef <id> += ..." declaration is parsed. The
|
for use by some built-in functions and scripts included with Bro.
|
||||||
function takes two arguments of the same type as the identifier, the first
|
|
||||||
being the old value of the variable and the second being the new
|
|
||||||
value given after the "+=" operator in the "redef" declaration. The
|
|
||||||
return value of the function will be the actual new value of the
|
|
||||||
variable after the "redef" declaration is parsed.
|
|
||||||
|
|
||||||
.. bro:attr:: &delete_func
|
.. bro:type:: void
|
||||||
|
|
||||||
Same as &add_func, except for "redef" declarations that use the "-="
|
An internal Bro type (i.e., "void" is not a reserved keyword in the Bro
|
||||||
operator.
|
scripting language) representing the absence of a return type for a
|
||||||
|
function.
|
||||||
|
|
||||||
.. bro:attr:: &expire_func
|
|
||||||
|
|
||||||
Called right before a container element expires. The function's
|
|
||||||
first parameter is of the same type of the container and the second
|
|
||||||
parameter the same type of the container's index. The return
|
|
||||||
value is an :bro:type:`interval` indicating the amount of additional
|
|
||||||
time to wait before expiring the container element at the given
|
|
||||||
index (which will trigger another execution of this function).
|
|
||||||
|
|
||||||
.. bro:attr:: &read_expire
|
|
||||||
|
|
||||||
Specifies a read expiration timeout for container elements. That is,
|
|
||||||
the element expires after the given amount of time since the last
|
|
||||||
time it has been read. Note that a write also counts as a read.
|
|
||||||
|
|
||||||
.. bro:attr:: &write_expire
|
|
||||||
|
|
||||||
Specifies a write expiration timeout for container elements. That
|
|
||||||
is, the element expires after the given amount of time since the
|
|
||||||
last time it has been written.
|
|
||||||
|
|
||||||
.. bro:attr:: &create_expire
|
|
||||||
|
|
||||||
Specifies a creation expiration timeout for container elements. That
|
|
||||||
is, the element expires after the given amount of time since it has
|
|
||||||
been inserted into the container, regardless of any reads or writes.
|
|
||||||
|
|
||||||
.. bro:attr:: &persistent
|
|
||||||
|
|
||||||
Makes a variable persistent, i.e., its value is written to disk (per
|
|
||||||
default at shutdown time).
|
|
||||||
|
|
||||||
.. bro:attr:: &synchronized
|
|
||||||
|
|
||||||
Synchronizes variable accesses across nodes. The value of a
|
|
||||||
``&synchronized`` variable is automatically propagated to all peers
|
|
||||||
when it changes.
|
|
||||||
|
|
||||||
.. bro:attr:: &encrypt
|
|
||||||
|
|
||||||
Encrypts files right before writing them to disk.
|
|
||||||
|
|
||||||
.. TODO: needs to be documented in more detail.
|
|
||||||
|
|
||||||
.. bro:attr:: &raw_output
|
|
||||||
|
|
||||||
Opens a file in raw mode, i.e., non-ASCII characters are not
|
|
||||||
escaped.
|
|
||||||
|
|
||||||
.. bro:attr:: &mergeable
|
|
||||||
|
|
||||||
Prefers set union to assignment for synchronized state. This
|
|
||||||
attribute is used in conjunction with :bro:attr:`&synchronized`
|
|
||||||
container types: when the same container is updated at two peers
|
|
||||||
with different value, the propagation of the state causes a race
|
|
||||||
condition, where the last update succeeds. This can cause
|
|
||||||
inconsistencies and can be avoided by unifying the two sets, rather
|
|
||||||
than merely overwriting the old value.
|
|
||||||
|
|
||||||
.. bro:attr:: &priority
|
|
||||||
|
|
||||||
Specifies the execution priority (as a signed integer) of a hook or
|
|
||||||
event handler. Higher values are executed before lower ones. The
|
|
||||||
default value is 0.
|
|
||||||
|
|
||||||
.. bro:attr:: &group
|
|
||||||
|
|
||||||
Groups event handlers such that those in the same group can be
|
|
||||||
jointly activated or deactivated.
|
|
||||||
|
|
||||||
.. bro:attr:: &log
|
|
||||||
|
|
||||||
Writes a record field to the associated log stream.
|
|
||||||
|
|
||||||
.. bro:attr:: &error_handler
|
|
||||||
|
|
||||||
Internally set on the events that are associated with the reporter
|
|
||||||
framework: :bro:id:`reporter_info`, :bro:id:`reporter_warning`, and
|
|
||||||
:bro:id:`reporter_error`. It prevents any handlers of those events
|
|
||||||
from being able to generate reporter messages that go through any of
|
|
||||||
those events (i.e., it prevents an infinite event recursion). Instead,
|
|
||||||
such nested reporter messages are output to stderr.
|
|
||||||
|
|
||||||
.. bro:attr:: &type_column
|
|
||||||
|
|
||||||
Used by the input framework. It can be used on columns of type
|
|
||||||
:bro:type:`port` and specifies the name of an additional column in
|
|
||||||
the input file which specifies the protocol of the port (tcp/udp/icmp).
|
|
Loading…
Add table
Add a link
Reference in a new issue