/*  -*- Mode: C;  -*- */

/******************************************************************************
*                                                                             *
*   Copyright 2005 University of Cambridge Computer Laboratory.               *
*                                                                             *
*   This file is part of Nprobe.                                              *
*                                                                             *
*   Nprobe is free software; you can redistribute it and/or modify            *
*   it under the terms of the GNU General Public License as published by      *
*   the Free Software Foundation; either version 2 of the License, or         *
*   (at your option) any later version.                                       *
*                                                                             *
*   Nprobe is distributed in the hope that it will be useful,                 *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of            *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
*   GNU General Public License for more details.                              *
*                                                                             *
*   You should have received a copy of the GNU General Public License         *
*   along with Nprobe; if not, write to the Free Software                     *
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *
*                                                                             *
******************************************************************************/

#ifndef _FLOWS_H_
#define _FLOWS_H_

#ifndef SWIG

#include "list.h"

#ifndef SINGLE_HOSTS

#define N_HOST_BUCKETS 32909	/* about 2^15 buckets for hash by hosts */
#define N_CONN_BUCKETS 13	/* about 2^4 buckets per above for hash by ports */

#else

#define N_HOST_BUCKETS 23	/* about 2^4 buckets for hash by hosts */
#define N_CONN_BUCKETS 32909	/* about 2^15 buckets per above for hash by ports */	/* about 2^4 buckets for hash by hosts */

#endif


/*
 * Most pkts will be from server - so compare src first
 */
#define IS_SAME_HOST_FLOW(ipp, hostflowp)             \
              ((*((unsigned int *)&((ipp)->ip_src))  == (hostflowp)->dstaddr \
                && *((unsigned int *)&((ipp)->ip_dst))  == (hostflowp)->srcaddr)\
             ||                                                          \
             (*((unsigned int *)&((ipp)->ip_src)) == (hostflowp)->srcaddr \
                && *((unsigned int *)&((ipp)->ip_dst)) == (hostflowp)->dstaddr))

#define IS_SAME_TCP_PORT_FLOW(sport, dport, portflowp, type)   \
     ((portflowp)->type == (type) &&   \
     (((sport) == (portflowp)->inner.dstport  \
       && (dport) == (portflowp)->inner.srcport)   \
    ||   \
     ((sport) == (portflowp)->inner.srcport  \
       && (dport) == (portflowp)->inner.dstport)))

/*
 * Hashed host/host flow structure
 * - by convention SRC will always be the client side
 */
struct host_flow 
{
  list_t hlist;		/* hash list links */
  listhdr_t *hflow_list;	/* head of hash list it's on */
  unsigned int srcaddr, dstaddr;	/* NBO */
  listhdr_t flow_conns[N_CONN_BUCKETS];	/* hash based on ports */
  int n_conns;		/* no. of tcp conns for these hosts */
#if !defined SWIG_ONLY && defined __ia64__
} __attribute__ ((packed));
#else
};
#endif
typedef struct host_flow host_flow_t;

#endif /* ifndef SWIG */

/* 
 * Common to TCP/UDP flows 
 */

struct flow_inner 
{
  unsigned int state;
  unsigned int src_atmdata, dst_atmdata;
  unsigned short srcport, dstport;	/* NBO */
  unsigned int srcaddr, dstaddr;	/* NBO - shadows vals in host_flow struct */
  us_clock_t last_arr_tm;	/* last packet arrival in absolute us */
  us_clock_t first_arr_tm;	/* first do - most other times are relative to this */
  unsigned char serv_type;
#if !defined SWIG_ONLY && defined __ia64__
  char padding[3];
} __attribute__ ((packed));
#else
};
#endif
typedef struct flow_inner flow_inner_t;


/*
 * Values for flow_common type field 
 */

#define FLOW_TCP 1
#define FLOW_UDP 2

#ifndef WREAD
 
struct flow_common 
{
  list_t hlist;		/* hash list links */
  list_t conn_timeo_q;	/* connection time out queue */
  struct host_flow *hconnp;/* ptr to the host_flow_t it hangs off */
  struct flow_inner inner;
  int port_indx;	/* indx into host_flow tcp conns hash table */
  unsigned char type;			/* eg. TCP, UDP */
 };
typedef struct flow_common flow_common_t;


/*
 * flows.c 
 */


listhdr_t *host_hashtbl_initialise();
int hash_flow(struct ip *ipp);
void flow_final_dump(listhdr_t *htbl);
host_flow_t *get_host_flow(listhdr_t *hlist, struct ip *ipp);
host_flow_t *new_hostflow(listhdr_t *hlist, struct ip *ip, int way);
void free_host_flow(host_flow_t *hfp);
flow_common_t *get_flow_conn(listhdr_t *conns, unsigned short sport, unsigned short dport, unsigned char type);


#endif /* ifndef WREAD */


#endif /* _FLOWS_H_ */

/*
 * end flows.h 
 */
