#ifndef _PAKETTO_H
#define _PAKETTO_H
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libnet.h>
#include <pcap.h>
#include <time.h>
#include "config.h"
#include "pk_crypt.h"

#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
#ifdef HAVE_SYS_IOCCOM_H
#include <sys/ioccom.h>
#endif
#ifndef _IOW
#error "We couldn't find the system macro _IOW on your machine...if you run find /usr/include | xargs grep _IOW and find some file other than sys/sockio.h containing the macro, email dan@doxpara.com and I'll get it in the next build."
#endif
   
#include <sys/types.h>
#include <sys/ioctl.h>

#ifndef IPV4_ADDR_LEN
#define IPV4_ADDR_LEN 4
#endif 

#ifndef MX_B
#define MX_B      8192
#endif

/* XXX use pragma pack 0 or some junk */
struct conn_key
{
	struct in_addr ip_dst;
	char ip_p;  /* guess what happens if you forget this */
	unsigned short l4_sport;
	unsigned short l4_dport;
}__attribute__ ((packed));

struct conn_state
{
	struct in_addr ip_src;
	u_char ether_dhost[ETHER_ADDR_LEN+1];
	u_char ether_shost[ETHER_ADDR_LEN+1];
	struct timeval last_packet; 
}__attribute__ ((packed));	

struct frame
{
	struct libnet_ethernet_hdr *eth;
	struct libnet_ip_hdr *ip;
	struct libnet_tcp_hdr *tcp;
	struct libnet_arp_hdr *arp;
	struct libnet_icmp_hdr *icmp;
	struct libnet_udp_hdr *udp;
	struct pk_dhcpv4_hdr *dhcp;
	char   *data;
}__attribute__ ((packed));

/*
 *  DHCP header
 *  Dynamic Host Configuration Protocol
 *  Static header size: f0 bytes
 */
struct pk_dhcpv4_hdr  /* yanked from libnet 1.1 */
{
    u_char dhcp_opcode;     /* opcode */
#define PK_DHCPV4_H                 0xf0
#define LIBNET_DHCP_MSGDISCOVER     0x01
#define LIBNET_DHCP_MSGOFFER        0x02
#define LIBNET_DHCP_MSGREQUEST      0x03
#define LIBNET_DHCP_MSGDECLINE      0x04
#define LIBNET_DHCP_MSGACK          0x05
#define LIBNET_DHCP_MSGNACK         0x06
#define LIBNET_DHCP_MSGRELEASE      0x07
#define LIBNET_DHCP_MSGINFORM       0x08
    u_char dhcp_htype;      /* hardware address type */
    u_char dhcp_hlen;       /* hardware address length */
    u_char dhcp_hopcount;   /* used by proxy servers */
    u_long dhcp_xid;        /* transaction ID */
    u_short dhcp_secs;      /* number of seconds since trying to bootstrap */
    u_short dhcp_flags;     /* flags for DHCP, unused for BOOTP */
    u_long dhcp_cip;        /* client's IP */
    u_long dhcp_yip;        /* your IP */
    u_long dhcp_sip;        /* server's IP */
    u_long dhcp_gip;        /* gateway IP */
    u_char dhcp_chaddr[16]; /* client hardware address */
    u_char dhcp_sname[64];  /* server host name */
    u_char dhcp_file[128];  /* boot file name */
    u_long dhcp_magic;      /* BOOTP magic header */
#define DHCP_MAGIC                  0x63825363
#define LIBNET_BOOTP_MIN_LEN        0x12c
#define LIBNET_DHCP_PAD             0x00
#define LIBNET_DHCP_SUBNETMASK      0x01
#define LIBNET_DHCP_TIMEOFFSET      0x02
#define LIBNET_DHCP_ROUTER          0x03
#define LIBNET_DHCP_TIMESERVER      0x04
#define LIBNET_DHCP_NAMESERVER      0x05
#define LIBNET_DHCP_DNS             0x06
#define LIBNET_DHCP_LOGSERV         0x07
#define LIBNET_DHCP_COOKIESERV      0x08
#define LIBNET_DHCP_LPRSERV         0x09
#define LIBNET_DHCP_IMPSERV         0x0a
#define LIBNET_DHCP_RESSERV         0x0b
#define LIBNET_DHCP_HOSTNAME        0x0c
#define LIBNET_DHCP_BOOTFILESIZE    0x0d
#define LIBNET_DHCP_DUMPFILE        0x0e
#define LIBNET_DHCP_DOMAINNAME      0x0f
#define LIBNET_DHCP_SWAPSERV        0x10
#define LIBNET_DHCP_ROOTPATH        0x11
#define LIBNET_DHCP_EXTENPATH       0x12
#define LIBNET_DHCP_IPFORWARD       0x13
#define LIBNET_DHCP_SRCROUTE        0x14
#define LIBNET_DHCP_POLICYFILTER    0x15
#define LIBNET_DHCP_MAXASMSIZE      0x16
#define LIBNET_DHCP_IPTTL           0x17
#define LIBNET_DHCP_MTUTIMEOUT      0x18
#define LIBNET_DHCP_MTUTABLE        0x19
#define LIBNET_DHCP_MTUSIZE         0x1a
#define LIBNET_DHCP_LOCALSUBNETS    0x1b
#define LIBNET_DHCP_BROADCASTADDR   0x1c
#define LIBNET_DHCP_DOMASKDISCOV    0x1d
#define LIBNET_DHCP_MASKSUPPLY      0x1e
#define LIBNET_DHCP_DOROUTEDISC     0x1f
#define LIBNET_DHCP_ROUTERSOLICIT   0x20
#define LIBNET_DHCP_STATICROUTE     0x21
#define LIBNET_DHCP_TRAILERENCAP    0x22
#define LIBNET_DHCP_ARPTIMEOUT      0x23
#define LIBNET_DHCP_ETHERENCAP      0x24
#define LIBNET_DHCP_TCPTTL          0x25
#define LIBNET_DHCP_TCPKEEPALIVE    0x26
#define LIBNET_DHCP_TCPALIVEGARBAGE 0x27
#define LIBNET_DHCP_NISDOMAIN       0x28
#define LIBNET_DHCP_NISSERVERS      0x29
#define LIBNET_DHCP_NISTIMESERV     0x2a
#define LIBNET_DHCP_VENDSPECIFIC    0x2b
#define LIBNET_DHCP_NBNS            0x2c
#define LIBNET_DHCP_NBDD            0x2d
#define LIBNET_DHCP_NBTCPIP         0x2e
#define LIBNET_DHCP_NBTCPSCOPE      0x2f
#define LIBNET_DHCP_XFONT           0x30
#define LIBNET_DHCP_XDISPLAYMGR     0x31
#define LIBNET_DHCP_DISCOVERADDR    0x32
#define LIBNET_DHCP_LEASETIME       0x33
#define LIBNET_DHCP_OPTIONOVERLOAD  0x34
#define LIBNET_DHCP_MESSAGETYPE     0x35
#define LIBNET_DHCP_SERVIDENT       0x36
#define LIBNET_DHCP_PARAMREQUEST    0x37
#define LIBNET_DHCP_MESSAGE         0x38
#define LIBNET_DHCP_MAXMSGSIZE      0x39
#define LIBNET_DHCP_RENEWTIME       0x3a
#define LIBNET_DHCP_REBINDTIME      0x3b
#define LIBNET_DHCP_CLASSSID        0x3c
#define LIBNET_DHCP_CLIENTID        0x3d
#define LIBNET_DHCP_NISPLUSDOMAIN   0x40
#define LIBNET_DHCP_NISPLUSSERVERS  0x41
#define LIBNET_DHCP_MOBILEIPAGENT   0x44
#define LIBNET_DHCP_SMTPSERVER      0x45
#define LIBNET_DHCP_POP3SERVER      0x46
#define LIBNET_DHCP_NNTPSERVER      0x47
#define LIBNET_DHCP_WWWSERVER       0x48
#define LIBNET_DHCP_FINGERSERVER    0x49
#define LIBNET_DHCP_IRCSERVER       0x4a
#define LIBNET_DHCP_STSERVER        0x4b
#define LIBNET_DHCP_STDASERVER      0x4c
#define LIBNET_DHCP_END             0xff

#define LIBNET_DHCP_MSGDISCOVER     0x01
#define LIBNET_DHCP_MSGOFFER        0x02
#define LIBNET_DHCP_MSGREQUEST      0x03
#define LIBNET_DHCP_MSGDECLINE      0x04
#define LIBNET_DHCP_MSGACK          0x05
#define LIBNET_DHCP_MSGNACK         0x06
#define LIBNET_DHCP_MSGRELEASE      0x07
#define LIBNET_DHCP_MSGINFORM       0x08
}__attribute__ ((packed));

struct link_state
{
	struct pcap_t *pcap;
	char dev[8];
	struct libnet_link_int *link;
	int trailer;
	char key[20];
};

static struct conn_key *key_buffer;
static struct conn_state *state_buffer;
static int num_of_entries = 0;
static int timeout = 360; 

void init_buffer();
int add_entry(struct conn_key *key, struct conn_state *state);
void dump_buffers();
void scrub_buffers(int verbose);
int find_entry_num(struct conn_key *key);
struct conn_state* find_entry(struct conn_key *key); 
int delete_entry(struct conn_key *key);

#define MAX_NUMBER_OF_ENTRIES 16384




int recalc_checksums(struct frame *x, int protocol);
int parse_layers(char *packet, int length, struct frame *x,
                 int input_layer, int datalink, int allow_short_tcp);
int ether_aton(char *dest, char *src);


int munge_icmp_echo(char *packet, struct pcap_pkthdr *pkthdr, struct frame *x);
int munge_arp_request(char *packet, struct pcap_pkthdr *pkthdr, struct frame *x,
    char *source_mac);
int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y);
#endif /* _PAKETTO_H */
void print_ip(char *x);
void print_tcp(char *target, int short_tcp);

