  <chapter>
    <title id="ch-using">Using &lnd;</title>
    <para>
      This chapter explains how to build &lnd;, what parts of &lnd;
      end up where on your system when you install it, and how to
      build other programs that use &lnd;.
    </para>
    <sect1>
      <title>Building &lnd;</title>
      <para>
      Building &lnd; will hopefully be easy. &lnd; has two dependencies,
      make sure these are installed before you try to build your copy:

      <itemizedlist>
	  <listitem>
	    <para>
              <emphasis>glib</emphasis>, version 1.2.10 or higher.
              Download it from <ulink url="http://www.gtk.org">gtk.org</ulink>
              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.
            </para>
	  </listitem>
	  <listitem>
	    <para>
              <emphasis>libpcapnav</emphasis>, downloadable from
              <ulink url="http://netdude.sf.net">netdude.sf.net</ulink>.
            </para>
	  </listitem>
      </itemizedlist>
      </para>
      <para>
        The build itself is made using the common <command>./configure && make
        && make install</command> sequence. Check <command>./configure --help</command>
        for a list of available options, particularly the <command>--with-pcapnav...</command>
        options to specify a &pcapnav; that's installed in an unusual location.
      </para>
    </sect1>
    <sect1>
      <title>Installation Layout</title>
      <para>
        The installation places files in the following locations (the full path
	depends on what <command>--prefix</command> option you passed to
	<command>configure</command>. The default value is <filename>/usr/local</filename>):	
        <itemizedlist>
	  <listitem>
	    <para>
	      <filename>$prefix/lib/</filename>: the core library, in static and dynamic
	      linking versions (unless disabled at configuration time).
            </para>
	  </listitem>
	  <listitem>
	    <para>
	      <filename>$prefix/include/libnetdude/VERSION</filename>: header files of the
	      core library.
            </para>
	  </listitem>
	  <listitem>
	    <para>
	      <filename>$prefix/include/libnetdude/VERSION/protocols</filename>:
	      header files of protocol plugins that are part of the core
	      distribution.
            </para>
	  </listitem>
	  <listitem>
	    <para>
	      <filename>$prefix/include/libnetdude/VERSION/plugins</filename>:
	      header files of feature plugins that are part of the core
	      distribution.
            </para>
	  </listitem>
	  <listitem>
	    <para>
	      <filename>$prefix/share/libnetdude/VERSION/protocols</filename>:
	      DLLs of protocol plugins that are part of the core
	      distribution.
            </para>
	  </listitem>
	  <listitem>
	    <para>
	      <filename>$prefix/share/libnetdude/VERSION/plugins</filename>:
	      DLLs of feature plugins that are part of the core
	      distribution.
            </para>
	  </listitem>
	  <listitem>
	    <para>
	      <filename>$prefix/bin</filename>: the <command>lndtool</command> program.
            </para>
	  </listitem>
        </itemizedlist>
      </para>
    </sect1>
    <sect1>
      <title>The <command>lndtool</command> Program</title>
      <para>
        &lnd; comes with a tool for querying the local &lnd; installation:
        <command>lndtool</command>. Have a look at its command line options:
        <programlisting>
<![CDATA[
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.
]]>
        </programlisting>
        As you can see, most of the options look familiar from package
        configuration scripts normally called &lt;package&gt;-config. &lnd; uses
        a separate program (and it is a binary executale, not a shell script)
        because in the case of &lnd; you may want to query settings that
        require &lnd; to be loaded and initialized, such as listing the
        installed plugins. <command>lndtool</command> behaves just like
        a <command>libnetdude-config</command> would, but has two additional
        features:
        <itemizedlist>
	  <listitem>
	    <para><command>--plugins</command>: this option lists all the
              plugins currently installed that register themselves successfully.
            </para>
          </listitem>
	  <listitem>
	    <para><command>--run,-r PLUGINNAME [PARAMS]</command>: this options
              allows you to run the feature plugin PLUGINNAME directly from the
              command line. Additional parameters are wrapped in a <type>LND_PluginArgs</type>
              structure and passed to the plugin. This shortcut significantly
              increases code modularity for reasons explained in the next section.              
            </para>
            <para>
             <note>
               <para>Plugin name lookups are case-insensitive.
	       </para>
             </note>
            </para>
          </listitem>
        </itemizedlist>
      </para>
    </sect1>
    <sect1>
      <title>Building Applications with &lnd;</title>
      <para>In this section, we'll first look at how you can check for &lnd;
        in <command>autoconf</command> scripts. Then we get a bit technical
        and explain how linking to the library and its plugins works.
      </para>
      <sect2>
        <title>Handy <command>autoconf</command> Code</title>
        <para>
        If you are using the <command>autoconf</command>/<command>automake</command>
	tools to configure your package, use the following check to
	detect &lnd;:
          <programlisting>
<![CDATA[
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 ...
]]>
          </programlisting>
	You can then use the compiler/linker flags that &lnd; requires in your
	<filename>Makefile.am</filename> using
	<computeroutput>@LIBNETDUDE_CFLAGS@</computeroutput> and
	<computeroutput>@LIBNETDUDE_LIBS@</computeroutput>.
        </para>
        <para>
          <note>
            <para>
	      Using the output of <filename>lndtool --cflags|--libs</filename> provides all the
	      compiler/linker flags you need to pull in the dependencies (&pcapnav; and glib).
	      You do not need to add extra checks and flags for those dependancies
              in your build scripts.
	    </para>
          </note>
        </para>
      </sect2>
      <sect2 id="plugin-linking">
        <title>Linking with &lnd; and its Plugins</title>
        <para>
          Let's assume you are writing a program that uses &lnd; and you want
          to link your compiled object files with &lnd; (we assume shared libraries here).
          If your program uses only symbols (functions, globals, etc) from &lnd;
          itself, this is not a problem: you simply use the linker flags provided
          by <command>lndtool --libs</command>. However, if you are using symbols
          from plugins, things are more tricky. Say we have a plugin called Boofar that
          defines functions <function>libnd_boofar_foo(LND_Trace *)</function> and
          <function>libnd_boofar_bar(LND_Trace *)</function>
          in a header file called <filename>libnd_boofar.h</filename>. 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.
          <programlisting>
<![CDATA[
#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;
}]]>
          </programlisting>
          At build time, the necessary declarations
          are taken from the plugin's header files (found because we pass the output
          of <command>lndtool --cflags</command> to the compiler), so the compilation
          completes
          fine. However, when you try linking your program, you will get something
          like this:
          <programlisting>
<![CDATA[
/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']]>
          </programlisting>
          The problem is that the Boofar plugin is loaded dynamically when &lnd;
          bootstraps, hence the plugin's symbols are not found when linking. There
          are two possible solutions to this problem:
          <itemizedlist>
	    <listitem>
	      <para>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 &lnd 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. 
              </para>
              <para> 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.
              </para>
            </listitem>
	    <listitem>
	      <para>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 &lnd;'s modular design. To run your program, you then
                use a wrapper program that calls your plugin on your behalf. Remember
                <command>lndtool --run</command>, described in the previous section?
                Now you know its purpose.
              </para>
            </listitem>
          </itemizedlist>
          Let's see how this works. We change the code to have a minimalistic but valid
          &lnd; feature plugin structure:
          <programlisting>
<![CDATA[
#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;
}]]>
          </programlisting>
          Now you compile and link this code as a &lnd 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 &lnd 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 <command>lndtool</command> like this:
          <programlisting>
<![CDATA[
lndtool --run Boofar-App mytracefile.trace
Opening trace file mytracefile.trace.]]>
          </programlisting>
          If you find this too cumbersome, wrap the call in a shell script as often
          done with Java applications and there's no visible difference.
        </para>
      </sect2>
    </sect1>
    <sect1>
      <title>&lnd;'s Testsuite</title>
      <para>
        Should you decide to delve into hacking &lnd; itself (yay!), you'll want to have
        a look at the contents of the <filename>test</filename> directory in the source tree.
        It contains a few programs that can be built using <command>make tests</command>
        and that are not installed. These programs are:
        <itemizedlist>
	  <listitem>
	    <para>
	      <filename>lnd-test</filename>: 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
              <link linkend="ch-plugins">&lnd Plugins</link>.
            </para>
	  </listitem>
	  <listitem>
	    <para>
	      <filename>lnd-test-filter</filename>: a small demo/test program that
              shows how to use the &lnd; filter API.
            </para>
	  </listitem>
	  <listitem>
	    <para>
	      <filename>lnd-test-plugins</filename>: a helper app that prints the names,
              versions, and authors of the installed feature and protocol plugins to
              the console.
            </para>
	  </listitem>
	  <listitem>
	    <para>
	      <filename>lnd-dump</filename>: 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 <filename>lnd-dump.c</filename> and see how easy the code is.
            </para>
	  </listitem>
        </itemizedlist>
      </para>
    </sect1>
  </chapter>
