diff --git a/doc/broids/index.rst b/doc/broids/index.rst index 0c94c914c1..dc19d7098a 100644 --- a/doc/broids/index.rst +++ b/doc/broids/index.rst @@ -24,7 +24,7 @@ rejected usernames and passwords occurring from a single address. We start by defining a threshold for the number of attempts, a monitoring interval (in minutes), and a new notice type. -.. code:: bro +.. sourcecode:: bro :caption: detect-bruteforcing.bro module FTP; @@ -53,7 +53,7 @@ function to break down the reply code and check if the first digit is a "5" or not. If true, we then use the :ref:`Summary Statistics Framework ` to keep track of the number of failed attempts. -.. code:: bro +.. sourcecode:: bro :caption: detect-bruteforcing.bro event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) @@ -70,7 +70,7 @@ Next, we use the SumStats framework to raise a notice of the attack when the number of failed attempts exceeds the specified threshold during the measuring interval. -.. code:: bro +.. sourcecode:: bro :caption: detect-bruteforcing.bro event bro_init() @@ -99,7 +99,7 @@ measuring interval. Below is the final code for our script. -.. code:: bro +.. sourcecode:: bro :caption: detect-bruteforcing.bro ##! FTP brute-forcing detector, triggering when too many rejected usernames or @@ -163,7 +163,7 @@ Below is the final code for our script. } } -.. console:: +.. sourcecode:: console $ bro -r ftp/bruteforce.pcap protocols/ftp/detect-bruteforcing.bro $ cat notice.log diff --git a/doc/conf.py b/doc/conf.py index a872a3c696..50a96794cc 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -26,7 +26,7 @@ sys.path.insert(0, os.path.abspath('ext')) # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions += ['bro', 'rst_directive', 'sphinx.ext.todo'] +extensions += ['bro', 'sphinx.ext.todo'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] diff --git a/doc/ext/bro_lexer/__init__.py b/doc/ext/bro_lexer/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/doc/ext/bro_lexer/bro.py b/doc/ext/bro_lexer/bro.py deleted file mode 100644 index ae2566a8de..0000000000 --- a/doc/ext/bro_lexer/bro.py +++ /dev/null @@ -1,76 +0,0 @@ -from pygments.lexer import RegexLexer, bygroups, include -from pygments.token import * - -__all__ = ["BroLexer"] - -class BroLexer(RegexLexer): - name = 'Bro' - aliases = ['bro'] - filenames = ['*.bro'] - - _hex = r'[0-9a-fA-F_]+' - _float = r'((\d*\.?\d+)|(\d+\.?\d*))([eE][-+]?\d+)?' - _h = r'[A-Za-z0-9][-A-Za-z0-9]*' - - tokens = { - 'root': [ - # Whitespace - ('^@.*?\n', Comment.Preproc), - (r'#.*?\n', Comment.Single), - (r'\n', Text), - (r'\s+', Text), - (r'\\\n', Text), - # Keywords - (r'(add|alarm|break|case|const|continue|delete|do|else|enum|event' - r'|export|for|function|if|global|local|module|next' - r'|of|print|redef|return|schedule|when|while)\b', Keyword), - (r'(addr|any|bool|count|counter|double|file|int|interval|net' - r'|pattern|port|record|set|string|subnet|table|time|timer' - r'|vector)\b', Keyword.Type), - (r'(T|F)\b', Keyword.Constant), - (r'(&)((?:add|delete|expire)_func|attr|(create|read|write)_expire' - r'|default|raw_output|encrypt|group|log' - r'|mergeable|optional|persistent|priority|redef' - r'|rotate_(?:interval|size)|synchronized)\b', bygroups(Punctuation, - Keyword)), - (r'\s+module\b', Keyword.Namespace), - # Addresses, ports and networks - (r'\d+/(tcp|udp|icmp|unknown)\b', Number), - (r'(\d+\.){3}\d+', Number), - (r'(' + _hex + r'){7}' + _hex, Number), - (r'0x' + _hex + r'(' + _hex + r'|:)*::(' + _hex + r'|:)*', Number), - (r'((\d+|:)(' + _hex + r'|:)*)?::(' + _hex + r'|:)*', Number), - (r'(\d+\.\d+\.|(\d+\.){2}\d+)', Number), - # Hostnames - (_h + r'(\.' + _h + r')+', String), - # Numeric - (_float + r'\s+(day|hr|min|sec|msec|usec)s?\b', Literal.Date), - (r'0[xX]' + _hex, Number.Hex), - (_float, Number.Float), - (r'\d+', Number.Integer), - (r'/', String.Regex, 'regex'), - (r'"', String, 'string'), - # Operators - (r'[!%*/+-:<=>?~|]', Operator), - (r'([-+=&|]{2}|[+-=!><]=)', Operator), - (r'(in|match)\b', Operator.Word), - (r'[{}()\[\]$.,;]', Punctuation), - # Identfier - (r'([_a-zA-Z]\w*)(::)', bygroups(Name, Name.Namespace)), - (r'[a-zA-Z_][a-zA-Z_0-9]*', Name) - ], - 'string': [ - (r'"', String, '#pop'), - (r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})', String.Escape), - (r'[^\\"\n]+', String), - (r'\\\n', String), - (r'\\', String) - ], - 'regex': [ - (r'/', String.Regex, '#pop'), - (r'\\[\\nt/]', String.Regex), # String.Escape is too intense. - (r'[^\\/\n]+', String.Regex), - (r'\\\n', String.Regex), - (r'\\', String.Regex) - ] - } diff --git a/doc/ext/rst_directive.py b/doc/ext/rst_directive.py deleted file mode 100644 index 43c95abc52..0000000000 --- a/doc/ext/rst_directive.py +++ /dev/null @@ -1,183 +0,0 @@ -def setup(app): - pass - -# -*- coding: utf-8 -*- -""" - -Modified version of the the Pygments reStructuredText directive. -Robin - -This provides two new directives: - - - .. code:: [] - - Highlights the following code block according to if - given (e.g., "c", "python", etc.). - - - .. console:: - - Highlits the following code block as a shell session. - - For compatibility with the original version, "sourcecode" is - equivalent to "code". - -Original comment: - - The Pygments reStructuredText directive - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - This fragment is a Docutils_ 0.5 directive that renders source code - (to HTML only, currently) via Pygments. - - To use it, adjust the options below and copy the code into a module - that you import on initialization. The code then automatically - registers a ``sourcecode`` directive that you can use instead of - normal code blocks like this:: - - .. sourcecode:: python - - My code goes here. - - If you want to have different code styles, e.g. one with line numbers - and one without, add formatters with their names in the VARIANTS dict - below. You can invoke them instead of the DEFAULT one by using a - directive option:: - - .. sourcecode:: python - :linenos: - - My code goes here. - - Look at the `directive documentation`_ to get all the gory details. - - .. _Docutils: http://docutils.sf.net/ - .. _directive documentation: - http://docutils.sourceforge.net/docs/howto/rst-directives.html - - :copyright: Copyright 2006-2010 by the Pygments team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -# Options -# ~~~~~~~ - -# Set to True if you want inline CSS styles instead of classes -INLINESTYLES = False - -from pygments.formatters import HtmlFormatter - -class MyHtmlFormatter(HtmlFormatter): - def format_unencoded(self, tokensource, outfile): - - # A NOP currently. - new_tokens = [] - for (i, piece) in tokensource: - new_tokens += [(i, piece)] - - return super(MyHtmlFormatter, self).format_unencoded(new_tokens, outfile) - -# The default formatter -DEFAULT = MyHtmlFormatter(noclasses=INLINESTYLES, cssclass="pygments") - -# Add name -> formatter pairs for every variant you want to use -VARIANTS = { - # 'linenos': HtmlFormatter(noclasses=INLINESTYLES, linenos=True), -} - - -import textwrap - -from docutils import nodes -from docutils.parsers.rst import directives, Directive - -from pygments import highlight -from pygments.lexers import get_lexer_by_name, guess_lexer, TextLexer -from pygments.token import Text, Keyword, Error, Operator, Name -from pygments.filter import Filter - -# Ugly hack to register the Bro lexer. I'm sure there's a better way to do it, -# but it's not obvious ... -from bro_lexer.bro import BroLexer -from pygments.lexers._mapping import LEXERS -LEXERS['BroLexer'] = ('bro_lexer.bro', BroLexer.name, BroLexer.aliases, BroLexer.filenames, ()) - -class Pygments(Directive): - """ Source code syntax hightlighting. - """ - #max_line_length = 68 - max_line_length = 0 - - required_arguments = 0 - optional_arguments = 1 - final_argument_whitespace = True - option_spec = dict([(key, directives.flag) for key in VARIANTS]) - has_content = True - - def wrapped_content(self): - content = [] - - if Console.max_line_length: - for line in self.content: - content += textwrap.wrap(line, Console.max_line_length, subsequent_indent=" ") - else: - content = self.content - - return u'\n'.join(content) - - def run(self): - self.assert_has_content() - - content = self.wrapped_content() - - if len(self.arguments) > 0: - try: - lexer = get_lexer_by_name(self.arguments[0]) - except (ValueError, IndexError): - # lexer not found, use default. - lexer = TextLexer() - else: - try: - lexer = guess_lexer(content) - except: - lexer = TextLexer() - - # import sys - # print >>sys.stderr, self.arguments, lexer.__class__ - - # take an arbitrary option if more than one is given - formatter = self.options and VARIANTS[self.options.keys()[0]] or DEFAULT - parsed = highlight(content, lexer, formatter) - return [nodes.raw('', parsed, format='html')] - -class MyFilter(Filter): - def filter(self, lexer, stream): - - bol = True - - for (ttype, value) in stream: - # Color the '>' prompt sign. - if bol and ttype is Text and value == ">": - ttype = Name.Variable.Class # This gives us a nice red. - - # Discolor builtin, that can look funny. - if ttype is Name.Builtin: - ttype = Text - - bol = value.endswith("\n") - - yield (ttype, value) - -class Console(Pygments): - required_arguments = 0 - optional_arguments = 0 - - def run(self): - self.assert_has_content() - content = self.wrapped_content() - lexer = get_lexer_by_name("sh") - lexer.add_filter(MyFilter()) - parsed = highlight(content, lexer, DEFAULT) - return [nodes.raw('', parsed, format='html')] - -directives.register_directive('sourcecode', Pygments) -directives.register_directive('code', Pygments) -directives.register_directive('console', Console) diff --git a/doc/frameworks/broker.rst b/doc/frameworks/broker.rst index 09463510b9..e00434ac5c 100644 --- a/doc/frameworks/broker.rst +++ b/doc/frameworks/broker.rst @@ -430,7 +430,7 @@ should always use the fully-qualified event name. For example, this will likely not work as expected: -.. code:: bro +.. sourcecode:: bro module MyModule; @@ -454,7 +454,7 @@ will never be called and also not any remote handlers either, even if :bro:see:`Broker::auto_publish` was used elsewhere for it. Instead, at minimum you would need change the ``bro_init()`` handler: -.. code:: bro +.. sourcecode:: bro event bro_init() { @@ -465,7 +465,7 @@ minimum you would need change the ``bro_init()`` handler: Though, an easy rule of thumb to remember would be to always use the explicit module namespace scoping and you can't go wrong: -.. code:: bro +.. sourcecode:: bro module MyModule; @@ -494,7 +494,7 @@ Manager Sending Events To Workers This is fairly straightforward, we just need a topic name which we know all workers are subscribed combined with the event we want to send them. -.. code:: bro +.. sourcecode:: bro event manager_to_workers(s: string) { @@ -524,10 +524,10 @@ all workers are subscribed combined with the event we want to send them. # eliminated by using the following conditional directives. # It's evaluated once per node at parse-time and, if false, # any code within is just ignored / treated as not existing at all. - @if ( Cluster::local_node_type() == Cluster::MANAGER ) + @if ( Cluster::local_node_type() == Cluster::MANAGER ) Broker::publish(Cluster::worker_topic, manager_to_workers, "hello v3"); - @endif + @endif } Worker Sending Events To Manager @@ -537,7 +537,7 @@ This should look almost identical to the previous case of sending an event from the manager to workers, except it simply changes the topic name to one which the manager is subscribed. -.. code:: bro +.. sourcecode:: bro event worker_to_manager(worker_name: string) { @@ -558,17 +558,17 @@ topology, this type of communication is a bit different than what we did before since we have to manually relay the event via some node that *is* connected to all workers. The manager or a proxy satisfies that requirement: -.. code:: bro +.. sourcecode:: bro event worker_to_workers(worker_name: string) { - @if ( Cluster::local_node_type() == Cluster::MANAGER || + @if ( Cluster::local_node_type() == Cluster::MANAGER || Cluster::local_node_type() == Cluster::PROXY ) Broker::publish(Cluster::worker_topic, worker_to_workers, worker_name) - @else + @else print "got event from worker", worker_name; - @endif + @endif } event some_event_handled_on_worker() @@ -597,7 +597,7 @@ we can make use of a `Highest Random Weight (HRW) hashing `_ distribution strategy to uniformly map an arbitrary key space across all available proxies. -.. code:: bro +.. sourcecode:: bro event worker_to_proxies(worker_name: string) { diff --git a/doc/frameworks/configuration.rst b/doc/frameworks/configuration.rst index 23a384a280..b1ecc8b7bb 100644 --- a/doc/frameworks/configuration.rst +++ b/doc/frameworks/configuration.rst @@ -42,7 +42,7 @@ Declaring options The "option" keyword allows variables to be declared as configuration options. -.. code:: bro +.. sourcecode:: bro module TestModule; @@ -67,7 +67,7 @@ being that there is no need to specify the :bro:attr:`&redef` attribute in the declaration of an option. For example, given the above option declarations, here are some possible redefs: -.. code:: bro +.. sourcecode:: bro redef TestModule::enable_feature = T; redef TestModule::my_networks += { 10.1.0.0/16, 10.2.0.0/16 }; @@ -90,7 +90,7 @@ only the manager node attempts to read the specified configuration files. For example, simply add something like this to local.bro: -.. code:: bro +.. sourcecode:: bro redef Config::config_files += { "/path/to/config.dat" }; @@ -131,7 +131,7 @@ supported by the config input reader. In that case you would need to use the Config::set_value function to change the value of such an option as shown in the following example. -.. code:: bro +.. sourcecode:: bro module TestModule; @@ -158,7 +158,7 @@ change handler for an option that has a data type of "addr" (for other data types, the return type and 2nd parameter data type must be adjusted accordingly): -.. code:: bro +.. sourcecode:: bro module TestModule; diff --git a/doc/frameworks/file-analysis.rst b/doc/frameworks/file-analysis.rst index 4b551497a7..fd7cdd7c94 100644 --- a/doc/frameworks/file-analysis.rst +++ b/doc/frameworks/file-analysis.rst @@ -41,7 +41,7 @@ Here's a simple example: :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -r http/get.trace file_analysis_01.bro file_state_remove @@ -88,7 +88,7 @@ calculate the MD5 of plain text files: :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -r http/get.trace file_analysis_02.bro new file, FakNcS1Jfe01uljb3 @@ -97,7 +97,7 @@ calculate the MD5 of plain text files: Some file analyzers might have tunable parameters that need to be specified in the call to :bro:see:`Files::add_analyzer`: -.. code:: bro +.. sourcecode:: bro event file_new(f: fa_file) { @@ -137,7 +137,7 @@ the input framework uses to uniquely identify an input stream. Example output of the above script may be: -.. console:: +.. sourcecode:: console $ echo "Hello world" > myfile $ bro file_analysis_03.bro diff --git a/doc/frameworks/geoip.rst b/doc/frameworks/geoip.rst index 06829bfcd5..4658fbbf9f 100644 --- a/doc/frameworks/geoip.rst +++ b/doc/frameworks/geoip.rst @@ -26,19 +26,19 @@ Before building Bro, you need to install libmaxminddb. * RPM/RedHat-based Linux: - .. console:: + .. sourcecode:: console sudo yum install libmaxminddb-devel * DEB/Debian-based Linux: - .. console:: + .. sourcecode:: console sudo apt-get install libmaxminddb-dev * FreeBSD: - .. console:: + .. sourcecode:: console sudo pkg install libmaxminddb @@ -58,7 +58,7 @@ and regions in addition to countries. `Download `__ the GeoLite2 city binary database: -.. console:: +.. sourcecode:: console wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz tar zxf GeoLite2-City.tar.gz @@ -69,7 +69,7 @@ and will vary depending on which platform and package you are using. For FreeBSD, use ``/usr/local/share/GeoIP``. For Linux, use ``/usr/share/GeoIP`` or ``/var/lib/GeoIP`` (choose whichever one already exists). -.. console:: +.. sourcecode:: console mv /GeoLite2-City.mmdb /GeoLite2-City.mmdb @@ -81,7 +81,7 @@ everything is setup correctly. After installing libmaxminddb and the GeoIP city database, and building Bro, you can quickly check if the GeoIP functionality works by running a command like this: -.. console:: +.. sourcecode:: console bro -e "print lookup_location(8.8.8.8);" @@ -113,7 +113,7 @@ Usage There is a built-in function that provides the GeoIP functionality: -.. code:: bro +.. sourcecode:: bro function lookup_location(a:addr): geo_location @@ -130,7 +130,7 @@ Example To show every ftp connection from hosts in Ohio, this is now very easy: -.. code:: bro +.. sourcecode:: bro event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) { diff --git a/doc/frameworks/input.rst b/doc/frameworks/input.rst index 01c1658d34..29e1dffded 100644 --- a/doc/frameworks/input.rst +++ b/doc/frameworks/input.rst @@ -53,7 +53,7 @@ the table content. The two records are defined as: -.. code:: bro +.. sourcecode:: bro type Idx: record { ip: addr; @@ -72,7 +72,7 @@ columns does not matter, because each column is identified by name. The log file is read into the table with a simple call of the :bro:id:`Input::add_table` function: -.. code:: bro +.. sourcecode:: bro global blacklist: table[addr] of Val = table(); @@ -109,7 +109,7 @@ Once the input framework finishes reading from a data source, it fires the :bro:id:`Input::end_of_data` event. Once this event has been received all data from the input file is available in the table. -.. code:: bro +.. sourcecode:: bro event Input::end_of_data(name: string, source: string) { # now all data is in the table @@ -121,7 +121,7 @@ just might not contain all lines from the input file before the event has fired. After the table has been populated it can be used like any other Bro table and blacklist entries can easily be tested: -.. code:: bro +.. sourcecode:: bro if ( 192.168.18.12 in blacklist ) # take action @@ -143,7 +143,7 @@ elements from the file will be updated. After the update is finished the In our example the call would look like: -.. code:: bro +.. sourcecode:: bro Input::force_update("blacklist"); @@ -155,7 +155,7 @@ of the :bro:id:`Input::add_table` call. Valid values are ``Input::MANUAL`` setting the value of the ``mode`` option in the previous example would look like this: -.. code:: bro +.. sourcecode:: bro Input::add_table([$source="blacklist.file", $name="blacklist", $idx=Idx, $val=Val, $destination=blacklist, @@ -189,7 +189,7 @@ item is added to, removed from, or changed in a table. The event definition looks like this (note that you can change the name of this event in your own Bro script): -.. code:: bro +.. sourcecode:: bro event entry(description: Input::TableDescription, tpe: Input::Event, left: Idx, right: Val) { @@ -199,7 +199,7 @@ this event in your own Bro script): The event must be specified in ``$ev`` in the ``add_table`` call: -.. code:: bro +.. sourcecode:: bro Input::add_table([$source="blacklist.file", $name="blacklist", $idx=Idx, $val=Val, $destination=blacklist, @@ -244,7 +244,7 @@ The following example filter will reject adding entries to the table when they were generated over a month ago. It will accept all changes and all removals of values that are already present in the table. -.. code:: bro +.. sourcecode:: bro Input::add_table([$source="blacklist.file", $name="blacklist", $idx=Idx, $val=Val, $destination=blacklist, @@ -307,7 +307,7 @@ discussed in much detail. To read the blacklist of the previous example into an event stream, the :bro:id:`Input::add_event` function is used. For example: -.. code:: bro +.. sourcecode:: bro type Val: record { ip: addr; diff --git a/doc/frameworks/logging-input-sqlite.rst b/doc/frameworks/logging-input-sqlite.rst index 52befb504f..21fd3141ef 100644 --- a/doc/frameworks/logging-input-sqlite.rst +++ b/doc/frameworks/logging-input-sqlite.rst @@ -69,7 +69,7 @@ same fields that are present in the ASCII log files:: Note that the ASCII ``conn.log`` will still be created. To prevent this file from being created, you can remove the default filter: -.. code:: bro +.. sourcecode:: bro Log::remove_filter(Conn::LOG, "default"); diff --git a/doc/frameworks/logging.rst b/doc/frameworks/logging.rst index 10e0b8fc16..712af7f385 100644 --- a/doc/frameworks/logging.rst +++ b/doc/frameworks/logging.rst @@ -65,7 +65,7 @@ done: In the following example, we create a new module "Foo" which creates a new log stream. -.. code:: bro +.. sourcecode:: bro module Foo; @@ -115,7 +115,7 @@ In this example, the :bro:id:`connection_established` event provides our data, and we also store a copy of the data being logged into the :bro:type:`connection` record: -.. code:: bro +.. sourcecode:: bro event connection_established(c: connection) { @@ -158,7 +158,7 @@ Let's say we want to add a boolean field ``is_private`` to :bro:type:`Conn::Info` that indicates whether the originator IP address is part of the :rfc:`1918` space: -.. code:: bro +.. sourcecode:: bro # Add a field to the connection log record. redef record Conn::Info += { @@ -184,7 +184,7 @@ In this example, since a connection's summary is generated at the time its state is removed from memory, we can add another handler at that time that sets our field correctly: -.. code:: bro +.. sourcecode:: bro event connection_state_remove(c: connection) { @@ -217,7 +217,7 @@ being logged. For these cases, a stream can specify an event that will be generated every time a log record is written to it. To do this, we need to modify the example module shown above to look something like this: -.. code:: bro +.. sourcecode:: bro module Foo; @@ -248,7 +248,7 @@ connection log stream raises the event :bro:id:`Conn::log_conn`. You could use that for example for flagging when a connection to a specific destination exceeds a certain duration: -.. code:: bro +.. sourcecode:: bro redef enum Notice::Type += { ## Indicates that a connection remained established longer @@ -275,7 +275,7 @@ Disable a Stream One way to "turn off" a log is to completely disable the stream. For example, the following example will prevent the conn.log from being written: -.. code:: bro +.. sourcecode:: bro event bro_init() { @@ -310,7 +310,7 @@ The easiest way to change a log filename is to simply replace the default log filter with a new filter that specifies a value for the "path" field. In this example, "conn.log" will be changed to "myconn.log": -.. code:: bro +.. sourcecode:: bro event bro_init() { @@ -335,7 +335,7 @@ if you want to restrict the set of fields being logged to the new file. In this example, a new filter is added to the Conn::LOG stream that writes two fields to a new log file: -.. code:: bro +.. sourcecode:: bro event bro_init() { @@ -366,7 +366,7 @@ corresponding ``exclude`` filter attribute that you can use instead of If you want to make this the only log file for the stream, you can remove the default filter: -.. code:: bro +.. sourcecode:: bro event bro_init() { @@ -383,7 +383,7 @@ allows, e.g., to record local and remote connections into separate files. To do this, you define a function that returns the desired path, and use the "path_func" filter attribute: -.. code:: bro +.. sourcecode:: bro # Note: if using BroControl then you don't need to redef local_nets. redef Site::local_nets = { 192.168.0.0/16 }; @@ -415,7 +415,7 @@ only with the :bro:enum:`Conn::LOG` stream as the record type is hardcoded into its argument list. However, Bro allows to do a more generic variant: -.. code:: bro +.. sourcecode:: bro function myfunc(id: Log::ID, path: string, rec: record { id: conn_id; } ) : string @@ -434,7 +434,7 @@ We have seen how to customize the columns being logged, but you can also control which records are written out by providing a predicate that will be called for each log record: -.. code:: bro +.. sourcecode:: bro function http_only(rec: Conn::Info) : bool { @@ -464,7 +464,7 @@ Or specifically for certain :bro:type:`Log::Filter` instances by setting their ``interv`` field. Here's an example of changing just the :bro:enum:`Conn::LOG` stream's default filter rotation. -.. code:: bro +.. sourcecode:: bro event bro_init() { @@ -503,7 +503,7 @@ Some writer options are global (i.e., they affect all log filters using that log writer). For example, to change the output format of all ASCII logs to JSON format: -.. code:: bro +.. sourcecode:: bro redef LogAscii::use_json = T; @@ -511,7 +511,7 @@ Some writer options are filter-specific (i.e., they affect only the filters that explicitly specify the option). For example, to change the output format of the ``conn.log`` only: -.. code:: bro +.. sourcecode:: bro event bro_init() { diff --git a/doc/frameworks/netcontrol.rst b/doc/frameworks/netcontrol.rst index 0bf6f22368..96215e5cef 100644 --- a/doc/frameworks/netcontrol.rst +++ b/doc/frameworks/netcontrol.rst @@ -65,7 +65,7 @@ Backends should be initialized in the :bro:see:`NetControl::init` event, calling the :bro:see:`NetControl::activate` function after the plugin instance has been initialized. The debug plugin can be initialized as follows: -.. code:: bro +.. sourcecode:: bro event NetControl::init() { @@ -143,7 +143,7 @@ plugin to print one line to the standard output, which contains information about the rule that was added. It will also cause creation of `netcontrol.log`, which contains information about all actions that are taken by NetControl: -.. console:: +.. sourcecode:: console $ bro -C -r tls/ecdhe.pcap netcontrol-1-drop-with-debug.bro netcontrol debug (Debug-All): init @@ -179,7 +179,7 @@ additional log called `netcontrol_drop.log`. This log file is much more succinct only contains information that is specific to drops that are enacted by NetControl: -.. console:: +.. sourcecode:: console $ cat netcontrol_drop.log #separator \x09 @@ -203,7 +203,7 @@ following code automatically blocks a recognized SSH guesser: :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -C -r ssh/sshguess.pcap netcontrol-2-ssh-guesser.bro netcontrol debug (Debug-All): init @@ -233,7 +233,7 @@ the :bro:see:`Notice::ACTION_DROP` action of the notice framework: :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -C -r ssh/sshguess.pcap netcontrol-3-ssh-guesser.bro netcontrol debug (Debug-All): init @@ -259,7 +259,7 @@ Using the :bro:see:`Notice::ACTION_DROP` action of the notice framework also will cause the `dropped` column in `notice.log` to be set to true each time that the NetControl framework enacts a block: -.. console:: +.. sourcecode:: console $ cat notice.log #separator \x09 @@ -326,7 +326,7 @@ drops all connections on the network: :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -C -r tls/ecdhe.pcap netcontrol-4-drop.bro netcontrol debug (Debug-All): init @@ -386,7 +386,7 @@ originating from the 192.168.* network: :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -C -r tls/ecdhe.pcap netcontrol-5-hook.bro netcontrol debug (Debug-All): init @@ -465,7 +465,7 @@ address is already blocked in the second connection. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -C -r tls/google-duplicate.trace netcontrol-6-find.bro netcontrol debug (Debug-All): init @@ -519,7 +519,7 @@ Using catch and release in your scripts is easy; just use :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -C -r tls/ecdhe.pcap netcontrol-7-catch-release.bro netcontrol debug (Debug-All): init @@ -535,7 +535,7 @@ first 10 minutes, it is blocked for 1 hour and then monitored for 24 hours, etc. Catch and release adds its own new logfile in addition to the already existing ones (netcontrol_catch_release.log): -.. console:: +.. sourcecode:: console $ cat netcontrol_catch_release.log #separator \x09 @@ -664,7 +664,7 @@ plugin. We manually block a few addresses in the :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro netcontrol-8-multiple.bro netcontrol debug (Debug-All): init @@ -675,7 +675,7 @@ output to the command line. The other two lines are handled by the OpenFlow plugin. We can verify this by looking at netcontrol.log. The plugin column shows which plugin handled a rule and reveals that two rules were handled by OpenFlow: -.. console:: +.. sourcecode:: console $ cat netcontrol.log #separator \x09 @@ -702,7 +702,7 @@ which plugin handled a rule and reveals that two rules were handled by OpenFlow: Furthermore, openflow.log also shows the two added rules, converted to OpenFlow flow mods: -.. console:: +.. sourcecode:: console $ cat openflow.log #separator \x09 @@ -792,7 +792,7 @@ to our very first example: :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -C -r tls/ecdhe.pcap netcontrol-10-use-skeleton.bro add, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::CONNECTION, conn=[orig_h=192.168.18.50, orig_p=56981/tcp, resp_h=74.125.239.97, resp_p=443/tcp], flow=, ip=, mac=], expire=20.0 secs, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_ids={ diff --git a/doc/frameworks/notice.rst b/doc/frameworks/notice.rst index d49bebb7ce..511e22e425 100644 --- a/doc/frameworks/notice.rst +++ b/doc/frameworks/notice.rst @@ -96,7 +96,7 @@ the server at 192.168.56.103: :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -C -r ssh/sshguess.pcap notice_ssh_guesser.bro $ cat notice.log @@ -121,7 +121,7 @@ Hooks can also have priorities applied to order their execution like events with a default priority of 0. Greater values are executed first. Setting a hook body to run before default hook bodies might look like this: -.. code:: bro +.. sourcecode:: bro hook Notice::policy(n: Notice::Info) &priority=5 { @@ -191,7 +191,7 @@ SSH analysis scripts sees enough failed logins to a given host, it raises a notice of the type :bro:see:`SSH::Password_Guessing`. The code in the base SSH analysis script which raises the notice looks like this: -.. code:: bro +.. sourcecode:: bro NOTICE([$note=Password_Guessing, $msg=fmt("%s appears to be guessing SSH passwords (seen in %d connections).", key$host, r$num), @@ -302,7 +302,7 @@ for session negotiations where the certificate or certificate chain did not validate successfully against the available certificate authority certificates. -.. code:: bro +.. sourcecode:: bro NOTICE([$note=SSL::Invalid_Server_Cert, $msg=fmt("SSL certificate validation failed with (%s)", c$ssl$validation_status), @@ -348,7 +348,7 @@ There is a field in the :bro:see:`Notice::Info` record named sent. An example of including some information from an HTTP request is included below. -.. code:: bro +.. sourcecode:: bro hook Notice::policy(n: Notice::Info) { diff --git a/doc/frameworks/signatures.rst b/doc/frameworks/signatures.rst index 1443f76ba1..b06cb62e87 100644 --- a/doc/frameworks/signatures.rst +++ b/doc/frameworks/signatures.rst @@ -20,9 +20,7 @@ Signature Framework Basics ====== -Let's look at an example signature first: - -.. code:: bro-sig +Let's look at an example signature first:: signature my-first-sig { ip-proto == tcp @@ -36,7 +34,7 @@ This signature asks Bro to match the regular expression ``.*root`` on all TCP connections going to port 80. When the signature triggers, Bro will raise an event :bro:id:`signature_match` of the form: -.. code:: bro +.. sourcecode:: bro event signature_match(state: signature_state, msg: string, data: string) @@ -117,9 +115,7 @@ evaluates to true, the whole header condition matches (exception: with ``!=``, the header condition only matches if all values differ). In addition to these pre-defined header keywords, a general header -condition can be defined either as - -.. code:: bro-sig +condition can be defined either as:: header [:] [& ] @@ -141,9 +137,7 @@ are not allowed in the value-list, though you can still inspect any 1, 2, or 4 byte section of an IPv6 header using this keyword. Putting it all together, this is an example condition that is -equivalent to ``dst-ip == 1.2.3.4/16, 5.6.7.8/24``: - -.. code:: bro-sig +equivalent to ``dst-ip == 1.2.3.4/16, 5.6.7.8/24``:: header ip[16:4] == 1.2.3.4/16, 5.6.7.8/24 @@ -162,9 +156,7 @@ Second, it may be prefixed with an analyzer-specific label, in which case the expression is matched against the data as extracted by the corresponding analyzer. -A ``payload`` condition has the form: - -.. code:: bro-sig +A ``payload`` condition has the form:: payload // @@ -272,7 +264,7 @@ two actions defined: Raises a :bro:id:`signature_match` event. The event handler has the following type: - .. code:: bro + .. sourcecode:: bro event signature_match(state: signature_state, msg: string, data: string) diff --git a/doc/frameworks/sumstats.rst b/doc/frameworks/sumstats.rst index 6eeddf9490..d18e87a9f0 100644 --- a/doc/frameworks/sumstats.rst +++ b/doc/frameworks/sumstats.rst @@ -81,7 +81,7 @@ inline documentation that does this with the Sumstats framework: When run on a sample PCAP file from the Bro test suite, the following output is created: -.. console:: +.. sourcecode:: console $ bro -r workshop_2011_browse.trace sumstats-countconns.bro Number of connections established: 6 @@ -103,7 +103,7 @@ real-world functional example, that is left to the Let's see if there are any hosts that crossed the threshold in a PCAP file containing a host running nmap: -.. console:: +.. sourcecode:: console $ bro -r nmap-vsn.trace sumstats-toy-scan.bro 192.168.1.71 attempted 5 or more connections diff --git a/doc/httpmonitor/index.rst b/doc/httpmonitor/index.rst index 9b10cc15bb..6342a54654 100644 --- a/doc/httpmonitor/index.rst +++ b/doc/httpmonitor/index.rst @@ -89,7 +89,7 @@ detect a reply for a ``GET http://`` request. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -r http/proxy.pcap http_proxy_01.bro A local server is acting as an open proxy: 192.168.56.101 @@ -104,7 +104,7 @@ will extend our basic script to also consider the additional codes. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -r http/proxy.pcap http_proxy_02.bro A local server is acting as an open proxy: 192.168.56.101 @@ -117,7 +117,7 @@ network. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -r http/proxy.pcap http_proxy_03.bro A local server is acting as an open proxy: 192.168.56.101 @@ -140,7 +140,7 @@ Below is the complete script. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -r http/proxy.pcap http_proxy_04.bro $ cat notice.log @@ -178,7 +178,7 @@ using the :ref:`File Analysis Framework ` :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -r bro.org.pcap file_extraction.bro Extracting file HTTP-FiIpIB2hRQSDBOSJRg.html diff --git a/doc/install/cross-compiling.rst b/doc/install/cross-compiling.rst index d47bd83fc0..ccf41a5019 100644 --- a/doc/install/cross-compiling.rst +++ b/doc/install/cross-compiling.rst @@ -25,14 +25,14 @@ You first need to compile a few build tools native to the host system for use during the later cross-compile build. In the root of your Bro source tree: -.. console:: +.. sourcecode:: console ./configure --builddir=../bro-buildtools ( cd ../bro-buildtools && make binpac bifcl ) Next configure Bro to use your cross-compilation toolchain: -.. console:: +.. sourcecode:: console ./configure --toolchain=/home/jon/x-tools/RaspberryPi-toolchain.cmake --with-binpac=$(pwd)/../bro-buildtools/aux/binpac/src/binpac --with-bifcl=$(pwd)/../bro-buildtools/src/bifcl @@ -71,13 +71,13 @@ something the following (using a Raspberry Pi as target system):: If that configuration succeeds you are ready to build: -.. console:: +.. sourcecode:: console make And if that works, install on your host system: -.. console:: +.. sourcecode:: console make install diff --git a/doc/install/install.rst b/doc/install/install.rst index ecc24671c3..d4d3b6cbe5 100644 --- a/doc/install/install.rst +++ b/doc/install/install.rst @@ -50,13 +50,13 @@ To install the required dependencies, you can use: * RPM/RedHat-based Linux: - .. console:: + .. sourcecode:: console sudo yum install cmake make gcc gcc-c++ flex bison libpcap-devel openssl-devel python-devel swig zlib-devel * DEB/Debian-based Linux: - .. console:: + .. sourcecode:: console sudo apt-get install cmake make gcc g++ flex bison libpcap-dev libssl-dev python-dev swig zlib1g-dev @@ -68,7 +68,7 @@ To install the required dependencies, you can use: Most required dependencies should come with a minimal FreeBSD install except for the following. - .. console:: + .. sourcecode:: console sudo pkg install bash cmake swig30 bison python py27-sqlite3 py27-ipaddress @@ -152,7 +152,7 @@ hosted at https://github.com/zeek. See our `git development documentation information on Bro's use of git revision control, but the short story for downloading the full source code experience for Bro via git is: -.. console:: +.. sourcecode:: console git clone --recursive https://github.com/zeek/zeek @@ -163,7 +163,7 @@ for downloading the full source code experience for Bro via git is: The typical way to build and install from source is (for more options, run ``./configure --help``): -.. console:: +.. sourcecode:: console ./configure make @@ -214,13 +214,13 @@ according to the platform/shell/package you're using. For example: Bourne-Shell Syntax: -.. console:: +.. sourcecode:: console export PATH=/usr/local/bro/bin:$PATH C-Shell Syntax: -.. console:: +.. sourcecode:: console setenv PATH /usr/local/bro/bin:$PATH diff --git a/doc/logs/index.rst b/doc/logs/index.rst index 1de56ded1a..61cb7cf848 100644 --- a/doc/logs/index.rst +++ b/doc/logs/index.rst @@ -41,7 +41,7 @@ As the fields of the log entries can be further customized by the user, the Logging Framework makes use of a header block to ensure that it remains self-describing. Here's the first few lines of a ``conn.log``. -.. console:: +.. sourcecode:: console $ cat conn.log #separator \x09 @@ -139,7 +139,7 @@ require the user to refer to fields referenced by their position). For example, the following command extracts just the given columns from a ``conn.log``: -.. console:: +.. sourcecode:: console $ cat conn.log | bro-cut id.orig_h id.orig_p id.resp_h duration 141.142.220.202 5353 224.0.0.251 - @@ -156,7 +156,7 @@ from a ``conn.log``: The corresponding ``awk`` command will look like this: -.. console:: +.. sourcecode:: console $ awk '/^[^#]/ {print $3, $4, $5, $6, $9}' conn.log 141.142.220.202 5353 224.0.0.251 5353 - @@ -223,7 +223,7 @@ includes the human readable time stamp, the unique identifier, the HTTP ``Host``, and HTTP ``URI`` as extracted from the ``http.log`` file: -.. console:: +.. sourcecode:: console $ bro-cut -d ts uid host uri < http.log 2011-03-18T19:06:08+0000 CUM0KZ3MLUfNB0cl11 bits.wikimedia.org /skins-1.5/monobook/main.css @@ -237,7 +237,7 @@ Often times log files from multiple sources are stored in UTC time to allow easy correlation. Converting the timestamp from a log file to UTC can be accomplished with the ``-u`` option: -.. console:: +.. sourcecode:: console $ bro-cut -u ts uid host uri < http.log 2011-03-18T19:06:08+0000 CUM0KZ3MLUfNB0cl11 bits.wikimedia.org /skins-1.5/monobook/main.css @@ -255,7 +255,7 @@ using the ``-D`` and ``-U`` flags, using the standard ``strftime`` syntax. For example, to format the timestamp in the US-typical "Middle Endian" you could use a format string of: ``%d-%m-%YT%H:%M:%S%z`` -.. console:: +.. sourcecode:: console $ bro-cut -D %d-%m-%YT%H:%M:%S%z ts uid host uri < http.log 18-03-2011T19:06:08+0000 CUM0KZ3MLUfNB0cl11 bits.wikimedia.org /skins-1.5/monobook/main.css @@ -285,7 +285,7 @@ largest number of bytes from the responder by redirecting the output for ``cat conn.log`` into bro-cut to extract the UID and the resp_bytes, then sorting that output by the resp_bytes field. -.. console:: +.. sourcecode:: console $ cat conn.log | bro-cut uid resp_bytes | sort -nrk2 | head -5 CwjjYJ2WqgTbAqiHl6 734 @@ -297,7 +297,7 @@ resp_bytes, then sorting that output by the resp_bytes field. Taking the UID of the first of the top responses, we can now crossreference that with the UIDs in the ``http.log`` file. -.. console:: +.. sourcecode:: console $ cat http.log | bro-cut uid id.resp_h method status_code host uri | grep UM0KZ3MLUfNB0cl11 CUM0KZ3MLUfNB0cl11 208.80.152.118 GET 304 bits.wikimedia.org /skins-1.5/monobook/main.css diff --git a/doc/mimestats/index.rst b/doc/mimestats/index.rst index 6a0f95c75a..4aba47dc9a 100644 --- a/doc/mimestats/index.rst +++ b/doc/mimestats/index.rst @@ -81,7 +81,7 @@ final code for our script. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -r http/bro.org.pcap mimestats.bro #separator \x09 diff --git a/doc/quickstart/index.rst b/doc/quickstart/index.rst index a6f17da0d5..4b9aca868b 100644 --- a/doc/quickstart/index.rst +++ b/doc/quickstart/index.rst @@ -44,20 +44,20 @@ installation that will manage a single Bro instance on the ``localhost``: Now start the BroControl shell like: -.. console:: +.. sourcecode:: console broctl Since this is the first-time use of the shell, perform an initial installation of the BroControl configuration: -.. console:: +.. sourcecode:: console [BroControl] > install Then start up a Bro instance: -.. console:: +.. sourcecode:: console [BroControl] > start @@ -74,7 +74,7 @@ policy and output the results in ``$PREFIX/logs``. You can leave it running for now, but to stop this Bro instance you would do: -.. console:: +.. sourcecode:: console [BroControl] > stop @@ -200,7 +200,7 @@ Let's continue on our path to modify the behavior for the two SSL notices. Looking at :doc:`/scripts/base/frameworks/notice/main.bro`, we see that it advertises: -.. code:: bro +.. sourcecode:: bro module Notice; @@ -212,7 +212,7 @@ we see that it advertises: That's exactly what we want to do for the first notice. Add to ``local.bro``: -.. code:: bro +.. sourcecode:: bro redef Notice::ignored_types += { SSL::Invalid_Server_Cert }; @@ -226,7 +226,7 @@ Then go into the BroControl shell to check whether the configuration change is valid before installing it and then restarting the Bro instance. The "deploy" command does all of this automatically: -.. console:: +.. sourcecode:: console [BroControl] > deploy checking configurations ... @@ -260,7 +260,7 @@ In ``local.bro``, let's define a new ``policy`` hook handler body: :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -r tls/tls-expired-cert.trace conditional-notice.bro $ cat notice.log @@ -325,7 +325,7 @@ Monitoring Live Traffic Analyzing live traffic from an interface is simple: -.. console:: +.. sourcecode:: console bro -i en0 @@ -345,7 +345,7 @@ Reading Packet Capture (pcap) Files Capturing packets from an interface and writing them to a file can be done like this: -.. console:: +.. sourcecode:: console sudo tcpdump -i en0 -s 0 -w mypackets.trace @@ -356,7 +356,7 @@ whole packets; in cases where it's not supported use ``-s 65535`` instead). After a while of capturing traffic, kill the ``tcpdump`` (with ctrl-c), and tell Bro to perform all the default analysis on the capture which primarily includes : -.. console:: +.. sourcecode:: console bro -r mypackets.trace @@ -365,7 +365,7 @@ Bro will output log files into the working directory. If you are interested in more detection, you can again load the ``local`` script that we include as a suggested configuration: -.. console:: +.. sourcecode:: console bro -r mypackets.trace local @@ -374,7 +374,7 @@ Telling Bro Which Scripts to Load A command-line invocation of Bro typically looks like: -.. console:: +.. sourcecode:: console bro @@ -391,7 +391,7 @@ directories are included in the default search path for Bro scripts:: These prefix paths can be used to load scripts like this: -.. console:: +.. sourcecode:: console bro -r mypackets.trace frameworks/files/extract-all @@ -420,7 +420,7 @@ customization" and is not overwritten when upgrades take place. To use the site-specific ``local.bro`` script, just add it to the command-line (can also be loaded through scripts with @load): -.. console:: +.. sourcecode:: console bro -i en0 local @@ -429,7 +429,7 @@ This causes Bro to load a script that prints a warning about lacking the information at the command line like this (supply your "local" subnets in place of the example subnets): -.. console:: +.. sourcecode:: console bro -r mypackets.trace local "Site::local_nets += { 1.2.3.0/24, 5.6.7.0/24 }" diff --git a/doc/script-reference/types.rst b/doc/script-reference/types.rst index 1c7a177ebe..1b15082058 100644 --- a/doc/script-reference/types.rst +++ b/doc/script-reference/types.rst @@ -305,7 +305,7 @@ Here is a more detailed description of each type: of an address gives the size in bits (32 for IPv4, and 128 for IPv6). Addresses can also be masked with ``/`` to produce a :bro:type:`subnet`: - .. code:: bro + .. sourcecode:: bro local a: addr = 192.168.1.100; local s: subnet = 192.168.0.0/16; @@ -315,7 +315,7 @@ Here is a more detailed description of each type: And checked for inclusion within a :bro:type:`subnet` using ``in`` or ``!in``: - .. code:: bro + .. sourcecode:: bro local a: addr = 192.168.1.100; local s: subnet = 192.168.0.0/16; @@ -329,7 +329,7 @@ Here is a more detailed description of each type: correspond to multiple IP addresses, the type of such a variable is "set[addr]". For example: - .. code:: bro + .. sourcecode:: bro local a = www.google.com; @@ -349,7 +349,7 @@ Here is a more detailed description of each type: A type allowing the specification of a set of related values that have no further structure. An example declaration: - .. code:: bro + .. sourcecode:: bro type color: enum { Red, White, Blue, }; @@ -379,13 +379,13 @@ Here is a more detailed description of each type: Here is an example of declaring a table indexed by "count" values and yielding "string" values: - .. code:: bro + .. sourcecode:: bro global a: table[count] of string; The yield type can also be more complex: - .. code:: bro + .. sourcecode:: bro global a: table[count] of table[addr, port] of string; @@ -396,7 +396,7 @@ Here is a more detailed description of each type: One way to initialize a table is by enclosing a set of initializers within braces, for example: - .. code:: bro + .. sourcecode:: bro global t: table[count] of string = { [11] = "eleven", @@ -405,7 +405,7 @@ Here is a more detailed description of each type: A table constructor can also be used to create a table: - .. code:: bro + .. sourcecode:: bro global t2 = table( [192.168.0.2, 22/tcp] = "ssh", @@ -416,7 +416,7 @@ Here is a more detailed description of each type: useful when a more complex index type could otherwise be ambiguous: - .. code:: bro + .. sourcecode:: bro type MyRec: record { a: count &optional; @@ -430,13 +430,13 @@ Here is a more detailed description of each type: Accessing table elements is provided by enclosing index values within square brackets (``[]``), for example: - .. code:: bro + .. sourcecode:: bro print t[11]; And membership can be tested with ``in`` or ``!in``: - .. code:: bro + .. sourcecode:: bro if ( 13 in t ) ... @@ -445,13 +445,13 @@ Here is a more detailed description of each type: Add or overwrite individual table elements by assignment: - .. code:: bro + .. sourcecode:: bro t[13] = "thirteen"; Remove individual table elements with :bro:keyword:`delete`: - .. code:: bro + .. sourcecode:: bro delete t[13]; @@ -461,7 +461,7 @@ Here is a more detailed description of each type: The number of elements in a table can be obtained by placing the table identifier between vertical pipe characters: - .. code:: bro + .. sourcecode:: bro |t| @@ -482,7 +482,7 @@ Here is a more detailed description of each type: Sets can be initialized by listing elements enclosed by curly braces: - .. code:: bro + .. sourcecode:: bro global s: set[port] = { 21/tcp, 23/tcp, 80/tcp, 443/tcp }; global s2: set[port, string] = { [21/tcp, "ftp"], [23/tcp, "telnet"] }; @@ -490,7 +490,7 @@ Here is a more detailed description of each type: A set constructor (equivalent to above example) can also be used to create a set: - .. code:: bro + .. sourcecode:: bro global s3 = set(21/tcp, 23/tcp, 80/tcp, 443/tcp); @@ -498,7 +498,7 @@ Here is a more detailed description of each type: useful when a more complex index type could otherwise be ambiguous: - .. code:: bro + .. sourcecode:: bro type MyRec: record { a: count &optional; @@ -511,7 +511,7 @@ Here is a more detailed description of each type: Set membership is tested with ``in`` or ``!in``: - .. code:: bro + .. sourcecode:: bro if ( 21/tcp in s ) ... @@ -521,7 +521,7 @@ Here is a more detailed description of each type: Elements are added with :bro:keyword:`add`: - .. code:: bro + .. sourcecode:: bro add s[22/tcp]; @@ -530,7 +530,7 @@ Here is a more detailed description of each type: And removed with :bro:keyword:`delete`: - .. code:: bro + .. sourcecode:: bro delete s[21/tcp]; @@ -540,7 +540,7 @@ Here is a more detailed description of each type: The number of elements in a set can be obtained by placing the set identifier between vertical pipe characters: - .. code:: bro + .. sourcecode:: bro |s| @@ -563,13 +563,13 @@ Here is a more detailed description of each type: :bro:type:`count` (and vector indexing is always zero-based). A vector is declared like: - .. code:: bro + .. sourcecode:: bro global v: vector of string; And can be initialized with the vector constructor: - .. code:: bro + .. sourcecode:: bro local v = vector("one", "two", "three"); @@ -577,7 +577,7 @@ Here is a more detailed description of each type: is useful for when a more complex yield type could otherwise be ambiguous. - .. code:: bro + .. sourcecode:: bro type MyRec: record { a: count &optional; @@ -591,14 +591,14 @@ Here is a more detailed description of each type: Accessing vector elements is provided by enclosing index values within square brackets (``[]``), for example: - .. code:: bro + .. sourcecode:: bro print v[2]; An element can be added to a vector by assigning the value (a value that already exists at that index will be overwritten): - .. code:: bro + .. sourcecode:: bro v[3] = "four"; @@ -606,21 +606,21 @@ Here is a more detailed description of each type: is normally equal to the number of elements in the vector) can be obtained by placing the vector identifier between vertical pipe characters: - .. code:: bro + .. sourcecode:: bro |v| A particularly common operation on a vector is to append an element to its end. You can do so using: - .. code:: bro + .. sourcecode:: bro v += e; where if e's type is ``X``, v's type is ``vector of X``. Note that this expression is equivalent to: - .. code:: bro + .. sourcecode:: bro v[|v|] = e; @@ -660,7 +660,7 @@ Here is a more detailed description of each type: same as local or global variables). An example record type definition: - .. code:: bro + .. sourcecode:: bro type MyRecordType: record { c: count; @@ -672,27 +672,27 @@ Here is a more detailed description of each type: :bro:attr:`&optional` or have a :bro:attr:`&default` attribute must be specified. First, there's a constructor syntax: - .. code:: bro + .. sourcecode:: bro local r: MyRecordType = record($c = 7); And the constructor can be explicitly named by type, too, which is arguably more readable: - .. code:: bro + .. sourcecode:: bro local r = MyRecordType($c = 42); And the third way is like this: - .. code:: bro + .. sourcecode:: bro local r: MyRecordType = [$c = 13, $s = "thirteen"]; Access to a record field uses the dollar sign (``$``) operator, and record fields can be assigned with this: - .. code:: bro + .. sourcecode:: bro local r: MyRecordType; r$c = 13; @@ -701,7 +701,7 @@ Here is a more detailed description of each type: 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 + .. sourcecode:: bro if ( r ?$ s ) ... @@ -715,7 +715,7 @@ Here is a more detailed description of each type: where *argument* is a (possibly empty) comma-separated list of arguments, and *type* is an optional return type. For example: - .. code:: bro + .. sourcecode:: bro global greeting: function(name: string): string; @@ -724,7 +724,7 @@ Here is a more detailed description of each type: have different function body values at different times. To define a function including a body value, the syntax is like: - .. code:: bro + .. sourcecode:: bro function greeting(name: string): string { @@ -739,7 +739,7 @@ Here is a more detailed description of each type: Here is an example function that takes no parameters and does not return a value: - .. code:: bro + .. sourcecode:: bro function my_func() { @@ -748,20 +748,20 @@ Here is a more detailed description of each type: Function types don't need to have a name and can be assigned anonymously: - .. code:: bro + .. sourcecode:: bro greeting = function(name: string): string { return "Hi, " + name; }; And finally, the function can be called like: - .. code:: bro + .. sourcecode:: bro print greeting("Dave"); Function parameters may specify default values as long as they appear last in the parameter list: - .. code:: bro + .. sourcecode:: bro global foo: function(s: string, t: string &default="abc", u: count &default=0); @@ -770,7 +770,7 @@ Here is a more detailed description of each type: body and they will still be used for function calls that lack those arguments. - .. code:: bro + .. sourcecode:: bro function foo(s: string, t: string, u: count) { @@ -779,7 +779,7 @@ Here is a more detailed description of each type: And calls to the function may omit the defaults from the argument list: - .. code:: bro + .. sourcecode:: bro foo("test"); @@ -792,7 +792,7 @@ Here is a more detailed description of each type: Example: - .. code:: bro + .. sourcecode:: bro event my_event(r: bool, s: string) { @@ -815,7 +815,7 @@ Here is a more detailed description of each type: Immediately queuing invocation of an event handler occurs like: - .. code:: bro + .. sourcecode:: bro event password_exposed(user, password); @@ -827,7 +827,7 @@ Here is a more detailed description of each type: This delays the invocation of event handlers until some time in the future. For example: - .. code:: bro + .. sourcecode:: bro schedule 5 secs { password_exposed(user, password) }; @@ -856,7 +856,7 @@ Here is a more detailed description of each type: where *argument* is a (possibly empty) comma-separated list of arguments. For example: - .. code:: bro + .. sourcecode:: bro global myhook: hook(s: string) @@ -864,7 +864,7 @@ Here is a more detailed description of each type: bodies have been defined for it yet. To define some hook handler bodies the syntax looks like: - .. code:: bro + .. sourcecode:: bro hook myhook(s: string) &priority=10 { @@ -891,13 +891,13 @@ Here is a more detailed description of each type: are called similarly to a function, except preceded by the ``hook`` keyword: - .. code:: bro + .. sourcecode:: bro hook myhook("hi"); or - .. code:: bro + .. sourcecode:: bro if ( hook myhook("hi") ) print "all handlers ran"; @@ -925,7 +925,7 @@ Here is a more detailed description of each type: function. For example, declare, open, and write to a file and finally close it like: - .. code:: bro + .. sourcecode:: bro local f = open("myfile"); print f, "hello, world"; @@ -945,7 +945,7 @@ Here is a more detailed description of each type: An example use of this type is the set of built-in functions which perform hashing: - .. code:: bro + .. sourcecode:: bro local handle = md5_hash_init(); md5_hash_update(handle, "test"); diff --git a/doc/scripting/index.rst b/doc/scripting/index.rst index a4c73e81bc..f4e2ba473c 100644 --- a/doc/scripting/index.rst +++ b/doc/scripting/index.rst @@ -41,7 +41,7 @@ script :doc:`/scripts/policy/frameworks/files/detect-MHR.bro` that is responsible for generating the appropriate DNS lookup, parsing the response, and generating a notice if appropriate. -.. code:: bro +.. sourcecode:: bro :caption: detect-MHR.bro ##! Detect file downloads that have hash values matching files in Team @@ -126,7 +126,7 @@ specific event (``event file_hash``). Don't get discouraged if you don't understand every section of the script; we'll cover the basics of the script and much more in following sections. -.. code:: bro +.. sourcecode:: bro :caption: detect-MHR.bro @load base/frameworks/files @@ -145,7 +145,7 @@ this level of granularity might not be entirely necessary. The ``@load`` direct are ensuring the Files framework, the Notice framework and the script to hash all files has been loaded by Bro. -.. code:: bro +.. sourcecode:: bro :caption: detect-MHR.bro export { @@ -196,7 +196,7 @@ Up until this point, the script has merely done some basic setup. With the next section, the script starts to define instructions to take in a given event. -.. code:: bro +.. sourcecode:: bro :caption: detect-MHR.bro function do_mhr_lookup(hash: string, fi: Notice::FileInfo) @@ -324,7 +324,7 @@ This effort resulted in built-in-function files organized such that each entry contains a descriptive event name, the arguments passed to the event, and a concise explanation of the functions use. -.. code:: bro +.. sourcecode:: bro ## Generated for DNS requests. For requests with multiple queries, this event ## is raised once for each. @@ -413,7 +413,7 @@ more layers of information about a connection. This will give us a chance to see the contents of the connection record without it being overly populated. -.. console:: +.. sourcecode:: console $ bro -b -r http/get.trace connection_record_01.bro [id=[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp], orig=[size=136, state=5, num_pkts=7, num_bytes_ip=512, flow_label=0, l2_addr=c8:bc:c8:96:d2:a0], resp=[size=5007, state=5, num_pkts=7, num_bytes_ip=5379, flow_label=0, l2_addr=00:10:db:88:d2:ef], start_time=1362692526.869344, duration=0.211484, service={ @@ -449,7 +449,7 @@ brackets, which would correspond to the ``$``-delimiter in a Bro script. :language: bro :linenos: -.. console:: +.. sourcecode:: console $bro -b -r http/get.trace connection_record_02.bro [id=[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp], orig=[size=136, state=5, num_pkts=7, num_bytes_ip=512, flow_label=0, l2_addr=c8:bc:c8:96:d2:a0], resp=[size=5007, state=5, num_pkts=7, num_bytes_ip=5379, flow_label=0, l2_addr=00:10:db:88:d2:ef], start_time=1362692526.869344, duration=0.211484, service={ @@ -562,7 +562,7 @@ would fail. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -b data_type_const.bro { @@ -711,7 +711,7 @@ You can see the full script and its output below. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro data_struct_set_declaration.bro SSL Port: 22/tcp @@ -735,7 +735,7 @@ to preserve a one-to-one mapping of keys to values. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro data_struct_table_declaration.bro Service Name: SSH - Common Port: 22/tcp @@ -771,7 +771,7 @@ security platform. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -b data_struct_table_complex.bro Harakiri was released in 1962 by Shochiku Eiga studios, directed by Masaki Kobayashi and starring Tatsuya Nakadai @@ -824,7 +824,7 @@ lengths. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro data_struct_vector_declaration.bro contents of v1: [1, 2, 3, 4] @@ -846,7 +846,7 @@ current item in the vector with ``addr_vector[i]``. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro -b data_struct_vector_iter.bro 1.2.0.0/18 @@ -923,7 +923,7 @@ For example, ``10.0.0.1 in 10.0.0.0/8`` would return true while script, we get the output listing the IP address and the subnet in which it belongs. -.. console:: +.. sourcecode:: console $ bro data_type_subnets.bro 172.16.4.56 belongs to subnet 172.16.0.0/20 @@ -959,7 +959,7 @@ produce a common date time formatted time stamp. When the script is executed we get an output showing the details of established connections. -.. console:: +.. sourcecode:: console $ bro -r wikipedia.trace data_type_time.bro 2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.118\x0a @@ -1009,7 +1009,7 @@ This time, when we execute the script we see an additional line in the output to display the time delta since the last fully established connection. -.. console:: +.. sourcecode:: console $ bro -r wikipedia.trace data_type_interval.bro 2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.118 @@ -1064,7 +1064,7 @@ excluding the actual matches. In this case, our pattern matches twice, and results in a table with three entries. The ``print`` statements in the script will print the contents of the table in order. -.. console:: +.. sourcecode:: console $ bro data_type_pattern_01.bro The @@ -1081,7 +1081,7 @@ on the result of the comparison between the pattern and the string. .. literalinclude:: data_type_pattern_02.bro -.. console:: +.. sourcecode:: console $ bro data_type_pattern_02.bro equality and /^?(equal)$?/ are not equal @@ -1126,7 +1126,7 @@ field is unique. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro data_struct_record_01.bro Service: dns(RFC1035) @@ -1153,7 +1153,7 @@ record. .. literalinclude:: data_struct_record_02.bro -.. console:: +.. sourcecode:: console $ bro data_struct_record_02.bro System: morlock @@ -1173,7 +1173,7 @@ It's also common to see a ``type`` used to simply alias a data structure to a more descriptive name. The example below shows an example of this from Bro's own type definitions file. -.. code:: bro +.. sourcecode:: bro :caption: init-bare.bro type string_array: table[count] of string; @@ -1240,7 +1240,7 @@ into the Logging Framework. :language: bro :linenos: -.. console:: +.. sourcecode:: console $ bro framework_logging_factorial_01.bro 1 @@ -1297,7 +1297,7 @@ Now, if we run this script, instead of generating logging information to stdout, no output is created. Instead the output is all in ``factor.log``, properly formatted and organized. -.. console:: +.. sourcecode:: console $ bro framework_logging_factorial_02.bro $ cat factor.log @@ -1371,7 +1371,7 @@ factorials that are a factors of 5, ``factor-non5.log`` with the factorials that are not factors of 5, and ``factor.log`` which would have included all factorials. -.. console:: +.. sourcecode:: console $ bro framework_logging_factorial_03.bro $ cat factor-mod5.log @@ -1473,7 +1473,7 @@ or not that notice is acted upon is decided by the local Notice Policy, but the script attempts to supply as much information as possible while staying concise. -.. code:: bro +.. sourcecode:: bro :caption: scripts/policy/protocols/ssh/interesting-hostnames.bro ##! This script will generate a notice if an apparent SSH login originates @@ -1604,7 +1604,7 @@ identifier. An identifier is a unique string of information collected from the connection relative to the behavior that has been observed by Bro. -.. code:: bro +.. sourcecode:: bro :caption: scripts/policy/protocols/ssl/expiring-certs.bro NOTICE([$note=Certificate_Expires_Soon,