/* 
 * $Id: idrp_proto.h,v 1.5 1995/10/31 17:13:35 skh Exp $
 * Merit IDRP release 1.1 (gated 3.5.4).  Copyright (c) 1994 by Merit Network, Inc. 
 */

/* 
 *    IDRP Protocol definitions
 */

#define IDRP_VERSION_1 1		/* Version of IDRP protocol */
#define IDRP_MAX_VERSION	IDRP_VERSION_1	/* maximum supported version of IDRP */ 

#define IDRP_PID	0x85		/* NLPID for IDRP */
#define CLNP_NLPID 0x81			/* Protocol ID for CLNP */

#ifndef	IP_NLPID
#define IP_NLPID 0xcc			/* Protocol ID for IP */
#endif

#ifndef	SIP_PROTO_PID
#define SIP_PROTO_PID	0x8000000086dd	/* PROTO_ID for SIP */
#endif
/* idrp timer constants determined by the protocol specification */

#define IDRP_MIN_ADVRD	60*15		/* minimum advertisement within RD = 30  */


/*
 * IDRP fixed header.  This header is on the front of all IDRP PDUs.
 * Specific PDU structures follow.
 */
 

typedef struct _idrp_fixed_pdu_header{
        u_char pid;                     /* Protocol ID */
        u_char pdu_length[2];           /* PDU length */
        u_char pdu_type;                /* PDU type */
        u_char seq[4];                  /* Sequence number */
        u_char ack[4];                  /* Acknowledgement */
	u_char credit_offered;		/* Credit offered to receiver */
	u_char credit_available;	/* Sender's idea of remaining credit */
        u_char validation[16];          /* Validation pattern */
} idrp_fixed_pdu_header;

typedef struct {
	struct iso_addr dest;		/* Destination address %% */
	struct iso_addr src;		/* Source address %% */
} idrp_udp_header;

typedef	struct	{
		idrp_udp_header	 hdr;		/* udp header */
		u_char		pdu[1];		/* offset to first byte of idrp pdu */
} idrp_fixed_udp_header;
 

typedef	struct	{
	struct	ip		hdr;		/* ip header upon receiving the pdu */
	u_char			pdu[1];		/* 1st byte of idrp pdu */ 
} idrp_fixed_ip_header;

typedef	struct	{
		struct	clnp_fixed	clnp_header;	/* clnp header upon receiving the pdu */
		struct	iso_addr	dest;		/* destination */ 
		struct	iso_addr	src;		/* source */
		u_char			pdu[1];		/* 1st byte of idrp pdu */	
} idrp_fixed_clnp_header;

typedef	struct	{
		struct	iso_addr	dest;	/* destination */
		struct	iso_addr	src;	/* source */
}idrp_idrp_header;

typedef	struct	{
		idrp_idrp_header	idrp_header;	/* idrp socket header for pdu */
		u_char			pdu[1];		/* 1st byte of data */
} idrp_fixed_idrp_header;

typedef struct _idrp_prot_header {
        union {
                idrp_fixed_udp_header	udp;
                idrp_fixed_ip_header	ip;
		idrp_fixed_clnp_header	clnp;
		idrp_fixed_idrp_header	idrp;
		} hdr;
} idrp_proto_header;


#define	MinPDULength	sizeof(idrp_fixed_pdu_header) /* minimum pdu length */ 

#define IDRP_IP_HEADER_LEN	sizeof(struct ip)	/* addition header length for  of PID */
#define	IDRP_UDP_HEADER_LEN	sizeof(idrp_udp_header)	/* additional header length of UDP packet */
#define	IDRP_CLNP_HEADER_LEN	sizeof(idrp_fixed_clnp_header)	/* additional header length of UDP packet */
#define	IDRP_IDRP_HEADER_LEN	sizeof(idrp_fixed_clnp_header)	/* additional header length of UDP packet */


 
/* PDU Types */
 
#define IDRP_OPEN_TYPE 1                /* OPEN */
#define IDRP_UPDATE_TYPE 2              /* UPDATE */
#define IDRP_ERROR_TYPE 3               /* ERROR */
#define IDRP_KEEPALIVE_TYPE 4           /* KEEPALIVE */
#define IDRP_CEASE_TYPE 5               /* CEASE */
#define IDRP_RIB_REFRESH_TYPE 6         /* RIB refresh */
#ifdef ECHOKLUDGE
#define IDRP_ECHO_TYPE 7		/* ECHO %% */
#define IDRP_ECHO_REPLY_TYPE 8		/* ECHO reply %% */
#define IDRP_PDUTYPE_MAX 8		/* Max PDU type number */
#else
#define IDRP_PDUTYPE_MAX 6 
#endif
 
 
 
/*
 * OPEN PDU
 */
 
 
typedef struct {
        u_char version;                 /* Version number */
        u_char idrp_hold_time[2];       /* Holding timer */
        u_char idrp_maxpdu_size[2];     /* Max PDU size */
} idrp_open_pdu_header;

#define IDRP_MIN_OPEN_PDU_SIZE 41	/* minimum length of OPEN PDU */
					/* fixed header + 11 */  
#define IDRP_MAX_OPEN_PDU_SIZE 3000	/* maximum length of OPEN PDU */

typedef struct {
        u_char source_RDI_length;       /* Length of RDI */
        u_char source_RDI[1];           /* RDI (variable) */
} idrp_source_RDI;

#define IDRP_MAX_RDI_LENGTH 20         		 /* Max length of an RDI */
#define IDRP_RDI_LENGTH_BYTE_LEN	1	/* RDIs are in bytes */ 

 
typedef struct {
        u_char RIB_att_count;           /* zero for now! */
} idrp_RIB_att;

#define RIB_ATT_DEFAULT_ONLY_COUNT	0	/* default rib attributes */	

 
typedef struct {
        u_char confed_id_count;         /* zero for now! */
} idrp_confed_id;

#define NO_RDC_SUPPORT_COUNT		0	/* no RDC support for now */	

/* maximum outstanding pdu size  definitions 
 */

#define IDRP_MAX_OUTSTANDING_PDU	255	/* maximum outstand pdus */ 

#define IDRP_AUTH_CODE_TEST    0	/* no authentication done */
#define IDRP_AUTH_CODE_CLEAR   1        /* Validation data is cleartext */
#define IDRP_AUTH_CODE_CRYPT   2        /* Validation data is encrypted */
/* %% */
#define	IDRP_AUTH_CODE_SIMPLE  3	/* validation of data simple password */
#define IDRP_AUTH_CODE_SIZE   16	/* sixteen bytes of Authentication data */
 
typedef struct {
        u_char authentication_code;     /* 1 = no encryption, 2 = encryption */
} idrp_authentication_code;
 
 
typedef struct {
    idrp_open_pdu_header header;        /* PDU Header (fixed) */
    idrp_source_RDI source_rdi;         /* Source RDI (variable) */
    idrp_RIB_att rib_att;               /* RIB attributes (variable) */
    idrp_confed_id confed_id;           /* Confederation ID (variable) */
    idrp_authentication_code auth_code; /* Authentication code (fixed) */
    u_char auth_data[1];                /* Authentication data (variable) */
} idrp_open_pdu;
 
/*
 * UPDATE PDU
 */
 
typedef struct {
	u_char id_byte[4];		/* Route ID */
} route_id;

typedef	struct	{
	route_id	id;		/* route ID */
	u_char		loc_pref;	/* local preference */
} route_separator; 

typedef struct {
	route_id	array[1];	 /* route_id array */
}route_id_array;


/*
 * Path attributes consist of a set of flag/type/length/value quadruplets.
 */
 
typedef struct _idrp_path_attr_hdr {
        u_char attr_flags;              /* Path attribute flags */
        u_char attr_type;               /* Path attribute type */
        u_char attr_length[2];          /* Path attribute length */
} idrp_path_attr_hdr;

#define		ATTRIBUTE_LENGTH_SIZE	2	/* size of ATTRIBUTE length field */

typedef struct {
        idrp_path_attr_hdr attr_hdr;    /* Attribute header */
        u_char attr_data[1];            /* Path attribute data (variable) */
} idrp_path_attr;
 

/* Attribute types */

/* local defined type */
#define IDRP_ATTR_LOCAL_RD	0			/* local RD path put as */

/* idrp defined type */

#define IDRP_ATTR_ROUTE_SEPARATOR 1			/* Route ID */
#define IDRP_ATTR_EXT_INFO	2 			/* External Info */
#define IDRP_ATTR_RD_PATH	3                       /* RD_Path */
#define IDRP_ATTR_NEXT_HOP	4                       /* NEXT_HOP */
#define IDRP_ATTR_DIST_LIST_INCL 5			/* DIST_LIST_INCL */
#define IDRP_ATTR_DIST_LIST_EXCL 6                      /* DIST_LIST_EXCL */
#define IDRP_ATTR_MULTI_EXIT_DISC 7                     /* MULTI-EXIT_DISC */
#define IDRP_ATTR_TRANSIT_DELAY  8			/* Transit_Delay */
#define IDRP_ATTR_RESIDUAL_ERROR 9                     /* Residual_Error */
#define IDRP_ATTR_EXPENSE 10                            /* Expense */
#define IDRP_ATTR_LOCALLY_DEF_QOS 11 			/* Local QOS */
#define IDRP_ATTR_HIERARCH_REC 12                       /* Hierarchical_Recording */
#define IDRP_ATTR_HOP_COUNT 13                          /* RD hop count */
#define IDRP_ATTR_SECURITY 14          			/* Source specific security */
#define IDRP_ATTR_CAPACITY 15                           /* Capacity */
#define IDRP_ATTR_PRIORITY 16                           /* Priority */
#define IDRP_ATTR_MAX 16				/* Number of types */
#define IDRP_ATTR_NO	IDRP_ATTR_MAX+1			 /* MAX plus Local */
#define IDRP_ATTR_MIN 1 
#define IDRP_ATTR_USR_MIN       128
#define	IDRP_ATTR_ATOMIC_AGGR	IDRP_ATTR_USR_MIN+1	/* BGP Atomic aggregator */
#define	IDRP_ATTR_AGGREGATOR	IDRP_ATTR_USR_MIN+2	/* BGP Aggregator */
#define	IDRP_ATTR_SDRP		IDRP_ATTR_USR_MIN+2	/* SDRP speaker */

#define IDRP_ATTR_USR_MAX	IDRP_ATTR_SDRP		/* we will support User Attributes */
#define IDRP_ATTR_USR_NO	IDRP_ATTR_USR_MAX-IDRP_ATTR_USR_MIN+1

#define	IDRP_XMIT_NEXT_HOP		0			/* first changable attribute is NEXT_HOP */
#define	IDRP_XMIT_MULTI_EXIT_DISC	1			/* 2nd changeable attribute is MULTI_EXIT */ 
#define	IDRP_XMIT_HIER			2			/* 3rd changeable attribute is DIST_LIST_INCL/EXCL */
#define	IDRP_XMIT_RDPATH		3			/* 3rd changeable attribute is DIST_LIST_INCL/EXCL */
#define	IDRP_XMIT_ATTR_MAX		IDRP_XMIT_RDPATH	/* 4th changeable attribute */		 
#define	IDRP_XMIT_ATTR_NO		IDRP_XMIT_ATTR_MAX+1	/* number of XMIT attributes */
	
		

/* attribute BIT types for idrp mask */
/* attribute mask = setting of all bit types */
/* 15 attributes = long variable for attribute types */ 

#define IDRP_ATTBT_LOCAL_RD		BIT(0x0)    /* no bits for this one */
#define IDRP_ATTBT_ROUTE_SEPARATOR	BIT(0x1)    /* route id present */ 
#define	IDRP_ATTBT_EXT_INFO		BIT(0x2)    /* ext info present */
#define IDRP_ATTBT_RD_PATH		BIT(0x4)    /* rd_path present  */
#define IDRP_ATTBT_NEXT_HOP		BIT(0x8)    /* next hop present */
#define IDRP_ATTBT_DIST_LIST_INCL 	BIT(0x10)   /* DIST_LIST_INCL */
#define IDRP_ATTBT_DIST_LIST_EXCL 	BIT(0x20)   /* DIST_LIST_EXCL */
#define IDRP_ATTBT_MULTI_EXIT_DISC 	BIT(0x40)   /* MULTI-EXIT_DISC */
#define IDRP_ATTBT_TRANSIT_DELAY 	BIT(0x80)   /* Transit_Delay */
#define IDRP_ATTBT_RESIDUAL_ERROR 	BIT(0x100)  /* Residual_Error */
#define IDRP_ATTBT_EXPENSE 		BIT(0x200)  /* Expense */
#define IDRP_ATTBT_LOCALLY_DEF_QOS      BIT(0x400)  /* Local QOS */
#define IDRP_ATTBT_HIERARCH_REC		BIT(0x800)  /* Hierarchical_Recording */
#define IDRP_ATTBT_HOP_COUNT 		BIT(0x1000) /* RD hop count */
#define IDRP_ATTBT_SECURITY 		BIT(0x2000) /* Source specific security */
#define IDRP_ATTBT_CAPACITY		BIT(0x4000) /* Capacity */
#define IDRP_ATTBT_PRIORITY		BIT(0x8000) /* Priority */
#define	IDRP_ATTBT_ATOMIC_AGGR		BIT(0x10000) /* BGP Atomic aggregator */
#define	IDRP_ATTBT_AGGREGATOR		BIT(0x20000) /* BGP Aggregator */
#define	IDRP_ATTBT_SDRP			BIT(0x40000) /* SDRP speaker */
#define IDRP_ATTBT_MAX 19 			/* Number of bits */
#define IDRP_ATTBT_MANDATORY   (IDRP_ATTBT_ROUTE_SEPARATOR | IDRP_ATTBT_RD_PATH | IDRP_ATTBT_HOP_COUNT | IDRP_ATTBT_CAPACITY)
					        /* mandatory */
#define IDRP_ATTBT_DISTINGUISH  (IDRP_ATTBT_TRANSIT_DELAY | IDRP_ATTBT_RESIDUAL_ERROR | IDRP_ATTBT_EXPENSE \
			 | IDRP_ATTBT_PRIORITY | IDRP_ATTBT_SECURITY | IDRP_ATTBT_LOCALLY_DEF_QOS)
#define	IDRP_ATTBT_NONDIST1 		(IDRP_ATTBT_MANDATORY | IDRP_ATTBT_EXT_INFO | IDRP_ATTBT_DIST_LIST_INCL | IDRP_ATTBT_DIST_LIST_EXCL \
					| IDRP_ATTBT_MULTI_EXIT_DISC | IDRP_ATTBT_HIERARCH_REC)
 
#define	IDRP_ATTBT_USR		(IDRP_ATTBT_ATOMIC_AGGR | IDRP_ATTBT_AGGREGATOR | IDRP_ATTBT_SDRP)

#define	IDRP_ATTBT_NON_DISTINGUISH	IDRP_ATTBT_NONDIST1 | IDRP_ATTBT_USR | IDRP_ATTBT_NEXT_HOP

#define	IDRP_ATTBT_ALL_BUT_NEXT_HOP	IDRP_ATTBT_NONDIST1 | IDRP_ATTBT_USR

#define IDRP_ATTBT_UNSUPPORTED -1 		/* valid, not supported Distingushing attributes */
#define IDRP_ATTBT_NEW  0			/* valid attributes */
						/* <= 0 */ 



/* Attribute flags */

#define IDRP_ATTR_FLAG_WELLKNOWN 0x40          /* well-known,mandatory   */
#define	IDRP_ATTR_FLAG_MANDATORY  0x01 		/* mandatory are well known */
#define	IDRP_ATTR_FLAG_DISCRET	  0x02		/* DISCRETIONARY ARE WEll known */

#define IDRP_ATTR_FLAG_OPTIONAL 0x80            /* optional flag */
#define IDRP_ATTR_FLAG_TRANSITIVE 0x40          /* transitive flag  */
#define IDRP_ATTR_FLAG_PARTIAL 0x20             /* Partial flag */

#define	IDRP_ATTR_FLAG_OPT_TRANS 0xc0		/* optional transitive flag */ 

#define	IDRP_ATTR_FLAG_WELLKNOWN  0x40		/* well know attributes have transitive bit on */


/* Attribute flag types */

#define	IDRP_ATTRFLG_LOCAL_RD		IDRP_ATTR_FLAG_PARTIAL	  /* make local RD a bogus value */
#define IDRP_ATTRFLG_ROUTE_SEPARATOR	IDRP_ATTR_FLAG_WELLKNOWN  /* Route ID */
#define IDRP_ATTRFLG_EXT_INFO   	IDRP_ATTR_FLAG_WELLKNOWN  /* External Info */
#define IDRP_ATTRFLG_RD_PATH    	IDRP_ATTR_FLAG_WELLKNOWN  /* RD_Path */
#define IDRP_ATTRFLG_NEXT_HOP   	IDRP_ATTR_FLAG_WELLKNOWN  /* NEXT_HOP */
#define IDRP_ATTRFLG_DIST_LIST_INCL 	IDRP_ATTR_FLAG_WELLKNOWN  /* DIST_LIST_INCL */
#define IDRP_ATTRFLG_DIST_LIST_EXCL 	IDRP_ATTR_FLAG_WELLKNOWN  /* DIST_LIST_EXCL */
#define IDRP_ATTRFLG_MULTI_EXIT_DISC	IDRP_ATTR_FLAG_OPTIONAL   /* MULTI-EXIT_DISC */
#define IDRP_ATTRFLG_TRANSIT_DELAY	IDRP_ATTR_FLAG_WELLKNOWN  /* Transit_Delay */
#define IDRP_ATTRFLG_RESIDUAL_ERROR	IDRP_ATTR_FLAG_WELLKNOWN  /* Residual_Error */
#define IDRP_ATTRFLG_EXPENSE		IDRP_ATTR_FLAG_WELLKNOWN  /* Expense */
#define IDRP_ATTRFLG_LOCALLY_DEF_QOS	IDRP_ATTR_FLAG_WELLKNOWN  /* Locally Defined QOS */
#define IDRP_ATTRFLG_HIERARCH_REC	IDRP_ATTR_FLAG_WELLKNOWN  /* Hierarchical_Recording */
#define IDRP_ATTRFLG_HOP_COUNT		IDRP_ATTR_FLAG_WELLKNOWN  /* RD hop count */
#define IDRP_ATTRFLG_SECURITY		IDRP_ATTR_FLAG_WELLKNOWN  /* security */
#define IDRP_ATTRFLG_CAPACITY		IDRP_ATTR_FLAG_WELLKNOWN  /* Capacity */
#define IDRP_ATTRFLG_PRIORITY		IDRP_ATTR_FLAG_WELLKNOWN  /* Priority */

/* optional attributes */

#define	IDRP_ATTRFLG_ATOMIC_AGGR	IDRP_ATTR_FLAG_OPT_TRANS /* BGP Atomic aggregator */
#define	IDRP_ATTRFLG_AGGREGATOR		IDRP_ATTR_FLAG_OPT_TRANS /* BGP Aggregator */
#define	IDRP_ATTRFLG_SDRP		IDRP_ATTR_FLAG_OPT_TRANS	/* SDRP speaker */
 

/* path attribute definitions */
/* Attribute types */

#define	IDRP_ATTRMAN_LOCAL_RD		IDRP_ATTR_FLAG_OPTIONAL  /* make local RD a bogus value */
#define IDRP_ATTRMAN_ROUTE_SEPARATOR	IDRP_ATTR_FLAG_MANDATORY /* Route ID */
#define IDRP_ATTRMAN_EXT_INFO   	IDRP_ATTR_FLAG_DISCRET	 /* External Info */
#define IDRP_ATTRMAN_RD_PATH    	IDRP_ATTR_FLAG_MANDATORY /* RD_Path */
#define IDRP_ATTRMAN_NEXT_HOP   	IDRP_ATTR_FLAG_DISCRET   /* NEXT_HOP */
#define IDRP_ATTRMAN_DIST_LIST_INCL 	IDRP_ATTR_FLAG_DISCRET   /* DIST_LIST_INCL */
#define IDRP_ATTRMAN_DIST_LIST_EXCL 	IDRP_ATTR_FLAG_DISCRET   /* DIST_LIST_EXCL */
#define IDRP_ATTRMAN_MULTI_EXIT_DISC	IDRP_ATTR_FLAG_OPTIONAL   /* MULTI-EXIT_DISC */
#define IDRP_ATTRMAN_TRANSIT_DELAY	IDRP_ATTR_FLAG_DISCRET   /* Transit_Delay */
#define IDRP_ATTRMAN_RESIDUAL_ERROR	IDRP_ATTR_FLAG_DISCRET   /* Residual_Error */
#define IDRP_ATTRMAN_EXPENSE		IDRP_ATTR_FLAG_DISCRET   /* Expense */
#define IDRP_ATTRMAN_LOCALLY_DEF_QOS	IDRP_ATTR_FLAG_DISCRET   /* Locally Defined QOS */
#define IDRP_ATTRMAN_HIERARCH_REC	IDRP_ATTR_FLAG_DISCRET   /* Hierarchical_Recording */
#define IDRP_ATTRMAN_HOP_COUNT		IDRP_ATTR_FLAG_MANDATORY /* RD hop count */
#define IDRP_ATTRMAN_SECURITY		IDRP_ATTR_FLAG_DISCRET   /* security */
#define IDRP_ATTRMAN_CAPACITY		IDRP_ATTR_FLAG_MANDATORY /* Capacity */
#define IDRP_ATTRMAN_PRIORITY		IDRP_ATTR_FLAG_DISCRET   /* Priority */
 

/* path attribute definitions */
/* attributes for modified transmited */


#define	IDRP_XMITATT_LOCAL_RD		FALSE	/* make local RD a bogus value */
#define IDRP_XMITATT_ROUTE_SEPARATOR	FALSE	/* Route ID */
#define IDRP_XMITATT_EXT_INFO   	FALSE	/* External Info */
#define IDRP_XMITATT_RD_PATH    	FALSE	/* RD_Path */
#define IDRP_XMITATT_NEXT_HOP   	TRUE	/* NEXT_HOP */
#define IDRP_XMITATT_DIST_LIST_INCL 	FALSE	/* DIST_LIST_INCL */
#define IDRP_XMITATT_DIST_LIST_EXCL 	FALSE	/* DIST_LIST_EXCL */
#define IDRP_XMITATT_MULTI_EXIT_DISC	TRUE	/* MULTI-EXIT_DISC */
#define IDRP_XMITATT_TRANSIT_DELAY	FALSE	/* Transit_Delay */
#define IDRP_XMITATT_RESIDUAL_ERROR	FALSE	/* Residual_Error */
#define IDRP_XMITATT_EXPENSE		FALSE	/* Expense */
#define IDRP_XMITATT_LOCALLY_DEF_QOS	FALSE	/* Locally Defined QOS */
#define IDRP_XMITATT_HIERARCH_REC	FALSE	/* Hierarchical_Recording */
#define IDRP_XMITATT_HOP_COUNT		FALSE	/* RD hop count */
#define IDRP_XMITATT_SECURITY		FALSE	/* security */
#define IDRP_XMITATT_CAPACITY		FALSE	/* Capacity */
#define IDRP_XMITATT_PRIORITY		FALSE	/* Priority */
 

/* path attribute definitions */
/* distinguished attributesattributes for modified transmited */


#define	IDRP_ATTRDIS_LOCAL_RD		FALSE	/* make local RD a bogus value */
#define IDRP_ATTRDIS_ROUTE_SEPARATOR	FALSE	/* Route ID */
#define IDRP_ATTRDIS_EXT_INFO   	FALSE	/* External Info */
#define IDRP_ATTRDIS_RD_PATH    	FALSE	/* RD_Path */
#define IDRP_ATTRDIS_NEXT_HOP   	FALSE	/* NEXT_HOP */
#define IDRP_ATTRDIS_DIST_LIST_INCL 	FALSE	/* DIST_LIST_INCL */
#define IDRP_ATTRDIS_DIST_LIST_EXCL 	FALSE	/* DIST_LIST_EXCL */
#define IDRP_ATTRDIS_MULTI_EXIT_DISC	TRUE	/* MULTI-EXIT_DISC */
#define IDRP_ATTRDIS_TRANSIT_DELAY	TRUE	/* Transit_Delay */
#define IDRP_ATTRDIS_RESIDUAL_ERROR	TRUE	/* Residual_Error */
#define IDRP_ATTRDIS_EXPENSE		TRUE	/* Expense */
#define IDRP_ATTRDIS_LOCALLY_DEF_QOS	TRUE	/* Locally Defined QOS */
#define IDRP_ATTRDIS_HIERARCH_REC	FALSE	/* Hierarchical_Recording */
#define IDRP_ATTRDIS_HOP_COUNT		FALSE	/* RD hop count */
#define IDRP_ATTRDIS_SECURITY		TRUE	/* security */
#define IDRP_ATTRDIS_CAPACITY		FALSE	/* Capacity */
#define IDRP_ATTRDIS_PRIORITY		TRUE	/* Priority */
 
/* path attribute definitions */

/*
 * The following occurs one or more times in an RD_PATH attribute:
 */

typedef struct {
	u_char path_seg_type;		/* Path segment type */
	u_char path_seg_len[2];		/* Path segment length */
} idrp_path_segment_header;

#define IDRP_PATH_SEGMENT_SET 		0x1	/* Path segment is a set */
#define IDRP_PATH_SEGMENT_SEQ 		0x2     /* Path segment is a sequence */
#define	IDRP_PATH_SEGMENT_ENTRY_SEQ     0x3	/* Path segment is a sequence of RDC */
#define	IDRP_PATH_SEGMENT_ENTRY_SET     0x4	/* Path segment is a set of RDC */
#define IDRP_PATH_SEGMENT_TYPE		0xF	/* Path segment type (above) */

#define IDRP_RDPATH_RDI_LENGTH_BYTE_LEN	1	/* one byte of length per RDI in pathway */


/*
 * The following occurs zero or more times in the NEXT_HOP attribute
 */
typedef struct {
	u_char snpa_len;		/* Length of this SNPA */
	u_char snpa[1];			/* SNPA (variable) */
} idrp_snpa;

/*
 * NEXT_HOP attribute
 */

/*
 * NLRI & NEXT HOP proto_info
 */

typedef struct _nlri_proto_info {
	u_char	proto_type;		/* protocol id type */
	u_char	proto_len;		/* protocol id length */
	u_char	proto_val[1];		/* protocol id value */
} nlri_proto_info;

#define IDRP_PROTO_TYPE_TR_9577   0x1	/* protocol type (CLNP, IP) */
#define	IDRP_PROTO_TYPE_8802_LSAP 0x2	/* prototype other */

#define	IDRP_CLNP_PROTO_LEN	1	/* protocol length for CLNP */
#define	IDRP_IP_PROTO_LEN	1	/* protocol length for IP */ 	
#define	IDRP_SIP_PROTO_LEN	6	/* protocol length for sip */

typedef struct {
	nlri_proto_info next_hop_proto;	 /* protocol ID for this next_hop */
	u_char net_len;			/* length of NET */
	u_char net[1];			/* NET (variable) */
	u_char snpa_count;		/* Count of SNPAs following */
	idrp_snpa snpas[1];		/* List of SNPAs (variable) */
} idrp_next_hop_info;
	
typedef struct {
	u_char idrp_server_allowed;		/* x'FF' if OK to redist next_hop info */
	idrp_next_hop_info next_hops[1];	/* List of next hops */
} idrp_next_hop_attribute;

#define IDRP_SERVER_ALLOWED 0xff	/* OK to redistribute this next_hop */
#define IDRP_SERVER_NOT_ALLOWED 0	/* Not OK to redistribute this next_hop */

#define	IDRP_NEXT_HOP_SPACE_FUDGE	30	/* fudge factor for sip/pip address */
#define	IDRP_NEXT_HOP_ADDRESS_SPACE	((sizeof(struct iso_net_addr) + sizeof(nlri_proto_info)) + sizeof(idrp_next_hop_attribute))	

/*
 * The following occurs one or more times in the "value" field in DIST_LIST_INCL and
 * DIST_LIST_EXCL attributes.
 */
typedef struct {
        u_char dist_length;             /* Length of RDI in octets */
        u_char dist_value[1];           /* RDI (variable) */
} idrp_dist_list;
 
/*
 * DIST_LIST_INCL, DIST_LIST_EXCL attributes
 */
typedef struct {
	byte	count;			/* number of RDIs */
	idrp_dist_list list[1];		/* zero or more RDIs */
} idrp_dist_list_attribute;


/* multi exit discriminator values */

#define IDRP_MAX_MULTI_EXIT_VALUE	255	



typedef struct _nlri_info {
	u_char addr_len[2];		/* Length of following data */
	struct iso_prefix prefixes[1];	/* A bunch of prefixes */
} nlri_info;

#define UNFEASIBLE_RT_CNT_LEN	2
typedef struct _idrp_update_pdu {
	u_char	 unfeasible_route_count[UNFEASIBLE_RT_CNT_LEN]; /* Count of withdrawn route IDs  */
	route_id unfeasible_routes[1];	/* Unfeasable route IDs (variable)  */
	u_char	 tot_path_att_len[2];	/* total path attribute length */
        idrp_path_attr attrs;           /* Path Attributes (variable) */
        nlri_info nlri[1];		/* Reachability info (variable) */
} idrp_update_pdu;

/* minimum is withdrawing 1 route */
/* minimum update body:
 * route-id 6 (2 route_id count)
 * route_id  4 octets length
 * plus 2 total_path_att_len) 
 */ 

#define		IDRP_NO_NLRI_UPDATE 	2
#define		IDRP_MIN_UPDATE_BODY	6		
#define		IDRP_MIN_UPDATE_SIZE	MinPDULength+IDRP_MIN_UPDATE_BODY

/*
 * Fixed-length attribute lengths
 */

#define IDRP_EXT_INFO_LENGTH	0	/* length of external information */
#define IDRP_ROUTE_ID_LENGTH 4
#define IDRP_ROUTE_SEPARATOR_LENGTH 5
#define IDRP_ROUTE_PREF_LENGTH 1
#define IDRP_MULTI_EXIT_DISC_LENGTH 1
#define IDRP_TRANSIT_DELAY_LENGTH 2
#define IDRP_RESIDUAL_ERROR_LENGTH 4
#define IDRP_EXPENSE_LENGTH 2
#define IDRP_HIERARCHICAL_RECORDING_LENGTH 1
#define IDRP_RD_HOP_COUNT_LENGTH 1
#define IDRP_CAPACITY_LENGTH 1
#define IDRP_PRIORITY_LENGTH 1

/* TRANSIT_DELAY RANGE */

#define	IDRP_DELAY_VALUE_MIN		0	
#define	IDRP_DELAY_VALUE_MAX		65535			

/* Residual error range - limited to 10000 for this application */

#define	IDRP_ERROR_VALUE_MIN		0	
#define	IDRP_ERROR_VALUE_MAX		1000000					

/* EXPENSE RANGE */

#define	IDRP_EXPENSE_VALUE_MIN		0	
#define	IDRP_EXPENSE_VALUE_MAX		65535			


/* security values */

#define	FAA_SECURITY_ID		01	
#define FAA_SEC_ID_LENGTH	01

#define FAA_INFOLENGTH		04
#define	FAA_OPEN_LENGTH		03
#define FAA_SECURITY_LENGTH 	07        

#define	ATTR_TLV_LENGTH		4
#define	QOS_ATTR		5	
/* DELAY, EXPENSE, ERROR, SECURITY, PRIORITY  */

#define	IDRP_UPDATE_QOS1	IDRP_TRANSIT_DELAY_LENGTH+IDRP_RESIDUAL_ERROR_LENGTH
#define	IDRP_UPDATE_QOS2	IDRP_EXPENSE_LENGTH+IDRP_PRIORITY_LENGTH+FAA_SECURITY_LENGTH
#define	IDRP_UPDATE_QOS_LENGTH	IDRP_UPDATE_QOS1+IDRP_UPDATE_QOS2


#define	IDRP_OPEN_QOS_MAX_LENGTH	IDRP_TRANSIT_DELAY_LENGTH+IDRP_RESIDUAL_ERROR_LENGTH+IDRP_EXPENSE_LENGTH+IDRP_PRIORITY_LENGTH+FAA_SECURITY_LENGTH


/* definitions for CAPACITY VALUES */

#define	IDRP_CAPACITY_VALUE_MIN		1
#define IDRP_CAPACITY_VALUE_MAX		255

/* definitions for PRIORITY VALUES */

#define	IDRP_PRIORITY_VALUE_MIN		1
#define IDRP_PRIORITY_VALUE_MAX		14 	/* maximum value for priority */


/* total IDRP mandatory attribute */

#define IDRP_LOCAL_MAN_ATT_LEN 	IDRP_ROUTE_SEPARATOR_LENGTH+IDRP_RD_HOP_COUNT_LENGTH+3*(sizeof(idrp_path_attr_hdr))  
				 	

/* below definition includes everything but the size of RDI path
 * must include size of 4 path attributes  initial ROUTE_ID attribute,
 * RD_PATH, and HOPCOUNT along with EXT_INFO header plus
 * the length of EXT_INFO + length of path segment header for RD_PATH
 * plus the size of the HOPCOUNT path attribute 
 * The code adds to this base the length of the RDI or RDIs in the RD_PATH
 * attribute created for this EXT_INFO 
 */  

#define IDRP_LOC_EXT_INFO_ATTR_BASE_LEN   (4* sizeof(idrp_path_attr_hdr)) + IDRP_ROUTE_ID_LENGTH + \
					 	IDRP_EXT_INFO_LENGTH + IDRP_RD_HOP_COUNT_LENGTH + \
						sizeof(idrp_path_segment_header)  
 
/*
 * ERROR PDU
 */
 
typedef struct {
        u_char error_code;              /* Error code */
        u_char error_subcode;           /* Error subcode */
} idrp_error_header;

#define	IDRP_ERROR_PDU_HEADER_LEN	2	 
/*
 * Error type codes
 */
 
#define IDRP_ERROR_OPEN_PDU 1           /* Error in OPEN PDU */
#define IDRP_ERROR_UPDATE_PDU 2         /* Error in UPDATE PDU */
#define IDRP_ERROR_HOLDTIME_EXPIRED 3   /* Hold timer expired */
#define IDRP_ERROR_FSM 4		/* FSM error */
#define IDRP_ERROR_RIB_REFRESH 5	/* Error in RIB_REFRESH PDU */
 
/*
 * Error subcodes for OPEN PDUs
 */
 
#define IDRP_OPEN_ERROR_UNSUP_VER 1             /* Unsupported version number */
#define IDRP_OPEN_ERROR_BAD_MAX_SIZE 2          /* Bad maximum PDU size */
#define IDRP_OPEN_ERROR_BAD_PEER_RD 3           /* Bad peer RD */
#define IDRP_OPEN_ERROR_UNSUP_AUTH_CODE 4       /* Unsupported authentication code */
#define IDRP_OPEN_ERROR_AUTH_FAILURE 5          /* Authentication failure */
#define IDRP_OPEN_ERROR_BAD_RIB_ATT_SET 7       /* Bad RIB-Att set */
#define IDRP_OPEN_ERROR_RDC_MISMATCH 7          /* RDC mismatch */
#define IDRP_OPEN_ERROR_MIN_SUBCODE 1
#define IDRP_OPEN_ERROR_MAX_SUBCODE 7 
 
/*
 * Error subcodes for UPDATE PDUs
 */
 
#define IDRP_UPDATE_ERROR_MALF_ATTR 1           /* Malformed attribute list */
#define IDRP_UPDATE_ERROR_UNREC_WELKN_ATTR 2    /* Unrecognized well-known attribute */
#define IDRP_UPDATE_ERROR_MISS_WELKN_ATTR 3     /* Missing well-known attribute */
#define IDRP_UPDATE_ERROR_ATTR_FLAGS_ERR 4      /* Attribute flags error */
#define IDRP_UPDATE_ERROR_ATTR_LEN_ERR 5        /* Attribute length error */
#define IDRP_UPDATE_ERROR_RD_ROUTING_LOOP 6     /* RD routing loop */
#define IDRP_UPDATE_ERROR_INV_NEXT_HOP_ATTR 7   /* Invalid NEXT_HOP attribute */
#define IDRP_UPDATE_ERROR_OPT_ATTR_ERR 8        /* Optional attribute error */
#define IDRP_UPDATE_ERROR_INV_REACH_INF 9       /* Invalid reachability information */
#define IDRP_UPDATE_ERROR_MISCON_RDCS 10        /* Misconfigured RDCs */
#define IDRP_UPDATE_ERROR_MALF_NLRI 11		/* Malformed_NLRI */
#define IDRP_UPDATE_ERROR_DUP_ATTR 12		/* Duplicate attribute */
#define IDRP_UPDATE_ERROR_ILL_RD_PATH_SEG 13	/* Illegal Path segement */
#define IDRP_UPDATE_ERROR_MIN_SUBCODE 1		/* minimum subcode value */
#define IDRP_UPDATE_ERROR_MAX_SUBCODE 13	/* maximum subcode value */

#define IDRP_HOLDTIME_EXPIRED_ERROR_SUBCODE 0	/* null value only valid subcode */

/* define additional internal error codes
 * and return that
 * may some day be reflected above
 */ 
#define ERROR_WELLKNOWN_ATTRIBUTE_TWICE		1 /* well know attribute twice */
#define WELLKNOWN_ROUTE_SEPARATOR_TWICE		2 /* route separator twice */
#define	WELLKNOWN_ATTRIBUTE_ONCE		3 /* well know attribute seen only once */	
#define	WELLKNOWN_DIST_ATTRIBUTE_ONCE		4 /* well know attribute seen only once */	
	

/*
 * Error subcodes for FSM errors
 */
#define IDRP_FSM_ERROR_CLOSED 1			/* Closed state */
#define IDRP_FSM_ERROR_OPEN_RCVED 2		/* Open-received state */
#define IDRP_FSM_ERROR_OPEN_SENT 3		/* Open-sent state */
#define IDRP_FSM_ERROR_CLOSE_WAIT 4		/* Close-wait state */
#define IDRP_FSM_ERROR_ESTABLISHED 5		/* Established state */
#define IDRP_FSM_ERROR_MIN_SUBCODE 1		/* minimum subcode */
#define IDRP_FSM_ERROR_MAX_SUBCODE 2		/* maximum subcode */
/*
 * Error subcodes for RIB_REFRESH errors
 */
#define IDRP_RIB_REFRESH_ERROR_INV_OPCODE 1	/* Invalid opcode */
#define IDRP_RIB_REFRESH_ERROR_UNSUP_ATTRS 2	/* Unsupported RIB-Atts */
#define IDRP_RIB_REFRESH_ERROR_MIN_SUBCODE 1	/* minimum subcode for REFRESH error */
#define IDRP_RIB_REFRESH_ERROR_MAX_SUBCODE 2	/* maximum, subcode for REFRESH error */
 
 
typedef struct {
        idrp_error_header header;       /* Error header */
        u_char data[1];                 /* Error data */
} idrp_error_pdu;

 
/*
 * KEEPALIVE PDU
 */
 
/* Keepalive PDUs consist only of a fixed header.
 * - fixed pdu header is offset for message
 *   with the lengths for the protocol this
 *   IDRP packet is running over
 */

#define IDRP_KEEPALIVE_SIZE sizeof(idrp_fixed_pdu_header)
 
 
/*
 * CEASE PDU
 */
 
/* Cease PDUs consist only of a fixed header plus offset
 *  for the protocol it is running over
 */
 
#define IDRP_CEASE_SIZE sizeof(idrp_fixed_pdu_header)
 
 
/*
 * RIB_REFRESH PDU
 */
 
typedef struct {
        u_char opcode;                  /* Opcode */
} idrp_rib_refresh_header;
 
/*
 * RIB_REFRESH PDU opcodes
 */
 
#define IDRP_RIB_REFRESH_REQ 1          /* Request */
#define IDRP_RIB_REFRESH_START 2        /* Start */
#define IDRP_RIB_REFRESH_END 3          /* End */
#define IDRP_RIB_REFRESH_MIN_CODE 1	/* request */
#define IDRP_RIB_REFRESH_MAX_CODE 3	/* end */ 
 
typedef struct {
        idrp_rib_refresh_header hdr;    /* Header (fixed) */
	idrp_RIB_att	rib_att[1];	/* rib attributes (variable) */
} idrp_rib_refresh_pdu;

#define	IDRP_RIB_DEFAULT_ATT_SIZE	sizeof(idrp_RIB_att)
#define IDRP_RIB_REFRESH_ADD_SIZE  sizeof(idrp_rib_refresh_pdu) + IDRP_RIB_DEFAULT_ATT_SIZE

/* IDRP RIB REFRESH SIZE minus the protocol overhead  */
 
#define	IDRP_RIB_REFRESH_SIZE		sizeof(idrp_fixed_pdu_header) + IDRP_RIB_REFRESH_ADD_SIZE  


#ifdef ECHOKLUDGE
/*
 * ECHO PDU %%
 */
 
/* Echo PDUs consist only of a fixed header. */
 
#define IDRP_ECHO_SIZE sizeof(idrp_fixed_pdu_header)
 
 
/*
 * ECHO REPLY PDU
 */
 
/* Echo reply PDUs consist only of a fixed header. */
 
#define IDRP_ECHO_REPLY_SIZE sizeof(idrp_fixed_pdu_header)
 
#endif
 
/*
 * General PDU structure
 */
 
typedef struct _idrpPdu {
        idrp_fixed_pdu_header header;
        union {
                idrp_open_pdu open;
                idrp_update_pdu update;
                idrp_error_pdu error;
                idrp_rib_refresh_pdu refresh;
        } pdu;
} idrpPdu;



/* note that the idrpPdu is the IDRP header stripped
 * of any protocol it is running over.
 * The protocol lengths are added to these prior to
 * sending out pdus.
 */
 
