libnetdude
This chapter explains how to build libnetdude
, what parts of libnetdude
end up where on your system when you install it, and how to
build other programs that use libnetdude
.
libnetdude
Building libnetdude
will hopefully be easy. libnetdude
has two dependencies,
make sure these are installed before you try to build your copy:
glib, version 1.2.10 or higher. Download it from gtk.org or just grab an RPM/DEB for it. Do not forget the development packages if your distibution uses those, since you will need the header files during the build process.
libpcapnav, downloadable from netdude.sf.net.
The build itself is made using the common ./configure && make
&& make install sequence. Check ./configure --help
for a list of available options, particularly the --with-pcapnav...
options to specify a libpcapnav
that's installed in an unusual location.
The installation places files in the following locations (the full path depends on what --prefix option you passed to configure. The default value is /usr/local):
$prefix/lib/: the core library, in static and dynamic linking versions (unless disabled at configuration time).
$prefix/include/libnetdude/VERSION: header files of the core library.
$prefix/include/libnetdude/VERSION/protocols: header files of protocol plugins that are part of the core distribution.
$prefix/include/libnetdude/VERSION/plugins: header files of feature plugins that are part of the core distribution.
$prefix/share/libnetdude/VERSION/protocols: DLLs of protocol plugins that are part of the core distribution.
$prefix/share/libnetdude/VERSION/plugins: DLLs of feature plugins that are part of the core distribution.
$prefix/bin: the lndtool program.
libnetdude
comes with a tool for querying the local libnetdude
installation:
lndtool. Have a look at its command line options:
lndtool -- libnetdude configuration and execution tool. USAGE: lndtool [OPTIONS] --help, -help, -h, -? This message. --prefix Installation prefix. --version, -v Prints out version info. --cflags Preprocessor flags needed for compilation. --libs Linker flags needed when linking.. --plugin-dir Plugin installation directory. --proto-dir Protocol installation directory. --include-dir Header files directory. --plugins Lists all plugins that register successfully. --run, -r PLUGINNAME PARAMS Run plugin PLUGINNAME with PARAMS. |
libnetdude
uses
a separate program (and it is a binary executale, not a shell script)
because in the case of libnetdude
you may want to query settings that
require libnetdude
to be loaded and initialized, such as listing the
installed plugins. lndtool behaves just like
a libnetdude-config would, but has two additional
features:
--plugins: this option lists all the plugins currently installed that register themselves successfully.
--run,-r PLUGINNAME [PARAMS]: this options allows you to run the feature plugin PLUGINNAME directly from the command line. Additional parameters are wrapped in a LND_PluginArgs structure and passed to the plugin. This shortcut significantly increases code modularity for reasons explained in the next section.
Plugin name lookups are case-insensitive. |
libnetdude
In this section, we'll first look at how you can check for libnetdude
in autoconf scripts. Then we get a bit technical
and explain how linking to the library and its plugins works.
If you are using the autoconf/automake
tools to configure your package, use the following check to
detect libnetdude
:
dnl ################################################## dnl # Check for libnetdude dnl ################################################## AC_ARG_WITH(lndtool, AC_HELP_STRING([--with-lndtool=FILE], [Use given lndtool]), [ lndtool="$withval" ], [ AC_PATH_PROG(lndtool, lndtool, AC_MSG_ERROR(Cannot find lndtool: is it in path?)) ]) LIBNETDUDE_CFLAGS=`$lndtool --cflags` LIBNETDUDE_LIBS=`$lndtool --libs` AC_SUBST(LIBNETDUDE_LIBS) AC_SUBST(LIBNETDUDE_CFLAGS) # same for any other options you require ... |
libnetdude
requires in your
Makefile.am using
@LIBNETDUDE_CFLAGS@ and
@LIBNETDUDE_LIBS@.
Using the output of lndtool --cflags|--libs provides all the
compiler/linker flags you need to pull in the dependencies ( |
libnetdude
and its Plugins Let's assume you are writing a program that uses libnetdude
and you want
to link your compiled object files with libnetdude
(we assume shared libraries here).
If your program uses only symbols (functions, globals, etc) from libnetdude
itself, this is not a problem: you simply use the linker flags provided
by lndtool --libs. However, if you are using symbols
from plugins, things are more tricky. Say we have a plugin called Boofar that
defines functions libnd_boofar_foo(LND_Trace *)
and
libnd_boofar_bar(LND_Trace *)
in a header file called libnd_boofar.h. Consider the
following code that opens a trace file passed on the command line (without
error checking, shame on them), and then passes the opened trace to these
two functions before closing the trace.
#include <libnd.h> #include <plugins/libnd_boofar.h> int main(int argc, char **argv) { LND_Trace *trace; libnd_init(); trace = libnd_trace_new(argv[0]); libnd_boofar_foo(trace); libnd_boofar_bar(trace); libnd_trace_free(trace); return 0; } |
/tmp/ccnIJufv.o(.text+0xa6): In function `main': : undefined reference to `libnd_boofar_foo' /tmp/ccnIJufv.o(.text+0xc0): In function `main': : undefined reference to `libnd_boofar_foo' |
libnetdude
bootstraps, hence the plugin's symbols are not found when linking. There
are two possible solutions to this problem:
Pass the plugin's shared object file when linking. This is
ugly for a number of reasons. You need to know the names of Boofar's
binary files. You need to make sure that your executable will find
them when it starts (likely using --rpath magic). Passing the plugin
binaries to the linker does not make sense, since libnetdude
will dynamically
link in the plugins when initialized. Worst of all, you
also need to pass the binary files of any other plugins that Boofar
requires.
In the end this approach boils down to passing all installed plugin binaries to the linker, defeating the intention of the plugins. This approach therefore is not acceptable.
Do not link your code into a standalone executable. This sounds
odd, but when you link the code into a shared executable, the linker
will not complain about unresolved symbols and defer the linking until
runtime. In short, your program becomes another plugin, which is exactly
the purpose of libnetdude
's modular design. To run your program, you then
use a wrapper program that calls your plugin on your behalf. Remember
lndtool --run, described in the previous section?
Now you know its purpose.
libnetdude
feature plugin structure:
#include <libnd.h> #include <plugins/libnd_boofar.h> const char * name(void) { return "Boofar-App"; } gboolean run(LND_Trace *unused, LND_PluginArgs *args) { LND_Trace *trace; printf("Opening trace file %s.\n", trace->filename); trace = libnd_trace_new(args->argv[0]); libnd_boofar_foo(trace); libnd_boofar_bar(trace); libnd_trace_free(trace); return TRUE; } |
libnetdude
plugin, for example using
the code template provided on the SourceForge site. Otherwise there is
no difference: your build environment will have to check for libnetdude
anyway.
The linker does not
find the Boofar symbols, but this time it does not complain. After installing the
plugin, you can then run your app using lndtool like this:
lndtool --run Boofar-App mytracefile.trace Opening trace file mytracefile.trace. |
libnetdude
's Testsuite Should you decide to delve into hacking libnetdude
itself (yay!), you'll want to have
a look at the contents of the test directory in the source tree.
It contains a few programs that can be built using make tests
and that are not installed. These programs are:
lnd-test: a test driver that consists of a set of
functions that exercise several aspects of the library, primarily
trace part management and trace navigation. More tests are highly welcomed
contributions, and may make the authors more apt to supporting extensions
of the library using the bribery method explained in the chapter on
libnetdude
Plugins.
lnd-test-filter: a small demo/test program that
shows how to use the libnetdude
filter API.
lnd-test-plugins: a helper app that prints the names, versions, and authors of the installed feature and protocol plugins to the console.
lnd-dump: a helper app gives you the equivalent of running tcpdump on a trace file, printing out the familiar ouput for each packet. Additionally, you get the offset of the packets (absolutely and relatively to the end of the pcap savefile header) prepended to the line. Have a look at lnd-dump.c and see how easy the code is.