From 22aa821506b094134cb814a0c898bea8d7632649 Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Thu, 31 Jul 2014 10:49:33 -0500 Subject: [PATCH 1/3] Split the types and attributes reference doc into two docs Also moved them up in the index so that the more fundamental material comes before the more advanced material in the table of contents. --- doc/script-reference/attributes.rst | 139 +++++++++++++++++ doc/script-reference/index.rst | 3 +- .../{builtins.rst => types.rst} | 144 +----------------- 3 files changed, 142 insertions(+), 144 deletions(-) create mode 100644 doc/script-reference/attributes.rst rename doc/script-reference/{builtins.rst => types.rst} (84%) diff --git a/doc/script-reference/attributes.rst b/doc/script-reference/attributes.rst new file mode 100644 index 0000000000..ca66ab2112 --- /dev/null +++ b/doc/script-reference/attributes.rst @@ -0,0 +1,139 @@ +Attributes +========== + +Attributes occur at the end of type or event declarations and change their +behavior. The syntax is ``&key`` or ``&key=val``, e.g., ``type T: +set[count] &read_expire=5min`` or ``event foo() &priority=-3``. The Bro +scripting language supports the following attributes. + +.. bro:attr:: &optional + + Allows a record field to be missing. For example the type ``record { + a: addr; b: port &optional; }`` could be instantiated both as + singleton ``[$a=127.0.0.1]`` or pair ``[$a=127.0.0.1, $b=80/tcp]``. + +.. bro:attr:: &default + + Uses a default value for a record field, a function/hook/event + 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 + + Allows for redefinition of initial object values. This is typically + used with constants, for example, ``const clever = T &redef;`` would + allow the constant to be redefined at some later point during script + execution. + +.. 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:: &add_func + + Can be applied to an identifier with &redef to specify a function to + be called any time a "redef += ..." 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 &add_func, except for "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:: &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). diff --git a/doc/script-reference/index.rst b/doc/script-reference/index.rst index bd600e4a97..a2c6f0a24f 100644 --- a/doc/script-reference/index.rst +++ b/doc/script-reference/index.rst @@ -5,10 +5,11 @@ Script Reference .. toctree:: :maxdepth: 1 + types + attributes notices proto-analyzers file-analyzers - builtins packages scripts Broxygen Example Script diff --git a/doc/script-reference/builtins.rst b/doc/script-reference/types.rst similarity index 84% rename from doc/script-reference/builtins.rst rename to doc/script-reference/types.rst index 85e9cd14c8..049b43c04a 100644 --- a/doc/script-reference/builtins.rst +++ b/doc/script-reference/types.rst @@ -1,8 +1,5 @@ -Types and Attributes -==================== - Types ------ +===== Every value in a Bro script has a type (see below for a list of all built-in types). Although Bro variables have static types (meaning that their type @@ -859,142 +856,3 @@ The Bro scripting language supports the following built-in types. executed due to one handler body exiting as a result of a ``break`` statement. -Attributes ----------- - -Attributes occur at the end of type/event declarations and change their -behavior. The syntax is ``&key`` or ``&key=val``, e.g., ``type T: -set[count] &read_expire=5min`` or ``event foo() &priority=-3``. The Bro -scripting language supports the following built-in attributes. - -.. bro:attr:: &optional - - Allows a record field to be missing. For example the type ``record { - a: addr; b: port &optional; }`` could be instantiated both as - singleton ``[$a=127.0.0.1]`` or pair ``[$a=127.0.0.1, $b=80/tcp]``. - -.. bro:attr:: &default - - Uses a default value for a record field, a function/hook/event - 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 - - Allows for redefinition of initial object values. This is typically - used with constants, for example, ``const clever = T &redef;`` would - allow the constant to be redefined at some later point during script - execution. - -.. 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:: &add_func - - Can be applied to an identifier with &redef to specify a function to - be called any time a "redef += ..." 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 &add_func, except for "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:: &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). From 5c9a7a92a49d5854a2732c03b72d5517bbf91888 Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Thu, 4 Sep 2014 13:32:24 -0500 Subject: [PATCH 2/3] Add more script language reference documentation Added new sections on operators, statements, and directives. Also improved the documentation on types and attributes by providing more examples and added a chart on the top of each page with links to each type and attribute for easier access to the information. --- doc/ext/bro.py | 7 + doc/script-reference/attributes.rst | 179 +++++++-- doc/script-reference/directives.rst | 173 ++++++++ doc/script-reference/index.rst | 3 + doc/script-reference/operators.rst | 179 +++++++++ doc/script-reference/statements.rst | 602 ++++++++++++++++++++++++++++ doc/script-reference/types.rst | 523 +++++++++++++----------- 7 files changed, 1385 insertions(+), 281 deletions(-) create mode 100644 doc/script-reference/directives.rst create mode 100644 doc/script-reference/operators.rst create mode 100644 doc/script-reference/statements.rst diff --git a/doc/ext/bro.py b/doc/ext/bro.py index 9295c63312..1df4a518c2 100644 --- a/doc/ext/bro.py +++ b/doc/ext/bro.py @@ -176,6 +176,10 @@ class BroIdentifier(BroGeneric): def get_index_text(self, objectname, name): return name +class BroKeyword(BroGeneric): + def get_index_text(self, objectname, name): + return name + class BroAttribute(BroGeneric): def get_index_text(self, objectname, name): return _('%s (attribute)') % (name) @@ -213,6 +217,7 @@ class BroDomain(Domain): 'type': ObjType(l_('type'), 'type'), 'namespace': ObjType(l_('namespace'), 'namespace'), 'id': ObjType(l_('id'), 'id'), + 'keyword': ObjType(l_('keyword'), 'keyword'), 'enum': ObjType(l_('enum'), 'enum'), 'attr': ObjType(l_('attr'), 'attr'), } @@ -221,6 +226,7 @@ class BroDomain(Domain): 'type': BroGeneric, 'namespace': BroNamespace, 'id': BroIdentifier, + 'keyword': BroKeyword, 'enum': BroEnum, 'attr': BroAttribute, } @@ -229,6 +235,7 @@ class BroDomain(Domain): 'type': XRefRole(), 'namespace': XRefRole(), 'id': XRefRole(), + 'keyword': XRefRole(), 'enum': XRefRole(), 'attr': XRefRole(), 'see': XRefRole(), diff --git a/doc/script-reference/attributes.rst b/doc/script-reference/attributes.rst index ca66ab2112..0160499fb9 100644 --- a/doc/script-reference/attributes.rst +++ b/doc/script-reference/attributes.rst @@ -1,38 +1,120 @@ Attributes ========== -Attributes occur at the end of type or event declarations and change their -behavior. The syntax is ``&key`` or ``&key=val``, e.g., ``type T: -set[count] &read_expire=5min`` or ``event foo() &priority=-3``. The Bro -scripting language supports the following attributes. +The Bro scripting language supports the following attributes. -.. bro:attr:: &optional ++-----------------------------+-----------------------------------------------+ +| 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 to be written to a log. | ++-----------------------------+-----------------------------------------------+ +| :bro:attr:`&optional` |Allow a record field value to be missing. | ++-----------------------------+-----------------------------------------------+ +| :bro:attr:`&default` |Specifies 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. | ++-----------------------------+-----------------------------------------------+ - Allows a record field to be missing. For example the type ``record { - a: addr; b: port &optional; }`` could be instantiated both as - singleton ``[$a=127.0.0.1]`` or pair ``[$a=127.0.0.1, $b=80/tcp]``. - -.. bro:attr:: &default - - Uses a default value for a record field, a function/hook/event - 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. +Here is a more detailed explanation of each attribute: .. bro:attr:: &redef - Allows for redefinition of initial object values. This is typically - used with constants, for example, ``const clever = T &redef;`` would - allow the constant to be redefined at some later point during script - execution. + Allows for redefinition of initial values of global objects declared as + constant. -.. bro:attr:: &rotate_interval + In this example, the constant (assuming it is global) can be redefined + with a :bro:keyword:`redef` at some later point:: - Rotates a file after a specified interval. + const clever = T &redef; -.. bro:attr:: &rotate_size +.. bro:attr:: &priority - Rotates a file after it has reached a given size in bytes. + 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 @@ -46,8 +128,8 @@ scripting language supports the following attributes. .. bro:attr:: &delete_func - Same as &add_func, except for "redef" declarations that use the "-=" - operator. + Same as :bro:attr:`&add_func`, except for :bro:keyword:`redef` declarations + that use the "-=" operator. .. bro:attr:: &expire_func @@ -76,23 +158,29 @@ scripting language supports the following attributes. 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:: &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. -.. 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 @@ -108,21 +196,11 @@ scripting language supports the following attributes. 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 @@ -135,5 +213,20 @@ scripting language supports the following attributes. .. 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 + :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; + }; + diff --git a/doc/script-reference/directives.rst b/doc/script-reference/directives.rst new file mode 100644 index 0000000000..e513e93911 --- /dev/null +++ b/doc/script-reference/directives.rst @@ -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". + diff --git a/doc/script-reference/index.rst b/doc/script-reference/index.rst index a2c6f0a24f..dc11447c5f 100644 --- a/doc/script-reference/index.rst +++ b/doc/script-reference/index.rst @@ -5,8 +5,11 @@ Script Reference .. toctree:: :maxdepth: 1 + operators types attributes + statements + directives notices proto-analyzers file-analyzers diff --git a/doc/script-reference/operators.rst b/doc/script-reference/operators.rst new file mode 100644 index 0000000000..7fa52cf4b2 --- /dev/null +++ b/doc/script-reference/operators.rst @@ -0,0 +1,179 @@ +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 `_. + +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* | If operands are strings, then | +| | | this performs string | +| | | concatenation. | ++------------------------------+-------------+-------------------------------+ +| Subtraction | *a* - *b* | | ++------------------------------+-------------+-------------------------------+ +| Multiplication | *a* \* *b* | | ++------------------------------+-------------+-------------------------------+ +| Division | *a* / *b* | | ++------------------------------+-------------+-------------------------------+ +| 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 string, set, | +| | | table, or 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 "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 | +| | |"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 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 "vector", "set",| +| | |"table", and "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 a "bool" | +| | |type. 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. | ++--------------------------------+-------------------+------------------------+ + diff --git a/doc/script-reference/statements.rst b/doc/script-reference/statements.rst new file mode 100644 index 0000000000..9c8b8de20d --- /dev/null +++ b/doc/script-reference/statements.rst @@ -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 ) + ; + diff --git a/doc/script-reference/types.rst b/doc/script-reference/types.rst index 049b43c04a..75988e0fb5 100644 --- a/doc/script-reference/types.rst +++ b/doc/script-reference/types.rst @@ -1,89 +1,114 @@ Types ===== -Every value in a Bro script has a type (see below for a list of all built-in -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. +The Bro scripting language supports the following built-in types: -Automatic conversions happen when a binary operator has operands of -different types. Automatic conversions are limited to converting between -numeric types. The numeric types are ``int``, ``count``, and ``double`` -(``bool`` is not a numeric type). -When an automatic conversion occurs, values are promoted to the "highest" -type in the expression. In general, this promotion follows a simple -hierarchy: ``double`` is highest, ``int`` comes next, and ``count`` is -lowest. ++-----------------------+--------------------+ +| Name | Description | ++=======================+====================+ +| :bro:type:`bool` | Boolean | ++-----------------------+--------------------+ +| :bro:type:`count`, | Numeric types | +| :bro:type:`int`, | | +| :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. - -.. 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. +Here is a more detailed description of each type: .. bro:type:: bool 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 - 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 - A numeric type representing a 64-bit signed integer. An ``int`` constant - is a string of digits preceded by a ``+`` or ``-`` sign, e.g. + A numeric type representing a 64-bit signed integer. An "int" constant + is a string of digits preceded by a "+" or "-" sign, e.g. ``-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 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 (``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``), assignment operators (``=``, ``+=``, ``-=``), 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 - intended type is inferred, e.g. ``local size_difference = 0`` will - infer :bro:type:`count`, while ``local size_difference = +0`` - will infer :bro:type:`int`. + intended type is inferred, e.g. "local size_difference = 0" will + infer ":bro:type:`count`", while "local size_difference = +0" + will infer "int". .. bro:type:: 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`` + A numeric type representing a 64-bit unsigned integer. 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 precede the hex digits), e.g. ``0xff`` or ``0xABC123``. - 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``. - -.. bro:type:: counter - - An alias to :bro:type:`count`. + The "count" type supports the same operators as the ":bro:type:`int`" + type, but a unary plus or minus applied to a "count" results in an + "int". .. bro:type:: double A numeric type representing a double-precision floating-point number. Floating-point constants are written as a string of digits 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``. - The ``double`` type supports the following operators: arithmetic + The "double" type supports the following operators: arithmetic operators (``+``, ``-``, ``*``, ``/``), comparison 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 - intended type is inferred, e.g. ``local size_difference = 5`` will - infer :bro:type:`count`, while ``local size_difference = 5.0`` - will infer :bro:type:`double`. + intended type is inferred, e.g. "local size_difference = 5" will + infer ":bro:type:`count`", while "local size_difference = 5.0" + will infer "double". .. bro:type:: time @@ -94,10 +119,10 @@ The Bro scripting language supports the following built-in types. Time values support the comparison operators (``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``). A ``time`` value can be subtracted from - another ``time`` value to produce an ``interval`` value. An ``interval`` - value can be added to, or subtracted from, a ``time`` value to produce a - ``time`` value. The absolute value of a ``time`` value is a ``double`` - with the same numeric value. + another ``time`` value to produce an :bro:type:`interval` value. An + ``interval`` value can be added to, or subtracted from, a ``time`` value + to produce a ``time`` value. The absolute value of a ``time`` value is + a :bro:type:`double` with the same numeric value. .. bro:type:: interval @@ -112,52 +137,58 @@ The Bro scripting language supports the following built-in types. ``3.5mins``. An ``interval`` can also be negated, for example ``-12 hr`` represents "twelve hours in the past". - Intervals support addition and subtraction. Intervals also support - division (in which case the result is a ``double`` value), the - comparison operators (``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``), - and the assignment operators (``=``, ``+=``, ``-=``). Also, an - ``interval`` can be multiplied or divided by an arithmetic type - (``count``, ``int``, or ``double``) to produce 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). + Intervals support addition and subtraction, the comparison operators + (``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``), the assignment + operators (``=``, ``+=``, ``-=``), and unary plus and minus (``+``, ``-``). + + Intervals also support division (in which case the result is a + :bro:type:`double` value). An ``interval`` can be multiplied or divided + by an arithmetic type (``count``, ``int``, or ``double``) to produce + 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 - A type used to hold character-string values which represent text. - String constants are created by enclosing text in double quotes (") - and the backslash character (\\) introduces escape sequences (all of - the C-style escape sequences are supported). + A type used to hold character-string values which represent text, although + strings in a Bro script can actually contain any arbitrary binary data. + + 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 also support the comparison operators (``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=``). The number of characters in a string can be found by enclosing the string within pipe characters (e.g., ``|"abc"|`` - is 3). - - 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" + is 3). Substring searching can be performed using the "in" or "!in" operators (e.g., "bar" in "foobar" yields true). - Note that Bro represents strings internally as a count and vector of - bytes rather than a NUL-terminated byte string (although string - constants are also automatically NUL-terminated). This is because - network traffic can easily introduce NULs into strings either by - nature of an application, inadvertently, or maliciously. And while - NULs are allowed in Bro strings, when present in strings passed as - arguments to many functions, a run-time error can occur as their - presence likely indicates a sort of problem. In that case, the - string will also only be represented to the user as the literal - "" string. + The subscript operator can extract a substring of a string. To do this, + specify the starting index to extract (if the starting index is omitted, + then zero is assumed), followed by a colon and index + one past the last character to extract (if the last index is omitted, + then the extracted substring will go to the end of the original string). + However, if both the colon and last index are omitted, then a string of + length one is extracted. 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. Here are a few examples:: + + 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 @@ -171,7 +202,7 @@ The Bro scripting language supports the following built-in types. and embedded. 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 string exactly matches the pattern. In exact matching, the ``^`` beginning-of-line and ``$`` end-of-line anchors are redundant since @@ -187,8 +218,8 @@ The Bro scripting language supports the following built-in types. yields false. The ``!=`` operator would yield the negation of ``==``. In embedded matching the ``in`` operator is used with one - :bro:type:`pattern` operand (which must be on the left-hand side) and - one :bro:type:`string` operand, but tests whether the pattern + "pattern" operand (which must be on the left-hand side) and + one ":bro:type:`string`" operand, but tests whether the pattern appears anywhere within the given string. For example:: /foo|bar/ in "foobar" @@ -200,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 ``!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 - 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 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``. Ports support the comparison operators (``==``, ``!=``, ``<``, ``<=``, @@ -252,14 +268,6 @@ The Bro scripting language supports the following built-in types. address) are treated internally as IPv4 addresses (for example, ``[::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 (``==``, ``!=``), and also for ordering (``<``, ``<=``, ``>``, ``>=``). The absolute value of an address gives the size in bits (32 for IPv4, and 128 for IPv6). @@ -282,8 +290,16 @@ The Bro scripting language supports the following built-in types. if ( a in s ) 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. + + 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 @@ -293,13 +309,24 @@ The Bro scripting language supports the following built-in types. number. For example, ``192.168.0.0/16`` or ``[fe80::]/64``. Subnets can be compared for equality (``==``, ``!=``). An - :bro:type:`addr` can be checked for inclusion in a subnet using - the "in" or "!in" operators. + "addr" can be checked for inclusion in a subnet using + the ``in`` or ``!in`` operators. -.. bro:type:: any +.. bro:type:: enum - Used to bypass strong typing. For example, a function can take an - argument of type ``any`` when it may be of different types. + 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. 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 @@ -313,24 +340,25 @@ The Bro scripting language supports the following built-in types. 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 global a: table[count] of string; - declares a table indexed by :bro:type:`count` values and yielding - :bro:type:`string` values. The yield type can also be more complex: + declares a table indexed by "count" values and yielding + "string" values. The yield type can also be more complex: .. code:: bro global a: table[count] of table[addr, port] of string; - which declares a table indexed by :bro:type:`count` and yielding - another :bro:type:`table` which is indexed by an :bro:type:`addr` - and :bro:type:`port` to yield a :bro:type:`string`. + which declares a table indexed by "count" and yielding + another "table" which is indexed by an "addr" + 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: .. code:: bro @@ -340,18 +368,17 @@ The Bro scripting language supports the following built-in types. [5] = "five", }; - A table constructor (equivalent to above example) can also be used - to create a table: + A table constructor can also be used to create a table: .. code:: bro - global t2: table[count] of string = table( - [11] = "eleven", - [5] = "five" + global t2 = table( + [192.168.0.2, 22/tcp] = "ssh", + [192.168.0.3, 80/tcp] = "http" ); 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: .. code:: bro @@ -378,17 +405,7 @@ The Bro scripting language supports the following built-in types. if ( 13 in t ) ... - - 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 ) + if ( [192.168.0.2, 22/tcp] in t2 ) ... Add or overwrite individual table elements by assignment: @@ -397,7 +414,7 @@ The Bro scripting language supports the following built-in types. t[13] = "thirteen"; - Remove individual table elements with ``delete``: + Remove individual table elements with :bro:keyword:`delete`: .. code:: bro @@ -413,6 +430,9 @@ The Bro scripting language supports the following built-in types. |t| + See the :bro:keyword:`for` statement for info on how to iterate over + the elements in a table. + .. bro:type:: set A set is like a :bro:type:`table`, but it is a collection of indices @@ -423,25 +443,22 @@ The Bro scripting language supports the following built-in types. 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 global s: set[port] = { 21/tcp, 23/tcp, 80/tcp, 443/tcp }; 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 create a set: .. 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 - useful for when a more complex index type could otherwise be + useful when a more complex index type could otherwise be ambiguous: .. code:: bro @@ -462,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, "ftp"] !in s2 ) ... - Iterate over a set with a ``for`` loop: - - .. code:: bro - - local s: set[port]; - for ( p in s ) - ... - - Elements are added with ``add``: + Elements are added with :bro:keyword:`add`: .. code:: bro @@ -482,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 the set. - And removed with ``delete``: + And removed with :bro:keyword:`delete`: .. code:: bro @@ -498,6 +507,9 @@ The Bro scripting language supports the following built-in types. |s| + See the :bro:keyword:`for` statement for info on how to iterate over + the elements in a set. + .. bro:type:: vector A vector is like a :bro:type:`table`, except it's always indexed by a @@ -512,7 +524,7 @@ The Bro scripting language supports the following built-in types. .. 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 is useful for when a more complex yield type could otherwise be @@ -536,14 +548,6 @@ The Bro scripting language supports the following built-in types. 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 that already exists at that index will be overwritten): @@ -574,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 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 - 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 - 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 @@ -587,85 +597,44 @@ The Bro scripting language supports the following built-in types. s: string &optional; }; - Access to a record field uses the dollar sign (``$``) operator: - - .. 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"]; - + Records can be initialized or assigned as a whole in three different ways. When assigning a whole record value, all fields that are not :bro:attr:`&optional` or have a :bro:attr:`&default` attribute must - be specified. - - To test for existence of a field that is :bro:attr:`&optional`, use the - ``?$`` operator: + be specified. First, there's a constructor syntax: .. code:: bro - if ( r?$s ) - ... - - Records can also be created using a constructor syntax: - - .. code:: bro - - global r2: MyRecordType = record($c = 7); + local r: MyRecordType = record($c = 7); And the constructor can be explicitly named by type, too, which - is arguably more readable code: + is arguably more readable: .. code:: bro - global r3 = MyRecordType($c = 42); + local r = 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: + And the third way is like this: .. 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); + local r: MyRecordType = [$c = 13, $s = "thirteen"]; - 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: + Access to a record field uses the dollar sign (``$``) operator, and + record fields can be assigned with this: .. code:: bro - global f: file = open("myfile"); - print f, "hello, world"; - close(f); + local r: MyRecordType; + r$c = 13; - Writing to files like this for logging usually isn't recommended, for better - logging support see :doc:`/frameworks/logging`. + 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 + + if ( r ?$ s ) + ... .. bro:type:: function @@ -697,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 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: .. code:: bro @@ -739,9 +718,20 @@ The Bro scripting language supports the following built-in types. Event handlers are nearly identical in both syntax and semantics to a :bro:type:`function`, with the two differences being that event handlers have no return type since they never return a value, and - you cannot call an event handler. 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: + you cannot call an event handler. + + 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 @@ -762,7 +752,7 @@ The Bro scripting language supports the following built-in types. This assumes that ``password_exposed`` was previously declared 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 the future. For example: @@ -786,8 +776,8 @@ The Bro scripting language supports the following built-in types. 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 can short-circuit the execution of remaining hook handlers simply by - exiting from the body as a result of a ``break`` statement (as - opposed to a ``return`` or just reaching the end of the body). + exiting from the body as a result of a :bro:keyword:`break` statement (as + opposed to a :bro:keyword:`return` or just reaching the end of the body). A hook type is declared like:: @@ -856,3 +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`` statement. +.. bro:type:: file + + Bro supports writing to files, but not reading from them (to read from + files see the :doc:`/frameworks/input`). 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 + + local f = 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:: opaque + + 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". + + An example use of this type is the set of built-in functions which + perform hashing: + + .. code:: bro + + local handle = 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 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. + +.. bro:type:: any + + 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. + + Note that users aren't expected to use this type. It's provided mainly + for use by some built-in functions and scripts included with Bro. + +.. 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. + From f24adc1a95e9e1e9e01624d996ab2ca8f67777dd Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Mon, 6 Oct 2014 13:27:21 -0500 Subject: [PATCH 3/3] Minor improvements to script language reference docs --- doc/script-reference/directives.rst | 4 +-- doc/script-reference/operators.rst | 44 ++++++++++++++++++----------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/doc/script-reference/directives.rst b/doc/script-reference/directives.rst index e513e93911..06122fec8b 100644 --- a/doc/script-reference/directives.rst +++ b/doc/script-reference/directives.rst @@ -16,7 +16,7 @@ executed. Directives are evaluated before script execution begins. Example:: - print "Directory:", @DIR + print "Directory:", @DIR; .. bro:keyword:: @FILENAME @@ -25,7 +25,7 @@ executed. Directives are evaluated before script execution begins. Example:: - print "File:", @FILENAME + print "File:", @FILENAME; .. bro:keyword:: @load diff --git a/doc/script-reference/operators.rst b/doc/script-reference/operators.rst index 7fa52cf4b2..07e02bf186 100644 --- a/doc/script-reference/operators.rst +++ b/doc/script-reference/operators.rst @@ -50,31 +50,37 @@ Arithmetic operators +------------------------------+-------------+-------------------------------+ | Name | Syntax | Notes | +==============================+=============+===============================+ -| Addition | *a* + *b* | If operands are strings, then | -| | | this performs string | -| | | concatenation. | +| Addition | *a* + *b* | For :bro:type:`string` | +| | | operands, this performs | +| | | string concatenation. | +------------------------------+-------------+-------------------------------+ | Subtraction | *a* - *b* | | +------------------------------+-------------+-------------------------------+ | Multiplication | *a* \* *b* | | +------------------------------+-------------+-------------------------------+ -| Division | *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. | +| | | "double". | +------------------------------+-------------+-------------------------------+ | Unary plus | \+ *a* | | +------------------------------+-------------+-------------------------------+ | Unary minus | \- *a* | | +------------------------------+-------------+-------------------------------+ | Pre-increment | ++ *a* | Operand type cannot be | -| | | double. | +| | | "double". | +------------------------------+-------------+-------------------------------+ | Pre-decrement | ``--`` *a* | Operand type cannot be | -| | | double. | +| | | "double". | +------------------------------+-------------+-------------------------------+ -| Absolute value | \| *a* \| | If operand is string, set, | -| | | table, or vector, this | +| 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. | +------------------------------+-------------+-------------------------------+ @@ -108,7 +114,8 @@ field name must be in the declaration of the record type. +==============================+=============+===============================+ | Field access | *a* $ *b* | | +------------------------------+-------------+-------------------------------+ -| Field value existence test | *a* ?$ *b* | Evaluates to type "bool". | +| 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. | @@ -122,7 +129,7 @@ Other operators | Name | Syntax | Notes | +================================+===================+========================+ | Membership test | *a* in *b* |Evaluates to type | -| | |"bool". Do not | +| | |:bro:type:`bool`. Do not| | | |confuse this use of "in"| | | |with that used in a | | | |:bro:keyword:`for` | @@ -135,7 +142,8 @@ Other operators | | |"!(a in b)". | +--------------------------------+-------------------+------------------------+ | Table or vector element access | *a* [ *b* ] |This operator can also | -| | |be used with a set, but | +| | |be used with a | +| | |:bro:type:`set`, but | | | |only with the | | | |:bro:keyword:`add` or | | | |:bro:keyword:`delete` | @@ -148,8 +156,11 @@ Other operators | Create a deep copy | copy ( *a* ) |This is relevant only | | | |for data types that are | | | |assigned by reference, | -| | |such as "vector", "set",| -| | |"table", and "record". | +| | |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 | @@ -162,8 +173,9 @@ Other operators | | |module. | +--------------------------------+-------------------+------------------------+ | Conditional | *a* ? *b* : *c* |The first operand must | -| | |evaluate to a "bool" | -| | |type. If true, then the| +| | |evaluate to type | +| | |:bro:type:`bool`. | +| | |If true, then the | | | |second expression is | | | |evaluated and is the | | | |result of the entire |