PMACCT PLUGIN WRITING HOW-TO

SHORT OVERVIEW
pmacct plugin architecture is thought to allow to implement own
backends without knowing much of core collectors functionalities
and independently by other plugins. Below are listed a few steps
to hook a new plugin in pmacct; pmacct is also extremely open to
new ideas, so if you wish to contribute your work, you will be the
most welcome. 

- minor hacks to configure.in script following the example of what
  has been done there for mysql plugin; same goes for requirements
  like paths to headers or libraries. By making use of the PLUGINS
  variable, it will not be required to touch the "src/Makefile.am"
  script. Definitions in configure.in (ie. AC_DEFINE(WITH_MYSQL, 1))
  whose existence can be checked via compiler preprocessor is an
  easy way to propagate user configuration choices at compilation
  time.

- [OPTIONAL] If the plugin needs to take configurable values, this
  can be achieved by defining configuration handlers (pmacct-data.h,
  cfg_handlers.h, cfg_handlers.c) and declaring config variables to
  deliver configured values to the plugin (cfg.h, struct configuration).
  If command-line parameters are also required, some getopt() related
  code needs to be dealt with (pmacct-defines.h and ie. pmacctd.c,
  nfacctd.c, sfacctd.c and uacctd.c). 
  
- Define the new plugin in pmacct; this can be done by adding an
  entry to the plugin_types_list[] array (pmacct-data.h). An entry
  consists of two fields: an id string and a pointer to a function
  to be called. The first is the string which will be used to call
  the plugin from within the configuration or command-line. The
  second is effectively the entry point to the plugin.

- [OPTIONAL] If the plugin needs any checks that require visibility
  in the global configuration for example for compatibility against
  other plugins instantiated (ie. tee plugin not compatible with any
  plugins) or the daemon itself (ie. nfprobe plugin only supported
  in pmacctd and uacctd daemons), such checks can be performed in
  the daemon code itself (ie. pmacctd.c, nfacctd.c, etc. - look in
  these files for the "PLUGIN_ID" string for examples). 

- Develop the plugin code. One of the existing plugins can be used
  as reference - of course, as long as the purpose of the plugin
  under development is same or similar in function (ie. data is
  extracted from the circular buffer, then aggregated and cached in
  memory for a configurable amount of time, ie. print_refresh_time, 
  and finally purged to the backend. Structures for parsing data
  coming out of the circular buffer are defined in the network.h
  file; structures for data caching are in print_common.h (at least
  three generations of caches were conceived over time: first the
  one used in the memory plugin; second the one used in SQL plugins,
  rich in features but challenging to control in size; third, and
  current, the one used in print, MongoDB and AMQP plugins which is
  defined, as said, in print_common.h). The basic layout for the
  main plugin loop can be grasped in the print_plugin.c file by
  looking at content of the "for (;;)" loop. 
