/*
 * @DEC_COPYRIGHT@
 */
/*
 * HISTORY
 * $Log:	ip_var.h,v $
 * Revision 4.3.2.2  91/12/18  21:47:11  William_Burns
 * 	Merge from ODE/TIN: revision 3.1.9.3
 * 	date: 91/11/14 15:40:39;  author: devrcs;  state: Exp;  lines added/del: 8/1
 * 	sccs rev: 3.3;  orig date: 91/11/04 15:51:44;  orig author: heather
 * 	fix for BYTE_ORDER undefined if _KERNEL not defined
 * 	[91/12/04  10:27:52  William_Burns]
 * 
 * Revision 4.3  91/11/26  11:11:44  devbld_zk3
 * 	Baselevel AG_BL0
 * 
 * Revision 4.2.2.2  91/11/05  10:34:46  William_Burns
 * 	Merge from ODE/TIN: revision 3.1.9.2
 * 	date: 91/10/24 16:33:47;  author: devrcs;  state: Exp;  lines added/del: 24/1
 * 	sccs rev: 3.2;  orig date: 91/10/10 15:46:10;  orig author: heather
 * 	add ipreass structure and lock macros to enable quota on reassembly queue
 * 	[91/10/29  10:57:54  William_Burns]
 * 
 * Revision 4.2  91/09/19  22:47:42  devbld
 * 	Adding ODE Headers
 * 
 * $EndLog$
 */
/*	
 *	@(#)$RCSfile: ip_var.h,v $ $Revision: 4.3.2.2 $ (DEC) $Date: 91/12/18 21:47:11 $
 */ 
/*
 */
/*
 * (c) Copyright 1990, OPEN SOFTWARE FOUNDATION, INC.
 * ALL RIGHTS RESERVED
 */
/*
 * OSF/1 Release 1.0
 */
/*
 * Copyright (C) 1988,1989 Encore Computer Corporation.  All Rights Reserved
 *
 * Property of Encore Computer Corporation.
 * This software is made available solely pursuant to the terms of
 * a software license agreement which governs its use. Unauthorized
 * duplication, distribution or sale are strictly prohibited.
 *
 */
/*
 * Copyright (c) 1982, 1986 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted provided
 * that: (1) source distributions retain this entire copyright notice and
 * comment, and (2) distributions including binaries display the following
 * acknowledgement:  ``This product includes software developed by the
 * University of California, Berkeley and its contributors'' in the
 * documentation or other materials provided with the distribution and in
 * all advertising materials mentioning features or use of this software.
 * Neither the name of the University nor the names of its contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *	Base:	ip_var.h	7.6 (Berkeley) 9/20/89
 *	Merged:	ip_var.h	7.7 (Berkeley) 6/28/90
 */
/*
 *	Revision History:
 *
 *  4-Nov-91	Heather Gray
 *	Include endian.h if BYTE_ORDER not defined
 *
 * 10-Oct-91	Heather Gray
 *	Place quota on reassembly queue
 */

#ifndef BYTE_ORDER
#include <machine/endian.h>
#endif

/*
 * Overlay for ip header used by other protocols (tcp, udp).
 */
struct ipovly {
	caddr_t	ih_next, ih_prev;	/* for protocol sequence q's */
	u_char	ih_x1;			/* (unused) */
	u_char	ih_pr;			/* protocol */
	short	ih_len;			/* protocol length */
	struct	in_addr ih_src;		/* source internet address */
	struct	in_addr ih_dst;		/* destination internet address */
};

/*
 * Ip reassembly queue structure.  Each fragment
 * being reassembled is attached to one of these structures.
 * They are timed out after ipq_ttl drops to 0, and may also
 * be reclaimed if memory becomes tight.
 */
struct ipq {
	struct	ipq *next,*prev;	/* to other reass headers */
	u_char	ipq_ttl;		/* time for reass q to live */
	u_char	ipq_p;			/* protocol of this fragment */
	u_short	ipq_id;			/* sequence id for reassembly */
	struct	ipasfrag *ipq_next,*ipq_prev;
					/* to ip headers of fragments */
	struct	in_addr ipq_src,ipq_dst;
};

/*
 * Ip header, when holding a fragment.
 *
 * Note: ipf_next must be at same offset as ipq_next above
 */
struct	ipasfrag {
#if	defined(_KERNEL) || defined(_NO_BITFIELDS)
	u_char	ip_vhl;
#else
#if BYTE_ORDER == LITTLE_ENDIAN 
	u_char	ip_hl:4,
		ip_v:4;
#endif
#if BYTE_ORDER == BIG_ENDIAN 
	u_char	ip_v:4,
		ip_hl:4;
#endif
#endif
	u_char	ipf_mff;		/* copied from (ip_off&IP_MF) */
	short	ip_len;
	u_short	ip_id;
	short	ip_off;
	u_char	ip_ttl;
	u_char	ip_p;
	u_short	ip_sum;
	struct	ipasfrag *ipf_next;	/* next fragment */
	struct	ipasfrag *ipf_prev;	/* previous fragment */
};

/*
 * Structure stored in mbuf in inpcb.ip_options
 * and passed to ip_output when ip options are in use.
 * The actual length of the options (including ipopt_dst)
 * is in m_len.
 */
#define MAX_IPOPTLEN	40

struct ipoption {
	struct	in_addr ipopt_dst;	/* first-hop dst if source routed */
	char	ipopt_list[MAX_IPOPTLEN];	/* options proper */
};

/* Source route holding structure (moved here from ip_input.c) */
struct ip_srcrt {
	struct	in_addr dst;			/* final destination */
	char	nop;				/* one NOP to align */
	char	srcopt[IPOPT_OFFSET + 1];	/* OPTVAL, OLEN and OFFSET */
	struct	in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)];
};

struct	ipstat {
	long	ips_total;		/* total packets received */
	long	ips_badsum;		/* checksum bad */
	long	ips_tooshort;		/* packet too short */
	long	ips_toosmall;		/* not enough data */
	long	ips_badhlen;		/* ip header length < data size */
	long	ips_badlen;		/* ip length < ip header length */
	long	ips_fragments;		/* fragments received */
	long	ips_fragdropped;	/* frags dropped (dups, out of space) */
	long	ips_fragtimeout;	/* fragments timed out */
	long	ips_forward;		/* packets forwarded */
	long	ips_cantforward;	/* packets rcvd for unreachable dest */
	long	ips_redirectsent;	/* packets forwarded on same net */
	long	ips_noproto;		/* unknown or unsupported protocol */
	long	ips_delivered;		/* packets consumed here */
	long	ips_localout;		/* total ip packets generated here */
	long	ips_odropped;		/* lost packets due to nobufs, etc. */
	long	ips_reassembled;	/* total packets reassembled ok */
	long	ips_fragmented;		/* output packets fragmented ok */
	long	ips_ofragments;		/* output fragments created */
	long	ips_cantfrag;		/* don't fragment flag was set, etc. */
#if	defined(_KERNEL) && LOCK_NETSTATS
	simple_lock_data_t ips_lock;	/* statistics lock */
#endif
};

struct ipreass {
	int	ipr_percent;		/* % buffer space avail for reass */
	long	ipr_max;		/* max space available for reass */
	long	ipr_inuse;		/* space currently used for reass */
	long	ipr_drops;		/* # of drops due to buffer unavail */
#if	defined(_KERNEL) && NETSYNC_LOCK
	simple_lock_data_t ipr_lock;	/* configuration lock */
#endif
};
#define IPR_DEFAULT	50		/* use 50% by default */

#ifdef _KERNEL
#if	NETSYNC_LOCK
extern	lock_data_t		ip_frag_lock;
extern	simple_lock_data_t	ip_misc_lock;
#define IPFRAG_LOCKINIT()	lock_init2(&ip_frag_lock, TRUE, LTYPE_IP)
#define IPFRAG_LOCK()		lock_write(&ip_frag_lock)
#define IPFRAG_UNLOCK()		lock_done(&ip_frag_lock)
#define IPMISC_LOCKINIT()	simple_lock_init(&ip_misc_lock)
#define IPMISC_LOCK()		simple_lock(&ip_misc_lock)
#define IPMISC_UNLOCK()		simple_unlock(&ip_misc_lock)
#define IPREASS_LOCKINIT()	simple_lock_init(&ipreass.ipr_lock)
#define IPREASS_LOCK()		simple_lock(&ipreass.ipr_lock)
#define IPREASS_UNLOCK()	simple_unlock(&ipreass.ipr_lock)
#else	/* !NETSYNC_LOCK */
#define IPMISC_LOCKINIT()
#define IPMISC_LOCK()
#define IPMISC_UNLOCK()
#define IPFRAG_LOCKINIT()
#define IPFRAG_LOCK()
#define IPFRAG_UNLOCK()
#define IPREASS_LOCKINIT()
#define IPREASS_LOCK()
#define IPREASS_UNLOCK()
#endif

/* flags passed to ip_output as last parameter */
#define	IP_FORWARDING		0x1		/* most of ip header exists */
#define	IP_ROUTETOIF		SO_DONTROUTE	/* bypass routing tables */
#define	IP_ALLOWBROADCAST	SO_BROADCAST	/* can send broadcast packets */

extern	CONST u_char inetctlerrmap[];
extern	struct	ipstat	ipstat;
extern	struct	ipq	ipq;			/* ip reass. queue */
extern	u_short	ip_id;				/* ip packet ctr, for ids */
#endif
