/*

Copyright (C) 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_tanalyzer_h
#define __libnd_tanalyzer_h

#include <libnd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>

/* We need the connection tracker plugin and
 * trace set plugins.
*/
#include <plugins/libnd_conntrack.h>
#include <plugins/libnd_traceset.h>

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

/* Two structures for UDP/TCP port number analysis */
typedef struct lnd_ta_conn
{
  guint16      sport;
  guint16      dport;
  gboolean     is_tcp;
  
} LND_TAConn;


typedef struct lnd_ta_data
{
  guint        packets_count;
  guint64      bytes_count;

} LND_TAData;


typedef struct lnd_tanalysis LND_TAnalysis;

/**
 * LND_TAProgressCallback - signature of callbacks that report progress of analysis.
 * @ta: analysis structure.
 * @done: how many of the registered traces have been analyzed.
 */
typedef void (*LND_TAProgressCB)(LND_TAnalysis *ta, int done, void *user_data);


/* Main analysis structure */
struct lnd_tanalysis
{
  LND_TraceSet      *traces;
  int                it_count;

  /* Callback to report progress */
  LND_TAProgressCB   cb;
  void              *cb_data;

  /* Configuration */
  gboolean           do_basic;
  gboolean           do_ip;
  gboolean           do_ports;
  gboolean           do_src_ports;
  gboolean           do_dst_ports;
  gboolean           do_flows;

  /* Statistics */
  guint64            packet_count;
  guint64            non_ip_packet_count;
  guint64            byte_count;
  guint64            non_ip_byte_count;

  /* Hash table that stores the connection data for
   * IP. The keys are the values of the IP protocol
   * field (8bit), data items are packet counters.
   * Both use the hash table pointers directly, so
   * no exta memory is used.
   */
  GHashTable        *ip_conns;  
  
  /* Hash table that stores the connection data for
   * TCP and UDP. Keys are ND_PAConn structures,
   * data items are ND_PAData structures.
   */
  GHashTable        *port_conns;
  GHashTable        *port_conns_dport;
  GHashTable        *port_conns_sport;

  /* Hash table for the TCP flow analysis. Managed
   * by the TCP Connection Tracker plugin.
   */
  LND_ConnTable     *tcp_conns;

};


/**
 * libnd_ta_new - creates new analysis structure.
 *
 * The function allocates and initializes a new analysis object. All
 * analysis parts are enabled by default.
 *
 * Returns: new structure, or %NULL on error.
 */
LND_TAnalysis  *libnd_ta_new(void);

/**
 * libnd_ta_free - releases an analysis structure.
 * @ta: structure to release.
 *
 * Use this function to release the memory of an analysis structure
 * obtained using libnd_ta_new().
 */
void            libnd_ta_free(LND_TAnalysis *ta);


/**
 * libnd_ta_set_traceset - sets a configured traceset for an analyzer.
 * @ta: analysis handle.
 * @set: traceset.
 *
 * The function makes the analyzer pointed to by @ta using @set
 * as the source of traces to analyze. The set is duplicated
 * internally.
 *
 * Returns: %TRUE on success, %FALSE otherwise.
 */
gboolean        libnd_ta_set_traceset(LND_TAnalysis *ta, const LND_TraceSet *set);


/**
 * libnd_ta_add_trace - adds an input trace to the analysis.
 * @ta: analysis handle.
 * @trace: trace to add.
 *
 * The function adds @trace to the traces analysed by the analysis
 * handle @ta. The trace does not become managed by @ta, thus you
 * need to release it yourself once you're done.
 *
 * Returns: %TRUE if successful, %FALSE if not.
 */
gboolean        libnd_ta_add_trace(LND_TAnalysis *ta, LND_Trace *trace);


/**
 * libnd_ta_add_trace_name - adds the name of a trace as input to the analysis.
 * @ta: analysis handle.
 * @file_name: name of trace to add.
 *
 * The function adds the trace named @file_name to the set of traces analysed
 * by the analysis handle @ta.
 *
 * Returns: %TRUE if successful, %FALSE if not.
 */
gboolean        libnd_ta_add_trace_name(LND_TAnalysis *ta, const char *file_name);


/**
 * libnd_ta_add_trace_name_list - adds the names of traces, taking from a file
 * @ta: analysis handle.
 * @file_name: list of a file containing names.
 *
 * The function adds the trace files listed in @file_name (one file name per line)
 * to the set of traces analysed by the analysis handle @ta.
 *
 * Returns: %TRUE if successful, %FALSE if not.
 */
gboolean        libnd_ta_add_trace_name_list(LND_TAnalysis *ta, const char *file_name);


/**
 * libnd_ta_set_progress_callback - registers progress callback.
 * @ta: analysis structure.
 * @callback: callback to register.
 * @user_data: data to pass to @callback.
 *
 * The function registers @callback to be called whenever the analysis @ta
 * completes one trace file.
 */
void            libnd_ta_set_progress_callback(LND_TAnalysis *ta,
					       LND_TAProgressCB callback,
					       void *user_data);

/**
 * libnd_ta_analyze - do an IP traffic analysis.
 * @ta: analysis handle.
 *
 * The function scans all packets in the traces added to the analysis
 * handle using libnd_ta_add_trace() and accumulates statistics on
 * packets, payload sizes, IP protocol usage, TCP flows, etc, depending
 * on which parts of the analysis are enabled. To serialize the results
 * into an output stream, use libnd_ta_write_results().
 *
 * Returns: %TRUE on success, %FALSE on error.
 */
gboolean        libnd_ta_analyze(LND_TAnalysis *ta);

/**
 * libnd_ta_do_all - set flags for all analysis parts.
 * @ta: analysis handle.
 *
 * The function sets the flags for all analysis components to %TRUE.
 */
void            libnd_ta_do_all(LND_TAnalysis *ta);

/**
 * libnd_ta_do_none - clear flags for all analysis parts.
 * @ta: analysis handle.
 *
 * The function sets the flags for all analysis components to %FALSE.
 */
void            libnd_ta_do_none(LND_TAnalysis *ta);

/**
 * libnd_ta_write_results - dumps results of analysis to an output stream.
 * @ta: analysis handle.
 * @output: output stream.
 *
 * The function writes the data gathered for the traces added to @ta into
 * the output stream @output. Only information for the analysis modules
 * enabled in @ta are written -- you can thus gather all required numbers
 * in one go, and write them to separate files by enabling analysis modes
 * selectively when calling this function.
 *
 * Returns: %TRUE on success, %FALSE on error.
 */
gboolean        libnd_ta_write_results(const LND_TAnalysis *ta, FILE *output);


#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif
