/*
 * Public Release 3
 * 
 * $Id: mld6.h,v 1.1.2.2 1999/02/10 14:15:07 wfs Exp $
 */

/*
 * ------------------------------------------------------------------------
 * 
 * Copyright (c) 1996, 1997, 1998 The Regents of the University of Michigan
 * All Rights Reserved
 *  
 * Royalty-free licenses to redistribute GateD Release
 * 3 in whole or in part may be obtained by writing to:
 * 
 * 	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.
 * 
 * ------------------------------------------------------------------------
 * 
 * Copyright (c) 1990,1991,1992,1993,1994,1995 by Cornell University.
 *     All rights reserved.
 * 
 * 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.
 * 
 * GateD is based on Kirton's EGP and UC Berkeley's routing
 * daemon	 (routed).
 * Development of GateD has been supported in part by the
 * National Science Foundation.
 * 
 * ------------------------------------------------------------------------
 * 
 * Portions of this software may fall under the following
 * copyrights:
 * 
 * Copyright (c) 1988 Regents of the University of California.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms are
 * permitted provided that the above copyright notice and
 * this paragraph are duplicated in all such forms and that
 * any documentation, advertising materials, and other
 * materials related to such distribution and use
 * acknowledge that the software was developed by the
 * University of California, Berkeley.  The name of the
 * University may not 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.
 */


/* 
 * local group database
 */
  
struct v6_group_list { 
    struct v6_group_list *forw, *back;
    struct in6_addr group_addr;          /* Group address */
    struct in6_addr last_addr;           /* Last host to report group */
    flag_t group_flags;                  /* status info about group */ 
    time_t refresh_time;                 /* Time of last refresh */
}; 

struct mtrace_request {
    u_int8_t	type;
    u_int8_t	code;
    u_int16_t	chksum;
    u_int16_t	ident;
    u_int16_t	max_resp_delay;
    struct 	in6_addr	group;
    struct 	in6_addr	source;
    struct 	in6_addr	dest;
    struct 	in6_addr	resp_addr;
    u_int32_t	resp_port;
};

struct mtrace_record {
    time_t	arrival;
    struct	in6_addr	incoming_intf;
    struct 	in6_addr	outgoing_intf;
    struct	in6_addr	rpf_router;
    u_int32_t	inpacket;		/* input packet count */
    u_int32_t	outpacket;		/* output packet count */
    u_int32_t	total;			/* Total packet for this group-src pair */
    u_int8_t	mrt_proto;		/* multicast routing protocol */
    u_int8_t	fwd_hop;		/* forwarding hops */
    u_int8_t	src_mask;		/* ??, FIXME Yixin */
    u_int8_t	fwd_err;		/* error in process */
};

/* %%%%%%%%%%%%   Had to add this for netbsd and inria. Need to test 
throughly */	
#ifdef NEED_MLD6_HDR
struct mld6_hdr {
	struct icmp6_hdr	mld6_hdr;
	struct in6_addr		mld6_addr;
};

#define mld6_type       mld6_hdr.icmp6_type 
#define mld6_code       mld6_hdr.icmp6_code
#define mld6_cksum      mld6_hdr.icmp6_cksum 
#define mld6_maxdelay   mld6_hdr.icmp6_data16[0]
#define mld6_reserved   mld6_hdr.icmp6_data16[1]
#endif	

#ifndef IPV6_ADDR_MC_SCOPE
#define IPV6_ADDR_MC_SCOPE(a)           ((a)->s6_addr8[1] & 0x0f)
#endif
/* 
 * tracing declarations
 */
#define TR_MLD6_INDEX_QUERY     5       /* Query packets */
#define TR_MLD6_INDEX_REPORT    6       /* New and old Report packets */
#define TR_MLD6_INDEX_LEAVE     7       /* Leave packets */
#define TR_MLD6_INDEX_MTRACE    8       /* Cisco & traceroute mcast packets */

#define TR_MLD6_DETAIL_QUERY    TR_DETAIL_1
#define TR_MLD6_DETAIL_REPORT   TR_DETAIL_2
#define TR_MLD6_DETAIL_LEAVE    TR_DETAIL_3 
#define TR_MLD6_DETAIL_MTRACE   TR_DETAIL_4

/*
 * Declaration used only for ICMPv6 Group management
 */
#define MLD6_BASE_TYPE		130
#define MLD6_MAX_TYPE		141	/* For MTRACE request */
#define MLD6_MIN_PACKET_LENGTH	24  	/* 24 octets */

#define ICMPV6_MAX_HOST_REPORT_DELAY	10

/*
 * Used to scan the local group database
 */

#define GROUP_LIST(gp, list)	{ for (gp = (list)->forw; gp != list; gp = gp->forw)
#define GROUP_LIST_END(gp, list)        if (gp == list) gp = (struct v6_group_list *) 0; }


/*
 * Group Change defines
 */
#define MLD6_ADDED		1
#define MLD6_REMOVED		2

#define MLD6_CONFIG_ENABLE	1
#define MLD6_CONFIG_DISABLE	2
#define MLD6_CONFIG_MAX		3

#define IFPS_DR_STATUS		IFPS_KEEP1

#define mld6_if_group_list	ifa_ps[RTPROTO_ICMPV6].ips_datas[0]
#define mld6_if_timer_timeout   ifa_ps[RTPROTO_ICMPV6].ips_datas[1]
#define mld6_if_proto           ifa_ps[RTPROTO_ICMPV6].ips_datas[2]

/* Global variable */
extern struct in6_addr icmpv6_ll_allnodes;
extern struct in6_addr icmpv6_ll_allrouters;

/* obnoxious gcc gives an extraneous warning about this constant... */
#if defined(__STDC__) || defined(__GNUC__)
#define JAN_1970    2208988800UL    /* 1970 - 1900 in seconds */
#else
#define JAN_1970    2208988800L /* 1970 - 1900 in seconds */
#define const       /**/
#endif

/* Prototype of routines */
PROTOTYPE(mld6_register_recv,
	  int,
	  (int,
	  _PROTOTYPE(callback, 
		     void,
		     (if_addr *,
		      sockaddr_un *,
		      sockaddr_un *,
		      struct mld6_hdr *,
		      size_t))));
PROTOTYPE(mld6_unregister_recv,
	  int,
	  (int));
PROTOTYPE(mld6_register_group_change,
	  int,
	  (_PROTOTYPE(callback,
           void,
           (int,
            if_addr *,
            u_int32))));
PROTOTYPE(mld6_unregister_group_change,
	  int,
	  (_PROTOTYPE(callback,
           void,
           (int,
            if_addr *,
            u_int32))));
PROTOTYPE(mld6_recv,
	  void,
	  (task *,
	   sockaddr_un *,
	   sockaddr_un *,
	   struct icmp6_hdr *,
	   size_t));
PROTOTYPE(mld6_join,
	  int,
	  (if_addr *,
	   sockaddr_un *));
PROTOTYPE(mld6_leave,
	  int,
	  (if_addr *,
	   sockaddr_un *));
PROTOTYPE(mld6_enable_dr_status,
	  void,
	  (if_addr *));
PROTOTYPE(mld6_disable_dr_status,
	  void,
	  (if_addr *));
PROTOTYPE(mld6_set_ifproto,
	  int,
	  (if_addr *,
	   int));
PROTOTYPE(mld6_reset_ifproto,
	  void,
	  (if_addr *,
	   int));
PROTOTYPE(mld6_get_ifproto,
	  int,
	  (if_addr *));
PROTOTYPE(mld6_var_init,
	  void,
	  (void));
PROTOTYPE(mld6_init,
	  void,
	  (void));
PROTOTYPE(mld6_dump,
	  void,
	  (task *,
	   FILE *));
