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.
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:
netdude --plugin-dir: this outputs the system-wide directory in which feature plugins are installed.
netdude --proto-dir: this outputs the system-wide directory in which protocol plugins are installed.
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.
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:
name: implement this function by returning a string containing the name of your plugin. This is the string that will show up in Netdude's menus.
description: implement this function by returning a string containing a brief description of your plugin. Don't forget to add the gettext macros around it, so that it can be translated.
author: implement this function by returning a string containing the plugin author's name.
version: implement this function by returning a string containing the plugin's version number.
run: this is where the bread meets the butter. This callback is called when you click on your plugin's menu item. It receives the currently edited trace as the only parameter. Inside that function, you can do whatever you need to provide the functionality intended.
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; } |
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)