Extending Netdude

Table of Contents
Writing A Feature Plugin
Writing a Protocol Plugin

Netdude is designed to provide a core set of functionality upon which protocol and feature support can be built in a modularized fashion. The mechanism used to achieve this is the dynamic linker library, libdl. Well actually it's the libtool wrapper, libltdl [Libtool]. No comments please. Therefore, Netdude plugins come as platform-dependant normal binary code in shared libraries. They are not interpreted scripts.

Note

You can find code templates for Netdude feature and protocol plugins on the Netdude site. They provide a working autoconf/automake setup that takes care of installing things in the right place.

When Netdude starts, it scans specific directories for plugins, dynamically opens them and looks for special symbols, actually hooks that provide callback implementations. The plugins are then initialized and hooked into the GUI as menu entries or, depending on the code, perform something else. The directories Netdude looks at can always be obtained by issuing the following commands, either at the command line or in your build scripts:

Usually the names will be /usr/share/netdude/plugins and /usr/share/netdude/protocols, or the /usr/local versions thereof. To allow users to install plugins privately, the directories ~/.nd/plugins and ~/.nd/protocols can also be used.

You can always check if a plugin was loaded correctly by looking at Netdude's About menu, which will list the loaded plugins and display info dialogs about them upon request:

Netdude's About menu.


Writing A Feature Plugin

Netdude plugins basically only need to provide one big hook that serves as the entry point into the plugin. In that callback implementation, the plugin can do anything the author desires -- usually this will be a GUI front end to some code that iterates over packets, manipulates packets, gathers statistics, etc.

Writing a feature plugin for Netdude is easy, assuming you have reasonable knowledge of the Netdude API (see also the API documentation). Again, you should probably start by downloading the plugin template from the download page.

Extract the tarball. If you want to keep multiple plugins in your package, add a directory for each one and update configure.ac/configure.in and the Makefile.ams accordingly. Details of handling the auto* tools are beyond the scope of this document, please consult the appropriate documentation [Autoconf] [Automake]. If you feel you're in trouble, please ask for help on the Netdude mailing lists. For the rest of this section we'll assume that you have a working build environment for your plugin(s).

The following piece of code, taken from nd_plugin.h, lists the callbacks you can provide in your plugin. You may leave out some if you wish, they all get initialized to no-ops by default.

typedef struct nd_plugin
{
  const char *(*name) (void);
  const char *(*description) (void);
  const char *(*author) (void);
  const char *(*version) (void);

  int         (*run) (ND_Trace *trace);

  char        *filename;
  lt_dlhandle  lt;

} ND_Plugin;
  

You don't need to worry about filename and lt, they're used internally by Netdude. The other function pointers are pretty much self-explanatory:

Caution

You must use the names given above for these hooks, otherwise Netdude won't find them when scanning the plugins!

The code of the plugin template is shown below. It outputs a message in the status bar every time you activate it, counting the number of times you activated it.


/* Enable debugging output */
#define ND_DEBUG 1

#include <nd.h>
#include <nd_gui.h>

/* This is a basic Netdude plugin skeleton, tweak as you see fit!
 * You don't need to fill in everything, the default functions simply
 * do nothing. The return values are currently not used, except for
 * name() of course.
 *
 * At the shell prompt, you can always find out where plugins are
 * installed by typing "netdude --plugin-dir".
 */


/* Return the name of the plugin, to be displayed
 * in the Plugins menu.
 */
const char *
name(void)
{
  return "/Template Plugin";
}


const char *
author(void)
{
  return "You, <your@email.foo>";
}

const char *
version(void)
{
  return "0.1";
}


/* This function is automatically called when the plugin is registered.
 * You can perform an initialization that your plugin requires here.
 * The return value is currently ignored.
 */
int
init(void)
{
  D(("Template plugin initialized.\n"));
  return 0;
}

/* Here's where the action is -- run() is called to launch the plugin. 
 * The return value is currently ignored.
 */
int
run(LND_Trace *trace)
{
  static int counter = 0;
  char message[MAXPATHLEN];

  g_snprintf(message, MAXPATHLEN, "Template Plugin called %i times.", ++counter);
  nd_gui_statusbar_set(message);

  return 0;
}
    

Writing a Protocol Plugin

To be written, sorry. Please have a look at the existing code in the meantime, or try writing a feature plugin, it's fun :o)