/**
* Contains all the defines required my the kernel module and the JNI code to
* interface with each other.
*
* @author : Asanga Udugama
* @date   : 02-may-2005
* @email  : adu@comnets.uni-bremen.de
*
*/

#ifndef JNET_H
#define JNET_H

#include <linux/types.h>
#include <linux/ioctl.h>

#define DEBUG
#ifdef DEBUG
#define PRINTK(f, a...)			printk(KERN_ALERT f, ## a)
#else
#define PRINTK(f, a...) 		do { } while(0)
#endif

#ifdef DEBUG
#define PRINTF(f, a...)			printf(f, ## a)
#else
#define PRINTF(f, a...) 		do { } while(0)
#endif

#define KERNEL_VERSION_CODE_2_4		132096
#define KERNEL_VERSION_CODE_2_6		132608

#if LINUX_VERSION_CODE < KERNEL_VERSION_CODE_2_6
#define MOD_USE_UP_BY_ONE	MOD_INC_USE_COUNT
#define MOD_USE_DOWN_BY_ONE	MOD_DEC_USE_COUNT
#else
#define MOD_USE_UP_BY_ONE  	try_module_get(THIS_MODULE)
#define MOD_USE_DOWN_BY_ONE	module_put(THIS_MODULE)
#endif


// useful defines
#define SUCCESS				0
#define FAILURE				(-1)
#define NOT_USED			(-1)

#define TRUE				1
#define FALSE				0

#ifndef NULL
#define NULL				0
#endif

#define MAJOR_NUM 			100
#define DEVICE_FILE_NAME 		"/dev/jnet"
#define DEVICE_NAME 			"/dev/jnet"
#define MAX_HOOKS			5

#define MAX_MAC_PAYLOAD_SIZE		2048
#define MAX_MAC_HEADER_SIZE		64
#define MAX_IFACE_NAME_SIZE		24
#define MAC_HEADER_SIZE			14
#define MAX_STORED_PACKETS		16
#define SLACK				16

// structure holding an IP address
typedef struct JNet_IP4Address {
	__u32 ip_address;
} JNet_IP4Address;

// struct to hold a single filter
typedef struct JNet_Filter {
	unsigned int chain;
	unsigned int judgment;

	unsigned int filter_seq;

	// Destination Network based filter
	int dest_net_criteria_active;
	JNet_IP4Address dest_ip;
	JNet_IP4Address dest_mask;

	// Transport layer protocol based filter
	int trans_proto_num_criteria_active;
	int trans_proto_num;

	// Network layer packet size based filter
	int net_packet_size_criteria_active;
	int net_packet_size;

	// define other filters .....

} JNet_Filter;

// struct to hold multiple copies of filters
typedef struct JNet_Filter_Array {
	int count;
	JNet_Filter filter[1]; // initial element; there can be many
} JNet_Filter_Array;

// struct to hold a single captured packet
typedef struct JNet_Packet {
	unsigned int received_chain;
	unsigned int given_judgment;

	char in_iface_name[MAX_IFACE_NAME_SIZE];
	char out_iface_name[MAX_IFACE_NAME_SIZE];

	char mac_header[MAX_MAC_HEADER_SIZE];
	char mac_payload[MAX_MAC_PAYLOAD_SIZE];
	int header_available;
	int payload_available;

} JNet_Packet;

// IOCTL commands
#define JNET_IOCTL_FLT_OP_ADD			_IOWR(MAJOR_NUM, 0, JNet_Filter *)
#define JNET_IOCTL_FLT_OP_DELETE		_IOWR(MAJOR_NUM, 1, JNet_Filter *)
#define JNET_IOCTL_FLT_OP_GET			_IOWR(MAJOR_NUM, 2, JNet_Filter *)
#define JNET_IOCTL_FLT_OP_REPLACE		_IOWR(MAJOR_NUM, 3, JNet_Filter *)
#define JNET_IOCTL_FLT_OP_INSERT		_IOWR(MAJOR_NUM, 4, JNet_Filter *)
#define JNET_IOCTL_FLT_OP_CLEAR_CHAIN		_IOWR(MAJOR_NUM, 5, JNet_Filter *)
#define JNET_IOCTL_FLT_OP_CLEAR_ALL_CHAINS	_IOWR(MAJOR_NUM, 6, JNet_Filter *)
#define JNET_IOCTL_FLT_OP_CLEAR_ALL_N_SET_ALL	_IOWR(MAJOR_NUM, 7, JNet_Filter_Array *)

// struct to hold one entry of in the Linked List 
typedef struct JNet_LinkedList_Entry {
	struct JNet_LinkedList_Entry *prev_entry;
	struct JNet_LinkedList_Entry *next_entry;
	char *data;

	// only valid for list header
	int entry_count;
	struct JNet_LinkedList_Entry *read_next_entry;
	

} JNet_LinkedList_Entry;



// JNet chain identification codes corresponding to Net Filter codes 
#define JNET_IP_PRE_ROUTING		300
#define JNET_IP_LOCAL_IN		301
#define JNET_IP_FORWARD 		302
#define JNET_IP_POST_ROUTING		303
#define JNET_IP_LOCAL_OUT		304

// JNet judgment identification codes corresponding to Net Filter codes 
#define JNET_DROP			500
#define JNET_ACCEPT			501
#define JNET_STOLEN			502
#define JNET_QUEUE			503
#define JNET_REPEAT			504

// define to get the array sequence given the Net Filter chain identification code
#define GET_NF_ARRAY_SEQ(nf_num)	(nf_num == NF_IP_PRE_ROUTING ? 0 : \
						(nf_num == NF_IP_LOCAL_IN ? 1 : \
						(nf_num == NF_IP_FORWARD ?  2 : \
						(nf_num == NF_IP_LOCAL_OUT ? 3 : \
						(nf_num == NF_IP_POST_ROUTING ? 4 : 255)))))

// define to get the Net Filter chain identification code given the array sequence  
#define GET_SEQ_OF_NF(seq_num)	(seq_num == 0 ? NF_IP_PRE_ROUTING : \
						(seq_num == 1 ? NF_IP_LOCAL_IN : \
						(seq_num == 2 ? NF_IP_FORWARD : \
						(seq_num == 3 ? NF_IP_LOCAL_OUT : \
						(seq_num == 4 ? NF_IP_POST_ROUTING : 255)))))

// define to get the corresponding Net Filter chain code given the JNet chain code  
#define GET_NF_CHAIN_FROM_JNET(jnet_num) (jnet_num == JNET_IP_PRE_ROUTING ? NF_IP_PRE_ROUTING : \
						(jnet_num == JNET_IP_LOCAL_IN ? NF_IP_LOCAL_IN : \
						(jnet_num == JNET_IP_FORWARD ? NF_IP_FORWARD : \
						(jnet_num == JNET_IP_LOCAL_OUT ? NF_IP_LOCAL_OUT : \
						(jnet_num == JNET_IP_POST_ROUTING ? NF_IP_POST_ROUTING : 255)))))

// define to get the corresponding JNet chain code given the Net Filter chain code    
#define GET_JNET_CHAIN_FROM_NF(nf_num) (nf_num == NF_IP_PRE_ROUTING ? JNET_IP_PRE_ROUTING : \
						(nf_num == NF_IP_LOCAL_IN ? JNET_IP_LOCAL_IN : \
						(nf_num == NF_IP_FORWARD ? JNET_IP_FORWARD : \
						(nf_num == NF_IP_LOCAL_OUT ? JNET_IP_LOCAL_OUT : \
						(nf_num == NF_IP_POST_ROUTING ? JNET_IP_POST_ROUTING : 255)))))

// define to get the corresponding Net Filter judgment code given the JNet judgment code  
#define GET_NF_JUDGMENT_FROM_JNET(jnet_num) (jnet_num == JNET_DROP ? NF_DROP : \
						(jnet_num == JNET_ACCEPT ? NF_ACCEPT : \
						(jnet_num == JNET_STOLEN ? NF_STOLEN : \
						(jnet_num == JNET_QUEUE ? NF_QUEUE : \
						(jnet_num == JNET_REPEAT ? NF_REPEAT : 255)))))

// define to get the corresponding JNet judgment code given the Net Filter judgment code    
#define GET_JNET_JUDGMENT_FROM_NF(nf_num) (nf_num == NF_DROP ? JNET_DROP : \
						(nf_num == NF_ACCEPT ? JNET_ACCEPT : \
						(nf_num == NF_STOLEN ? JNET_STOLEN : \
						(nf_num == NF_QUEUE ? JNET_QUEUE : \
						(nf_num == NF_REPEAT ? JNET_REPEAT : 255)))))



// Socket types
// can send any packet; cannot read any
#define SOCKET_TYPE_RAW		1 

// these 3 ; can send UDP/TCP/ICMP; can read UDP/TCP/ICMP packets, respectively
#define SOCKET_TYPE_RAW_UDP	2
#define SOCKET_TYPE_RAW_TCP	3
#define SOCKET_TYPE_RAW_ICMP	4

#define SOCKET_TYPE_MIN_NUM	1
#define SOCKET_TYPE_MAX_NUM	4

// define to get the corresponding IPPROTO value given the Net Filter judgment code    
#define GET_IPPROTO_FROM_JNETPROTO(jnet_proto) (jnet_proto == SOCKET_TYPE_RAW ? IPPROTO_RAW : \
						(jnet_proto == SOCKET_TYPE_RAW_UDP ? IPPROTO_UDP : \
						(jnet_proto == SOCKET_TYPE_RAW_TCP ? IPPROTO_TCP : \
						(jnet_proto == SOCKET_TYPE_RAW_ICMP ? IPPROTO_ICMP : (-1)))))

#endif
