/*

Copyright (C) 2000 - 2004 Christian Kreibich <christian@whoop.org>.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies of the Software and its documentation and acknowledgment shall be
given in the documentation and software packages that this Software was
used.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

*/
#ifndef __libnd_filter_h
#define __libnd_filter_h

#include <libnd_types.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

typedef enum {
  LND_FILTER_MODE_AND,
  LND_FILTER_MODE_OR
} LND_FilterMode;
 
/**
 * LND_FilterInitFunc - function to initialize a stateful filter.
 * @filter: filter to initialize.
 * @trace: trace to initialize the filter for.
 * @filter_data: filter-specific data.
 *
 * This is the signature for filter initializers.
 *
 * Returns: %TRUE when initialization was successful,
 % FALSE otherwise.
 */
typedef gboolean (*LND_FilterInitFunc)(LND_Filter *filter,
				       LND_Trace *trace,
				       void *filter_data);


/**
 * LND_FilterFunc - function prototype used by the filters.
 * @filter: filter to apply.
 * @packet: packet to filter.
 * @filter_data: filter-specific data.
 *
 * This is the signature for filter hooks.
 *
 * Returns: TRUE if the packet passes the filter, FALSE otherwise.
 */
typedef gboolean (*LND_FilterFunc)(LND_Filter *filter,
				   LND_Packet *packet,
				   void *filter_data);


/**
 * LND_FilterCleanupFunc - function to cleanup a stateful filter.
 * @filter: filter to clean up.
 * @filter_data: filter-specific data.
 *
 * This is the signature for filter cleanup callbacks.
 */
typedef void (*LND_FilterCleanupFunc)(LND_Filter *filter,
				      void *filter_data);


/**
 * LND_FilterFreeFunc - function to free filter data.
 * @filter_data: filter-specific data.
 *
 * This is the signature for callbacks called when a filter
 * is released, to clean up the filter data the filter was using.
 */
typedef void (*LND_FilterFreeFunc)(void *filter_data);


struct lnd_filter
{
  /* Name of this filter */
  char                   *name;

  /* Init function, run before iterated over a trace's packets */
  LND_FilterInitFunc      filter_init;
  /* Actual filtering function, called for each packet */
  LND_FilterFunc          filter_func;
  /* Cleanup, called after a trace is filtered */
  LND_FilterCleanupFunc   filter_cleanup;

  LND_FilterFreeFunc      filter_data_free;
  void                   *filter_data;

  LND_FilterFactory      *factory;
};  


/**
 * libnd_filter_new - creates a new packet filter.
 * @name: name of the filter.
 * @filter_init: initialization function to run before packets are iterated.
 * @filter_func: actual filter function, run on every packet.
 * @filter_cleanup: cleanup function, run after packets are iterated.
 * @filter_data_free: cleanup function for filter data.
 * @filter_data: arbitrary user data the filter might require.
 *
 * The function creates and returns a new filter with the given callbacks
 * that implement the filter behaviour. If you don't require some of the
 * functionality (e.g., when your filter is not stateful) then just pass
 * %NULL. @filter_data can be any data structure that contains the state
 * your filter requires for operation. It is cleaned up when the filter
 * is destroyed, using a call to @filter_data_free().
 *
 * Returns: new filter, or %NULL if an error occurred.
 */
LND_Filter *libnd_filter_new(const char *name,
			     LND_FilterInitFunc filter_init,
			     LND_FilterFunc filter_func,
			     LND_FilterCleanupFunc filter_cleanup,
			     LND_FilterFreeFunc filter_data_free,
			     void *filter_data);

/**
 * libnd_filter_free - releases a filter.
 * @filter: filter to release.
 * 
 * The function releases all memory that @filter occupies.
 */
void        libnd_filter_free(LND_Filter *filter);

/**
 * libnd_filter_set_factory - sets a filter's factory.
 * @filter: filter whose factory to set.
 * @factory: @filter's new factory.
 *
 * If your filter is created through a factory, the factory should
 * call this function to make sure there is a connection from an
 * instantiated filter to the factory that created it.
 */
void        libnd_filter_set_factory(LND_Filter *filter, LND_FilterFactory *factory);

/**
 * libnd_filter_apply - applies a filter to a packet.
 * @filter: filter to apply.
 * @packet: packet to apply filter to.
 *
 * The function applies @filter to @packet.
 *
 * Returns: %TRUE when the packet passed the filter, %FALSE
 * otherwise.
 */
gboolean    libnd_filter_apply(LND_Filter *filter, LND_Packet *packet);

/**
 * libnd_filter_list_apply - applies a list of filters to a packet.
 * @filters: list of filters to apply.
 * @packet: packet to apply filter to.
 * @mode: mode to use for filtering.
 *
 * The function applies @filters to @packet. @filters is assumed
 * to be a list of LND_Filter*s. Depending on @mode, the function
 * returns %TRUE only when @packet passes all filters
 * (%LND_FILTER_MODE_AND), or when it passes at least one filter
 * (%LND_FILTER_MODE_OR).
 *
 * Returns: %TRUE when the packet passed the filter, %FALSE
 * otherwise.
 */
gboolean    libnd_filter_list_apply(GList *filters,
				    LND_Packet *packet,
				    LND_FilterMode mode);

/**
 * libnd_filter_list_init - initializes a list of filters.
 * @filters: list of filters to initialize.
 * @trace: trace to initialize with.
 *
 * The function initializes all filters for @trace.
 */
void        libnd_filter_list_init(GList *filters, LND_Trace *trace);

/**
 * libnd_filter_list_cleanup - cleans up state for a list of filters.
 * @filters: list of filters to clean up.
 *
 * The function cleans up the state of all filters int @filters.
 */
void        libnd_filter_list_cleanup(GList *filters);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif
