#ifndef fireflier_h
#define fireflier_h
#include <endian.h>
#include <byteswap.h>
#include <assert.h>
namespace ff
{
    // Commands in network communication (=first byte of each message)
    enum Commands {
        CMD_INVALID = -1,
	CMD_PACKET_AVAIL = 0,
	CMD_SOURCE, // get source of packet
	CMD_RULES, // get iptables rules
	CMD_ACCEPT, // allow packet(s)/create rule allowing packets
	CMD_DROP, // deny packet(s)/create rule denying packets
	CMD_DELETE_RULE, // delete iptables rule
	CMD_URULES, // get userpace rules
	CMD_DELETE_URULE, // delete userspace rule
	CMD_AUTH,  // authenticate
	CMD_DELETE_CONN, // tracked connection closed
	CMD_UPDATE_CONN, // new and modified tracked connections
	CMD_ACTIVATE_CONNTRACK, // activate connection tracking - very cpu intensive
	CMD_DEACTIVATE_CONNTRACK, // deactivate connection tracking
	CMD_ACTIVATE_MONITOR_CONNTRACK,
	CMD_DEACTIVATE_MONITOR_CONNTRACK
    };

    enum Select_bits {
        SB_UNUSED,
	SB_IP_SRC,
	SB_IP_DST,
	SB_PORT_SRC,
	SB_PORT_DST,
	SB_INTERFACE_IN,
	SB_INTERFACE_OUT,
	SB_RESERVED_FOR_MAC,
	SB_PROTOCOL,
	SB_CONNTRACK,
        SB_PROGRAMNAME
    };

    enum Chains {
	CHAIN_UNUSED,
        CHAIN_BEGIN=1,
	CHAIN_INPUT=1,
	CHAIN_FORWARD,
	CHAIN_OUTPUT
    };

    enum Rulecommands {
	RC_UNUSED,
	RC_THIS_PACKET,
	RC_QUEUED_PACKETS,
	RC_CREATE_RULE
    };
    enum Protocols {
	PROT_UNKNOWN=0,
	PROT_ICMP=1,
	PROT_TCP=6,
	PROT_UDP=17,
	PROT_GRE=47
    };
    enum Actions {
	ACTION_UNUSED,
	ACTION_ACCEPT,
	ACTION_DROP,
	ACTION_QUEUE
    };

}

// byte order swap methods
#if __BYTE_ORDER == __BIG_ENDIAN
/** swaps T to/from network byte order storing the new value back to t
 */
template<typename T>
inline void netbswap(T& t)
{
}

/** swaps T to/from network byte order returning the new value
 */
template<typename T>
inline T rnetbswap(const T& t)
{
	return t;
}
#elif __BYTE_ORDER == __LITTLE_ENDIAN
/** swaps T to/from network byte order storing the new value back to t
 */
template<typename T>
inline void netbswap(T& t)
{
	if (sizeof(T) == 1)
		return;
	if (sizeof(T) == 2)
		t = bswap_16(t);
	else if (sizeof(T) == 4)
		t = bswap_32(t);
	else if (sizeof(T) == 8)
		t = bswap_64(t);
	else
		assert(t == 0);
}

/** swaps T to/from network byte order returning the new value
 */
template<typename T>
inline T rnetbswap(const T& t)
{
	if (sizeof(T) == 1)
		return t;
	if (sizeof(T) == 2)
		return bswap_16(t);
	if (sizeof(T) == 4)
		return bswap_32(t);
	if (sizeof(T) == 8)
		return bswap_64(t);
	assert(t == 0);
}
#endif


// maximum number of packets remaining in queue.
// if this queue is full, further packets are dropped
#define QUEUE_LENGTH 10
// libipq buffer size
#define BUFSIZE 16384

#endif
