******************* TRAP library (TRaffic Analysis Platform) *******************

Introduction
============

In Nemea (NEtwork MEasurement and Analysis) framework, there are various modules
for network traffic analysis and other related tasks. These modules are
standalone processes which can be easily added or removed and they can be 
interconnected using various types of interfaces. Thus one can easily create 
a complex traffic-analysis system using simple modules, see an example on the
diagram below. Because some interfaces support communication through a network, 
the system may even be distributed to several machines very easily.

TRAP (TRaffic Analysis Platform) is a library which implements the interfaces
and some supporting functions for Nemea modules.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

                                    .----------------------------------------.
                                    v                                        |
                          +-----------+        detection       +----------+  |
                          |  anomaly  |         results        |  attack  |--'
                flows.--->| detector1 |----------------------->| reporter |
  +-----------+     /     +-----------+                        +----------+
  |   flow    |----'                                               ^   ^
  | collector |----.                             +-------------+   |   |
  +-----------+     \     +-------------+        | time-series |   |   |
                flows'--->|    stats    |------->|  detector1  |---'   |
                          | computation |--.     +-------------+       |
                          +-------------+   \    +-------------+       |
                                set of stats '-->| time-series |-------'
                                 every 5 min     |  detector2  |   detection
                                                 +-------------+    results

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
       Example of a system consisting of several interconnected modules


Each module specifies a number of input and output interfaces and data types
(structures) it expects/sends on each of them. The type of interface
(TCP/IP, Unix socket, shared memory) and parameters needed for connection 
(e.g. port number) are specified by user at start-up.

You may start the modules in an arbitrary order. When no module is listening 
on the other side of an interface, the library just tries to establish 
a connection until it succeeds (or the module is terminated). 
When an established connection is broken for some reason, no error is reported 
and the interface automatically tries to reconnect.

When a record can't be sent to an interface (e.g. because of connection is not 
establised or buffer is full), there are three modes of behavior:
  - The record is dropped (no waiting).
  - The send function blocks until it's possible to send the record or a timeout
    elapses (limited waiting).
  - The send function blocks until it's possible to send the record (unlimited
    waiting).
The mode is set by a parameter of the send function.


Installation
============

1. Installation from binary packages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

At first, get RPM files libtrap*.rpm. They are available in homeproj.cesnet.cz
repository or can be built from sources via 'make rpm'.
Installation of packages from the repository can be done by executing 
`yum install "libtrap*"` or from a local RPM file by executng
`yum localinstall "libtrap*.rpm"` if you use yum(8) package manager.
If you use rpm(8) execute `rpm -i libtrap*.rpm`.

2. Installation from source codes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You need to initialize your libtrap directory and prepare the build system by
executing bootstrap.sh script that is packed with sources. It is required to
have these applications installed to run bootstrap.sh and to build libtrap:
autoconf, automake, libtool
These are parts of GNU autotools project.

Having bootstrap.sh successfuly performed, you can continue by executing
`./configure`. Possible settings of configure script can be printed by 
`./configure --help`.

To compile library, execute `make`.

Installation or uninstallation can be done by `make install` or `make uninstall`
respectively.
Note: remember to set --prefix and other paths, if they vary from default 
values.


Documentation
=============

If libtrap-devel package is installed, documetation can be found in
/usr/local/share/libtrap/doxygen.

Or you can look at in-code comments in trap.h header file.


How to implement a TRAP module
==============================

There are two ways to write a module depending on its complexity.

1. Basic functionality - use example_module.c
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Use for a simple module whose function can be described as something like "read 
a record from input - process it - send result to output - repeat".

Copy the example_module.c and modify it according to the following instructions:

 1. Modify the file header (filename, breif description, author, year).

 2. Modify module_info struct at the beginning of file. Fill in the name of 
    the module, desription of its function and number of its input and output
    interfaces. Data formats used by the interfaces should be specified in 
    the desription.

 3. Add any variables you will need to the beginning of the main function.
 
 4. Implement the module's algorithm into the main processing loop.
    Typically the first thing to do after reading data from the input interface 
    is to cast these data to a type (or struct) you expect to receive.
    The rest depends on what your module should do.

 5. If you allocated some memory dynamically, opened a file, etc., add a 
    cleanup code at the end of the main function.

Notes:
 - You don't have to call trap_send_data in every iteration of the loop.
   Or you may call it several times (i.e. send some data to more output
   interfaces).

 - You may have a module with no input or output interfaces (in that case,
   just remove the call of trap_get_data or trap_send_data function).

Of course, you may also modify other parts of the example module, if you know 
what you are doing (read the documetation).


2. More complex cases
~~~~~~~~~~~~~~~~~~~~~
Use when:
 - you want to write a module which can't be easily implemented by modification
   of the example module,
 - you already have a program and you just want to modify it to use TRAP
   interfaces,
 - you don't want to use the method 1 for some other reason.

Step-by-step instructions:

 1. Include <libtrap/trap.h>.

 2. Create a structure with information about the module (trap_module_info_t).
    Example:
      trap_module_info_t module_info = {
         "Module name",
         "Module description",
         1, // number of input interfaces
         1  // number of output interfaces
      };
    The desription should specify (among other information) the data formats 
    used by the interfaces.
    
    All values are typically known and constant for a given module, so this  
    structure is usually hard-coded, but it may also be created dynamically
    if needed.

 3. For initialization, you will need to fill trap_ifc_spec_t structure,
    which specifies types of interfaces (e.g. TCP or shared memory) and their
    parameters (e.g. address and port to connect to).
    You can get the interface specification in two ways:

      a. The standard way in which a user passes all information needed using
         the same command-line arguments as in other TRAP modules.

         In that case, pass the argc and argv parameters of your main function
         to the trap_parse_params function. It will extract the parameters for
         TRAP and fill trap_ifc_spec_t for you. Besides the mandatory parameter
         for interface specification ("-i ifc_spec") it also processes verbose
         and help parameters ("-v", "-h").
         When trap_ifc_spec_t is not needed (typically after it's passed to
         trap_init) release its contents from memory by calling 
         trap_free_ifc_spec.
         See documentation for details and example_module.c for example usage.

      b. Use your own way to get the interface specification, e.g. from a 
         configuration file or it may even be hard-coded in the program.
         
         In that case you have to fill two arrays in trap_ifc_spec_t:
           char *types;
           char **params;
         The first one is a string of length equal to total number of moudle's
         interfaces, where i-th character specifies a type of i-th interface
         (arranged as: input interfaces first, then output interfaces).
         For mapping of characters to interface types see the documentation
         or run some module with "-h".
         "params" is an array of strings where i-th string contains parameters
         for i-th interface. Format of these strings depends on interface types.
         
         Example usage for module with one input and one output interface:
           trap_ifc_spec_t ifc_spec;
           ifc_spec.types = "tt";
           char *ifc_params[] = {"loalhost,12300", "12301"};
           ifc_spec.params = ifc_params;

 4. Initiliaze TRAP by calling trap_init. Pass in the trap_module_info_t 
    structure created in 2 and trap_ifc_spec_t stucture created in 3.
    
 5. Now you can call trap_get_data and trap_send_data functions anywhere to 
    receive/send data from/to TRAP interfaces.
    See documentation for details about function parameters.

 6. If you are using blocking versions of reading/writing (timeout=TRAP_WAIT) 
    or long timeouts, you may need some way to interrupt these blocking calls
    (e.g. when the program has to be ended). This is done by calling 
    trap_terminate function.
    
    A typical usage is to register a handler for SIGTERM and SIGINT signals in
    which you set a variable saying your program to stop and call trap_terminate
    to interrupt any possible blocking call (it also set all interfaces to 
    terminated state so any later call of recv/send function will return an
    error). Thus the module can exit cleanly after pressing Ctrl-C, for example.

 7. When you don't need TRAP interfaces anymore (typically at the end of the 
    program), call trap_finalize.
    You should't call trap_get_data or trap_send_data after this.
    Although it's not usual, you CAN call trap_init again.



Compilation and linking of a module
===================================

No special compilation parameters are needed. To link, just add "-ltrap"
parameter. 

