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.
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. |
--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. |
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 ... |
![]() | Using the output of lndtool --cflags|--libs provides all the compiler/linker flags you need to pull in the dependencies (libpcapnav and glib). You do not need to add extra checks and flags for those dependancies in your build scripts. |
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' |
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.
#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; } |
lndtool --run Boofar-App mytracefile.trace Opening trace file mytracefile.trace. |
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.