/* Copyright 1984 by the Massachusetts Institute of Technology */

/* Structure definitions for InterNet addresses and packets.
 * IN packets are viewed as strings of bytes, which are stored in
 * PDP11 memory in the obvious fashion. Since words are sent high
 * order byte first in the byte stream, they must be byte swapped
 * before being treated as word data entities.
 * The following fields probably need to have their bytes swapped to
 * be interesting: i_id
 * The following fields HAVE to have their bytes swapped before using
 * them in any way: i_len, i_fofflg group.
 */

/*
 *------------------------------------------------------------------
 * $Source: /mit/cgw/src/gw/in/RCS/in.h,v $
 * $Revision: 1.4 $
 * $Date: 89/03/15 08:36:39 $
 *------------------------------------------------------------------
 */


#define	inaddr	union	inadru

inaddr	{	long		i_long;		/* IN name structure */

		struct	{	unss	i_wordh;
				unss	i_wordl;
			}	i_word;

		struct	{	byte	i_byteh;
				byte	i_byteu;
				byte	i_bytem;
				byte	i_bytel;
			}	i_byte;

		struct	{	unsb	i_snet;
				unsb	i_ssnet;
				unsb	i_srsd;
				unsb	i_shst;
			}	i_saddr;

		struct	{	unsb	i_anet;
				unsb	i_ahsth;
				unsb	i_ahstm;
				unsb	i_ahstl;
			}	i_aaddr;

		struct	{	unss	i_bnet;
				unsb	i_bhsth;
				unsb	i_bhstl;
			}	i_baddr;

		struct {	unss	i_cneth;
				byte	i_cnetl;
				unsb	i_chst;
			}	i_caddr;
	};


#define	mkina(x)	((inaddr *) (x))
#define	mksina(x)	mkunsb(mkina(x)->i_byte.i_byteh), \
			(mkina(x)->i_byte.i_byteu), \
			(mkina(x)->i_byte.i_bytem), \
			mkunsb(mkina(x)->i_byte.i_bytel)


#define	AMSK	0200		/* Mask values used to decide on which */
#define	AVAL	0000		/* class of address we have */
#define	BMSK	0300
#define	BVAL	0200
#define	CMSK	0340		/* The associated macros take an arg */
#define	CVAL	0300		/* of the form in_addr.i_aaddr.i_anet */
#define	IVAL	0340

/* #define INLNBRD 0xffffffff	 The VAXen don't yet do this right. */
#define	INLNBRD	0x0		/* Local net broadcast address */
				/* This should go away soon and be replaced by
				 * the internet broadcast standard. */

#define	in_isa(x)	(((x) & AMSK) == AVAL)
#define	in_isb(x)	(((x) & BMSK) == BVAL)
#define	in_isc(x)	(((x) & CMSK) == CVAL)
#define	in_isi(x)	(((x) & CMSK) == IVAL)

#define	CLMSK	0340		/* Alternative method, for case statements */
#define	CLSHFT	5		/* Make C generate hyper-optimized case */
#define	CLA0	0		/* It takes the same arg; you mask it off, */
#define	CLA1	1		/* shift, and then do a case statment with */
#define	CLA2	2		/* some code having more than one label. */
#define	CLA3	3		/* Values for class A */
#define	CLB0	4
#define	CLB1	5		/* B */
#define	CLC	6		/* C */
#define	CLI	7		/* Illegal */



#define	inpkt	struct	inpstr

inpkt	{	byte	i_ihlver;	/* Inet hdr length and hdr version */
		bitb	i_tos;		/* Type of service */
		unss	i_len;		/* Total packet length */
		unss	i_id;		/* ID (fragmentation, etc) */
		unss	i_fofflg;	/* Fragment offset and flags */
		unsb	i_ttl;		/* Time left to live */
		byte	i_prot;		/* Protocol number */
		unss	i_cksum;	/* Header checksum */
		inaddr	i_src;		/* Source */
		inaddr	i_dst;		/* Destination */
/*		byte	i_opts[];	/* Not necessarily there */
					/* i_opts was removed because zero
					 * length structure elements are not
					 * allowed and since options aren't
					 * used the structure shouldn't be
					 * any bigger. */
		};

#define	mkin(x)		((inpkt *) (x))

/* Internet Protocol ids */
#define INICMP	1
#define INGGP	3
#define INTCP	6
#define INEGP	8
#define	INUDP	17
#define INRVD	66

/* Internet field constants */
#define INTOS		0	/* Type of service */
#define INTTL		255	/* Time to live */

/* Constants; fundamental and defined */

#define	INHVERM		0360	/* Mask for version */
#define	INHVER		0100	/* Header version 4 - shifted left */
#define	INHLENM		017	/* Header length mask */
#define	INFOFFM		017777	/* Fragment offset mask */
#define	INMFRG		020000	/* More fragments flag */
#define	INDNTF		040000	/* Don't fragment flag */
#define	INUNUF		0100000	/* Unused flag */

#define	INMINH		5	/* Min length of IN header in hdr words */
#define	INBPHW		4	/* Number of bytes in INH word */
#define	INWPHW		2	/* And words */
#define	INMAX		576	/* Max size IN packet must support */
#define	INFRGQ		8	/* Fragmentation quantum */

#ifdef	BIG_ENDIAN
# define INTTLCKA	0x0100	/* Value to adjust cksum by when doing TTL */
#endif
#ifdef	LITTLE_ENDIAN
# define INTTLCKA	01
#endif

/* Structure definition for IN address initialization tables.
 */

#define	inia	struct	inintaddr

inia	{	byte	inia_addr[4];
		inia	*inia_link;
		byte	inia_smask[4];
		bits	inia_flags;
		};

#define	mkinia(x)	((inia *) (x))

/* Since IP is a big endian protocol, big endian machines don't need
 * things byte swapped. */
#ifdef BIG_ENDIAN
#define ip2s(x) (x)
#define s2ip(x) (x)
#define l2ip(x) (x)
#define ip2l(x) (x)
#else
#define ip2s(x) swab(x)
#define s2ip(x) swab(x)
#define l2ip(x) swabl(x)
#define ip2l(x) swabl(x)
#endif

/* Flags for init */
#define IF_RIP 1	/* Set if should send RIP pkts to this address. */
#define IF_RIP_IGN 2	/* Set if should ignore RIP pkts from this
			 * net. If this is set for any address on a
			 * net, then all RIP packets from that net are
			 * ignored. */
#define IF_RIP_PR 4     /* Set if should split horizon with poisoned reverse */
#define IF_PPP_PROXY 8  /* Set if this interface is a point to point interface
			   and there is a host on the other end, not a gateway.
			   We will pretend to be the host and forward all
			   packets to him ... */

/* Definitions for logging */
ext bitf inflg;
#define MSGFLG inflg
