Use sourcecode Sphinx directive more widely

It looks better by default with the RTD theme, Bro syntax highlighting
is supported well enough, and I think will be more more consistent
with the literalinclude usages, so being able to drop the extra Sphinx
extension seems good.
This commit is contained in:
Jon Siwek 2018-12-19 17:02:59 -06:00
parent 9f642bfe5b
commit a80d7ead6c
24 changed files with 209 additions and 476 deletions

View file

@ -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 start by defining a threshold for the number of attempts, a monitoring
interval (in minutes), and a new notice type. interval (in minutes), and a new notice type.
.. code:: bro .. sourcecode:: bro
:caption: detect-bruteforcing.bro :caption: detect-bruteforcing.bro
module FTP; 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 "5" or not. If true, we then use the :ref:`Summary Statistics Framework
<sumstats-framework>` to keep track of the number of failed attempts. <sumstats-framework>` to keep track of the number of failed attempts.
.. code:: bro .. sourcecode:: bro
:caption: detect-bruteforcing.bro :caption: detect-bruteforcing.bro
event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) 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 the number of failed attempts exceeds the specified threshold during the
measuring interval. measuring interval.
.. code:: bro .. sourcecode:: bro
:caption: detect-bruteforcing.bro :caption: detect-bruteforcing.bro
event bro_init() event bro_init()
@ -99,7 +99,7 @@ measuring interval.
Below is the final code for our script. Below is the final code for our script.
.. code:: bro .. sourcecode:: bro
:caption: detect-bruteforcing.bro :caption: detect-bruteforcing.bro
##! FTP brute-forcing detector, triggering when too many rejected usernames or ##! 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 $ bro -r ftp/bruteforce.pcap protocols/ftp/detect-bruteforcing.bro
$ cat notice.log $ cat notice.log

View file

@ -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 # Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. # 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. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View file

@ -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)
]
}

View file

@ -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:: [<format>]
Highlights the following code block according to <format> 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)

View file

@ -430,7 +430,7 @@ should always use the fully-qualified event name.
For example, this will likely not work as expected: For example, this will likely not work as expected:
.. code:: bro .. sourcecode:: bro
module MyModule; 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 :bro:see:`Broker::auto_publish` was used elsewhere for it. Instead, at
minimum you would need change the ``bro_init()`` handler: minimum you would need change the ``bro_init()`` handler:
.. code:: bro .. sourcecode:: bro
event bro_init() 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 Though, an easy rule of thumb to remember would be to always use the
explicit module namespace scoping and you can't go wrong: explicit module namespace scoping and you can't go wrong:
.. code:: bro .. sourcecode:: bro
module MyModule; module MyModule;
@ -494,7 +494,7 @@ Manager Sending Events To Workers
This is fairly straightforward, we just need a topic name which we know 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. all workers are subscribed combined with the event we want to send them.
.. code:: bro .. sourcecode:: bro
event manager_to_workers(s: string) 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. # eliminated by using the following conditional directives.
# It's evaluated once per node at parse-time and, if false, # It's evaluated once per node at parse-time and, if false,
# any code within is just ignored / treated as not existing at all. # 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, Broker::publish(Cluster::worker_topic, manager_to_workers,
"hello v3"); "hello v3");
@endif @endif
} }
Worker Sending Events To Manager 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 from the manager to workers, except it simply changes the topic name to
one which the manager is subscribed. one which the manager is subscribed.
.. code:: bro .. sourcecode:: bro
event worker_to_manager(worker_name: string) 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* 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: connected to all workers. The manager or a proxy satisfies that requirement:
.. code:: bro .. sourcecode:: bro
event worker_to_workers(worker_name: string) 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 ) Cluster::local_node_type() == Cluster::PROXY )
Broker::publish(Cluster::worker_topic, worker_to_workers, Broker::publish(Cluster::worker_topic, worker_to_workers,
worker_name) worker_name)
@else @else
print "got event from worker", worker_name; print "got event from worker", worker_name;
@endif @endif
} }
event some_event_handled_on_worker() event some_event_handled_on_worker()
@ -597,7 +597,7 @@ we can make use of a `Highest Random Weight (HRW) hashing
<https://en.wikipedia.org/wiki/Rendezvous_hashing>`_ distribution strategy <https://en.wikipedia.org/wiki/Rendezvous_hashing>`_ distribution strategy
to uniformly map an arbitrary key space across all available proxies. to uniformly map an arbitrary key space across all available proxies.
.. code:: bro .. sourcecode:: bro
event worker_to_proxies(worker_name: string) event worker_to_proxies(worker_name: string)
{ {

View file

@ -42,7 +42,7 @@ Declaring options
The "option" keyword allows variables to be declared as configuration options. The "option" keyword allows variables to be declared as configuration options.
.. code:: bro .. sourcecode:: bro
module TestModule; 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 the declaration of an option. For example, given the above option
declarations, here are some possible redefs: declarations, here are some possible redefs:
.. code:: bro .. sourcecode:: bro
redef TestModule::enable_feature = T; redef TestModule::enable_feature = T;
redef TestModule::my_networks += { 10.1.0.0/16, 10.2.0.0/16 }; 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: For example, simply add something like this to local.bro:
.. code:: bro .. sourcecode:: bro
redef Config::config_files += { "/path/to/config.dat" }; 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 the Config::set_value function to change the value of such an option as
shown in the following example. shown in the following example.
.. code:: bro .. sourcecode:: bro
module TestModule; 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 data types, the return type and 2nd parameter data type must be adjusted
accordingly): accordingly):
.. code:: bro .. sourcecode:: bro
module TestModule; module TestModule;

View file

@ -41,7 +41,7 @@ Here's a simple example:
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -r http/get.trace file_analysis_01.bro $ bro -r http/get.trace file_analysis_01.bro
file_state_remove file_state_remove
@ -88,7 +88,7 @@ calculate the MD5 of plain text files:
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -r http/get.trace file_analysis_02.bro $ bro -r http/get.trace file_analysis_02.bro
new file, FakNcS1Jfe01uljb3 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 Some file analyzers might have tunable parameters that need to be
specified in the call to :bro:see:`Files::add_analyzer`: specified in the call to :bro:see:`Files::add_analyzer`:
.. code:: bro .. sourcecode:: bro
event file_new(f: fa_file) 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: Example output of the above script may be:
.. console:: .. sourcecode:: console
$ echo "Hello world" > myfile $ echo "Hello world" > myfile
$ bro file_analysis_03.bro $ bro file_analysis_03.bro

View file

@ -26,19 +26,19 @@ Before building Bro, you need to install libmaxminddb.
* RPM/RedHat-based Linux: * RPM/RedHat-based Linux:
.. console:: .. sourcecode:: console
sudo yum install libmaxminddb-devel sudo yum install libmaxminddb-devel
* DEB/Debian-based Linux: * DEB/Debian-based Linux:
.. console:: .. sourcecode:: console
sudo apt-get install libmaxminddb-dev sudo apt-get install libmaxminddb-dev
* FreeBSD: * FreeBSD:
.. console:: .. sourcecode:: console
sudo pkg install libmaxminddb sudo pkg install libmaxminddb
@ -58,7 +58,7 @@ and regions in addition to countries.
`Download <http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz>`__ `Download <http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz>`__
the GeoLite2 city binary database: the GeoLite2 city binary database:
.. console:: .. sourcecode:: console
wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
tar zxf 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`` FreeBSD, use ``/usr/local/share/GeoIP``. For Linux, use ``/usr/share/GeoIP``
or ``/var/lib/GeoIP`` (choose whichever one already exists). or ``/var/lib/GeoIP`` (choose whichever one already exists).
.. console:: .. sourcecode:: console
mv <extracted subdir>/GeoLite2-City.mmdb <path_to_database_dir>/GeoLite2-City.mmdb mv <extracted subdir>/GeoLite2-City.mmdb <path_to_database_dir>/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 city database, and building Bro, you can quickly check if the GeoIP
functionality works by running a command like this: functionality works by running a command like this:
.. console:: .. sourcecode:: console
bro -e "print lookup_location(8.8.8.8);" 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: There is a built-in function that provides the GeoIP functionality:
.. code:: bro .. sourcecode:: bro
function lookup_location(a:addr): geo_location 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: 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) event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool)
{ {

View file

@ -53,7 +53,7 @@ the table content.
The two records are defined as: The two records are defined as:
.. code:: bro .. sourcecode:: bro
type Idx: record { type Idx: record {
ip: addr; 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 The log file is read into the table with a simple call of the
:bro:id:`Input::add_table` function: :bro:id:`Input::add_table` function:
.. code:: bro .. sourcecode:: bro
global blacklist: table[addr] of Val = table(); 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 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. data from the input file is available in the table.
.. code:: bro .. sourcecode:: bro
event Input::end_of_data(name: string, source: string) { event Input::end_of_data(name: string, source: string) {
# now all data is in the table # 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 fired. After the table has been populated it can be used like any other Bro
table and blacklist entries can easily be tested: table and blacklist entries can easily be tested:
.. code:: bro .. sourcecode:: bro
if ( 192.168.18.12 in blacklist ) if ( 192.168.18.12 in blacklist )
# take action # 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: In our example the call would look like:
.. code:: bro .. sourcecode:: bro
Input::force_update("blacklist"); 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 setting the value of the ``mode`` option in the previous example
would look like this: would look like this:
.. code:: bro .. sourcecode:: bro
Input::add_table([$source="blacklist.file", $name="blacklist", Input::add_table([$source="blacklist.file", $name="blacklist",
$idx=Idx, $val=Val, $destination=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 The event definition looks like this (note that you can change the name of
this event in your own Bro script): this event in your own Bro script):
.. code:: bro .. sourcecode:: bro
event entry(description: Input::TableDescription, tpe: Input::Event, event entry(description: Input::TableDescription, tpe: Input::Event,
left: Idx, right: Val) { 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: The event must be specified in ``$ev`` in the ``add_table`` call:
.. code:: bro .. sourcecode:: bro
Input::add_table([$source="blacklist.file", $name="blacklist", Input::add_table([$source="blacklist.file", $name="blacklist",
$idx=Idx, $val=Val, $destination=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 they were generated over a month ago. It will accept all changes and all
removals of values that are already present in the table. removals of values that are already present in the table.
.. code:: bro .. sourcecode:: bro
Input::add_table([$source="blacklist.file", $name="blacklist", Input::add_table([$source="blacklist.file", $name="blacklist",
$idx=Idx, $val=Val, $destination=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. into an event stream, the :bro:id:`Input::add_event` function is used.
For example: For example:
.. code:: bro .. sourcecode:: bro
type Val: record { type Val: record {
ip: addr; ip: addr;

View file

@ -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 Note that the ASCII ``conn.log`` will still be created. To prevent this file
from being created, you can remove the default filter: from being created, you can remove the default filter:
.. code:: bro .. sourcecode:: bro
Log::remove_filter(Conn::LOG, "default"); Log::remove_filter(Conn::LOG, "default");

View file

@ -65,7 +65,7 @@ done:
In the following example, we create a new module "Foo" which creates In the following example, we create a new module "Foo" which creates
a new log stream. a new log stream.
.. code:: bro .. sourcecode:: bro
module Foo; 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 and we also store a copy of the data being logged into the
:bro:type:`connection` record: :bro:type:`connection` record:
.. code:: bro .. sourcecode:: bro
event connection_established(c: connection) 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 :bro:type:`Conn::Info` that indicates whether the originator IP address
is part of the :rfc:`1918` space: is part of the :rfc:`1918` space:
.. code:: bro .. sourcecode:: bro
# Add a field to the connection log record. # Add a field to the connection log record.
redef record Conn::Info += { 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 the time its state is removed from memory, we can add another handler
at that time that sets our field correctly: at that time that sets our field correctly:
.. code:: bro .. sourcecode:: bro
event connection_state_remove(c: connection) 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 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: need to modify the example module shown above to look something like this:
.. code:: bro .. sourcecode:: bro
module Foo; 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 could use that for example for flagging when a connection to a
specific destination exceeds a certain duration: specific destination exceeds a certain duration:
.. code:: bro .. sourcecode:: bro
redef enum Notice::Type += { redef enum Notice::Type += {
## Indicates that a connection remained established longer ## 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 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: example, the following example will prevent the conn.log from being written:
.. code:: bro .. sourcecode:: bro
event bro_init() 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" 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": field. In this example, "conn.log" will be changed to "myconn.log":
.. code:: bro .. sourcecode:: bro
event bro_init() 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 In this example, a new filter is added to the Conn::LOG stream that writes
two fields to a new log file: two fields to a new log file:
.. code:: bro .. sourcecode:: bro
event bro_init() 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 If you want to make this the only log file for the stream, you can
remove the default filter: remove the default filter:
.. code:: bro .. sourcecode:: bro
event bro_init() 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, files. To do this, you define a function that returns the desired path,
and use the "path_func" filter attribute: and use the "path_func" filter attribute:
.. code:: bro .. sourcecode:: bro
# Note: if using BroControl then you don't need to redef local_nets. # Note: if using BroControl then you don't need to redef local_nets.
redef Site::local_nets = { 192.168.0.0/16 }; 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 into its argument list. However, Bro allows to do a more generic
variant: variant:
.. code:: bro .. sourcecode:: bro
function myfunc(id: Log::ID, path: string, function myfunc(id: Log::ID, path: string,
rec: record { id: conn_id; } ) : 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 you can also control which records are written out by providing a
predicate that will be called for each log record: predicate that will be called for each log record:
.. code:: bro .. sourcecode:: bro
function http_only(rec: Conn::Info) : bool 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 their ``interv`` field. Here's an example of changing just the
:bro:enum:`Conn::LOG` stream's default filter rotation. :bro:enum:`Conn::LOG` stream's default filter rotation.
.. code:: bro .. sourcecode:: bro
event bro_init() 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 that log writer). For example, to change the output format of all ASCII
logs to JSON format: logs to JSON format:
.. code:: bro .. sourcecode:: bro
redef LogAscii::use_json = T; 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 that explicitly specify the option). For example, to change the output
format of the ``conn.log`` only: format of the ``conn.log`` only:
.. code:: bro .. sourcecode:: bro
event bro_init() event bro_init()
{ {

View file

@ -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 the :bro:see:`NetControl::activate` function after the plugin instance has been
initialized. The debug plugin can be initialized as follows: initialized. The debug plugin can be initialized as follows:
.. code:: bro .. sourcecode:: bro
event NetControl::init() 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`, 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: 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 $ bro -C -r tls/ecdhe.pcap netcontrol-1-drop-with-debug.bro
netcontrol debug (Debug-All): init 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 only contains information that is specific to drops that are enacted by
NetControl: NetControl:
.. console:: .. sourcecode:: console
$ cat netcontrol_drop.log $ cat netcontrol_drop.log
#separator \x09 #separator \x09
@ -203,7 +203,7 @@ following code automatically blocks a recognized SSH guesser:
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -C -r ssh/sshguess.pcap netcontrol-2-ssh-guesser.bro $ bro -C -r ssh/sshguess.pcap netcontrol-2-ssh-guesser.bro
netcontrol debug (Debug-All): init netcontrol debug (Debug-All): init
@ -233,7 +233,7 @@ the :bro:see:`Notice::ACTION_DROP` action of the notice framework:
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -C -r ssh/sshguess.pcap netcontrol-3-ssh-guesser.bro $ bro -C -r ssh/sshguess.pcap netcontrol-3-ssh-guesser.bro
netcontrol debug (Debug-All): init 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 will cause the `dropped` column in `notice.log` to be set to true each time that
the NetControl framework enacts a block: the NetControl framework enacts a block:
.. console:: .. sourcecode:: console
$ cat notice.log $ cat notice.log
#separator \x09 #separator \x09
@ -326,7 +326,7 @@ drops all connections on the network:
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -C -r tls/ecdhe.pcap netcontrol-4-drop.bro $ bro -C -r tls/ecdhe.pcap netcontrol-4-drop.bro
netcontrol debug (Debug-All): init netcontrol debug (Debug-All): init
@ -386,7 +386,7 @@ originating from the 192.168.* network:
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -C -r tls/ecdhe.pcap netcontrol-5-hook.bro $ bro -C -r tls/ecdhe.pcap netcontrol-5-hook.bro
netcontrol debug (Debug-All): init netcontrol debug (Debug-All): init
@ -465,7 +465,7 @@ address is already blocked in the second connection.
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -C -r tls/google-duplicate.trace netcontrol-6-find.bro $ bro -C -r tls/google-duplicate.trace netcontrol-6-find.bro
netcontrol debug (Debug-All): init netcontrol debug (Debug-All): init
@ -519,7 +519,7 @@ Using catch and release in your scripts is easy; just use
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -C -r tls/ecdhe.pcap netcontrol-7-catch-release.bro $ bro -C -r tls/ecdhe.pcap netcontrol-7-catch-release.bro
netcontrol debug (Debug-All): init 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 Catch and release adds its own new logfile in addition to the already existing
ones (netcontrol_catch_release.log): ones (netcontrol_catch_release.log):
.. console:: .. sourcecode:: console
$ cat netcontrol_catch_release.log $ cat netcontrol_catch_release.log
#separator \x09 #separator \x09
@ -664,7 +664,7 @@ plugin. We manually block a few addresses in the
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro netcontrol-8-multiple.bro $ bro netcontrol-8-multiple.bro
netcontrol debug (Debug-All): init 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 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: which plugin handled a rule and reveals that two rules were handled by OpenFlow:
.. console:: .. sourcecode:: console
$ cat netcontrol.log $ cat netcontrol.log
#separator \x09 #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 Furthermore, openflow.log also shows the two added rules, converted to OpenFlow
flow mods: flow mods:
.. console:: .. sourcecode:: console
$ cat openflow.log $ cat openflow.log
#separator \x09 #separator \x09
@ -792,7 +792,7 @@ to our very first example:
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -C -r tls/ecdhe.pcap netcontrol-10-use-skeleton.bro $ 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=<uninitialized>, ip=<uninitialized>, mac=<uninitialized>], expire=20.0 secs, priority=0, location=, out_port=<uninitialized>, mod=<uninitialized>, id=2, cid=2, _plugin_ids={ 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=<uninitialized>, ip=<uninitialized>, mac=<uninitialized>], expire=20.0 secs, priority=0, location=, out_port=<uninitialized>, mod=<uninitialized>, id=2, cid=2, _plugin_ids={

View file

@ -96,7 +96,7 @@ the server at 192.168.56.103:
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -C -r ssh/sshguess.pcap notice_ssh_guesser.bro $ bro -C -r ssh/sshguess.pcap notice_ssh_guesser.bro
$ cat notice.log $ 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 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: 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 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 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: in the base SSH analysis script which raises the notice looks like this:
.. code:: bro .. sourcecode:: bro
NOTICE([$note=Password_Guessing, NOTICE([$note=Password_Guessing,
$msg=fmt("%s appears to be guessing SSH passwords (seen in %d connections).", key$host, r$num), $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 not validate successfully against the available certificate authority
certificates. certificates.
.. code:: bro .. sourcecode:: bro
NOTICE([$note=SSL::Invalid_Server_Cert, NOTICE([$note=SSL::Invalid_Server_Cert,
$msg=fmt("SSL certificate validation failed with (%s)", c$ssl$validation_status), $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 sent. An example of including some information from an HTTP request is
included below. included below.
.. code:: bro .. sourcecode:: bro
hook Notice::policy(n: Notice::Info) hook Notice::policy(n: Notice::Info)
{ {

View file

@ -20,9 +20,7 @@ Signature Framework
Basics Basics
====== ======
Let's look at an example signature first: Let's look at an example signature first::
.. code:: bro-sig
signature my-first-sig { signature my-first-sig {
ip-proto == tcp 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 all TCP connections going to port 80. When the signature triggers, Bro
will raise an event :bro:id:`signature_match` of the form: 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) 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). ``!=``, the header condition only matches if all values differ).
In addition to these pre-defined header keywords, a general header In addition to these pre-defined header keywords, a general header
condition can be defined either as condition can be defined either as::
.. code:: bro-sig
header <proto>[<offset>:<size>] [& <integer>] <cmp> <value-list> header <proto>[<offset>:<size>] [& <integer>] <cmp> <value-list>
@ -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. 2, or 4 byte section of an IPv6 header using this keyword.
Putting it all together, this is an example condition that is 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``: equivalent to ``dst-ip == 1.2.3.4/16, 5.6.7.8/24``::
.. code:: bro-sig
header ip[16:4] == 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 case the expression is matched against the data as extracted by the
corresponding analyzer. corresponding analyzer.
A ``payload`` condition has the form: A ``payload`` condition has the form::
.. code:: bro-sig
payload /<regular expression>/ payload /<regular expression>/
@ -272,7 +264,7 @@ two actions defined:
Raises a :bro:id:`signature_match` event. The event handler has the Raises a :bro:id:`signature_match` event. The event handler has the
following type: following type:
.. code:: bro .. sourcecode:: bro
event signature_match(state: signature_state, msg: string, data: string) event signature_match(state: signature_state, msg: string, data: string)

View file

@ -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 When run on a sample PCAP file from the Bro test suite, the following output
is created: is created:
.. console:: .. sourcecode:: console
$ bro -r workshop_2011_browse.trace sumstats-countconns.bro $ bro -r workshop_2011_browse.trace sumstats-countconns.bro
Number of connections established: 6 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 Let's see if there are any hosts that crossed the threshold in a PCAP file
containing a host running nmap: containing a host running nmap:
.. console:: .. sourcecode:: console
$ bro -r nmap-vsn.trace sumstats-toy-scan.bro $ bro -r nmap-vsn.trace sumstats-toy-scan.bro
192.168.1.71 attempted 5 or more connections 192.168.1.71 attempted 5 or more connections

View file

@ -89,7 +89,7 @@ detect a reply for a ``GET http://`` request.
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -r http/proxy.pcap http_proxy_01.bro $ bro -r http/proxy.pcap http_proxy_01.bro
A local server is acting as an open proxy: 192.168.56.101 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 :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -r http/proxy.pcap http_proxy_02.bro $ bro -r http/proxy.pcap http_proxy_02.bro
A local server is acting as an open proxy: 192.168.56.101 A local server is acting as an open proxy: 192.168.56.101
@ -117,7 +117,7 @@ network.
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -r http/proxy.pcap http_proxy_03.bro $ bro -r http/proxy.pcap http_proxy_03.bro
A local server is acting as an open proxy: 192.168.56.101 A local server is acting as an open proxy: 192.168.56.101
@ -140,7 +140,7 @@ Below is the complete script.
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -r http/proxy.pcap http_proxy_04.bro $ bro -r http/proxy.pcap http_proxy_04.bro
$ cat notice.log $ cat notice.log
@ -178,7 +178,7 @@ using the :ref:`File Analysis Framework <file-analysis-framework>`
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -r bro.org.pcap file_extraction.bro $ bro -r bro.org.pcap file_extraction.bro
Extracting file HTTP-FiIpIB2hRQSDBOSJRg.html Extracting file HTTP-FiIpIB2hRQSDBOSJRg.html

View file

@ -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 for use during the later cross-compile build. In the root of your
Bro source tree: Bro source tree:
.. console:: .. sourcecode:: console
./configure --builddir=../bro-buildtools ./configure --builddir=../bro-buildtools
( cd ../bro-buildtools && make binpac bifcl ) ( cd ../bro-buildtools && make binpac bifcl )
Next configure Bro to use your cross-compilation toolchain: 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 ./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: If that configuration succeeds you are ready to build:
.. console:: .. sourcecode:: console
make make
And if that works, install on your host system: And if that works, install on your host system:
.. console:: .. sourcecode:: console
make install make install

View file

@ -50,13 +50,13 @@ To install the required dependencies, you can use:
* RPM/RedHat-based Linux: * 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 sudo yum install cmake make gcc gcc-c++ flex bison libpcap-devel openssl-devel python-devel swig zlib-devel
* DEB/Debian-based Linux: * 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 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 Most required dependencies should come with a minimal FreeBSD install
except for the following. except for the following.
.. console:: .. sourcecode:: console
sudo pkg install bash cmake swig30 bison python py27-sqlite3 py27-ipaddress 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 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: for downloading the full source code experience for Bro via git is:
.. console:: .. sourcecode:: console
git clone --recursive https://github.com/zeek/zeek 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, The typical way to build and install from source is (for more options,
run ``./configure --help``): run ``./configure --help``):
.. console:: .. sourcecode:: console
./configure ./configure
make make
@ -214,13 +214,13 @@ according to the platform/shell/package you're using. For example:
Bourne-Shell Syntax: Bourne-Shell Syntax:
.. console:: .. sourcecode:: console
export PATH=/usr/local/bro/bin:$PATH export PATH=/usr/local/bro/bin:$PATH
C-Shell Syntax: C-Shell Syntax:
.. console:: .. sourcecode:: console
setenv PATH /usr/local/bro/bin:$PATH setenv PATH /usr/local/bro/bin:$PATH

View file

@ -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 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``. it remains self-describing. Here's the first few lines of a ``conn.log``.
.. console:: .. sourcecode:: console
$ cat conn.log $ cat conn.log
#separator \x09 #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 For example, the following command extracts just the given columns
from a ``conn.log``: from a ``conn.log``:
.. console:: .. sourcecode:: console
$ cat conn.log | bro-cut id.orig_h id.orig_p id.resp_h duration $ cat conn.log | bro-cut id.orig_h id.orig_p id.resp_h duration
141.142.220.202 5353 224.0.0.251 - 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: The corresponding ``awk`` command will look like this:
.. console:: .. sourcecode:: console
$ awk '/^[^#]/ {print $3, $4, $5, $6, $9}' conn.log $ awk '/^[^#]/ {print $3, $4, $5, $6, $9}' conn.log
141.142.220.202 5353 224.0.0.251 5353 - 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`` HTTP ``Host``, and HTTP ``URI`` as extracted from the ``http.log``
file: file:
.. console:: .. sourcecode:: console
$ bro-cut -d ts uid host uri < http.log $ 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 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 allow easy correlation. Converting the timestamp from a log file to
UTC can be accomplished with the ``-u`` option: UTC can be accomplished with the ``-u`` option:
.. console:: .. sourcecode:: console
$ bro-cut -u ts uid host uri < http.log $ 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 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 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`` 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 $ 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 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 for ``cat conn.log`` into bro-cut to extract the UID and the
resp_bytes, then sorting that output by the resp_bytes field. 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 $ cat conn.log | bro-cut uid resp_bytes | sort -nrk2 | head -5
CwjjYJ2WqgTbAqiHl6 734 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 Taking the UID of the first of the top responses, we can now
crossreference that with the UIDs in the ``http.log`` file. 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 $ 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 CUM0KZ3MLUfNB0cl11 208.80.152.118 GET 304 bits.wikimedia.org /skins-1.5/monobook/main.css

View file

@ -81,7 +81,7 @@ final code for our script.
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -r http/bro.org.pcap mimestats.bro $ bro -r http/bro.org.pcap mimestats.bro
#separator \x09 #separator \x09

View file

@ -44,20 +44,20 @@ installation that will manage a single Bro instance on the ``localhost``:
Now start the BroControl shell like: Now start the BroControl shell like:
.. console:: .. sourcecode:: console
broctl broctl
Since this is the first-time use of the shell, perform an initial installation Since this is the first-time use of the shell, perform an initial installation
of the BroControl configuration: of the BroControl configuration:
.. console:: .. sourcecode:: console
[BroControl] > install [BroControl] > install
Then start up a Bro instance: Then start up a Bro instance:
.. console:: .. sourcecode:: console
[BroControl] > start [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: You can leave it running for now, but to stop this Bro instance you would do:
.. console:: .. sourcecode:: console
[BroControl] > stop [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`, notices. Looking at :doc:`/scripts/base/frameworks/notice/main.bro`,
we see that it advertises: we see that it advertises:
.. code:: bro .. sourcecode:: bro
module Notice; 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``: 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 }; 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 is valid before installing it and then restarting the Bro instance. The
"deploy" command does all of this automatically: "deploy" command does all of this automatically:
.. console:: .. sourcecode:: console
[BroControl] > deploy [BroControl] > deploy
checking configurations ... checking configurations ...
@ -260,7 +260,7 @@ In ``local.bro``, let's define a new ``policy`` hook handler body:
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -r tls/tls-expired-cert.trace conditional-notice.bro $ bro -r tls/tls-expired-cert.trace conditional-notice.bro
$ cat notice.log $ cat notice.log
@ -325,7 +325,7 @@ Monitoring Live Traffic
Analyzing live traffic from an interface is simple: Analyzing live traffic from an interface is simple:
.. console:: .. sourcecode:: console
bro -i en0 <list of scripts to load> bro -i en0 <list of scripts to load>
@ -345,7 +345,7 @@ Reading Packet Capture (pcap) Files
Capturing packets from an interface and writing them to a file can be done Capturing packets from an interface and writing them to a file can be done
like this: like this:
.. console:: .. sourcecode:: console
sudo tcpdump -i en0 -s 0 -w mypackets.trace 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), 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 : and tell Bro to perform all the default analysis on the capture which primarily includes :
.. console:: .. sourcecode:: console
bro -r mypackets.trace 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`` If you are interested in more detection, you can again load the ``local``
script that we include as a suggested configuration: script that we include as a suggested configuration:
.. console:: .. sourcecode:: console
bro -r mypackets.trace local bro -r mypackets.trace local
@ -374,7 +374,7 @@ Telling Bro Which Scripts to Load
A command-line invocation of Bro typically looks like: A command-line invocation of Bro typically looks like:
.. console:: .. sourcecode:: console
bro <options> <scripts...> bro <options> <scripts...>
@ -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: These prefix paths can be used to load scripts like this:
.. console:: .. sourcecode:: console
bro -r mypackets.trace frameworks/files/extract-all 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 the site-specific ``local.bro`` script, just add it to the command-line (can
also be loaded through scripts with @load): also be loaded through scripts with @load):
.. console:: .. sourcecode:: console
bro -i en0 local 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 information at the command line like this (supply your "local" subnets
in place of the example 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 }" bro -r mypackets.trace local "Site::local_nets += { 1.2.3.0/24, 5.6.7.0/24 }"

View file

@ -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). 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`: Addresses can also be masked with ``/`` to produce a :bro:type:`subnet`:
.. code:: bro .. sourcecode:: bro
local a: addr = 192.168.1.100; local a: addr = 192.168.1.100;
local s: subnet = 192.168.0.0/16; 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`` And checked for inclusion within a :bro:type:`subnet` using ``in``
or ``!in``: or ``!in``:
.. code:: bro .. sourcecode:: bro
local a: addr = 192.168.1.100; local a: addr = 192.168.1.100;
local s: subnet = 192.168.0.0/16; 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 correspond to multiple IP addresses, the type of such a variable is
"set[addr]". For example: "set[addr]". For example:
.. code:: bro .. sourcecode:: bro
local a = www.google.com; 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 A type allowing the specification of a set of related values that
have no further structure. An example declaration: have no further structure. An example declaration:
.. code:: bro .. sourcecode:: bro
type color: enum { Red, White, Blue, }; 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 Here is an example of declaring a table indexed by "count" values
and yielding "string" values: and yielding "string" values:
.. code:: bro .. sourcecode:: bro
global a: table[count] of string; global a: table[count] of string;
The yield type can also be more complex: The yield type can also be more complex:
.. code:: bro .. sourcecode:: bro
global a: table[count] of table[addr, port] of string; 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 One way to initialize a table is by enclosing a set of initializers within
braces, for example: braces, for example:
.. code:: bro .. sourcecode:: bro
global t: table[count] of string = { global t: table[count] of string = {
[11] = "eleven", [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: A table constructor can also be used to create a table:
.. code:: bro .. sourcecode:: bro
global t2 = table( global t2 = table(
[192.168.0.2, 22/tcp] = "ssh", [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 useful when a more complex index type could otherwise be
ambiguous: ambiguous:
.. code:: bro .. sourcecode:: bro
type MyRec: record { type MyRec: record {
a: count &optional; 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 Accessing table elements is provided by enclosing index values within
square brackets (``[]``), for example: square brackets (``[]``), for example:
.. code:: bro .. sourcecode:: bro
print t[11]; print t[11];
And membership can be tested with ``in`` or ``!in``: And membership can be tested with ``in`` or ``!in``:
.. code:: bro .. sourcecode:: bro
if ( 13 in t ) 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: Add or overwrite individual table elements by assignment:
.. code:: bro .. sourcecode:: bro
t[13] = "thirteen"; t[13] = "thirteen";
Remove individual table elements with :bro:keyword:`delete`: Remove individual table elements with :bro:keyword:`delete`:
.. code:: bro .. sourcecode:: bro
delete t[13]; 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 The number of elements in a table can be obtained by placing the table
identifier between vertical pipe characters: identifier between vertical pipe characters:
.. code:: bro .. sourcecode:: bro
|t| |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: 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 s: set[port] = { 21/tcp, 23/tcp, 80/tcp, 443/tcp };
global s2: set[port, string] = { [21/tcp, "ftp"], [23/tcp, "telnet"] }; global s2: set[port, string] = { [21/tcp, "ftp"], [23/tcp, "telnet"] };
@ -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 A set constructor (equivalent to above example) can also be used to
create a set: create a set:
.. code:: bro .. sourcecode:: bro
global s3 = set(21/tcp, 23/tcp, 80/tcp, 443/tcp); 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 useful when a more complex index type could otherwise be
ambiguous: ambiguous:
.. code:: bro .. sourcecode:: bro
type MyRec: record { type MyRec: record {
a: count &optional; a: count &optional;
@ -511,7 +511,7 @@ Here is a more detailed description of each type:
Set membership is tested with ``in`` or ``!in``: Set membership is tested with ``in`` or ``!in``:
.. code:: bro .. sourcecode:: bro
if ( 21/tcp in s ) 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`: Elements are added with :bro:keyword:`add`:
.. code:: bro .. sourcecode:: bro
add s[22/tcp]; add s[22/tcp];
@ -530,7 +530,7 @@ Here is a more detailed description of each type:
And removed with :bro:keyword:`delete`: And removed with :bro:keyword:`delete`:
.. code:: bro .. sourcecode:: bro
delete s[21/tcp]; 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 The number of elements in a set can be obtained by placing the set
identifier between vertical pipe characters: identifier between vertical pipe characters:
.. code:: bro .. sourcecode:: bro
|s| |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 :bro:type:`count` (and vector indexing is always zero-based). A vector
is declared like: is declared like:
.. code:: bro .. sourcecode:: bro
global v: vector of string; global v: vector of string;
And can be initialized with the vector constructor: And can be initialized with the vector constructor:
.. code:: bro .. sourcecode:: bro
local v = vector("one", "two", "three"); 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 is useful for when a more complex yield type could otherwise be
ambiguous. ambiguous.
.. code:: bro .. sourcecode:: bro
type MyRec: record { type MyRec: record {
a: count &optional; 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 Accessing vector elements is provided by enclosing index values within
square brackets (``[]``), for example: square brackets (``[]``), for example:
.. code:: bro .. sourcecode:: bro
print v[2]; print v[2];
An element can be added to a vector by assigning the value (a value An element can be added to a vector by assigning the value (a value
that already exists at that index will be overwritten): that already exists at that index will be overwritten):
.. code:: bro .. sourcecode:: bro
v[3] = "four"; 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 is normally equal to the number of elements in the vector) can be obtained
by placing the vector identifier between vertical pipe characters: by placing the vector identifier between vertical pipe characters:
.. code:: bro .. sourcecode:: bro
|v| |v|
A particularly common operation on a vector is to append an element A particularly common operation on a vector is to append an element
to its end. You can do so using: to its end. You can do so using:
.. code:: bro .. sourcecode:: bro
v += e; v += e;
where if e's type is ``X``, v's type is ``vector of X``. Note that where if e's type is ``X``, v's type is ``vector of X``. Note that
this expression is equivalent to: this expression is equivalent to:
.. code:: bro .. sourcecode:: bro
v[|v|] = e; 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 same as local or global variables). An example record type
definition: definition:
.. code:: bro .. sourcecode:: bro
type MyRecordType: record { type MyRecordType: record {
c: count; 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 :bro:attr:`&optional` or have a :bro:attr:`&default` attribute must
be specified. First, there's a constructor syntax: be specified. First, there's a constructor syntax:
.. code:: bro .. sourcecode:: bro
local r: MyRecordType = record($c = 7); local r: MyRecordType = record($c = 7);
And the constructor can be explicitly named by type, too, which And the constructor can be explicitly named by type, too, which
is arguably more readable: is arguably more readable:
.. code:: bro .. sourcecode:: bro
local r = MyRecordType($c = 42); local r = MyRecordType($c = 42);
And the third way is like this: And the third way is like this:
.. code:: bro .. sourcecode:: bro
local r: MyRecordType = [$c = 13, $s = "thirteen"]; local r: MyRecordType = [$c = 13, $s = "thirteen"];
Access to a record field uses the dollar sign (``$``) operator, and Access to a record field uses the dollar sign (``$``) operator, and
record fields can be assigned with this: record fields can be assigned with this:
.. code:: bro .. sourcecode:: bro
local r: MyRecordType; local r: MyRecordType;
r$c = 13; 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 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): ``T`` if the field has been assigned a value, or ``F`` if not):
.. code:: bro .. sourcecode:: bro
if ( r ?$ s ) 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 where *argument* is a (possibly empty) comma-separated list of
arguments, and *type* is an optional return type. For example: arguments, and *type* is an optional return type. For example:
.. code:: bro .. sourcecode:: bro
global greeting: function(name: string): string; 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 have different function body values at different times. To define
a function including a body value, the syntax is like: a function including a body value, the syntax is like:
.. code:: bro .. sourcecode:: bro
function greeting(name: string): string 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 Here is an example function that takes no parameters and does not
return a value: return a value:
.. code:: bro .. sourcecode:: bro
function my_func() 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: 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; }; greeting = function(name: string): string { return "Hi, " + name; };
And finally, the function can be called like: And finally, the function can be called like:
.. code:: bro .. sourcecode:: bro
print greeting("Dave"); print greeting("Dave");
Function parameters may specify default values as long as they appear Function parameters may specify default values as long as they appear
last in the parameter list: last in the parameter list:
.. code:: bro .. sourcecode:: bro
global foo: function(s: string, t: string &default="abc", u: count &default=0); 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 body and they will still be used for function calls that lack those
arguments. arguments.
.. code:: bro .. sourcecode:: bro
function foo(s: string, t: string, u: count) 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: And calls to the function may omit the defaults from the argument list:
.. code:: bro .. sourcecode:: bro
foo("test"); foo("test");
@ -792,7 +792,7 @@ Here is a more detailed description of each type:
Example: Example:
.. code:: bro .. sourcecode:: bro
event my_event(r: bool, s: string) 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: Immediately queuing invocation of an event handler occurs like:
.. code:: bro .. sourcecode:: bro
event password_exposed(user, password); 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 This delays the invocation of event handlers until some time in
the future. For example: the future. For example:
.. code:: bro .. sourcecode:: bro
schedule 5 secs { password_exposed(user, password) }; 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 where *argument* is a (possibly empty) comma-separated list of
arguments. For example: arguments. For example:
.. code:: bro .. sourcecode:: bro
global myhook: hook(s: string) 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 have been defined for it yet. To define some hook handler
bodies the syntax looks like: bodies the syntax looks like:
.. code:: bro .. sourcecode:: bro
hook myhook(s: string) &priority=10 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`` are called similarly to a function, except preceded by the ``hook``
keyword: keyword:
.. code:: bro .. sourcecode:: bro
hook myhook("hi"); hook myhook("hi");
or or
.. code:: bro .. sourcecode:: bro
if ( hook myhook("hi") ) if ( hook myhook("hi") )
print "all handlers ran"; 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 function. For example, declare, open, and write to a file and finally
close it like: close it like:
.. code:: bro .. sourcecode:: bro
local f = open("myfile"); local f = open("myfile");
print f, "hello, world"; 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 An example use of this type is the set of built-in functions which
perform hashing: perform hashing:
.. code:: bro .. sourcecode:: bro
local handle = md5_hash_init(); local handle = md5_hash_init();
md5_hash_update(handle, "test"); md5_hash_update(handle, "test");

View file

@ -41,7 +41,7 @@ script :doc:`/scripts/policy/frameworks/files/detect-MHR.bro`
that is responsible for generating the that is responsible for generating the
appropriate DNS lookup, parsing the response, and generating a notice if appropriate. appropriate DNS lookup, parsing the response, and generating a notice if appropriate.
.. code:: bro .. sourcecode:: bro
:caption: detect-MHR.bro :caption: detect-MHR.bro
##! Detect file downloads that have hash values matching files in Team ##! 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 understand every section of the script; we'll cover the basics of the
script and much more in following sections. script and much more in following sections.
.. code:: bro .. sourcecode:: bro
:caption: detect-MHR.bro :caption: detect-MHR.bro
@load base/frameworks/files @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 are ensuring the Files framework, the Notice framework and the script to hash all files has
been loaded by Bro. been loaded by Bro.
.. code:: bro .. sourcecode:: bro
:caption: detect-MHR.bro :caption: detect-MHR.bro
export { 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 the next section, the script starts to define instructions to take in
a given event. a given event.
.. code:: bro .. sourcecode:: bro
:caption: detect-MHR.bro :caption: detect-MHR.bro
function do_mhr_lookup(hash: string, fi: Notice::FileInfo) 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 each entry contains a descriptive event name, the arguments passed to
the event, and a concise explanation of the functions use. 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 ## Generated for DNS requests. For requests with multiple queries, this event
## is raised once for each. ## 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 chance to see the contents of the connection record without it being
overly populated. overly populated.
.. console:: .. sourcecode:: console
$ bro -b -r http/get.trace connection_record_01.bro $ 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={ [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 :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$bro -b -r http/get.trace connection_record_02.bro $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={ [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 :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -b data_type_const.bro $ bro -b data_type_const.bro
{ {
@ -711,7 +711,7 @@ You can see the full script and its output below.
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro data_struct_set_declaration.bro $ bro data_struct_set_declaration.bro
SSL Port: 22/tcp SSL Port: 22/tcp
@ -735,7 +735,7 @@ to preserve a one-to-one mapping of keys to values.
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro data_struct_table_declaration.bro $ bro data_struct_table_declaration.bro
Service Name: SSH - Common Port: 22/tcp Service Name: SSH - Common Port: 22/tcp
@ -771,7 +771,7 @@ security platform.
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -b data_struct_table_complex.bro $ bro -b data_struct_table_complex.bro
Harakiri was released in 1962 by Shochiku Eiga studios, directed by Masaki Kobayashi and starring Tatsuya Nakadai Harakiri was released in 1962 by Shochiku Eiga studios, directed by Masaki Kobayashi and starring Tatsuya Nakadai
@ -824,7 +824,7 @@ lengths.
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro data_struct_vector_declaration.bro $ bro data_struct_vector_declaration.bro
contents of v1: [1, 2, 3, 4] contents of v1: [1, 2, 3, 4]
@ -846,7 +846,7 @@ current item in the vector with ``addr_vector[i]``.
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro -b data_struct_vector_iter.bro $ bro -b data_struct_vector_iter.bro
1.2.0.0/18 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 script, we get the output listing the IP address and the subnet in
which it belongs. which it belongs.
.. console:: .. sourcecode:: console
$ bro data_type_subnets.bro $ bro data_type_subnets.bro
172.16.4.56 belongs to subnet 172.16.0.0/20 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 When the script is executed we get an output showing the details of
established connections. established connections.
.. console:: .. sourcecode:: console
$ bro -r wikipedia.trace data_type_time.bro $ 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 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 output to display the time delta since the last fully established
connection. connection.
.. console:: .. sourcecode:: console
$ bro -r wikipedia.trace data_type_interval.bro $ 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 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 twice, and results in a table with three entries. The ``print`` statements
in the script will print the contents of the table in order. in the script will print the contents of the table in order.
.. console:: .. sourcecode:: console
$ bro data_type_pattern_01.bro $ bro data_type_pattern_01.bro
The The
@ -1081,7 +1081,7 @@ on the result of the comparison between the pattern and the string.
.. literalinclude:: data_type_pattern_02.bro .. literalinclude:: data_type_pattern_02.bro
.. console:: .. sourcecode:: console
$ bro data_type_pattern_02.bro $ bro data_type_pattern_02.bro
equality and /^?(equal)$?/ are not equal equality and /^?(equal)$?/ are not equal
@ -1126,7 +1126,7 @@ field is unique.
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro data_struct_record_01.bro $ bro data_struct_record_01.bro
Service: dns(RFC1035) Service: dns(RFC1035)
@ -1153,7 +1153,7 @@ record.
.. literalinclude:: data_struct_record_02.bro .. literalinclude:: data_struct_record_02.bro
.. console:: .. sourcecode:: console
$ bro data_struct_record_02.bro $ bro data_struct_record_02.bro
System: morlock 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 structure to a more descriptive name. The example below shows an
example of this from Bro's own type definitions file. example of this from Bro's own type definitions file.
.. code:: bro .. sourcecode:: bro
:caption: init-bare.bro :caption: init-bare.bro
type string_array: table[count] of string; type string_array: table[count] of string;
@ -1240,7 +1240,7 @@ into the Logging Framework.
:language: bro :language: bro
:linenos: :linenos:
.. console:: .. sourcecode:: console
$ bro framework_logging_factorial_01.bro $ bro framework_logging_factorial_01.bro
1 1
@ -1297,7 +1297,7 @@ Now, if we run this script, instead of generating
logging information to stdout, no output is created. Instead the logging information to stdout, no output is created. Instead the
output is all in ``factor.log``, properly formatted and organized. output is all in ``factor.log``, properly formatted and organized.
.. console:: .. sourcecode:: console
$ bro framework_logging_factorial_02.bro $ bro framework_logging_factorial_02.bro
$ cat factor.log $ 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 factorials that are not factors of 5, and ``factor.log`` which would have
included all factorials. included all factorials.
.. console:: .. sourcecode:: console
$ bro framework_logging_factorial_03.bro $ bro framework_logging_factorial_03.bro
$ cat factor-mod5.log $ 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 Policy, but the script attempts to supply as much information as
possible while staying concise. possible while staying concise.
.. code:: bro .. sourcecode:: bro
:caption: scripts/policy/protocols/ssh/interesting-hostnames.bro :caption: scripts/policy/protocols/ssh/interesting-hostnames.bro
##! This script will generate a notice if an apparent SSH login originates ##! 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 from the connection relative to the behavior that has been observed by
Bro. Bro.
.. code:: bro .. sourcecode:: bro
:caption: scripts/policy/protocols/ssl/expiring-certs.bro :caption: scripts/policy/protocols/ssl/expiring-certs.bro
NOTICE([$note=Certificate_Expires_Soon, NOTICE([$note=Certificate_Expires_Soon,