/*

Copyright (C) 2000 - 2006 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_registry_h
#define __libnd_filter_registry_h

#include <libnd_types.h>

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

typedef enum {
  LND_FILTER_ADDED             = (1 << 0),
  LND_FILTER_DELETED           = (1 << 1)
} LND_FilterRegObserverOp;

typedef struct lnd_filter_reg_observer
{
  void  (*filter_added) (LND_Filter *filter);
  void  (*filter_deleted) (LND_Filter *filter);

} LND_FilterRegObserver;


/**
 * LND_FilterRegFunc - function prototype used by the filter registry.
 * @filter: filter passed in.
 * @user_data: user data.
 *
 * This is the signature for callbacks passed to
 * libnd_filter_registry_foreach().
 */
typedef void (*LND_FilterRegFunc)(LND_Filter *filter, void *user_data);


/**
 * libnd_filter_registry_init - initializes the filter registry.
 *
 * The filter registry is Netdude's central repository for currently
 * known packet filters. These can be implemented in any way desired,
 * the typical example is a BPF filter. This function sets up the
 * necessary data structures and is called when the library is
 * initialized.
 */
void       libnd_filter_registry_init(void);


/**
 * libnd_filter_registry_add - adds a filter to the registry.
 * @filter: the added filter.
 *
 * In order to register a filter in the registry, use this function.
 * It checks if the filter is already registered and in that case,
 * simply returns.
 */
void       libnd_filter_registry_add(LND_Filter *filter);


/**
 * libnd_filter_registry_del - removes a filter from the registry.
 * @filter: filter to remove.
 *
 * Removes a filter from the registry.
 */
void       libnd_filter_registry_del(LND_Filter *filter);


/**
 * libnd_filter_registry_foreach - calls a function for each registered filter.
 * @callback: a function of type #LND_FilterRegFunc
 * @user_data: arbitrary data passed through to the callback
 *
 * The function calls @callback for every trace currently registered
 * and passes it as first argument. The second argument is the user data,
 * which is simply passed through.
 */
void       libnd_filter_registry_foreach(LND_FilterRegFunc callback, void *user_data);


/* -------------------------- Filter Registry Observers ---------------------- */


/**
 * libnd_filter_reg_observer_new - creates new filter registry observer.
 *
 * The function allocates a new, empty filter observer. You should
 * then fill in callbacks for the events you're interested in,
 * and register it using libnd_filter_reg_add_observer().
 */
LND_FilterRegObserver *libnd_filter_registry_observer_new(void);

/**
 * libnd_filter_registry_observer_free - deleted filter observer.
 * @ob: observer to delete.
 * 
 * The function releases all memory associated with @ob.
 */
void            libnd_filter_registry_observer_free(LND_FilterRegObserver *ob);


/**
 * libnd_filter_registry_add_observer - registers a new filter observer.
 * @ob: new observer to register.
 *
 * The function registers the new observer for notifications about
 * future changes to the filter registry.
 */
void            libnd_filter_registry_add_observer(LND_FilterRegObserver *ob);

/**
 * libnd_filter_registry_del_observer - deletes a filter registry observer.
 * @ob: observer to drop.
 *
 * The function stops filter registry updates from being reported to
 * @ob. It does not release @ob's memory, use libnd_filter_registry_observer_free()
 * for that. 
 */
void            libnd_filter_registry_del_observer(LND_FilterRegObserver *ob);

/**
 * libnd_filter_tell_observer - push operations to registered observers.
 * @filter: filter to report operation on.
 * @op: operation type.
 *
 * The function reports the given operation on the given filter to all
 * registered observers.
 */
void            libnd_filter_registry_tell_observers(LND_Filter *filter, LND_FilterRegObserverOp op);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif
