/*
 * Copyright (c) 2004-2005 Endace Technology Ltd, Hamilton, New Zealand.
 * All rights reserved.
 *
 * This source code is proprietary to Endace Technology Limited and no part
 * of it may be redistributed, published or disclosed except as outlined in
 * the written contract supplied with this product.
 *
 * $Id: filters.h 11724 2009-08-06 05:37:39Z wilson.zhu $
 */
/** \defgroup PFAPI Packet Filtering API
 */
/*@{*/
/**
 * \brief High-level filter processing
 *
 * Data types and functions used when processing high-level filters
 * (Endace rules) to convert them into low-level
 * filter rules (i.e. CAM entries).
 *
 * Display functions for some data types.
 */
#ifndef FILTERS_H
#define FILTERS_H

/* Project headers. */
#include "filter_rule_types.h"

/** \defgroup PFHLP High-level filter processing
 */
/*@{*/
/**
 * Array of CAM entries
 * TODO: move it to dag_filter.h and use it instead of cam_entry_t
 */
typedef struct cam_array_t
{
	uint32_t count; /**< number of entries in the array */
	cam_entry_t** entries; /**< Valid entries are in [1]..[count]. */

} cam_array_t;

/**
 * Array of addresses (covering a certain range, for example)
 */
typedef struct addr_array_t
{
	unsigned int count; /**< number of entries in the array */
	ip_address_t* entries; /**< Array of ip_address_t */

} addr_array_t;

/**
 * Array of ports (covering a certain range, for example)
 */
typedef struct port_array_t
{
	unsigned int count; /**< number of entries in the array */
	cam_port_t* entries; /**< Array of cam_port_t */

} port_array_t;

/**
 * Temporary filter entry
 *
 * It is used to help building the real CAM entries for each rule
 */
typedef struct temp_filter_entry_t
{
	struct temp_filter_entry_t* next; /**< For building the list. */
	filter_rule_t* rule; /**< The rule that this cam entry relates to. */

	uint16_t exact_colour;
	addr_array_t src_addresses;  /**< List of matching source IP addresses. */
	addr_array_t dst_addresses;  /**< List of matching destination IP addresses. */
	port_array_t src_ports;      /**< List of matching source ports. */
	port_array_t dst_ports;      /**< List of matching destination ports. */

	cam_entry_t cam_entry;

} temp_filter_entry_t;

/**
 * List of temporary filter entries
 */
typedef struct temp_filter_list_t
{
	temp_filter_entry_t* head; /**< first item in the list */
	temp_filter_entry_t* tail; /**< last item in the list */

} temp_filter_list_t;

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

/** \defgroup PFFPF High-level filter processing functions
 */
/*@{*/

/**
 * Create a temporary filter entry 
 *
 * \param rule  filter rule to be used
 * \return pointer to temporary filter entry
 */
temp_filter_entry_t* new_temp_filter_entry(filter_rule_t* rule);

/**
 * Dispose temporary filter entry
 *
 * Free all buffers associated with the temporary filter emtry
 *
 * \param temp_entry temporary filter entry
 */
void dispose_temp_filter_entry(temp_filter_entry_t* temp_entry);


/**
 * Create port filter entries
 *
 * Determine how many CAM entries are required to deal with this port
 * definition.  Return the relevant ports in an array.
 *
 * \param result pointer to array of port entries for CAM
 * \param port   pointer to port definition
 */
void create_port_filter_entries(port_array_t* result, ipf_port_t* port);

/**
 * Create address filter entries
 *
 * Determine how many CAM entries are required to deal with this
 * address definition (consider the don't care bits replaced with all
 * the combinations of exact matches). Prepend the relevant addresses
 * to the address list.
 *
 * \param result      pointer to array of addressport entries for CAM
 * \param temp_entry  pointer to temporary filter entry
 * \param inverse     whether to invert bits in the address
 * \param head        pointer to head of IP address list
 */
void create_address_filter_entries(addr_array_t* result,
                                   temp_filter_entry_t* temp_entry,
                                   uint8_t inverse,
                                   list_node_t* head);

/**
 * Expand temporary filter entry
 *
 * Create one CAM entry for each (source IP, dest IP, source port,
 * dest port) combination and append it to the CAm entry list.
 *
 * \param list         pointer to list of filters
 * \param temp_filter  pointer to temporary filter entry
 */
void expand_temp_filter_entry(temp_filter_list_t* list, temp_filter_entry_t* temp_filter);

/************************ Debugging ************************/
/* TODO: separate file? */

/**
 * Display filter IP address definition
 *
 * Print the IP address definition in ASCII as binary number, using '-' for don't-care bits.
 *
 * \param outfile  FILE pointer to print to
 * \param address  pointer to the IP address definition
 */
void display_filter_ip_address(FILE* outfile, ip_address_t* address);

/**
 * Display filter port definition
 *
 * Print the port definition in ASCII  as binary number, using '-' for don't-care bits.
 *
 * \param outfile  FILE pointer to print to
 * \param port     pointer to the port definition
 */
void display_filter_port(FILE* outfile, cam_port_t* cam_port);

/**
 * Display filter TCP flags definition
 *
 * Print the flags defintion in ASCII  as binary number, using '-' for don't-care bits.
 *
 * \param outfile   FILE pointer to print to
 * \param tcp_flags pointer to the TCP flags definition
 */
void display_filter_tcp_flags(FILE* outfile, tcp_flags_t* tcp_flags);

/**
 * Display high-level filter entry 
 *
 * Print the ASCII representation of a high-level filter entry, i.e. a filter rule.
 * TODO: rename it to display_cam_entry
 *
 * \param outfile  FILE pointer to print to
 * \param entry    pointer to the filter entry
 */
void display_filter_entry(FILE* outfile, cam_entry_t* entry);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* FILTERS_H */
/*@}*/
/*@}*/
/*@}*/

