/* ipip.h    general configuration info
 *
 * $Id: ipip.h,v 1.8 1995/03/19 17:21:06 bdale Exp $
 *
 * Copyright 1991, Michael Westerhof, Sun Microsystems, Inc.
 * This software may be freely used, distributed, or modified, providing
 * this header is not removed.
 *
 * Added support for Linux - Ron Atkinson N8FOW
 */

/* setup the log class to be used when calling syslog - probably LOG_LOCALn */
#define IPIP_SYSLOG LOG_LOCAL0

/* and the location of the file to log the daemon's pid to */
#define PIDLOG "/var/run/ipip.pid"

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* The strtoul routine converts a string to a long unsigned integer.
 * Some system (SunOS for instance) don't have this routine; they tend
 * to allow long unsigned implicitly.  If your system supports the strtoul
 * routine, use it!  Otherwise, try defining "NO_STRTOUL" below...
 * you'll get an immediate bomb-out on execution of the resultant binary
 * if strtol("0xffffffff",NULL,0) != 0xffffffff
 */

#ifdef sun
#define NO_STRTOUL
#endif

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifdef NO_STRTOUL
#define strtoul(a,b,c) strtol(a,b,c)
#endif

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#define DEFAULTCONFIG "/etc/ipip/config"
#define DEFAULTROUTE  "/etc/ipip/routes"

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#define MAX_SIZE 2048		/* largest IP packet we will handle */
#define MAX_IFACES 8		/* Total number of interfaces we support */
#define MAX_ROUTES 1024		/* Max entries in the route table */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

int debugd;
int debugt;
char progname[32];
int no_timestamp;
int stat_interval;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/* The main per-interface data structure */

struct interface {

	int type;		/* The type of interface this is       */
#define IF_TYPE_NONE  0
#define IF_TYPE_IPIP  1
#define IF_TYPE_IPUDP 2
#define IF_TYPE_SLIP  3
#define IF_TYPE_TUN   4

	int status;		/* status flags for this interface        */
#define IF_STAT_OPEN 1
#define IF_STAT_CALL_AGAIN 2	/* call even though no data on the fd!    */
	char *id;		/* The name assigned to this interface    */

	char *devname;		/* (opt) the device name (/dev/ttya)      */
	int unit;		/* IP prot ID, udp port, baud rate, etc   */

	int fd;			/* the file descriptor to use             */
	char *private;		/* (opt) pointer to private data struct   */

	int (*ifopen)();	/* routine to call to open                */
	int (*ifread)();	/* routine to call to read a packet       */
	int (*ifsend)();	/* routine to call to send a packet       */

	long in;		/* count of packets in                    */
	long out;		/* count of packets out                   */
	long out_overruns;	/* count of output overrun errors	  */
	long martians_in;	/* count of bogus packets coming in       */
	long looped_in;		/* count of packets looped		  */
	long bogus_in;		/* count of bogus packets in		  */
};

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Note: the ip addresses and the port numbers are always in net order   */

struct message {
	int length;			/* number of characters in packet  */
	struct interface *from_if;	/* the interface this came from	   */
	struct interface *to_if;	/* the interface this goes to      */
	unsigned long fip;		/* ip address from (IP/UDP only)   */
	unsigned long tip;		/* ip address to (IP/UDP only)     */
	unsigned short fport;		/* port number from (UDP only)     */
	unsigned short tport;		/* port number to (UDP only)       */
	unsigned char msg[MAX_SIZE];	/* the packet itself               */
};

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifdef LINUX
struct ipip_route {
#else
struct route {
#endif
	unsigned long ipaddr;		/* the ip address (network order) */
	unsigned long mask;		/* the bit-mask to apply          */
	struct interface *destif;	/* the destination interface      */
	unsigned long destaddr;		/* the destination ip address     */
	unsigned short destport;	/* the destination udp port       */
	long hits;			/* number of times route selected */
};

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifdef LINUX
struct ipip_route rts[MAX_ROUTES];
#else
struct route rts[MAX_ROUTES];
#endif
int rts_top;

struct interface ifs[MAX_IFACES];
int ifs_top;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
 * Our version of the perror routine... just make sure we ID things first!
 */
#define PERR(x) {(void)syslog(LOG_ERR,x);}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
 * Some driver routing error checking macros...
 * Note that these require that the symbol IF_NAME be defined as the
 * name of the driver; e.g. #define IF_NAME "slip"
 */

#define CK_MNULL(x) \
	if((x)==NULL){ \
		(void)fprintf(stderr,"%sInternal error: NULL message buffer passed to %s driver\n",progname,IF_NAME);\
		return -1;\
	}

#define CK_IFNULL(x) \
	if((x)==NULL){ \
		(void)fprintf(stderr,"%sInternal error: NULL interface passed to %s driver\n",progname,IF_NAME);\
		return -1;\
	}

#define CK_IFTYPE(x,y) \
	if((x)->type != (y)){ \
		(void)fprintf(stderr,"%sInternal error: incorrect interface type passed to %s driver\n",progname,IF_NAME);\
		return -1;\
	}

#define CK_IFTYPE2(x,y,z) \
	if(((x)->type != (y)) && ((x)->type != (z))){ \
		(void)fprintf(stderr,"%sInternal error: incorrect interface type passed to %s driver\n",progname,IF_NAME);\
		return -1;\
	}

#define CK_IFOPEN(x) \
	if(((x)->status & IF_STAT_OPEN)==0){ \
		(void)fprintf(stderr,"%sInternal error: interface has not been opened (%s driver)\n",progname,IF_NAME);\
		return -1;\
	}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
/* slip.c */
int slip_open();
int slip_send();
int slip_read();

/* ip.c */
int ip_open();
int ip_send();
int ip_read();

/* tun.c */
int tun_open();
int tun_send();
int tun_read();

/* route.c */
int read_routes();

/* config.c */
int read_config();

/* run.c */
void send_stats();
int run_it();
