/*
 * ip_i.h
 *
 * x-kernel v3.3
 *
 * Copyright (c) 1993,1991,1990,1996  Arizona Board of Regents
 *
 * $Revision: 1.2 $
 * $Date: 1996/02/01 15:31:51 $
 */

#ifndef ip_i_h
#define ip_i_h

#ifndef ip_h
#include "ip.h"
#endif

#ifndef vnet_h
#include "vnet.h"
#endif

#include "route.h"
#include "route_i.h"

#define	IPHLEN	(sizeof(IPheader))

#define IPVERS	(4 << 4)
#define VERS_MASK 0xf0
#define HLEN_MASK 0x0f
#define GET_HLEN(h) ((h)->vers_hlen & HLEN_MASK)
#define GET_VERS(h) ( ((h)->vers_hlen & VERS_MASK) >> 4 )

#define IPMAXINTERFACES  10
#define IPOPTPACKET 512
#define IPMAXPACKET 65000*4	/* I mean maximum possible for protocol */
#define IPDEFAULTDGTTL  30
#define IP_GC_INTERVAL 30 * 1000 * 1000		/* 30 seconds */

/* fragment stuff */
#define DONTFRAGMENT  0x4000
#define MOREFRAGMENTS  0x2000
#define FRAGOFFMASK   0x1fff
#define FRAGOFFSET(fragflag)  ((fragflag) & FRAGOFFMASK)
#define COMPLETEPACKET(hdr) (!((hdr).frag & (FRAGOFFMASK | MOREFRAGMENTS)))
#define INFINITE_OFFSET      65000

#define IP_ACTIVE_MAP_SZ	101
#define IP_FORWARD_MAP_SZ	101
#define IP_PASSIVE_MAP_SZ	23
#define IP_PASSIVE_SPEC_MAP_SZ	23
#define IP_FRAG_MAP_SZ		23

typedef struct ipheader {
  	u_char 	vers_hlen;	/* high 4 bits are version, low 4 are hlen */
	u_char  type;
	u_short	dlen;
	u_short ident;
	u_short frag;
	u_char  time;
	u_char  prot;
	u_short checksum;
  	IPhost	source;		/* source address */
  	IPhost	dest;		/* destination address */
} IPheader; 

typedef struct pstate {
    Protl	self;
    Map 	activeMap;
    Map		fwdMap;
    Map  	passiveMap;
    Map  	passiveSpecMap;
    Map		fragMap;
    int		numIfc;
    Map		netMaskMap;
    rtinfo	Route;
    route	*Rtable[ROUTETABLESIZE];
    IPhost	ipSiteGateway;
} PState;

typedef struct sstate {
    IPheader	hdr;
    int		mtu;		   /* maximum transmission unit on intface */
} SState;

/*
 * The active map is keyed on the local and remote hosts rather than
 * the lls because the lls may change due to routing while the hosts
 * in the IP header will not.
 */
typedef struct {
    long	protNum;
    IPhost	remote;	/* remote host  */
    IPhost	local;	/* local host	*/
}	ActiveId;

typedef IPhost	FwdId;

typedef long	PassiveId;

typedef struct {
    long	prot;
    IPhost	host;
} PassiveSpecId;


/*
 * fragmentation structures
 */

typedef struct {
    IPhost source, dest;
    u_char prot;
    u_char pad;
    u_short seqid;
} FragId;

typedef struct hole_ent {
    u_short first, last;
} Hole_ent;

#define RHOLE  1
#define RFRAG  2

typedef struct fragif {
    u_char type;
    union {
	Hole_ent  *hole;
	Msg	  frag;
    } data;
    struct fragif *next, *prev;
} Fraginfo;

typedef struct Fragtable {
    u_short  	nholes;
    Fraginfo 	*listhead;
    Binding    	binding;
    bool	gcMark;
} Fragtable;

#define ERR_FRAG ((Fragtable *)-1)

#include "route.h"

#ifdef __STDC__

int		ipControlProtl( Protl, int, char *, int );
int		ipControlSessn( Sessn, int, char *, int );
Part            *ipGetParticipants(Sessn);
Sessn		ipCreatePassiveSessn( Protl, Sessn, ActiveId *, FwdId * );
XkReturn	ipDemux( Protl, Sessn, Msg * );
void 		ipDumpHdr( IPheader * );
void 		ipDumpHdr( IPheader * );
Enable *	ipFindEnable( Protl, int, IPhost * );
XkReturn 	ipForwardPop( Sessn, Sessn, Msg *, VOID * );
void		ipFreeFragtable( Fragtable * );
XkReturn 	ipFwdBcastPop( Sessn, Sessn, Msg *, VOID * );
int		ipGetHdr( Msg *, IPheader *, char * );
void		ipHdrStore( VOID *, char *, long, VOID * );
int		ipHostOnLocalNet( PState *, IPhost *);
int		ipIsMyAddr( Protl, IPhost * );
XkReturn	ipMsgComplete( Sessn, Sessn, Msg *, VOID * );
void		ipProcessRomFile( Protl );
XkReturn	ipReassemble( Sessn, Sessn, Msg *, IPheader * );
int		ipRemoteNet( PState *, IPhost *, route *);
void		ipRouteChanged( PState *, route *,
			       int (*)(PState *, IPhost *, route *) );
int		ipSameNet( PState *, IPhost *, route *);
XkHandle	ipSend( Sessn s, Sessn lls, Msg *msg, IPheader *hdr );
XkReturn	ipStdPop( Sessn, Sessn, Msg *, VOID * );
void		scheduleIpFragCollector( PState * );

#else

int		ipControlProtl();
int		ipControlSessn();
Part            *ipGetParticipants();
Sessn		ipCreatePassiveSessn();
XkReturn	ipDemux();
Enable *	ipFindEnable();
XkReturn 	ipForwardPop();
void		ipFreeFragtable();
XkReturn 	ipFwdBcastPop();
int		ipGetHdr();
void		ipHdrStore();
int		ipIsMyAddr();
XkReturn	ipMsgComplete();
void		ipProcessRomFile();
XkReturn	ipReassemble();
int		ipRemoteNet();
void		ipRouteChanged();
int		ipSameNet();
XkHandle	ipSend();
XkReturn	ipStdPop();
void		scheduleIpFragCollector();

#endif

extern int 	traceipp;
/* extern IPhost	ipSiteGateway; */

#define ip_i_h_end

#endif /* ip_i_h */
