/*
 * Copyright (c) 1996 The Regents of the University of Michigan
 * All Rights Reserved
 * 
 * License to use, copy, modify, and distribute this software and its
 * documentation can be obtained from Merit at the University of Michigan.
 * 
 * Merit GateDaemon Project
 * 4251 Plymouth Road, Suite C
 * Ann Arbor, MI 48105
 * 
 * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF THE
 * UNIVERSITY OF MICHIGAN AND MERIT DO NOT WARRANT THAT THE
 * FUNCTIONS CONTAINED IN THE SOFTWARE WILL MEET LICENSEE'S REQUIREMENTS OR
 * THAT OPERATION WILL BE UNINTERRUPTED OR ERROR FREE. The Regents of the
 * University of Michigan and Merit shall not be liable for
 * any special, indirect, incidental or consequential damages with respect
 * to any claim by Licensee or any third party arising from use of the
 * software. GateDaemon was originated and developed through release 3.0
 * by Cornell University and its collaborators.
 * 
 * Please forward bug fixes, enhancements and questions to the
 * gated mailing list: gated-people@gated.merit.edu.
 * 
 * This copyright has ben automaticly added by the util/addcopyright.pl program.
 * __END_OF_COPYRIGHT__
 */

#ifndef _NETINET_IN_H_
#define _NETINET_IN_H_ 	1
#include <netinet/in.h>
#endif

#ifdef	PROTO_PIMV6
#define IPPROTO_PIMV6		104
#define	PIMV6_VERSION		2
#define PIMV6_MASK_LEN		128
#define PIMV6_PACKET_MAX	4096
#define PIMV6_PORT		525

/*
 * PIMV6 Message Types
 */
#define PIMV6_HELLO				0
#define PIMV6_REGISTER				1
#define PIMV6_REGISTER_STOP			2
#define PIMV6_JOIN_PRUNE			3
#define PIMV6_BOOTSTRAP				4
#define PIMV6_ASSERT				5
#define PIMV6_GRAFT				6
#define PIMV6_GRAFT_ACK				7
#define PIMV6_CANDIDATE_RP_ADVERTISEMENT	8

/*
 * PIMV6 Assert Preferences
 */
#define	PIMV6_DIRECT_PREFERENCE	0
#define	PIMV6_STATIC_PREFERENCE	1
#define	PIMV6_OSPF_PREFERENCE	110
#define	PIMV6_ISIS_PREFERENCE	115
#define	PIMV6_RIPNG_PREFERENCE	120
#define	PIMV6_SLSP_PREFERENCE	130
#define	PIMV6_EGP_PREFERENCE	140
#define	PIMV6_BGP_PREFERENCE	200
#define	PIMV6_IDRP_PREFERENCE	210
#define	PIMV6_KERNEL_PREFERENCE	220
#define	PIMV6_HELLO_PREFERENCE	255

#define	PIMV6_ENABLED		0x01	/* PIMV6 protocol status bit */

extern int pimv6_config_status;		/* if PIMV6 is enabled in new config */

extern time_t pimv6_default_hellointerval;
extern time_t pimv6_default_routertimeout;
extern time_t pimv6_default_prunetimeout;
extern time_t pimv6_default_inactivitytimeout;
extern time_t pimv6_default_graftacktimeout;

/* 
 * PIMV6 Address Families 
 */
#define PIMV6_AF_RESERVED	0	/* Reserved */
#define PIMV6_AF_IP		1	/* IP version 4 */
#define PIMV6_AF_IP6		2	/* IP version 6 */
#define PIMV6_AF_NSAP		3	/* NSAP */
#define PIMV6_AF_HDLC		4	/* HDLC, 8-bit multidrop */
#define PIMV6_AF_BBN_1822	5	/* BBN 1822 */
#define PIMV6_AF_802		6	/* 802, all 802 media plus Ethernet */
#define PIMV6_AF_E_163		7	/* E.163 */
#define PIMV6_AF_E_164		8	/* E.164, SMDS, Frame Relay, ATM */
#define PIMV6_AF_F_69		9	/* F.69, Telex */
#define PIMV6_AF_X_121		10	/* X.121, X.25, Frame Relay */
#define PIMV6_AF_IPX		11	/* IPX */
#define PIMV6_AF_APPLETALK	12	/* Appletalk */
#define PIMV6_AF_DECNET_4	13	/* Decnet IV */
#define PIMV6_AF_BANYAN_VINES	14	/* Banyan Vines */
#define PIMV6_AF_E_164_NSAP	15	/* E.164 with NSAP format subaddr */

/* Encoded-Unicast-Address */
struct eu6_addr {
	u_int8	addr_family;		/* PIMV6 Addr Family */
	u_int8	enc_type;		/* Encoding Type (0) */
	struct in6_addr	u_6;		/* Unicast Address */
};

/* Encoded-Group-Address */
struct eg6_addr {
	u_int8	addr_family;		/* PIMV6 Addr Family */
	u_int8	enc_type;		/* Encoding Type (0) */
	u_int8	reserved;		/* Reserved (0) */
	u_int8	mask_len;		/* Mask Length (128 for IPv6) */
	struct in6_addr g_6;		/* Group Multicast Address */
};

/* Encoded-Source_Address */
struct es6_addr {
	u_int8	addr_family;		/* PIMV6 Addr Family */
	u_int8	enc_type;		/* Encoding Type (0) */
	u_int8	flags;			/* Reserved (0) +SWR */
	u_int8	mask_len;		/* Mask Length (128 for IPv6) */
	struct in6_addr s_6;		/* Source Address */
};
	
/*
 * protocol message formats
 */

/* PIMV6 header format */
struct pimv6hdr {
#if BYTE_ORDER == LITTLE_ENDIAN 
    u_int8	type:4,			/* PIMv6 type field */
    		version:4;		/* PIMv6 version code = 2 */
#endif
#if BYTE_ORDER == BIG_ENDIAN
    u_int8      version:4,        	/* PIMv6 version code = 2 */
    			type:4;           	/* PIMv6 type field */
#endif
    u_int8	reserved;		/* unused, should be zero */
    u_int16	cksum;			/* IP-style checksum */
};

/* PIMV6 HELLO message format */
struct pimv6hello {
    u_int16	hello_type;		/* OptionType = 1 */
    u_int16	hello_len;		/* OptionLength = 2 */
    u_int32	hello_value;		/* OptionValue = Holdtime */
};

/* PIMV6 JOIN/PRUNE/GRAFT message format */
struct pimv6joinhdr {
    struct eu6_addr 	rpf_addr;	/* Encoded-Unicast-Upstream Neighbor */
    u_int8		reserved;	/* Reserved */
    u_int8		num_groups;	/* Num groups */
    u_int16		holdtime;	/* Hold time */
};

/* PIMV6 group header */
struct pimv6group {
    struct eg6_addr	group_addr;	/* Encoded-Group-Address */
    u_int16		num_join;	/* Num of join sources */
    u_int16		num_prune;	/* Num of prune sources */
    char		source_data[1];	/* Encoded addresses data */
};

#define	PIMV6_SOURCE_S_BIT	0x04		/* Sparse Bit */
#define	PIMV6_SOURCE_W_BIT	0x02		/* Wildcard Bit */
#define	PIMV6_SOURCE_R_BIT	0x01		/* RP Bit */

#define	PIMV6_ASSERT_TIMEOUT	5		/* timeout assert in seconds */
#define	PIMV6_ASSERT_RPBIT	0x80000000	/* MSB in preference */


struct pimv6assert {
    struct eg6_addr group_addr;		/* Group triggering mask */
    struct eu6_addr src_addr;		/* Source in msg triggering assert */
    u_int32	preference;		/* pref. of unicast routing protocol */
					/* includes high order RP bit */
    u_int32	metric;			/* unicast routing metric */
};

/*
#define	PIMV6_MODE_DENSE	0x0
#define	PIMV6_MODE_SPARSE	0x1
*/

/*
 * Join delay timer range in seconds
 */

#define	PIMV6_JOIN_DELAY_MIN	1
#define	PIMV6_JOIN_DELAY_MAX	3

/*
 * defines used by parser
 */

#define	PIMV6_LIMIT_HELLOINTERVAL	1, 3600		/* 1 hour */
#define	PIMV6_LIMIT_ROUTERTIMEOUT	1, 10800	/* 3 * 1 hour */
#define	PIMV6_LIMIT_PRUNETIMEOUT	1, 3600		/* 1 hour */
#define	PIMV6_LIMIT_INACTIVITYTIMEOUT	1, 3600		/* 1 hour */
#define	PIMV6_LIMIT_GRAFTACKTIMEOUT	1, 300		/* 5 minutes */

#define	PIMV6_CONFIG_ENABLE		1
#define	PIMV6_CONFIG_DISABLE		2
#define	PIMV6_CONFIG_MODE		3
#define	PIMV6_CONFIG_PRUNETIMEOUT	4
#define	PIMV6_CONFIG_INACTIVITYTIMEOUT	5
#define	PIMV6_CONFIG_MAX		6

extern adv_entry *pimv6_int_policy;	/* PIMV6 control info */


/*
 * tracing declarations
 */

extern trace *pimv6_trace_options;	/* PIMV6 tracing configuration */
extern const bits pimv6_trace_types[];	/* List of PIMV6 specific trace flags */

#define	TR_PIMV6_DETAIL_HELLO		TR_DETAIL_1	/* hello */
#define	TR_PIMV6_DETAIL_REGISTER	TR_DETAIL_2	/* register, rp */
#define	TR_PIMV6_DETAIL_REGISTER_STOP	TR_DETAIL_2	/* register, rp */
#define	TR_PIMV6_DETAIL_JOIN_PRUNE	TR_DETAIL_3	/* join, prune */
#define	TR_PIMV6_DETAIL_BOOTSTRAP	TR_DETAIL_2	/* register, rp */
#define	TR_PIMV6_DETAIL_ASSERT		TR_DETAIL_4	/* assert */
#define	TR_PIMV6_DETAIL_GRAFT		TR_DETAIL_5	/* graft */
#define	TR_PIMV6_DETAIL_GRAFT_ACK	TR_DETAIL_5	/* graft */

#define	TR_PIMV6_INDEX_PACKETS	0	/* All packets */
#define	TR_PIMV6_INDEX_HELLO	1	/* Hello packets */
#define	TR_PIMV6_INDEX_REGISTER	2	/* Register packets */
#define	TR_PIMV6_INDEX_RP	2	/* RP related packets */
#define	TR_PIMV6_INDEX_JOIN	3	/* Join/Prune packets */
#define	TR_PIMV6_INDEX_PRUNE	3	/* Join/Prune Other packets */
#define	TR_PIMV6_INDEX_ASSERT	4	/* Assert packets */
#define	TR_PIMV6_INDEX_GRAFT	5	/* Graft/Graft Ack packets */

/**/
PROTOTYPE(pimv6_init,
	  extern void,
	  (void));
PROTOTYPE(pimv6_var_init,
	  extern void,
	  (void));
PROTOTYPE(pimv6_set_pref,
	  extern void,
	  (int,
	   pref_t));

#endif	/* PROTO_PIMV6 */

/**/
