mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 07:38:19 +00:00
Restructuring the main documentation index.
I'm merging in the remaining pieces from the former doc directory and restructuring things into sub-directories.
This commit is contained in:
parent
12e4dd8066
commit
25bf563e1c
41 changed files with 7679 additions and 100 deletions
231
doc/components/broccoli-python/README.rst
Normal file
231
doc/components/broccoli-python/README.rst
Normal file
|
@ -0,0 +1,231 @@
|
|||
.. -*- mode: rst-mode -*-
|
||||
..
|
||||
.. Version number is filled in automatically.
|
||||
.. |version| replace:: 0.54
|
||||
|
||||
============================
|
||||
Python Bindings for Broccoli
|
||||
============================
|
||||
|
||||
.. rst-class:: opening
|
||||
|
||||
This Python module provides bindings for Broccoli, Bro's client
|
||||
communication library. In general, the bindings provide the same
|
||||
functionality as Broccoli's C API.
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
Download
|
||||
--------
|
||||
|
||||
You can find the latest Broccoli-Python release for download at
|
||||
http://www.bro.org/download.
|
||||
|
||||
Broccoli-Python's git repository is located at `git://git.bro.org/broccoli-python.git
|
||||
<git://git.bro.org/broccoli-python.git>`__. You can browse the repository
|
||||
`here <http://git.bro.org/broccoli-python.git>`__.
|
||||
|
||||
This document describes Broccoli-Python |version|. See the ``CHANGES``
|
||||
file for version history.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Installation of the Python module is pretty straight-forward. After
|
||||
Broccoli itself has been installed, it follows the standard installation
|
||||
process for Python modules::
|
||||
|
||||
python setup.py install
|
||||
|
||||
Try the following to test the installation. If you do not see any
|
||||
error message, everything should be fine::
|
||||
|
||||
python -c "import broccoli"
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
The following examples demonstrate how to send and receive Bro
|
||||
events in Python.
|
||||
|
||||
The main challenge when using Broccoli from Python is dealing with
|
||||
the data types of Bro event parameters as there is no one-to-one
|
||||
mapping between Bro's types and Python's types. The Python modules
|
||||
automatically maps between those types which both systems provide
|
||||
(such as strings) and provides a set of wrapper classes for Bro
|
||||
types which do not have a direct Python equivalent (such as IP
|
||||
addresses).
|
||||
|
||||
Connecting to Bro
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The following code sets up a connection from Python to a remote Bro
|
||||
instance (or another Broccoli) and provides a connection handle for
|
||||
further communication::
|
||||
|
||||
from broccoli import *
|
||||
bc = Connection("127.0.0.1:47758")
|
||||
|
||||
An ``IOError`` will be raised if the connection cannot be established.
|
||||
|
||||
Sending Events
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Once you have a connection handle ``bc`` set up as shown above, you can
|
||||
start sending events::
|
||||
|
||||
bc.send("foo", 5, "attack!")
|
||||
|
||||
This sends an event called ``foo`` with two parameters, ``5`` and
|
||||
``attack!``. Broccoli operates asynchronously, i.e., events scheduled
|
||||
with ``send()`` are not always sent out immediately but might be
|
||||
queued for later transmission. To ensure that all events get out
|
||||
(and incoming events are processed, see below), you need to call
|
||||
``bc.processInput()`` regularly.
|
||||
|
||||
Data Types
|
||||
~~~~~~~~~~
|
||||
|
||||
In the example above, the types of the event parameters are
|
||||
automatically derived from the corresponding Python types: the first
|
||||
parameter (``5``) has the Bro type ``int`` and the second one
|
||||
(``attack!``) has Bro type ``string``.
|
||||
|
||||
For types which do not have a Python equivalent, the ``broccoli``
|
||||
module provides wrapper classes which have the same names as the
|
||||
corresponding Bro types. For example, to send an event called ``bar``
|
||||
with one ``addr`` argument and one ``count`` argument, you can write::
|
||||
|
||||
bc.send("bar", addr("192.168.1.1"), count(42))
|
||||
|
||||
The following table summarizes the available atomic types and their
|
||||
usage.
|
||||
|
||||
======== =========== ===========================
|
||||
Bro Type Python Type Example
|
||||
======== =========== ===========================
|
||||
addr ``addr("192.168.1.1")``
|
||||
bool bool ``True``
|
||||
count ``count(42)``
|
||||
double float ``3.14``
|
||||
enum Type currently not supported
|
||||
int int ``5``
|
||||
interval ``interval(60)``
|
||||
net Type currently not supported
|
||||
port ``port("80/tcp")``
|
||||
string string ``"attack!"``
|
||||
subnet ``subnet("192.168.1.0/24")``
|
||||
time ``time(1111111111.0)``
|
||||
======== =========== ===========================
|
||||
|
||||
The ``broccoli`` module also supports sending Bro records as event
|
||||
parameters. To send a record, you first define a record type. For
|
||||
example, a Bro record type::
|
||||
|
||||
type my_record: record {
|
||||
a: int;
|
||||
b: addr;
|
||||
c: subnet;
|
||||
};
|
||||
|
||||
turns into Python as::
|
||||
|
||||
my_record = record_type("a", "b", "c")
|
||||
|
||||
As the example shows, Python only needs to know the attribute names
|
||||
but not their types. The types are derived automatically in the same
|
||||
way as discussed above for atomic event parameters.
|
||||
|
||||
Now you can instantiate a record instance of the newly defined type
|
||||
and send it out::
|
||||
|
||||
rec = record(my_record)
|
||||
rec.a = 5
|
||||
rec.b = addr("192.168.1.1")
|
||||
rec.c = subnet("192.168.1.0/24")
|
||||
bc.send("my_event", rec)
|
||||
|
||||
.. note:: The Python module does not support nested records at this time.
|
||||
|
||||
Receiving Events
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
To receive events, you define a callback function having the same
|
||||
name as the event and mark it with the ``event`` decorator::
|
||||
|
||||
@event
|
||||
def foo(arg1, arg2):
|
||||
print arg1, arg2
|
||||
|
||||
Once you start calling ``bc.processInput()`` regularly (see above),
|
||||
each received ``foo`` event will trigger the callback function.
|
||||
|
||||
By default, the event's arguments are always passed in with built-in
|
||||
Python types. For Bro types which do not have a direct Python
|
||||
equivalent (see table above), a substitute built-in type is used
|
||||
which corresponds to the type the wrapper class' constructor expects
|
||||
(see the examples in the table). For example, Bro type ``addr`` is
|
||||
passed in as a string and Bro type ``time`` is passed in as a float.
|
||||
|
||||
Alternatively, you can define a _typed_ prototype for the event. If you
|
||||
do so, arguments will first be type-checked and then passed to the
|
||||
call-back with the specified type (which means instances of the
|
||||
wrapper classes for non-Python types). Example::
|
||||
|
||||
@event(count, addr)
|
||||
def bar(arg1, arg2):
|
||||
print arg1, arg2
|
||||
|
||||
Here, ``arg1`` will be an instance of the ``count`` wrapper class and
|
||||
``arg2`` will be an instance of the ``addr`` wrapper class.
|
||||
|
||||
Protoyping works similarly with built-in Python types::
|
||||
|
||||
@event(int, string):
|
||||
def foo(arg1, arg2):
|
||||
print arg1, arg2
|
||||
|
||||
In general, the prototype specifies the types in which the callback
|
||||
wants to receive the arguments. This actually provides support for
|
||||
simple type casts as some types support conversion to into something
|
||||
different. If for instance the event source sends an event with a
|
||||
single port argument, ``@event(port)`` will pass the port as an
|
||||
instance of the ``port`` wrapper class; ``@event(string)`` will pass it
|
||||
as a string (e.g., ``"80/tcp"``); and ``@event(int)`` will pass it as an
|
||||
integer without protocol information (e.g., just ``80``). If an
|
||||
argument cannot be converted into the specified type, a ``TypeError``
|
||||
will be raised.
|
||||
|
||||
To receive an event with a record parameter, the record type first
|
||||
needs to be defined, as described above. Then the type can be used
|
||||
with the ``@event`` decorator in the same way as atomic types::
|
||||
|
||||
my_record = record_type("a", "b", "c")
|
||||
@event(my_record)
|
||||
def my_event(rec):
|
||||
print rec.a, rec.b, rec.c
|
||||
|
||||
Helper Functions
|
||||
----------------
|
||||
|
||||
The ``broccoli`` module provides one helper function: ``current_time()``
|
||||
returns the current time as a float which, if necessary, can be
|
||||
wrapped into a ``time`` parameter (i.e., ``time(current_time()``)
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
There are some example scripts in the ``tests/`` subdirectory of the
|
||||
``broccoli-python`` repository
|
||||
`here <http://git.bro.org/broccoli-python.git/tree/HEAD:/tests>`_:
|
||||
|
||||
- ``broping.py`` is a (simplified) Python version of Broccoli's test program
|
||||
``broping``. Start Bro with ``broping.bro``.
|
||||
|
||||
- ``broping-record.py`` is a Python version of Broccoli's ``broping``
|
||||
for records. Start Bro with ``broping-record.bro``.
|
||||
|
||||
- ``test.py`` is a very ugly but comprehensive regression test and part of
|
||||
the communication test-suite. Start Bro with ``test.bro``.
|
Loading…
Add table
Add a link
Reference in a new issue