Next Previous Contents

1. DESIGN

1.1 Concept

I want to provide a flexible, almost universal logging daemon for netfilter ULOG target. Although it provides wide range of functions I'm trying to keep it as simple as possible. These are my thoughts about how the architecture which is most capable of doing that:

Input plugins

It should be possible to add plugins / runtime modules for new protocols, etc. For example the standard logging daemon provides source-ip, dest-ip, source-port, dest-port, etc. Logging for variuos other protocols (GRE, IPsec, ...) may be implemented as modules.

Output plugins

... describe how and where to put the information gained by input plugins. The easiest way is to build a line per packet and fprint it to a file. Some people might want to log into a SQL database or want an output conforming to the intrusion detection systems communication draft from the IETF.

1.2 Details

The major clue is providing a framework which is as flexible as possible. Nobody knows what strange network protocols are out there :) Flexibility depends on the communication between the output of the input plugins and input of the output plugins.

Harald, following Rusty's advise, implemented type-key-value triples, which work quite well for that purpose. Structure used for exchanging data between input and output plugins is defined in specter.h, and is called specter_iret_t. Most of time, output plugins precisely know what data they need, so there must exist good querying system, as input keys are dynamically defined and stored. Up to ulogd 0.3 this was done by several linked list iterations, which weren't obviously very fast. In 0.9 Harald implemented usage of hash tables initialized during init. The idea was good, but deep levels of data structures one had to dig into to get simple value and somewhat obscure style (like accessing ulogd_keyh[] from the inside of plugin) forced me (Michal) to rewrite this again. That's when fork from ulogd happened. Abandoning hash tables, specter implementation use only pointers accessed by general function find_iret(). To simplify usage of that pointers, simple data structure specter_local_ret_t and few macros defined in plugins/lret.h were also created. Note they're not the obligatory extension; one can create his own implementation based on single find_iret() definition.

Important part of specter is dynamic division into execution groups. Each group have its own set of plugins, which are invoked independently. That also means they have separate sets of configure options and data. This model allows you to set various iptables rules and bind different actions for them. Currently there are two methods of grouping implemented - one based on netlink groups, other on the netfilter marks. See the grouping option description for details. This functionality allows you to adjust specter strictly to your needs - it can be small and simple substitute to netfilter LOG target or universal utility to distribute large portions of logs.


Next Previous Contents