/* $Id: anep.h,v 1.1 2000/07/06 13:03:52 sdalu Exp $ */

/*
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 *
 * The Original Code is ANEP socket implementation code, released
 * April 27, 2000.
 *
 * The Initial Developer of the Original Code is LORIA-INRIA.
 *
 * Homepage: http://www.loria.fr/~sdalu/ANEP
 * Initial author: Stephane D'Alu <sdalu@loria.fr>
 *
 * Contributor(s): 
 */
 
#ifndef _LINUX_ANEP_H
#define _LINUX_ANEP_H

/*
 * ANEP header 
 *-------------
 *
 *   0                   1                   2                   3
 *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |   Version     |     Flags     |            Type ID            |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |      ANEP Header Length       |     ANEP Packet Length        |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 */

struct anephdr {
    __u8   version;
    __u8   flags;
    __u16  type;
    __u16  header_len;
    __u16  packet_len;
};

/* Version */
#define ANEP_VERSION         0x01

/* Flags */
#define ANEP_FLAG_DISCARD    0x80


/*
 * Options headers
 *-----------------
 *
 *   0                   1                   2                   3
 *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  |FLG|       Option Type         |         Option Length         |
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 */

struct anep_optionhdr {
	__u16	type;
	__u16	length;
#if !defined __STRICT_ANSI__ && defined __GNUC__ && __GNUC__ >= 2
	char	data[0];
#endif
};

#define ANEP_OPT_TYPE_MAX   0x3fff
#define ANEP_OPT_TYPE_MASK  0x3fff /* but is also used as max value */
#define ANEP_OPT_FLAG_MASK  0xc000

/* Flag */
#define ANEP_OPT_PRIVATE    0x8000
#define ANEP_OPT_DISCARD    0x4000

/* Option type */
#define ANEP_OPTION_SRCID		1
#define ANEP_OPTION_DESTID		2
#define ANEP_OPTION_CHECKSUM		3
#define ANEP_OPTION_NNAUTH		4

/* Source/Destination Identifier */
#define ANEP_ADDR_SCHEME_IPv4		1
#define ANEP_ADDR_SCHEME_IPv6		2
#define ANEP_ADDR_SCHEME_802d3		3

/* Authentication Identifier */
#define ANEP_AUTH_SCHEME_SPKI		1
#define ANEP_AUTH_SCHEME_X509		2



/*
 * Socket ANEP
 */
struct sockaddr_anep {
    __u16		sanep_family;	/* AF_{INET,INET6}	*/
    __u16		sanep_type;	/* Type	ID		*/
    __u32		unused;		/* (64bits alignment)	*/
    union {
	struct {
	    __u32		flowinfo;  /* IPv6 flow information  */
	    __u32		scope_id;  /* scope id (new in RFC2553) */
	    struct in6_addr	addr;      /* IPv6 address           */
	} ipv6;
	struct {
	    struct in_addr	addr;	   /* IPv4 address           */
	} ipv4;
    } addr_u;
};

#define sanep_ipv6_addr		addr_u.ipv6.addr
#define sanep_ipv6_flowinfo	addr_u.ipv6.flowinfo
#define sanep_ipv6_scope_id	addr_u.ipv6.scope_id
#define sanep_ipv4_addr		addr_u.ipv4.addr


/*
 * [sg]etsockopt structures/definitions
 */
#define ANEP_OPTION		1 /* {send,recv}msg only              */
#define ANEP_OPTYPE		2
#define ANEP_OPTYPE_COUNT	3 /* not documented (will be removed) */
#define ANEP_DISCARD		4
#define ANEP_PKTOPTIONS		5
#define ANEP_OPTBUFFER		6
#define ANEP_OPTBUFFER_COUNT	7 /* not documented (will be removed) */

/*
 * Size restriction
 */
#define ANEP_RESTRICTED_PKTOPTIONS_SIZE	((((unsigned int)~0) >> 1) -1)
#define ANEP_RESTRICTED_OPTBUFFER_SIZE	(ANEP_OPT_TYPE_MAX * sizeof(struct anep_optbuffer))
#define ANEP_RESTRICTED_OPTYPE_SIZE	(ANEP_OPT_TYPE_MAX * sizeof(struct anep_optype))

/* this one is defined in socket.h, but this file could
 * be included to compile a standard program
 */
#ifndef __KERNEL__
#ifndef SOL_ANEP
#  define SOL_ANEP		107	/* Active Network */
#endif
#endif

/* Define the options one wants to listen on */
struct anep_optype {
	__u16 action;    /* type of action (see below)        */
	__u16 beg_type;  /* starting type ...                 */
	__u16 end_type;  /*   ... ending type for this action */
};

#define ANEP_OPTYPE_KNOWN	0x1   /* option marked as known     */
#define ANEP_OPTYPE_MEMORIZE	0x2   /* make ancillary data for it */

/* Define the option buffer dispatcher */
struct anep_optbuffer {
	void	*buff;    /* buffer start pointer        */
	__u16	 length;  /* buffer length in bytes      */
	__u16	 type;    /* option type including flags */
};

#define ANEP_OPTBUFFER_SEND	0x01  /* option buffer for sending   */
#define ANEP_OPTBUFFER_RECV	0x02  /* option buffer for receiving */

#define ANEP_OPTBUFFER_SET_SIDE(x, y)			\
	do {						\
		(x)->buff   = NULL;			\
		(x)->length = 0;			\
		(x)->type   = y;			\
	} while(0)

#define ANEP_OPTION_SIZE(datasize) ((sizeof(struct anep_optionhdr) + \
				     datasize + 3) & ~3)

#endif	/* _LINUX_ANEP_H */
