text: /*
   *  Copyright (c) 2017, Peter Haag
   *  Copyright (c) 2014, Peter Haag
   *  Copyright (c) 2009, Peter Haag
   *  Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
   *  All rights reserved.
   *  
   *  Redistribution and use in source and binary forms, with or without 
   *  modification, are permitted provided that the following conditions are met:
   *  
   *   * Redistributions of source code must retain the above copyright notice, 
   *     this list of conditions and the following disclaimer.
   *   * Redistributions in binary form must reproduce the above copyright notice, 
   *     this list of conditions and the following disclaimer in the documentation 
   *     and/or other materials provided with the distribution.
   *   * Neither the name of the auhor nor the names of its contributors may be 
   *     used to endorse or promote products derived from this software without 
   *     specific prior written permission.
   *  
   *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
   *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
   *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
   *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
   *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
   *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
   *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
   *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
   *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
   *  POSSIBILITY OF SUCH DAMAGE.
   *  
   */
  
  #ifndef _NFLOWCACHE_H
  #define _NFLOWCACHE_H 1
  
  #include "config.h"
  
  #include <sys/types.h>
  #ifdef HAVE_STDINT_H
  #include <stdint.h>
  #endif
  
  #include "nfx.h"
  #include "nffile.h"
  
  /* Definitions */
  
  /*
   * Flow Table
   * In order to aggregate flows or to generate any flow statistics, the flows passed the filter
   * are stored into an internal hash table.
   */
  
  /* Element of the Flow Table ( cache ) */
  typedef struct FlowTableRecord {
  	// record chain - points to next record with same hash in case of a hash collision
  	struct FlowTableRecord *next;	
  
  	// Hash papameters
  	uint32_t	hash;		// the full 32bit hash value
  	char		*hash_key;	// all keys in sequence to generate the hash 
  
  	// flow counter parameters for FLOWS, INPACKETS, INBYTES, OUTPACKETS, OUTBYTES
  	uint64_t	counter[5];
  
  	extension_info_t	   *map_info_ref;
  	exporter_info_record_t *exp_ref;
  	// flow record follows
  	// flow data size may vary depending on the number of extensions
  	// common_record_t already contains a pointer to more data ( extensions ) at the end
  	common_record_t	flowrecord;
  
  	// no further vars beyond this point! The flow record above has additional data.
  } FlowTableRecord_t;
  
  typedef struct MemoryHandle_s {
  	/* 
  	 * to speedup aggregation/record statistics, the internal hash tables use their own memory management.
  	 * memory is allocated with malloc in chunks of MemBlockSize. All memory blocks are kept in the
  	 * memblock array. Memory blocks are allocated on request up to the number of MaxMemBlocks. If more 
  	 * blocks are requested, the memblock array is automatically extended.
  	 * Memory allocated from a memblock is aligned accoording ALIGN
  	 */
  
  	uint32_t	BlockSize;		/* max size of each pre-allocated memblock */
  
  	/* memory blocks - containing the flow records and keys */
  	void		**memblock;		/* array holding all NumBlocks allocated memory blocks */
  	uint32_t 	MaxBlocks;		/* Size of memblock array */
  	uint32_t 	NumBlocks;		/* number of allocated flow blocks in memblock array */
  	uint32_t	CurrentBlock;	/* Index of current memblock to allocate memory from */
  	uint32_t 	Allocted;		/* Number of bytes already allocated in memblock */
  
  } MemoryHandle_t;
  
  #ifdef __x86_64
  # 	define ALIGN_MASK 0xFFFFFFF8
  #else
  # 	define ALIGN_MASK 0xFFFFFFFC
  #endif
  
  // number of bits for hash width for floe table
  // Size: 0 < HashBits < 32
  // typically 20 - tradeoff memory/speed
  #define HashBits 20
  
  // Each pre-allocated memory block is 10M
  #define MemBlockSize 10*1024*1024
  #define MaxMemBlocks	256
  
  
  typedef struct hash_FlowTable {
  	/* hash table data */
  	uint16_t 			NumBits;		/* width of the hash table */
  	uint32_t			IndexMask;		/* Mask which corresponds to NumBits */
  	uint32_t			NumRecords;		/* number of records in table */
  	FlowTableRecord_t 	**bucket;		/* Hash entry point: points to elements in the flow block */
  	FlowTableRecord_t 	**bucketcache;	/* in case of index collisions, this array points to the last element with that index */
  
  	uint32_t			keylen;			/* key length of hash key as number of 4byte ints */
  	uint32_t			keysize;		/* size of key in bytes */
  
  	/* use a MemoryHandle for the table */
  	MemoryHandle_t		mem;
  
  	/* src/dst IP aggr masks - use to properly maks the IP before printing */
  	uint64_t			IPmask[4];		// 0-1 srcIP, 2-3 dstIP
  	int					has_masks;
  	int					apply_netbits;	// bit 0: src, bit 1: dst
  
  } hash_FlowTable;
  
  hash_FlowTable *GetFlowTable(void);
  
  int Init_FlowTable(void);
  
  void Dispose_FlowTable(void);
  
  char *VerifyStat(uint16_t Aggregate_Bits);
  
  int SetStat(char *str, int *element_stat, int *flow_stat);
  
  void InsertFlow(common_record_t *raw_record, master_record_t *flow_record, extension_info_t *extension_info);
  
  void AddFlow(common_record_t *raw_record, master_record_t *flow_record, extension_info_t *extension_info );
  
  int SetBidirAggregation( void );
  
  int ParseAggregateMask( char *arg, char **aggr_fmt  );
  
  master_record_t *GetMasterAggregateMask(void);
  
  #endif //_NFLOWCACHE_H
  