/*
 * Copyright (c) 2004 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: packet.h 8180 2008-01-16 02:35:01Z jomi $
 */

#ifndef _PACKETH
#define _PACKETH

#include "dagrandom.h"
#include "list.h"

// Bit operation macros
#define BITGET(set,bit)		(set >> (bit-1)) & ~(~0 << 1)
#define BITSET(set,bit)		set |= (~(~0 << 1)) << (bit-1)
#define BITUNSET(set,bit) 	set &= ~(~(~0 << 1) << (bit))
#define BITCLEAR(set)		set = 0

// MAC type
#define	MAC_STATIC	1
#define MAC_WILDCARD	2
#define MAC_RANDOM	3
#define MAC_VARIABLE    4

// Packet types
#define PKT_ETH802_3	1
#define PKT_ETH_II	2
#define PKT_POS		3
#define PKT_ATM		4
#define PKT_AAL5	5
#define PKT_IB          6

// Header lengths
#define HEADER_ETH_LENGTH	14
#define HEADER_POS_LENGTH	4

// Payload types
#define PLOAD_HEXASTRING	1
#define PLOAD_COUNTER		2
#define PLOAD_DUMMY		3
#define PLOAD_WLEN		4
#define PLOAD_COUNTER_MASK	5

// ATM values
#define ATM_TYPE_UNI		1
#define ATM_TYPE_NNI		2

//INFINIBAND TYPES
#define IB_TYPE_RAW		0
#define IB_TYPE_NONIB		1
#define IB_TYPE_LOCAL		2
#define IB_TYPE_GLOBAL		3

// Counter types
#define COUNTER_NORMAL		1
#define COUNTER_REPEAT		2
#define COUNTER_MASK		3

//
// Data structures
//
// Remember: this data structures are used as an intermediate step
// towards the final file. Some data types are not equal to the
// ones we are writting to disk, so don't be worried if it doesn't
// match the real format.
//

typedef struct {
	unsigned char type;
	unsigned char mac[6];
	unsigned int bitset;
} mac_t;
	
// Common declaration for all ethernet packets
typedef struct {
	char src_addr_type;	// type of mac address (static or variable)
	mac_t * src_addr;	// static mac address (includes wildcard and random)
	list_t * src_addr_var;  // variable mac address (as payload)

	char dst_addr_type;	// type of mac address (static or variable)
	mac_t * dst_addr;	// static mac address (includes wildcard and random)
	list_t * dst_addr_var;  // variable mac address (as payload)

	unsigned int fcs_size;
	unsigned int rx_error;
	list_t * payload;
} packet_eth_t;

typedef struct {
	char src_addr_type;
	mac_t * src_addr;	// static mac address (includes wildcard and random)
	list_t * src_addr_var;  // variable mac address (as payload)

	char dst_addr_type;	// type of mac address (static or variable)
	mac_t * dst_addr;	// static mac address (includes wildcard and random)
	list_t * dst_addr_var;  // variable mac address (as payload)

	unsigned int fcs_size;
	unsigned int rx_error;
	list_t * payload;
} packet_eth802_3_t;

typedef struct {
	char src_addr_type;
	mac_t * src_addr;	// static mac address (includes wildcard and random)
	list_t * src_addr_var;  // variable mac address (as payload)

	char dst_addr_type;	// type of mac address (static or variable)
	mac_t * dst_addr;	// static mac address (includes wildcard and random)
	list_t * dst_addr_var;  // variable mac address (as payload)

	unsigned int fcs_size;
	unsigned int rx_error;
	list_t * payload;

	// Declaring protocol here and not before payload, we make this
	// header compatible with Eth802.3 and can reuse functions, because
	// we use the same type casting
	unsigned short int protocol;
} packet_eth_II_t;

typedef struct {
	unsigned char address;
	unsigned char control;
	unsigned char protocol_size;
	unsigned short int protocol;
	list_t * payload;
	unsigned char fcs_size;
	unsigned int rx_error; 
} packet_pos_t;

typedef struct {
	unsigned char type;
	distribution_t * gfc;
	distribution_t * vpi;
	distribution_t * vci;
	distribution_t * pt;
	distribution_t * clp;
	list_t * payload;
} packet_atm_t;

typedef struct {
	unsigned char type;
	distribution_t * gfc;
	distribution_t * vpi;
	distribution_t * vci;
	distribution_t * pt;
	distribution_t * clp;
	list_t * payload;

	distribution_t * uu;
	distribution_t * cpi;
	distribution_t * crc;
} packet_aal5_t;

typedef struct {
	unsigned char type;
	distribution_t * lrh_vl;
	distribution_t * lrh_lver;
	distribution_t * lrh_slid;
	distribution_t * lrh_dlid;
	distribution_t * lrh_slevel;
	distribution_t * bth_opcode;
	distribution_t * bth_qp;
	distribution_t * bth_psn;	
	distribution_t * bth_tver;
	distribution_t * src_qp;
	list_t * payload;
} packet_ib_t;

typedef struct {
	unsigned char type;	// Packet type
	char * id;		// Packet identifier (symbol)
	void * p;		// Pointer to inner packet (i.e. eth802_3)
} packet_t;

typedef struct {
	char type;
	void *contents;
	distribution_t * distr;
} payload_t;

typedef struct {
	char * id;
	distribution_t * distr;
	unsigned char size;
} counter_t;

/*
typedef struct {
	unsigned int gfc : 4;
	unsigned int vpi : 8;
	unsigned int vci : 16;
	unsigned int pt  : 3;
	unsigned int clp : 1;
} header_atm_uni_t;

typedef struct {
	unsigned int vpi : 12;
	unsigned int vci : 16;
	unsigned int pt  : 3;
	unsigned int clp : 1;
} header_atm_nni_t;
*/

typedef struct {
	unsigned char uu;
	unsigned char cpi;
	unsigned short int length;
	unsigned int crc;
} trailer_aal5_t;

//
// Function declarations
//

packet_t * packetNew (unsigned char type, char * id);
packet_eth802_3_t * packetNewEth802_3 ();
packet_pos_t * packetNewPos ();
packet_eth_II_t * packetNewEth_II ();
void packetFree (packet_t * p);
void packetFreeEth (packet_eth_t * p);
void packetFreePos (packet_pos_t * p);
mac_t * macNew ();
void macGet (mac_t * mac, unsigned char * array);
payload_t * payloadNew (char, void *, distribution_t *);
counter_t * counterNew (char * id, distribution_t *, unsigned char size);
packet_atm_t * packetNewAtm ();
packet_aal5_t * packetNewAal5 ();

packet_ib_t* packetNewIB();



#endif

