/* 
 * $Id: idrp.h,v 1.13 1996/05/25 13:31:34 skh Exp $
 * Merit IDRP release 1.1 (gated 3.5.4).  Copyright (c) 1994 by Merit Network, Inc. 
 */

#ifndef _IDRP_H
#define _IDRP_H
#include "iso.h"
#ifdef BSD_IDRP
#ifndef _CLNP_H 
#define	_CLNP_H
#include "netiso/clnp.h"  
#endif /* _CLNP_H */
#endif	/* BSD_IDRP */
#include "idrp_proto.h"
typedef u_char          boolean;

extern trace *idrp_trace_options;  
extern const bits idrp_trace_types[];	/* IDRP specific trace flags */

/* other includes at bottom */

#define	IDRP_SMALL_BLOCK_SIZE	128				/* small block size */
#define	IDRP_MEDIUM_BLOCK_SIZE sizeof(idrp_attribute_record)+50 /* medium block size */
#define	IDRP_BIG_BLOCK_SIZE   sizeof(idrpPeer)   		/* big block size */
#define IDRP_HUGE_BLOCK_SIZE  IDRP_PKTSIZE  			/* enough for max pdu send size */

#define	IDRP_MAX_LOCAL_ROUTES	150	/* Maximum local routes */	
#define IDRP_MAX_PEERS 		10 	/* Max number of peers */
#define IDRP_HASH_TABLE_SIZE	20	/* hash table size */
#define	IDRP_SMALL_BLOCK_SIZE	128	/* small block size */
#define	IDRP_MAX_LOCAL_NETS	10	/* maximum NETs per this box  - 1 per interface */
#define	IDRP_MAX_LOCAL_INTF	10	/* maximum INTFs per this box */
#define IDRP_RD_PATH_ARRAY_SIZE 10     	/* Number of RDIs per array in path */
#define	IDRP_RDPATH_HASH_SIZE	10	/* Size of Hash table */
#define	IDRP_OATT_PDU_SPACE	100	/* 100 bytes for additions to oubound pdus */
#define	IDRP_MAX_RDC_NESTING	2	/* 2 levels of RDCs nestings */
#define	IDRP_MAX_RDCS		5	/* 5 RDCs */
#define	IDRP_MAX_PATH_SEG	10	/* 10 path segments */

#define	IDRP_MAX_RIBS		15	/* 15 ribs per peer  */ 

/* timing and packet size definitions 
 * for defaults
 */

#define IDRP_PKTSIZE 4096		/* Bogus packet size for now */
#define IDRP_HOLD_TIME 30		/* Croak if the this timer expires */
#define IDRP_MAX_CREDIT 5		/* Maximum credit offered */
#define IDRP_REXMIT_TIME 2		/* Rexmit timeout value */
#define IDRP_CLOSE_WAIT_TIME 30		/* Time to sit in close_wait state */
#define IDRP_START_TIME 10		/* Time to wait before initial start event */
#define	IDRP_MIN_ADV_TIME 	30	/* 30 seconds for mininum advertisement */	
#define IDRP_CLOSE_STAY_TIME  5         /* stay in closed state before start event */
#define	IDRP_RIB_CHECK_TIME_DEF	2000	/* time to check rib checksum */

#define	IDRP_TSI_SIZE	1		/* TSI size */

/* global definitions for this build that may change 
 */

#define	IDRP_AS_SIZE		2	/* two octets for AS number */ 
#define IDRP_PORT 10747			/* Bogus UDP port number */


/* definitions of echo kludge
 */
 


/* here I need to add some cute assign stuff to make sure idrp_small_block = 
 * the greater of idrp_canon_rd_path, and idrpRoute_entry 
 * - John can help I think  
 */ 

#define	IDRP_MEDIUM_BLOCK_SIZE sizeof(idrp_attribute_record)+50 /* medium block size */

/* medium size block must be bigger than attribute record 
 * and the idrpRoute block - watch this
 * again some clever assign stuff needs to insure that 
 */
 
#define	IDRP_BIG_BLOCK_SIZE   sizeof(idrpPeer)   /* big block size */

/* policy definitions for now */

#define IDRP_METRIC_NONE 255		/* No metric in IDRP */

/* prefix Address comparison  */

#define	PFX_ADDR_EQUAL		0		/* addr1 = addr 2 */
#define PFX_ADDR_LESS_THAN	1		/* addr1 < addr 2 */
#define PFX_ADDR_GREATER_THAN	2		/* addr1 > addr 2 */ 	

#define	ISO_ADDR_EQUAL		0		/* addr1 = addr 2 */
#define ISO_ADDR_LESS_THAN	1		/* addr1 < addr 2 */
#define ISO_ADDR_GREATER_THAN	2		/* addr1 > addr 2 */ 	



/*
 *  Buffer structure
 */

typedef struct _idrpBuffer {
    struct _idrpBuffer *next;		/* Forward link */
    u_int seq;				/* Sequence number */
    idrp_proto_header	*pdu_proto;	/* beginning of PDU with protocol header */
    u_int proto_len;			/* length with protocol header */
    idrpPdu *pdu;			/* PDU */
    u_int length;			/* Length of buffer alone */
    u_int buf_len;			/* Length of buffer alone */
    u_int sequenced;			/* TRUE if PDU is sequenced (reliable) */
    u_int ref;				/* reference count */
} idrpBuffer;


/*
 * Route redistribution map.  A bit for each peer.
 */
typedef struct {
    u_int mapword[(IDRP_MAX_PEERS-1)/32+1];	/* Bitmap words */
} redist_map;

#define IDRP_MAPWORD(x) ((x)/32)
#define IDRP_MAPMASK(x) (1 << ((x)%32))

/*
 * Attributes on a route - entry per type of
 * idrp attribute 
 */

typedef struct {
	u_char present;			/* TRUE if attribute is present */
	u_char flags;			/* Attribute flags */
	u_short length;			/* Attribute length */
	u_char *data;			/* Pointer to attribute */
} idrp_attribute_entry;

typedef struct {
	u_char present;			/* TRUE if attribute is present */
	u_char flags;			/* Attribute flags */
	u_short length;			/* Attribute length */
	u_char *data;			/* Pointer to attribute data */
	u_char attr;			/* Attribute value */ 	
	u_char data_in[4];		/*  data inline */
} idrp_attr_data_entry;

/* idrp attribute entry list structure for
 * optional attributes -
 * - not as effective, but necessary when there
 * is no idea of how many these are 
 */
typedef struct _idrp_attribute_entry_list {
	struct _idrp_attribute_entry_list *p_next;	/* next on list */ 
	u_short type;			/* Attribute type field */
	u_char flags;			/* Attribute flags */
	u_short length;			/* Attribute length */
	u_char *data;			/* Pointer to attribute */
} idrp_attribute_entry_list;
 

/* here we are currently getting the idrp entry to have the */
/* attribute structure per record.   */

/* canonical IDRP paths */

typedef struct  _idrp_canon_rdpath {
	struct	_idrp_canon_rdpath	*p_next;	/* next RD struct */
	struct	_idrp_canon_rdpath	*p_prev;	/* prev RD struct */
	struct	_rdi			*p_rdi;		/* pointer to global rdi structure */	
} idrp_canon_rdpath;

typedef struct  _idrp_global_canon_rdpath {
	struct	_idrp_global_canon_rdpath	*p_next;	/* next RD struct */
	struct	_idrp_global_canon_rdpath	*p_prev;	/* prev RD struct */
	struct	_idrp_canon_rdpath		*p_rdi_list;	/* pointer to rdi list */	
	idrp_attribute_entry			*p_ate;		/* attribute entry for RDI LIST */
} idrp_global_canon_rdpath;



/* next hop attribute information saved at top */

#define NO_NEXT_HOP		0x0	/* no next hop specified in pdu */	
#define	NEXT_HOP_AF_INET	0x1	/* next hop - has IP NET */ 
#define NEXT_HOP_AF_ISO		0x2	/* next hop - has AFI.ISO NET */

/* List of idrpRoute structure with IDs */
 
#define	IDRP_NLRI_FAMILIES_SUPPORTED	2 	/* NLRI supported */
#define	IDRP_NLRI_ISO			0	/* NLRI AF_ISO */
#define	IDRP_NLRI_IP			1	/* NLRI AF_INET */	
#define IDRP_NLRI_UNDEFINED		25	/* high integer to cause crashes if used */

typedef	struct	_nlri_fam {
	byte	family;
	int	nlri_id;
} nlri_fam;

typedef	struct	_fam_nlri {
	u_int	family;
	int	nlri_id;
} fam_nlri;
	
	
#define	SNPA_SIZE	8		/* 8 octet SNPAs */

typedef	struct	_snpa_entry {
	struct	_snpa_entry	*p_next;	/* list of SNPAS for this next hop */	
	int	len;				/* length of snpa */	
	u_char	snpa[SNPA_SIZE];		/* array of SNPAs */
} snpa_entry;
	
typedef struct	_snpa_list {
	u_int   	pdu_len;	/* length of list in the pdus */	
	u_int		cnt;		/* count of snpa's in list */
	snpa_entry	snpa1;		/* list of snpa entryies */
} snpa_list;

typedef struct _idrpRoute_entry {
	struct _idrpRoute_entry	*p_next	;	/* link list of route_id structures */
	int	 		route_id;	/* route-ID */
	int			loc_pref;	/* preference on this group of route-ids */
	int			status;		/* route-id status */

#define IDRP_ATTR_ROUTE_ID_WITH 0x1		/* deleting this route id */
#define IDRP_ATTR_ROUTE_ID_NORM 0x0		/* normal setting */
#define	IDRP_LOCAL_ROUTE_RECONFIG 0x2		/* reconfiguring this local route_id */
#define	IDRP_ATTR_ROUTE_ID_OSILOCAL	 0x4		/* OSILOCAL */

	struct _idrpPeer	*peer;		/* peer for this route_id */			
	struct _idrpRoute	*p_route[IDRP_NLRI_FAMILIES_SUPPORTED];	/* link list of route-id structures */
	struct _idrpRoute	*p_route_tail[IDRP_NLRI_FAMILIES_SUPPORTED];	/* link list of route-id structures */
} idrpRoute_entry; 

/* jgs -- Magic cookies.  I would prefer to see these explicitly defined as real big numbers */
/* jgs -- rather than using negatives (since route ID is unsigned */
/* jgs -- (Later)  Actually they should all turn into status flags instead. */

#define IDRP_LOCAL_ROUTE_ID	-1		/* local route id is illegal */ 
#define	IDRP_EXT_INFO_ROUTE_ID	-2		/* IDRP ext_info route id */
#define IDRP_INIT_ROUTE_ID	-3		/* magic cookie, use very restricted, should go away later */

typedef struct _idrpRoute_list {
	idrpRoute_entry		*head;		/* route list head */
	idrpRoute_entry		*tail;		/* route list tail */
} idrpRoute_list;

typedef	struct	 _idrpRoute_link	{
	struct	_idrpRoute	*head;		/* head of idrpRoute list */
	struct	_idrpRoute	*tail;		/* tail of idrpRoute list */
} idrpRoute_link;


typedef	struct	_idrp_rt_chain_walk	{
	struct	_idrp_rt_chain_walk	*p_next;	/* next on list */
	rt_entry			*p_rt;		/* entry for chain */
} idrp_rt_chain_walk;

/* list types */

#define	IDRP_ROUTE_LIST_LINKED		0	/* linked route list */
#define IDRP_ROUTE_LIST_CIRCULAR	1	/* circular linked list */


typedef	struct	_idrpAdvRt {
	struct	_idrpAdvRt	*p_next;	/* next idrpAdvRt struct on list */
	int	interval;			/* second to set this route list */
	idrpRoute_link	routes[IDRP_NLRI_FAMILIES_SUPPORTED];
						/* routes */
} idrpAdvRt;

 
/* idrp for IP special - */
/* contained in idrp route is an AS_PATHS structure */

typedef struct _idrp_attribute_record {
	struct	_idrp_attribute_record 	*next;		/* linked list */
	struct	_idrp_attribute_record 	*prev;		/* linked list */
	struct	_idrp_attribute_record	*p_parse_next;	/* parsing linked list */
	idrpRoute_entry			*p_parse_re;	/* parsing route entry for new route id */
	int	ref_cnt;				/* reference count */	
	struct	_idrpPeer		*peer_alloc;	/* peer allocated struct*/	
	idrpRoute_entry			*route_id_list;	/* route id's attached to this attribute record */	
	u_int	rib_id;					/* internal ID of AdjRib */
	u_int	idrp_mask;				/* mask of attribute
							 * use the IDRP*_ATTR from idrp_proto.h
							 */
						
	u_int	local_mask;				/* mask of local route bits */ 

#define	IDRP_LOCAL_RDPATH_RESET_LENGTH	0x1		/* reset length */
#define	IDRP_LOCAL_NO_PDU		0x2		/* no pdu for local node route */
#define IDRP_LOCAL_EXT_INFO		0x4		/* EXT_INFO is local RD */
#define	IDRP_LOCAL_DONT_SEND_NEXT_HOP		0x8		/* don't sent the Next hop */
#define	IDRP_LOCAL_ROUTE_SERVER_FLAG		0x10		/* set route server flag on NEXT HOP */
#define IDRP_LOCAL_DONT_SEND_NEXT_HOP_OFF	0xF7		/*  send NEXT hop */ 
#define	IDRP_LOCAL_REUSE			0x20		/* reusing attribute */ 
#define	IDRP_LOCAL_OUTPUT_ATTR			0x40		/* output only attribute */
#define	IDRP_LOCAL_EXPORT_INVALID		0x80		/* this route has been determined to have faulty RDCs */ 

	struct	_idrpRoute_options	*p_opts;/* idrpRoute options form of the pdu */ 
	idrp_canon_rdpath 	*rd_path;	/* cannonical rep of RD path */
	struct	_rdpath_list	*p_rd_opath;	/* actual RD_PATH (as received) */ 
						/* next hop points into options field as
						 * short cut for policy and installation of routes
						 */ 
	sockaddr_un		*next_hop;	/* next hop for route */
	snpa_list		*snpa_list;	/* snpas for this route */


#ifdef	IDRP_ASPATH
	struct _as_path		*as_path;	/* AS path pointer for path */
#endif /* IDRP_ASPATH */
	idrp_attribute_entry_list	*p_transitive;	/* transitive attributes */
	idrp_attribute_entry attrib[IDRP_ATTR_NO];	     /* Attributes */
	idrp_attribute_entry usr_attrib[IDRP_ATTR_USR_NO];   /* Attributes */
	u_char				*p_attr_pdu;	/* copy of attributes from pdu */ 
	int				attr_len;	/* length of attributes from pdu */	
	int                             ref_no;         /* a tmp # to reference in dump routines */
} idrp_attribute_record;




#define	IDRP_ASPATH_EXT_INFO		0		/* AS PATH for EXT_INFO from route */
#define	IDRP_ASPATH_BGP_XFR		1		/* AS PATH for BGP-4 transfer */


/* idrp outbound attribute flags - used in routine calls and
 * in the attribute record created 
 */ 

#define	IDRP_OATT_MASK			0xFF		/* mask of outbound changes from inbound */

#define	IDRP_OATT_MULTI_EXIT_DISC	0x01		/* change in multi-exit - need new attribute */
#define	IDRP_OATT_RDPATH_CONFED		0x02		/* change in RDPATH due to confederation boundary */
#define	IDRP_OATT_RDPATH_CONFED_POL	0x04		/* change in RDPATH due to confederation policy */
#define	IDRP_OATT_RDPATH_AGGR		0x08		/* change in RDPATH due to aggregation of path */
#define	IDRP_OATT_DIST_LIST_NEW		0x10		/* change in DIST_LIST	*/
#define	IDRP_OATT_DIST_LIST_EXIST	0x20		/* change in DIST_LIST	*/
#define	IDRP_OATT_DIST_LIST_NOCHG	0x00		/* no change in DIST_LIST */ 
#define	IDRP_OATT_CAPACITY		0x40		/* change in capacity */ 	

#define	IDRP_EXPORT_INVALID		0x00		/* valid export route */
#define IDRP_EXPORT_ERROR		0x01		/* ERROR PDU as result of route */
#define	IDRP_EXPORT_VALID		0x02		/* valid export route */ 	

typedef struct	_idrp_att_list {
	struct	_idrp_attribute_record	*p_start;
	struct	_idrp_attribute_record	*p_end;
} idrp_att_list;



/* idrp osi route option structure
 * - where we will read in the snpas,
 * - multi_EXIT value
 * - and temporarily the dist_lists
 *   until we go through gated export and import
 *   (bletch - but a workable set-up for a default
 *    DIST_LIST) 
 *
 */

typedef	struct	_qos_operator {
	int		operator;
	u_int		value;
} qos_operator;

/*
 * These are flags for the qos "operator" --SJR
 */
#define IDRP_QOS_OP_NO  0 	/* This QoS not used/valid/present. */
#define IDRP_QOS_OP_LE  1 	/* Like FORTRAN:  LE <=> <=  */
#define IDRP_QOS_OP_LT  2 	/* Like FORTRAN:  LT <=> <   */
#define IDRP_QOS_OP_EQ  3 	/* Like FORTRAN:  EQ <=> ==  */
#define IDRP_QOS_OP_NE  4 	/* Like FORTRAN:  NE <=> !=  */
#define IDRP_QOS_OP_GT  5 	/* Like FORTRAN:  GT <=> >   */
#define IDRP_QOS_OP_GE  6 	/* Like FORTRAN:  GE <=> >=  */

static char *char_qos_operators[]=
{
	"none",
	"<=",
	"<",
	"==",
	"!=",
	">",
	">=",
	(char *) NULL
};

		
typedef struct  _idrp_distinguish_att { 
	int		rib_id;			/* rib id */ 
	u_int		idrp_mask;		/* mask of attribute */
	qos_operator	delay;			/* value of TRANSIT_DELAY */
	qos_operator	error;			/* value of RESIDUAL ERROR */
	qos_operator	expense;		/* value of EXPENSE */
	qos_operator	priority;		/* value of priority */
	qos_operator	sec_type;		/* security type */		
	qos_operator	sec_value;		/* security value */	
} idrp_distinguish_att;


typedef struct _idrp_rdi_mem {
	int	mem_need;	/* DIST_LIST_INCL/EXCL memory needed for this path */
	int	cnt;		/* count of rdis in list */
} idrp_rdi_mem;

typedef	struct	_idrp_next_hop {
	sockaddr_un		*p_net;		/* next hop net in sockaddr_un form */	
	struct _idrp_next_hop 	*p_next;	/* link list of route_id structures */
	int			cnt;		/* count of next hops for this nlri */ 
	snpa_list		next_hop_snpas;	/* snpas associated with this next hop */
} idrp_next_hop;
	
/* struct	iso_net_addr	net;	  type cast this to any sockaddr_un */

typedef struct _idrpRoute_options {
	int		rib_id;			/* rib id of routes */
	idrp_next_hop	next_hop[IDRP_NLRI_FAMILIES_SUPPORTED];	/* next route route */	
	sockaddr_un	*p_intf;		/* sockaddr of next hop for ip interface  */

	flag_t		status;			/* flags */


#define	IDRP_OPTS_ROUTE_SERVER		BIT(0x01) /* route server on */
#define IDRP_OPTS_MULTI_EXIT		BIT(0x02) /* multi-exit on */
#define IDRP_OPTS_EXT_INFO		BIT(0x04) /* external info set */
#define IDRP_OPTS_HIER_REC		BIT(0x08) /* hierarchical recording on */
#define IDRP_OPTS_TYPE			BIT(0x0F)

	int			multi_exit_rcvd;	/* multi_exit received */
	u_int			multi_exit_peers; 	/* multi-exit peers configured */
	u_int			multi_exit[IDRP_MAX_PEERS];	/* multi_exit value per link */

	proto_t			idrp_local_proto;	/* mask of local protocols  */
	qos_operator		capacity;		/* value for capacity */
	int			hopcnt_pref;		/* hopcount function */
	u_int			hopcount;		/* path length */
	idrp_canon_rdpath 	*p_DIST_LIST_INCL;	/* list RDs to pass route to */
	idrp_canon_rdpath	*p_DIST_LIST_EXCL;	/* distribute list exclude */
	idrp_canon_rdpath	*p_DIST_LIST[IDRP_MAX_PEERS];	/* distribution list outbound */
	idrp_distinguish_att	*p_qos;			/* associated dist atts */ 

	struct	_idrpRoute_options	*p_local_opts;	/* global route options cookie */
							/* cutter from */
	struct _idrpRoute_options	*p_extinfo;	/* cookie cutter indication ext_info */
} idrpRoute_options;

#define		IDRP_OPTIONS_EMPTY	-1	/* set rib id to value so can know when
						 * options are set
						 */ 

/* Withdrawl ID storage structure  */

#define	IDRP_WITHDRAW_MAX_IDs	(IDRP_PKTSIZE - MinPDULength)/4  

typedef struct {
        u_int   	count;		/* count of route_id's to withdrawl */
        int		withdraw[IDRP_WITHDRAW_MAX_IDs];	/* withdrawl array */
} Withdrawl;


typedef struct _refresh_pdu_parse  {
	struct	_refresh_pdu_parse	*p_next; /* next attribute record info for this pdu */
	idrp_attribute_record	*p_att;		/* attribute record for this update pdu */
	idrp_attribute_record	*p_parse_next;	/* next attribute on update pdus chain */
	idrpRoute_entry		*p_parse_re;	/* route id's attribute record for this refresh entry */	
	struct	_idrpPeer	*peer;
} refresh_pdu_parse;


/* Parse results from update pdu array */

typedef struct {
	int		route_id_in;	/* route_id */
	idrp_attribute_record *p_att;	/* attribute record */
	idrp_attribute_record  *p_att_rs; /* current Route Separator attribute record */
	u_char		*p_pdu;		/* pdu to save until
					 * DUMP ERROR MESSAGE or good pdu
					 */
	refresh_pdu_parse *p_refresh;	/* refresh save of parse pdu status */

	int		nlri_cnt;	/* count of nlris associated with this result/attribute */ 
	u_int		status;		/* status of ROUTE_ID such as RD_LOOP */ 
	Withdrawl	*withdraw; 	/* withdrawl structure */
	
} parse_results;  
 

/* idrp route id hash table entry */

/* initialized hash table has IDRP_RID_EMPTY marked in all entries */

typedef struct  _idrp_rid_hash {
        int   route_id;               /* route id */       
	u_int   status;			/* status flags */
        struct  _idrp_rid_hash *next;	/* hash chain */ 
        struct _idrpRoute *p_idrp_rt[IDRP_NLRI_FAMILIES_SUPPORTED];
				        /* Route lists per nlri */
} idrp_rid_hash; 

#define IDRP_RID_EMPTY		0x04	/* Nothing in this route ID entry */
#define	IDRP_RID_ROUTE_GONE	0x02
#define	IDRP_RID_ROUTE_LOOP	0x01
#define	IDRP_RID_NORMAL		0x00



/* idrp last error structure  */

typedef struct {
	u_char	error_code; 	/* error pdu error code */
	u_char	error_subcode;	/* error pdu error subcode */
	u_char	*data;		/* pointer to data */
     	u_int	data_len;	/* length of data */
	u_char	*data2;		/* pointer to secondary data */
	u_int	data2_len;	/* length of secondary data */
} error_info;

 
typedef	struct	_idrpRoute_out {
	struct	_idrpRoute	*p_next;	/* next idrpRoute structure */
	struct	_idrpRoute	*p_back;	/* prev idrpRoute structure */
	idrp_attribute_record	*p_att;		/* outbound attribute record */	
	int	route_id;			/* route id */
} idrpRoute_out;
	
/* idrp_best_ext structure
 * We use this track best external routes:  for efficiency, routes to the same dest
 * (nlri) are insertion-sorted in pref_cal order as we receive them, and an idrp_best_ext
 * structure is used to track the route with the best pref_cal for each nlri.
 * We also have invented the concept of a best external routes RIB (BER-Rib).  This 
 * consists of all of the idrp_best_ext structs strung together in unsorted order.  We
 * can use it to dump the entire set of best ext routes when we bring up an I-IDRP peer.
 */
typedef struct _idrp_best_ext {
	struct	_idrpRoute	*p_best_ext;	/* link to best extern route for this destination */
	struct	_idrp_best_ext	*p_prev;	/* link to prev best ext struct in BER-Rib */
	struct	_idrp_best_ext	*p_next;	/* link to next best ext struct in BER-Rib */
	int	refcount;
} idrp_best_ext;


typedef	struct	_idrp_iso_gw {
	gw_entry		gw[IDRP_MAX_LOCAL_NETS-1];
	struct	iso_net_addr	net[IDRP_MAX_LOCAL_NETS-1];
} idrp_iso_gw;

/* idrp Route structure  */
/* saved as rt_data (protocol specific data in rt_entry */
/* of gated */

typedef struct _idrpRoute {
	rt_entry	*p_rt;		/* link to gated routed table */ 
	struct _idrpPeer *peer;		/* Peer from which we received */
					/* this route */
	sockaddr_un	*p_loc_rt_peer;	/* pointer to peer description */
					/* for local route */ 
	gw_entry 	*p_loc_intf;	/* gateway this router is attached to */	
	idrp_attribute_record *p_attr;	/* Attribute record */
					/* pointers to required attributes */
#ifdef	IDRP_QOS		
	struct	_idrpRoute	*p_qos_def;		/* default qos idrpRoute */
	struct	_idrpRoute	*p_rt_qos[IDRP_MAX_RIBS]; /* qos idrpRoute */
#endif
	int	route_id_in;		/* Route ID received */
	int	pref_cal;		/* calculated idrp preference */
	int	pref_rcvd;		/* preference received from internal peer */
	pref_t	gated_pref;		/* gated preference for a route calculated */

	struct	_idrpRoute	*p_next_nlri;	/* > 1 nlri/route id - link list */
	struct	_idrpRoute	*p_with;	/* next on withdrawl list processing -- forward */
	struct	_idrpRoute	*p_with_back;	/* prev on withdrawal list processing -- back */
						/* phase1 or phase 3 uses */
	struct	_idrpRoute	*p_ann_nlri;	/* announcing nlri forward link */
	struct	_idrpRoute	*p_ann_back;	/* announcing nlri back link */
	struct	_idrpRoute	*p_replace;	/* old route this route replacing */
	struct	_idrpRoute	*p_damped_clear;	/* clear the damped route since it has only announced routes  */

    	struct	_idrpRoute	*p_min_adv;	/* link for min route advertisement timer */
	struct	_idrpRoute	*p_min_adv_back;/* back link */
    	struct	_idrpRoute	*p_min_advRD;	/* link for min route within RD timer */
	struct	_idrpRoute	*p_min_advRD_back; /* back link */

	struct	_idrpRoute	*p_next_best;	/* link to next-best external route (if this route */
						/* is external to begin with) */
	struct	_idrpRoute	*p_better;	/* link to next-better external route (if this route */
						/* is external to begin with) */
	struct	_idrp_best_ext	*p_p_best_ext;	/* pointer to idrp_best_ext structure.  Reference */
						/* off of idrp_best_ext to find the best ext route */

#define NLRI_LINKED_P_NEXT	0		/* NLRI linked on P_NEXT */
#define	NLRI_LINKED_P_WITH	1		/* NLRI linked on WITH */
#define	NLRI_LINKED_P_ANN	2		/* NLRI LINKED on ANN */
#define	NLRI_LINKED_P_MINADV	3		/* NLRI LINKED on min_adv */
#define	NLRI_LINKED_P_MIN_ADV_RD 4		/* NLRI LINKED on min_adv_rd */
	
	idrpRoute_out	route_out[IDRP_MAX_PEERS];
					/* Array of outbound route ID */
					/* by peer for this route */
					/* also contains list of other */
					/* nlri announced in route-id */
					/* nlri linked - circular linked list */
	struct iso_prefix nlri;		/* NLRI stored in prefix format */ 
	int	family;			/* family route belongs to */
	int	nlri_id;		/* nlri id for to */
	int	status;			/* status */

#define	IDRP_STATUS_ADJ_RIB		0x1	/* idrp Route AdjRib */
#define	IDRP_STATUS_BEST_EXT		0x2	/* best exterior route */
#define	IDRP_STATUS_LOC_RIB		0x4	/* idrp loc_RIB */
#define	IDRP_STATUS_EXT_INFO		0x8	/* route entry handles ext_info */
					/* annoumeent for idrp */
#define IDRP_STATUS_WITH		0x10	/* withdraw set on this route */
#define	IDRP_STATUS_DEL_SEND 		0x20	/* delete after send route to peer */
#define	IDRP_STATUS_MIN_ADV_CHG		0x40	/* change during min advertisement*/
#define	IDRP_STATUS_REPLACE 		0x80	/* withdrawal/replace */
						/* pdu withdraw id/announce */
						/* timer duration for this route */
#define IDRP_STATUS_DELETE		0x100	/* delete this route */
#define IDRP_STATUS_RECONFIGURE		0x200	/* reconfigure this route */
#define IDRP_STATUS_LOCAL_DAMP_DEL	0x400	/* deleted local route awaiting undamping to delete */
#define	IDRP_STATUS_LOCAL_NEW_ROUTE	0x1000	/* local new route */
#define	IDRP_STATUS_LOCAL_PH3_NEW_ROUTE 0x2000	/* local new route */
#define	IDRP_STATUS_WITH_EARLY_PROC	0x4000	/* early processing of withdraw nlri with others */
						/* of the same route_id outbound */
#define	IDRP_STATUS_REPLACE_PROC	0x8000	/* early processing of REPLACE */

#define	IDRP_STATUS_IGP			0x10000	/* route was learned from the IGP.  Doesn't */
						/* mean we trust routes from ALL IGP's, e.g., RIP. */
#define IDRP_STATUS_LOCAL_RD		0x20000	/* comes from local RD */
#define IDRP_STATUS_DELETED		0x40000 /* this would happen if it were the old damped route, */
						/* and we did a change underneath it */
#define	IDRP_STATUS_MIN_ADV_CHG_RDS	0x80000	/* change during min advertisement*/
#define	IDRP_STATUS_RDLOOP		0x100000  /* nlri from loop deleted route - not installed not advised */
#define	IDRP_STATUS_RID_BAD		0x200000  /* nlri from loop deleted route - not installed not advised */

#define	IDRP_STATUS_LOCAL_ROUTE		0x0	/* local route should have no status bits set */

#define IDRP_STATUS_RD_ROUTE	(IDRP_STATUS_LOCAL_RD | IDRP_STATUS_IGP )
				/* rather trivial, isn't it?  Any route that originated within our RD */

#ifdef	IDRP_QOS
	u_int	qos_status;		/* QOS status flags */

#define	IDRP_STATUS_QOS_NOTACTIVE		0x00
#define	IDRP_STATUS_QOS_ACTIVE			0x01
#define	IDRP_STATUS_QOS_LAST_ACTIVE		0x02
#define	IDRP_STATUS_QOS_CHG			0x04
#define	IDRP_STATUS_QOS_NEW			0x08
#define	IDRP_STATUS_QOS_DEL			0x10
		

#endif 	IDRP_QOS

#define IDRP_STATUS_INT_MASK	(IDRP_STATUS_ADJ_RIB | IDRP_STATUS_BEST_EXT | IDRP_STATUS_LOC_RIB) 
        idrpRoute_options *p_import_opts; /* for storing the "desired" route options... */
        idrpRoute_options *p_export_opts; /* ...as specified by import or export policy */
} idrpRoute;


typedef struct  _rdi{
	struct  _rdi		*p_next;        /* next RDI in global list */
	struct  _rdi		*p_prev;        /* previous global structure */
	u_int			order;		/* order of rdi in global list */
	u_int			refcnt;         /* reference count */   
	struct  iso_net_addr	rdi;		/* saving rdi value */
} rdi;          

#define	IDRP_GLOBAL_RDI_SPACING		3
#define	IDRP_GLOBAL_RDI_ZERO_VALUE	10
/* rdpath  structure used for policy, and for
 * classifying RDI's
 * this structure uses global pointers to
 * a global RDI list
 * -  zero rdi value implies none 
 */

typedef struct  _rdi_array {
	struct  _rdi_array      *p_next;
	struct  _rdi_array      *p_prev;
	rdi     *p_rdi_array[IDRP_RD_PATH_ARRAY_SIZE];
} rdi_array;    


typedef struct _rdpath {
        flag_t          status;                 /* type of path segment */
#define IDRP_RDPATH_SET         	BIT(0x01)
#define IDRP_RDPATH_SEQ         	BIT(0x02)
#define	IDRP_RDPATH_RDC_ENTRY_SEQ	BIT(0x03)
#define	IDRP_RDPATH_RDC_ENTRY_SET	BIT(0x04)

#define IDRP_RDPATH_SINGLE      BIT(0x05)    /* represents '.' */
#define IDRP_RDPATH_ANY         BIT(0x06)    /* represents '.*' */
#define IDRP_RDPATH_OR          BIT(0x07)    /* represents RDI in '|' list */
#define IDRP_RDPATH_TYPE        BIT(0x0f)    /* Gives the policy or actual path element type */
#define IDRP_RDPATH_SUBSET      BIT(0x40)    /* policy RD path's SETs can be a subset of the actual RD path's SETs (otherwise, the match must be exact! */
#define IDRP_RDPATH_NOT         BIT(0x80)    /* may not be needed if we allow */
#define IDRP_RDPATH_FLAG        BIT(0xf0)    /* gives the policy flag */
	struct  _rdpath *p_next;        /* next path segment */
	struct  _rdpath *p_prev;        /* previous path segment */
	u_int	cnt;			/* total number of RDIs in this segment */
	rdi_array rdi_list;             /* RDIs for this path segment */ 
	rdi_array *p_last;		/* last rdi array in this path segement */
} rdpath;

typedef	struct	_rdpath_list {
	struct	_rdpath_list	*p_next;		/* next on global chain */
	struct	_rdpath_list	*p_prev;		/* previous on global chain */ 
	rdpath	*p_start;				/* start of pathway rdi structures */
	rdpath	*p_end;					/* end of pathway rdi structures */
	int	cnt;					/* count of RDIs in pathway list */
	int	path_seg_cnt;				/* count of path segments */ 
	int	refcnt;					/* reference count for rdpath */ 
} rdpath_list;	


typedef struct  _idrp_rdpath_hash {
	struct	_idrp_rdpath_hash	*p_next;   /* list hash table lists that map to same id */ 
	struct	_idrp_rdpath_hash	*p_prev;   /* previous on match on list */ 
        rdi	*p_rdi; 			           /* global rdi pointer */       
        rdpath_list	*p_pl_start;		   /* hash chain of rdpath_lists starting with this rdi */ 
	rdpath_list	*p_pl_end;		   /* end of hash chain of paths starting with rdi */
} idrp_rdpath_hash;


/* PDU like structure to save local RDI in for ease of copying
 * into pdus -- may want to get rid of later
 */ 

typedef struct _RD_path {
	idrp_path_segment_header rd_header;
	struct iso_addr rdi;
} RD_path;


#define RDI_LENGTH_BYTE_LEN		1

/* rdc structure equivalent to rdcConfig 
 * 
 * Set id, idrp_canon_rdpath
 *
 * same set id - same level RDCs
 * different set id - different level of nesting
 * 
 */

typedef	struct	_rdcConfig {
	int	  confed;		/* confederation id */
	u_int	cnt;			/* total number of RDIs in this segment */
	rdi_array rdi_list;             /* RDIs for this path segment */ 
	rdi_array *p_last;		/* last rdi array in this path segement */
} rdcConfig;

typedef	struct	_rdc_ordered {
	int	nest_level;		/* global nest level */
	rdi	*p_rdi;
	int	status;
} rdc_ordered;	

typedef	struct	rdc_path_chk	{
	int	cnt;		/* count of RDCs found in segement */
	int	rdi_index[IDRP_MAX_RDCS]; /* index of RDCs */ 
	rdpath	*p_path;	/* path segement pointer */ 	
} rdc_path_chk;	


/* processing structure for RDCs
 */

typedef struct	_rdc_check {
	u_int			status;		/* status of the rdc */
	
#define	RDC_CHK_STATUS_NOTFOUND		0x00
#define	RDC_CHK_STATUS_FOUND		0x01
#define	RDC_CHK_STATUS_FOUND_TWICE	0x02
#define	RDC_CHK_STATUS_RDC_ENTRY_SEQ	0x10
#define	RDC_CHK_STATUS_RDC_ENTRY_SET	0x20
		
	struct	_rdi		*p_rdi;		/* pointer to global rdi */ 
	struct	_rdpath 	*p_rd_opath;	/* pointer to output path */
	rdi_array		*p_array;	/* pointer to array within rdpath */  		
	int			array_cnt;	/* count of rdi arrays */				
	int			aseq_cnt;	/* count within rdi array  */
	int			pseq_cnt;	/* count of path sequence within sequences  */
	int			rdi_cnt;	/* count within global list */
	int			nest_level;	/* nesting level */
} rdc_check; 

	
/* send list that is created for 
 * send out pdus
 */

typedef struct _idrp_send_list {
	struct	_idrp_send_list	*p_next;	/* next structure on send list */
	idrp_attribute_record 	*p_attr;	/* attr record assoc */
	int	rib_id;				/* rib id of this list */
	u_int	pdu_bytes;			/* pdu bytes used nrli and withdraw id */
	u_int	pdu_bytes_attr;			/* pdu bytes used for attribute */
	byte	loc_pref;			/* local preference */
	idrpRoute_link	ann_nlri[IDRP_NLRI_FAMILIES_SUPPORTED];  
	Withdrawl	*withdraw;		/* withdraw structure */
} idrp_send_list;
		

typedef struct _idrp_ann_list {
	struct	_idrp_ann_list	*p_next;	/* next structure on announce list */
	int	rib_id;				/* rib id of this list */
	idrp_attribute_record 	*p_attr;	/* attr record assoc */
	struct	_idrpPeer	*peer;		/* peer received from */ 
	idrpRoute_link	ann_nlri[IDRP_NLRI_FAMILIES_SUPPORTED];  
	idrpRoute_link	with_nlri[IDRP_NLRI_FAMILIES_SUPPORTED];
} idrp_ann_list;
	
#define	RIB_ID_DEFAULT	0		/* default RIB */


typedef struct _idrpRefresh {
	struct _idrpRefresh	*p_next;	/* linked list */
	idrpPdu		*p_pdu;		/* pdu */ 
	parse_results	*results;	/* results array */
					/* for update parsing */
} idrpRefresh;  

/* idrp RIB REFRESH structure for peer */

typedef	struct {
	u_int	seq_start;	/* sequence number of RIB REFRESH Start */
	idrpRefresh	*pdu_list_start;	/* pdu list for UPDATEs */
	idrpRefresh	*pdu_list_end;		/* pdu list for Updates */	
	u_int	seq_stop;	/* sequence number of RIB REFRESH Stop */
	u_int	cnt;		/* count of pdus to process */  
	u_int	rib_no;		/* internal rib id */
} refresh_info;	 

 

/*
 *  IDRP peer structure
*/

typedef struct _idrpPeer {
    struct _idrpPeer *p_next;        	/* Pointer to next idrpPeer table */
    struct _idrpPeer *p_prev;        	/* Pointer to prev in idrpPeer table */

    u_int type;				/* internal or external neighbor */
#define IDRP_PEER_EXTERNAL	0	/* external peer */
#define IDRP_PEER_INTERNAL	1	/* internal peer */
#define IDRP_PEER_TEST		2	/* debugging peer */
#define IDRP_PEER_LOCAL		3	/* local node's peer structure */

    u_int	proto_sock;		/* protocol IDRP runs over */
    u_int	last_proto_sock;	/* last protocol socket peer structure re-inited */

/* definitions for socket */
#define	IDRP_PDU_PROTO_IP_RAW	0	/* IP PID used for PDU transmission */
#define	IDRP_PDU_PROTO_UDP	1	/* IP UDP used for PDU transmission */
#define	IDRP_PDU_PROTO_CLNP	2	/* CLNP used for PDU transmission */
#define	IDRP_PDU_PROTO_IDRP	3	/* CLNP IDRP socket used for PDU transmission */

    struct iso_net_addr	neighbor;	/* Neighbor's address ISO */
    struct iso_net_addr iso_gw_addr;	/* ---skh to be change iso gw until we meld neighbor */	
    struct iso_net_addr iso_intf_addr;	/* Interface address for iso */ 
					/* IP address of the neighbor is kept in the gw_entry struct */
#define ip_neighbor	gw.gw_addr
    sockaddr_un		*ip_intf_addr;

    struct iso_net_addr	rdi;		/* Neighbor's RDI is always an ISO Address */
					/* be it IP or ISO */ 
#define rdi_addr	rdi.isoa_genaddr
#define rdi_length	rdi.isoa_len


    rdcConfig	rdc_peer[IDRP_MAX_RDC_NESTING];	 	/* Peer's rdcs */
    rdcConfig	rdc_peer_diff[IDRP_MAX_RDC_NESTING];	/* Peer's rdcs */

    int		no_rdc;					/* number of RDCs peer is in */ 
    int		no_rdc_diff;				/* number of RDCs different from this node's */ 	
    rdc_ordered	rdc_diff[IDRP_MAX_RDCS];		/* Peers rdcs in ordered list */	
    rdc_ordered	rdc_not_diff[IDRP_MAX_RDCS];		/* peers rdcs not different */	

#define		IDRP_RDC_PEER		00		/* RDC process for all peer RDCs */
#define		IDRP_RDC_LOCAL		01		/* RDC process for all local nodes RDCs */ 	
#define		IDRP_RDC_DIFF		02		/* RDC processing for difference RDCs between two peers */ 

    u_int	version;		/* version number */
    snpa_list	snpa;			/* SNPAs for this peer reception */ 
					/* RDC goes here */
    u_int	AuthType;		/* Authentication type */ 
    u_int	AuthCodelen;		/* Size of PW or Auth code value */
    u_char	AuthCode[IDRP_AUTH_CODE_SIZE];  	/* Authentication code for this peer */
    u_int       Capacity;               /* capacity */
    u_int	Expense;                /* expense */
    u_int	multi_exit;		/* multi_exit set on neighbor */
    u_int	Priority;		/* min priority to forward PDU */    
    u_short	pdu_maxsendsize;	/* Max PDU size to send */
    u_short	pdu_maxrcvsize;		/* Max PDU size to receive */
    u_int       rdLRE;                  /* configured error rate */
    u_int       rdTransitDelay;         /* configured error rate */
    u_int	route_server;		/* router server allowed function */

    u_int	listen_for_open;	/* listen for open in close state */
    u_int	max_open_sent;		/* max number open to send in seq */
					/* before going into close wait */ 

    u_int	refresh_flags;		/*  flag about rib refresh */

#define		SEND_RIB_REFRESH_ON_HUP	0x01		/* send the rib refresh */
#define		SEND_UPDATE_ON_HUP	0x00		/* send deltas in updates */ 
 	
    u_int	nlri_supp[IDRP_NLRI_FAMILIES_SUPPORTED];	/* nlri supported */
								/* filled with AF_xxx */
							        /* of protocol supported */
    int		nrib_supp;			/* number of ribs supported by the peer */ 	
    int		nrib_last_supp;			/* number of ribs supported by the peer */ 	

#ifdef		IDRP_QOS
    u_int	rib_supp[IDRP_MAX_RIBS];	/* ribs supported by the peer */	
    u_int	last_rib_supp[IDRP_MAX_RIBS];	/* last_ribs supported by the peer */	
#endif		/* IDRP_QOS */

   idrpRoute_options	*p_ext_info;	/* Default External attribute information   
					 * to be set on ext_info translated into
					 * idrp routes.   
					 * Exporting of routes may give another attribute
					 */

   idrpRoute_options	*p_local_info;	/* Default Local attribute information   `
					 * to be set on ext_info translated into
					 * idrp routes.   
					 * Exporting of routes may give another attribute
					 */
	
/* stateInfo */

    u_int state;                   	/* Protocol State */
    u_int send_next;			/* Seq of next PDU to send */
    u_int upper_window_edge;		/* Seq+1 of last PDU we can send */
    u_int send_unack;			/* Seq of oldest unacked PDU */

    u_int rcv_seq_expected;		/* Expected seq of next PDU received */
    u_char rcv_credit;			/* Max outstanding PDUs to receive */
    u_char rcved_credit_avail;		/* Last received credit_available */
    u_int cred_avail_zero_seq;		/* Sequence # of last seqed PDU with cred_avail = 0 */
    u_int cred_avail_zero_seq_last;	/* Previous value of above */
    refresh_info	refresh;	/* RIB REFRESH information */

/* Counters */

    u_int	open_sent;		/* open bispdus sent since start event */
    u_int	updatesIn;		/* Update pdu received from peer */
    u_int	updatesOut;		/* Update pdu send to peer */
    u_int	totalBISPDUIn;		/* total BISPDUs received from peer */
    u_int	totalBISPDUOut;		/* total BISPDUs sent to peer */
    u_int	keepAlives_Since_last_Update;
					/* keepalives from peer */
 
/* information on AdjRibIn */ 
 
    u_int checksum;			/* checksum for AdjRibIn for peer */ 
    u_int AdjRibBad;			/* indication that AdjRibIn is bad */

/* general  helps for gated */
    flag_t idrp_flags;                 	/* Protocol Flags */
    u_int config_options;                 	/* User specified options */

#define   IDRP_CNF_OPT_NET_AUTO_CONFIG    0x01            /* NET creates NLRI */
#define   IDRP_CNF_OPT_EXPAND_NEXT_HOP    0x02            /* Expanded next hop definitions */
#define   IDRP_CNF_OPT_EXPAND_NEXT_HOP_OFF 0xFD           /* next hop off */

#define   IDRP_CNF_OPT_DEFAULT            0x00            /* no bits set */

    task *task;                    	/* Pointer to task */
    trace *trace_options;            	/* Trace info from parser */

#define	IDRP_TRACE_PDUS		0x01	/* trace pdus send/xmt */
#define	IDRP_TRACE_POLICY	0x02	/* trace pdus send/xmt */
#define IDRP_TRACE_SM		0x04	/* trace SM changes */
#define IDRP_TRACE_SM_ERR	0x08	/* trace SM errors, reception of Error pdus */
#define IDRP_TRACE_MINADV	0x10	/* trace Minimum route advertisement logic */
#define IDRP_TRACE_HOLDTIME	0x20	/* trace holdtime logic */
#define IDRP_TRACE_REXMIT	0x10	/* trace Retransmit timer logic */
#define IDRP_TRACE_CLOSE	0x10	/* trace close timer and close stay timers and logic */
#define IDRP_TRACE_PHASE1_LOG	0x20	/* trace phase1 logic */
#define IDRP_TRACE_PHASE3_LOG	0x40	/* trace phase3 logic */
#define IDRP_TRACE_NLRI		0x80	/* nlri rcved or sent pdus */
#define IDRP_TRACE_DEBUG	0x100	/* debugging information pdus */
#define IDRP_TRACE_ROUTE_TIES	0x100	/* trace IDRP ROUTE TIES */

#define	IDRP_TRACE_SM_INFO	IDRP_TRACE_SM | IDRP_TRACE_SM_ERR
#define IDRP_TRACE_TIMERS	IDRP_TRACE_MINADV | IDRP_TRACE_HOLDTIME | IDRP_TRACE_REXMIT |IDRP_TRACE_CLOSE
 
#define IDRP_TRACE_LOGIC	IDRP_TRACE_PHASE1_LOG | IDRP_TRACE_PHASE3_LOG | IDRP_TRACE_ROUTE_TIES

#define IDRP_TRACE_DEFAULT	(IDRP_TRACE_SM_ERR | IDRP_TRACE_TIMERS | IDRP_TRACE_LOGIC | IDRP_TRACE_NLRI )


    char name[61];              	/* Name of this peer */
    gw_entry iso_gw;			/* iso gateway for this peer */ 
    gw_entry gw;                   	/* GW block for this peer */
 					/* note IP address kept in gw block */
					/* policy linked in gated structures */ 

    idrp_iso_gw *p_local_iso_gw;	/* extra iso gateways for multiple NETs */

/* idrp_addr = gw.gw_addr  - changed here to make sure I catch all the address assignments */
#define idrp_import     gw.gw_import
#define idrp_export     gw.gw_export
#define idrp_time       gw.gw_time


/* route ID out information */ 

    u_int route_id_out;			/* current route_id_out */
    u_int  id;				/* Peer id in idrpRouteout */

/* route ID inbound hash table */
    struct	_idrp_rid_hash	hash_table[IDRP_HASH_TABLE_SIZE];
					/* hash table for route_id in */ 
/* debugging for idrp */

    error_info	last_error_pdu;		/* error codes last ERROR pdu sent */ 
					/* used in parsing of pdus */

/* timers */
/* switches for  timers running */

    u_char rexmit_timer_running;	/* NZ if rexmit timer is running */
    u_char start_timer_running;		/* NZ if start timer is running */

/* time values for the timers */

    time_t max_rib_integ_check;		/* rib checksum time */	
    time_t ribcheck_timer;		/* rib checksum timer */	
    time_t keepalive_time;		/* Send keepalives more often than this */
    time_t hold_time;			/* Kill connection if this time goes by */
    time_t close_wait;			/* close wait time */
    time_t rexmit_time;			/* Retransmit outstanding packets after this time */
    time_t opensent_time;		/* time between open pdus sent to peer */ 
					/* if zero, 1 pdu and holdtime to close */
    time_t min_adv_time;		/* time for min_advertisement */
    time_t min_advRD_time;		/* time for min_advertisement within this RD. Only used */
    					/* local node. */
    time_t cpu_overload_time;		/* time between checking for CPU overload */
    time_t closestay;			/* time to stay in close */
    time_t qos_poll_time;		/* time to poll qos */
    	
    idrpBuffer *xmit_queue_head;	/* Transmit queue; can be kinda long */
    idrpBuffer **xmit_queue_tail;	/* Transmit queue tail */
    idrpBuffer *rexmit_queue_head;	/* Retransmit queue */
    idrpBuffer **rexmit_queue_tail;	/* Retransmit queue tail */

/* timers */
    task_timer *idrp_keepalive_timer;
    task_timer *idrp_closewait_timer;
    task_timer *idrp_closestay_timer;
    task_timer *idrp_hold_timer;
    task_timer *idrp_start_timer;
    task_timer *idrp_retransmit_timer;
    task_timer *idrp_minadvRD_timer;
    task_timer *idrp_minadv_timer;
    task_timer *idrp_opensent_timer;
    task_timer *idrp_qos_timer;

/* minimum route advertisement timer */
#define IDRP_MIN_ADV_TIMER_TYPE		0	/* minimum route advertisement timer  */
#define IDRP_MIN_ADVRD_TIMER_TYPE 	1	/* minimum route Adv timer with RD */

#define	IDRP_MIN_ADV_TYPE		0	/* minimum route advertisement timer list */
#define	IDRP_MIN_ADVRD_TYPE		1	/* minimum route advertisement RD timer list */
#define IDRP_MINADV_PHASE1		0	/* minimum route adver processing phase 1 */
#define	IDRP_MINADV_PHASE3		1	/* minimum route adver processing phase 3 */	

    time_t	min_adv_started;	/* time min adv started */ 
    int		start_min_adv;		/* flag for need to start min_adv with current time slot */	
    idrpAdvRt	*p_minadv_head;		/* minimum route advertisement list */
    idrpAdvRt	*p_minadv_tail;		/* current adding min adver list */

    time_t	min_advRD_started;	/* time min_advRD started */
    int		start_min_advRD;	/* flag for need to start min_adv with current time slot */
    idrpAdvRt	*p_minadvRD_head;	/* minimum rt AdvRd list head  */
    idrpAdvRt	*p_minadvRD_tail;	/* minimum rt advRD list tail  */	
} idrpPeer;

typedef	struct	_idrp_group_parms {

    u_int			type;	/* type of the peer */
    struct	iso_net_addr   rdi;	/* rdi	            */
} idrp_group_parms;	

 
/* idrp status flags */
#define	IDRPF_UNCONFIGURED	0x00	/* incomplete configuration if zero */
#define	IDRPF_DELETE		0x01	/* delete this peer - it has been deleted from config */
#define	IDRPF_TRY_CONNECT	0x02	/* idrp trying to connect - but connection down */
#define	IDRPF_CONNECT		0x04	/* idrp peer connected */
#define	IDRPF_WRITEFAILED	0x10	/* idrp write to task socket failed */
#define IDRPF_IDLED             0x40    /* This peer is permanently idled - by off on config line */

/* Timers */
#define IDRPTIMER_KEEPALIVE     0       /* Fire when we should send a keepalive */
#define IDRPTIMER_HOLDTIME      1       /* Fire when hold time expires */
#define IDRPTIMER_REXMIT	2	/* Fire when we should retransmit a packet */
#define IDRPTIMER_CLOSEWAIT	3	/* Fire when close waiting is done */
#define IDRPTIMER_START		4	/* Fire when starting up the first time */
#define	IDRPTIMER_OPENSENT	5	/* Fire when open sent x times before restart */ 
#define IDRPTIMER_MIN_ADV	6	/* Fire when minimum route advertisement */
#define IDRPTIMER_CLOSESTAY     7
#define IDRPTIMER_MAX		8	
#define IDRP_MASTER_TIMER_MIN_ADV	0	/* Fire when minimum route advertisement */
#define IDRP_MASTER_TIMER_MIN_ADVRD	1	/* Fire when minimum route advertisement */
#define IDRP_MASTER_TIMER_QOS		2	/* Fire when minimum route advertisement */
 
#define IDRP_MASTER_TIMERS_MAX	3	/* timers for master task */

/* Protocol States--MUST BE THE SAME AS FSM_ERROR CODES!! */
#define IDRP_CLOSED		1	/* Connection closed */
#define IDRP_OPEN_RCVD		2	/* Open received */
#define IDRP_OPEN_SENT		3	/* Open sent */
#define IDRP_CLOSE_WAIT		4	/* Closing connection */
#define IDRP_ESTABLISHED	5	/* Connection established */
 
/* Events */
#define IDRP_START_EVENT	0	/* Start a connection */
#define IDRP_STOP_EVENT		1	/* Stop a connection */
#define IDRP_CLOSE_TIMEOUT	2	/* Close_wait timeout */
#define IDRP_HOLDTIME_TIMEOUT	3	/* Hold time timeout */
#define IDRP_HEADER_ERROR	4	/* BISPDU header error */
#define IDRP_KEEPALIVE		5	/* KEEPALIVE with no errors */
#define IDRP_CEASE		6	/* IDRP CEASE with no errors */
#define IDRP_OPEN_ERROR		7	/* IDRP OPEN with errors */
#define IDRP_OPEN		8	/* IDRP OPEN with no errors */
#define	IDRP_UPDATE_ERROR	9	/* IDRP UPDATE with errors */
#define	IDRP_UPDATE		10	/* IDRP UPDATE with no errors */
#define	IDRP_ERROR_ERROR	11	/* IDRP ERROR with errors */
#define IDRP_ERROR		12	/* IDRP ERROR with no errors */
#define IDRP_REFRESH_ERROR	13	/* IDRP RIB REFRESH with errors */
#define IDRP_REFRESH		14	/* IDRP RIB REFRESH with no errors */
#define IDRP_REXMIT_TIMEOUT	15	/* Retransmission timeout */
#define IDRP_KEEPALIVE_TIMEOUT	16	/* Keepalive timeout */
#define IDRP_SEND_PDU		17	/* Send a PDU */


/* Management event codes */

#define IDRP_BAD_LENGTH 	0	/* PDU length bad */
#define IDRP_BAD_PDU_TYPE	1	/* PDU type bad */
#define IDRP_PDU_HEADER_ERROR	2	/* PDU header bad */
#define IDRP_ERROR_PDU_ERROR	3	/* ERROR PDU has error */


/* Management event types */

#define IDRP_PDU_HEADER_ERR_BAD_TYPE	1	/* bad type on HEADER */

/* EXT_INFO information */

#define	IDRP_EXT_INFO_EXT_INFO	10	/* external information from other protocols */
#define	IDRP_EXT_INFO_IGP	5	/* external to idrp but internal to is-is (IGP) */  


/* UPDATE processing flags */

#define	IDRP_UPDATE_PARSE_OK		0	/* update parses OK */	
#define	IDRP_UPDATE_PARSE_ERROR		1	/* update parse error */
#define	IDRP_UPDATE_PARSE_RDLOOP_ERROR	2	/* update RD LOOP error */

#define IDRP_RDPATH_PARSE_FAILED	0	/* parse of RD path failed */
#define	IDRP_RDPATH_RDLOOP		1	/* loop found in RD path */
#define	IDRP_RDPATH_LOCAL_LOOP		2	/* adding local RD added loop */  	
#define	IDRP_RDPATH_VALID		3	/* rdpath valid */ 



/* Tracing */

#define	TR_IDRP_DETAIL_OPEN	TR_DETAIL_1
#define	TR_IDRP_DETAIL_UPDATE	TR_DETAIL_2
#define	TR_IDRP_DETAIL_KEEPALIVE	TR_DETAIL_3

#define	TR_IDRP_INDEX_PACKETS	0
#define	TR_IDRP_INDEX_OPEN	1
#define	TR_IDRP_INDEX_UPDATE	2
#define	TR_IDRP_INDEX_KEEPALIVE	3

#define	TR_MINADV		TR_USER_1
#define	TR_PHASE1		TR_USER_2
#define	TR_PHASE3		TR_USER_3
#define TR_ROUTE_TIES		TR_USER_4
#define TR_IDRP_DEBUG		TR_USER_5

#include "idrp_policy.h"
#include "idrp_qos.h" 	
#include "idrp_globals.h"
#include "idrp_prototypes.h"
#include "idrp_macros.h"
#include "idrp_proto_parse.h"

#endif /* not defined _idrp_h */



