/*
 *	Mobile IPv6 header-file
 *
 *	Authors:
 *	Sami Kivisaari		<skivisaa@cc.hut.fi>
 *
 *	$Id: mipv6.h,v 1.13 2001/07/23 06:44:56 antti Exp $
 *
 *	This program is free software; you can redistribute it and/or
 *      modify it under the terms of the GNU General Public License
 *      as published by the Free Software Foundation; either version
 *      2 of the License, or (at your option) any later version.
 *
 *      Changelog:
 *      24/11/99: Converted binding-update-flags to bitfield-format
 */



#ifndef _MIPV6_H
#define _MIPV6_H

#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/in6.h>

/*
 * Global configuration flags
 */
extern int mipv6_is_ha;
extern int mipv6_is_mn;

/*
 * Home Agent information record (for HA and MN)
 */
struct ha_info {
	struct in6_addr addr;
	__u32 prefixlen;
	int preference;
	unsigned long lifetime;
	rwlock_t lock;
};

/*
 *
 * Statuscodes for binding acknowledgements
 *
 */
#define SUCCESS					0
#define REASON_UNSPECIFIED			128
#define ADMINISTRATIVELY_PROHIBITED		130
#define INSUFFICIENT_RESOURCES			131
#define HOME_REGISTRATION_NOT_SUPPORTED		132
#define NOT_HOME_SUBNET				133
#define INCORRECT_INTERFACE_ID_LEN		136
#define NOT_HA_FOR_MN				137
#define DUPLICATE_ADDR_DETECT_FAIL		138

/*
 *
 * Mobile IPv6 constants
 *
 */
#define INITIAL_BINDACK_TIMEOUT   1	/* seconds 			*/
#define MAX_BINDACK_TIMEOUT       256 	/* seconds 			*/
#define MAX_UPDATE_RATE           1	/* once per s (min delay=1s) 	*/
#define SLOW_UPDATE_RATE          10	/* once per 10 s (max delay=10s)*/
#define MAX_FAST_UPDATES          5 	/* transmissions 		*/
#define MAX_ADVERT_REXMIT         3 	/* transmissions 		*/
#define TIMERDELAY                HZ/10 

/* Mobile IPv6 ICMP type numbers          */
/* TODO: The Mobility Support draft (13) defines two new ICMP types
 * called Home Agent Address Discovery Request Message and Home Agent
 * Address Discovery Reply Message.  However, type numbers for these
 * are still to be assigned by IANA.  For testing we have assign some
 * (non conflicting) tentative values. 
 */
#define MIPV6_HA_ADDR_DISC_REQUEST       150
#define MIPV6_HA_ADDR_DISC_REPLY         151

/* Mobile IPv6 suboption codes            */
#define MIPV6_SUBOPT_PAD1		0x00
#define MIPV6_SUBOPT_PADN		0x01
#define MIPV6_SUBOPT_UNIQUEID		0x02
#define MIPV6_SUBOPT_ALTERNATE_COA	0x04

/* Binding update flag codes              */
#define MIPV6_BU_F_ACK                  0x80
#define MIPV6_BU_F_HOME                 0x40
#define MIPV6_BU_F_ROUTER               0x20
#define MIPV6_BU_F_DAD                  0x10

/* constants for sending of BUs*/
#define HA_BU_DELAY 0 

#define HA_BU_DEF_LIFETIME 10000
#define CN_BU_DELAY 500 /* In case there is some data pckets to add the bu to */
#define CN_BU_DEF_LIFETIME 60 /* 60s is short, could be longer */  
#define DUMB_CN_BU_LIFETIME 600 /* BUL entry lifetime in case of dumb CN */
#define ROUTER_BU_DEF_LIFETIME 10 /* For packet forwarding from previous coa */

#define EXPIRE_SANITY_CHECK /* check bul expire values */
#ifdef EXPIRE_SANITY_CHECK
#define ERROR_DEF_LIFETIME DUMB_CN_BU_LIFETIME
#endif

//#define CN_REQ_ACK /* Request Acks from CN's */
 
/*
 * Definition for control structure that is stored in end of skb->cb field
 */

struct mipv6_skbcb_data
{
	int cookie;
	int tunneled_packet;
};

#define MIPV6_SKBCB_COOKIE 0xdeadbeef
#define MIPV6_SKBCB_DATA(skb) ((struct mipv6_skbcb_data *) \
    ((__u8 *)skb->cb) + (sizeof(skb->cb) - sizeof(struct mipv6_skbcb_data)))


/*
 *
 * Option structures
 *
 */
struct mipv6_dstopt_bindupdate
{
	__u8	type;			/* type-code for option 	*/
	__u8	length;			/* option length 		*/
	__u8    flags;                  /* Ack, Router and Home flags   */
	__u8	prefixlen;		/* length of prefix		*/
	__u16	seq;			/* sequence number of BU	*/
	__u32	lifetime;		/* lifetime of BU		*/
	/* SUB OPTIONS */
} __attribute__ ((packed));

struct mipv6_dstopt_bindack
{
	__u8	type;			/* type-code for option 	*/
	__u8	length;			/* option length 		*/
	__u8	status;			/* statuscode			*/
	__u16	seq;			/* sequence number of BA	*/
	__u32	lifetime;		/* lifetime in CN's bcache	*/
	__u32	refresh;		/* recommended refresh-interval	*/
	/* SUB OPTIONS */
} __attribute__ ((packed));

struct mipv6_dstopt_bindrq
{
	__u8	type;			/* type-code for option 	*/
	__u8	length;			/* option length 		*/
	/* SUB OPTIONS */
} __attribute__ ((packed));

struct mipv6_dstopt_homeaddr
{
	__u8		type;		/* type-code for option 	*/
	__u8		length;		/* option length 		*/
	struct in6_addr	addr;		/* home address 		*/
	/* SUB OPTIONS */
} __attribute__ ((packed));



/*
 *
 * Suboption structures
 *
 */
struct mipv6_subopt_unique_id
{
	__u8		type;		/* type-code for suboption	*/
	__u8		length;		/* suboption length  		*/
	__u16		unique_id;	/* unique identifier		*/
} __attribute__ ((packed));

struct mipv6_subopt_ha_list
{
	__u8		type;		/* type-code for suboption	*/
	__u8		length;		/* suboption length  		*/
	struct in6_addr	addrs[1];	/* list of home agents		*/
	/* Possibly more home agent addresses */
} __attribute__ ((packed));

struct mipv6_subopt_alternate_coa
{
        __u8		type;		/* type-code for suboption	*/
	__u8		length;		/* suboption length  		*/
	struct in6_addr	addr;		/* alternate care-of-address	*/
} __attribute__ ((packed));


int mipv6_prefix_compare(
        struct in6_addr *addr,
	struct in6_addr *prefix,
	unsigned int nprefix);

int mipv6_suffix_compare(
	struct in6_addr *addr,
	struct in6_addr *suffix,
	unsigned int nsuffix);

#endif








