Tutorial: Plugin dependencies

In order to avoid reinventing the wheel, T2 provides the means to access other plugins results. Before we start doing this, clean out your plugin .so directory if this is the first tutorial you follow. Then all unnecessary plugins should be deleted from the plugin folder ~/.tranalyzer/plugins and compile basicFlow, basicStats and txtSink.

$ t2build -e
Are you sure you want to empty the plugin folder '/home/wurst/.tranalyzer/plugins' (y/N)? y
Plugin folder emptied
$ t2build tranalyzer2 basicFlow txtSink

If you didn’t read the tutorials before, here is the basis plugin which we will extend: tcpWin

The anonymized sample pcap can be downloaded here: annoloc2.pcap. Please extract it under your data folder: ~/data, if you haven’t already. Now you are all set for dependency stuff.

Accessing core internal information

If you need the number of TCP packets or any other global counts defined in 2stats.h, which is included in t2Plugins.h every plugin includes. So no dependency is needed.

$ tranalyzer2
$ vi src/t2stats.h

So if you need any of these variables, which denote the aggregated counts over all packets up to the time of request, just use them. BUT NEVER EVER WRITE TO THEM !!! We give you as developer the freedom to access core variables and function as we do not try to treat programmers as airbus treats pilots. So we give you access, please treat the anteater respectfully.

Accessing other plugins information

If you need the number of TCP packets or any other global counts defined in t2stat.h, no dependency is needed.

For plugins, a bit differently. Hence, the following rules apply:

  • the plugin supplying data must have a number lower than yours
  • the header file (pluginName.h) of the plugin must be included at the beginning of your plugin
  • Replace T2_PLUGIN_INIT(...) with T2_PLUGIN_INIT_WITH_DEPS(...) (and add the dependencies)
  • the path of the plugin must be added in your Makefile.am
  • variables you are interested in must be declared as extern ... __attribute__((weak));

It may sound complicated, but it actually is not. Just stick to the plugin coding rules and you’ll be fine.

In this example, we will add a dependency to the basicStats plugin, to access the number of transmitted packets numTPkts. Open your tcpWin.c and replace T2_PLUGIN_INIT(...) with T2_PLUGIN_INIT_WITH_DEPS(...). Just add the lines marked by <--

So we can use the basicStats flow struct now. Open tcpWin.c and add the lines marked by <-- in the onFlowTerminate(...) callback function. There we define a pointer to the struct of that very flowIndex. Then we replace tcpWinFlowP->pktTcpCnt with bSFlowP->numTPkts.

and add an output column for the relative windowsize threshold measure in the printHeader.

That’s it for the code part. Now we need to tell the compiler what we want:

For meson add the depending plugin in the inc statement in meson.build

$ tcpWin
ä vi meson.build
inc = include_directories(
    join_paths('..', '..', 'utils'),
    join_paths('..', '..', 'tranalyzer2', 'src'),
    join_paths('..', 'basicStats', 'src'), # <--

For cmake in the target_include_directories of CMakeLists.txt

$ vi CMakeLists.txt

And for autotools open the Makefile.am and add the path to the source of the basicStats plugin in libtcpWin_la_CFLAGS as outlined below

$ vi src/Makefile.am
lib_LTLIBRARIES = libtcpWin.la

libtcpWin_la_SOURCES = tcpWin.c

libtcpWin_la_CFLAGS = \
        -I$(top_srcdir)/../../utils \

libtcpWin_la_CFLAGS += -D_DARWIN_C_SOURCE  # OSX specific flags
libtcpWin_la_CFLAGS += -D_GNU_SOURCE

libtcpWin_la_LDFLAGS = -shrext .so  # extension for shared library

Then your plugin does its job for all build methods. Fine, now try to build your changes and see whether it complains. If all is good run t2 on the pcap, otherwise, debug. If you have difficulties, please don’t hesitate to send the Anteater an mail.

$ t2build tcpWin
$ t2 -r ~/data/annoloc2.pcap -w ~/results

Change to your results window and look at the flow file.

$ tcol annoloc2_flows.txt

You will notice that the relative measure matches the ones from previous tutorials.

Make your Plugin a dependency

This is very easy, open tcpWin.h and look at the end of the file:

The extern tcpWinFlow_t *tcpWinFlows; statement assures that whoever includes your tcpWin.h file will have access to the tcpWinFlow_t flow memory. Any plugin global variable or structure you define here as extern is in principle available for other plugins to access.

The real pointers to the whole struct flow memory have to be defined in your tcpWin.c file as global variables.

So the tcpWinFlows structure of tcpWin was already eligible as a dependency.

Have fun!

The next tutorial will teach you how to write a sink plugin

See Also