diff -ru linux/Documentation/Configure.help linux-2.3.99-pre5+anep/Documentation/Configure.help
--- linux/Documentation/Configure.help	Tue Apr 11 08:02:59 2000
+++ linux-2.3.99-pre5+anep/Documentation/Configure.help	Thu Apr 27 10:20:45 2000
@@ -3806,6 +3806,22 @@
   say Y to "Kernel/User network link driver" and to "Routing
   messages" instead.
   
+IPv6: multicast for IPv4 mapped IPv6 addresses
+CONFIG_IPV6_MAPPED_MCAST
+  This is experimental support for multicast using IPv4 mapped
+  IPv6 addresses.
+
+The ANEP protocol
+CONFIG_ANEP
+  This is experimental support for the ANEP protocol.
+
+Build ANEP over IPv6 only
+CONFIG_ANEP_IPV6_ONLY
+  Build only the ANEPv6 part, so that it could be entirely defined
+  in the IPv6 module.
+  Consequences are that it won't support IPv4 mapped IPv6 addresses 
+  or compatible addresses.
+
 Kernel httpd acceleration (EXPERIMENTAL)
 CONFIG_KHTTPD
   The kernel httpd acceleration daemon (kHTTPd) is a (limited) 
Only in linux-2.3.99-pre5+anep/Documentation/networking: anep.txt
diff -ru linux/arch/sparc64/kernel/sys_sparc32.c linux-2.3.99-pre5+anep/arch/sparc64/kernel/sys_sparc32.c
--- linux/arch/sparc64/kernel/sys_sparc32.c	Mon Apr  3 00:49:08 2000
+++ linux-2.3.99-pre5+anep/arch/sparc64/kernel/sys_sparc32.c	Thu Apr 27 10:20:46 2000
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.142 2000/03/24 04:17:38 davem Exp $
+/* $Id: sys_sparc32.c,v 1.1 2000/04/21 09:00:22 sdalu Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -53,6 +53,11 @@
 #include <asm/semaphore.h>
 
 #include <net/scm.h>
+#if defined(CONFIG_ANEP)
+#  include <linux/in.h>
+#  include <linux/in6.h>
+#  include <linux/anep.h>
+#endif
 
 /* Use this to get at 32-bit user passed pointers. */
 /* Things to consider: the low-level assembly stub does
@@ -441,6 +446,13 @@
 	unsigned int		__unused2;
 };
 
+#if defined(CONFIG_ANEP)
+struct anep_optbuffer32 {
+	__kernel_size_t32	buff;    /* buffer start pointer        */
+	__u16			length;  /* buffer length in bytes      */
+	__u16			type;    /* option type including flags */
+};
+#endif
                                                         
 /*
  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
@@ -2415,7 +2427,7 @@
 
 		tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
 		       CMSG_ALIGN(sizeof(struct cmsghdr)));
-		kcmlen += tmp;
+		kcmlen += CMSG_ALIGN(tmp);
 		ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
 	}
 	if(kcmlen == 0)
@@ -2802,6 +2814,78 @@
 		kfree(kfilter);
 		return ret;
 	}
+
+	if ((level == SOL_ANEP) && (optname == ANEP_PKTOPTIONS))
+	    return -ENOPROTOOPT;
+
+
+	if ((level == SOL_ANEP) && (optname == ANEP_OPTBUFFER)) {
+		mm_segment_t old_fs;
+		struct anep_optbuffer    *optbuff = NULL;
+		struct anep_optbuffer    *opt;
+		struct anep_optbuffer32   opt32;
+		int count = optlen / sizeof(struct anep_optbuffer32);
+		int ret;
+		int i;
+
+		/* No convertion to do */
+		if (optlen == 0 || optval == NULL)
+			return sys_setsockopt(fd, level, 
+					      optname, optval, optlen);
+
+		/* Sanity check */
+		if (optlen < 0 || (optlen % sizeof(struct anep_optbuffer32)))
+			return -EINVAL;
+
+		/* Size constraint */
+		/* XXX: this isn't really true, because this will also
+		 *      be checked by the 64bits version, so one can get an
+		 *      EINVAL even when respecting this constraint in the
+		 *      first place
+		 */
+		if (optlen > ANEP_RESTRICTED_OPTBUFFER_SIZE)
+			return -EINVAL;
+
+		/* Allocate memory */
+		opt = optbuff = kmalloc(count * sizeof(struct anep_optbuffer), 
+					GFP_KERNEL);
+		if (optbuff == NULL)
+			return -ENOMEM;
+
+		/* Do 32 -> 64 conversion */
+		for (i = 0; i < count ; i++) {
+			/* fetch data */
+			if (copy_from_user(&opt32, optval, 
+					   sizeof(struct anep_optbuffer32))) {
+			    kfree(optbuff);
+			    return -EFAULT;
+			}
+
+			/* conversion */
+			opt->buff   = (void *)A(opt32.buff);
+			opt->length = opt32.length;
+			opt->type   = opt32.type;
+
+			/* next */
+			opt++;
+			optval += sizeof(struct anep_optbuffer32);
+		}
+		
+		/* call the setsockopt function */
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		ret = sys_setsockopt(fd, level, optname, 
+				     (void *)optbuff, 
+				     count * sizeof(struct anep_optbuffer));
+		set_fs(old_fs);
+
+		/* free memory */
+		kfree(optbuff);
+		
+		/* return */
+		return ret;
+	}
+	
 	return sys_setsockopt(fd, level, optname, optval, optlen);
 }
 
Only in linux-2.3.99-pre5+anep/include/linux: anep.h
diff -ru linux/include/linux/in.h linux-2.3.99-pre5+anep/include/linux/in.h
--- linux/include/linux/in.h	Wed Apr 12 02:31:26 2000
+++ linux-2.3.99-pre5+anep/include/linux/in.h	Thu Apr 27 10:20:45 2000
@@ -21,6 +21,7 @@
 #include <linux/types.h>
 
 /* Standard well-defined IP protocols.  */
+/* See: http://www.isi.edu/in-notes/iana/assignments/protocol-numbers */
 enum {
   IPPROTO_IP = 0,		/* Dummy protocol for TCP		*/
   IPPROTO_ICMP = 1,		/* Internet Control Message Protocol	*/
@@ -37,6 +38,7 @@
   IPPROTO_IPV6	 = 41,		/* IPv6-in-IPv4 tunnelling		*/
 
   IPPROTO_PIM    = 103,		/* Protocol Independent Multicast	*/
+  IPPROTO_ANEP   = 107,         /* Active Network			*/
 
   IPPROTO_ESP = 50,            /* Encapsulation Security Payload protocol */
   IPPROTO_AH = 51,             /* Authentication Header protocol       */
diff -ru linux/include/linux/skbuff.h linux-2.3.99-pre5+anep/include/linux/skbuff.h
--- linux/include/linux/skbuff.h	Wed Apr 12 02:31:49 2000
+++ linux-2.3.99-pre5+anep/include/linux/skbuff.h	Thu Apr 27 10:20:45 2000
@@ -73,6 +73,7 @@
 	{
 		struct tcphdr	*th;
 		struct udphdr	*uh;
+		struct anephdr	*ah;
 		struct icmphdr	*icmph;
 		struct igmphdr	*igmph;
 		struct iphdr	*ipiph;
diff -ru linux/include/linux/socket.h linux-2.3.99-pre5+anep/include/linux/socket.h
--- linux/include/linux/socket.h	Wed Apr 12 02:31:26 2000
+++ linux-2.3.99-pre5+anep/include/linux/socket.h	Thu Apr 27 10:20:45 2000
@@ -232,6 +232,7 @@
 #define SOL_UDP		17
 #define SOL_IPV6	41
 #define SOL_ICMPV6	58
+#define SOL_ANEP	107	/* Active Network */
 #define SOL_RAW		255
 #define SOL_IPX		256
 #define SOL_AX25	257
@@ -252,10 +253,16 @@
 extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
 extern int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, 
 				int offset, int len);
+extern int memcpy_fromkiovecend(unsigned char *kdata, struct iovec *iov, 
+				int offset, int len);
 extern int csum_partial_copy_fromiovecend(unsigned char *kdata, 
 					  struct iovec *iov, 
 					  int offset, 
 					  unsigned int len, int *csump);
+extern int csum_partial_copy_fromkiovecend(unsigned char *kdata, 
+					   struct iovec *iov, 
+					   int offset, 
+					   unsigned int len, int *csump);
 
 extern int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode);
 extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
Only in linux-2.3.99-pre5+anep/include/net: anep.h
diff -ru linux/include/net/ipv6.h linux-2.3.99-pre5+anep/include/net/ipv6.h
--- linux/include/net/ipv6.h	Wed Apr 12 02:32:53 2000
+++ linux-2.3.99-pre5+anep/include/net/ipv6.h	Thu Apr 27 10:20:45 2000
@@ -4,7 +4,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>
  *
- *	$Id: ipv6.h,v 1.20 2000/02/27 19:51:38 davem Exp $
+ *	$Id: ipv6.h,v 1.4 2000/03/07 16:41:41 sdalu Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -37,6 +37,7 @@
 #define NEXTHDR_ICMP		58	/* ICMP for IPv6. */
 #define NEXTHDR_NONE		59	/* No next header */
 #define NEXTHDR_DEST		60	/* Destination options header. */
+#define NEXTHDR_ANEP		107	/* Active Network */
 
 #define NEXTHDR_MAX		255
 
@@ -100,6 +101,13 @@
 #define UDP6_INC_STATS(field)		SNMP_INC_STATS(udp_stats_in6, field)
 #define UDP6_INC_STATS_BH(field)	SNMP_INC_STATS_BH(udp_stats_in6, field)
 #define UDP6_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(udp_stats_in6, field)
+#if defined(CONFIG_ANEP)
+extern struct anep_mib		anep_stats_in6[NR_CPUS*2];
+#define ANEP6_INC_STATS(field)		SNMP_INC_STATS(anep_stats_in6, field)
+#define ANEP6_INC_STATS_BH(field)	SNMP_INC_STATS_BH(anep_stats_in6, field)
+#define ANEP6_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(anep_stats_in6, field)
+#endif
+
 extern atomic_t			inet6_sock_nr;
 
 struct ip6_ra_chain
diff -ru linux/include/net/snmp.h linux-2.3.99-pre5+anep/include/net/snmp.h
--- linux/include/net/snmp.h	Thu Feb 10 05:08:09 2000
+++ linux-2.3.99-pre5+anep/include/net/snmp.h	Thu Apr 27 10:20:45 2000
@@ -171,6 +171,16 @@
 	unsigned long	__pad[0];
 };
 
+struct anep_mib
+{
+ 	unsigned long	AnepInDatagrams;
+ 	unsigned long	AnepInErrors;
+ 	unsigned long	AnepOutDatagrams;
+	unsigned long	AnepNoType;
+	unsigned long	AnepForwarded;
+	unsigned long	__pad[32-5];
+};
+
 struct linux_mib 
 {
 	unsigned long	SyncookiesSent;
diff -ru linux/include/net/sock.h linux-2.3.99-pre5+anep/include/net/sock.h
--- linux/include/net/sock.h	Wed Apr 12 02:32:50 2000
+++ linux-2.3.99-pre5+anep/include/net/sock.h	Thu Apr 27 10:20:45 2000
@@ -204,6 +204,45 @@
 };
 #endif
 
+#if defined(CONFIG_ANEP)
+struct anep_opt {
+	__u16			 type;
+	__u16			 connected_type;
+	__u8			 flags;
+
+	struct	anep_func	*af_specific;
+	struct	anep_optype	*optype;
+	int			 optype_count;
+
+	struct {
+		struct	iovec		*opts_iov;
+		int			 opts_iov_len;
+	} cache;
+
+	/* sticky options */
+	struct {
+		struct	cmsghdr		*cmsg;
+		int			 cmsglen;
+		struct iovec		*opts_iov;
+		int			 opts_iov_len;
+		__u32			 opts_len;
+	} sticky;
+
+	/* option buffers (ie: how to not used sendmsg) */
+	struct {
+		struct iovec		 iov[1];
+		int			 send_count;
+		struct anep_optbuffer	*send;
+		int			 recv_count;
+		struct anep_optbuffer	*recv;
+	} optbuff;
+
+//	::TODO:: struct anep_filter	filter;
+};
+
+#define sk_anep tp_pinfo.af_anep
+
+#endif /* ANEP */
 
 /* This defines a selective acknowledgement block. */
 struct tcp_sack_block {
@@ -525,6 +564,9 @@
 #if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE)
 		struct spx_opt		af_spx;
 #endif /* CONFIG_SPX */
+#if defined(CONFIG_ANEP)
+		struct anep_opt		af_anep;
+#endif /* CONFIG_ANEP */
 
 	} tp_pinfo;
 
@@ -661,6 +703,8 @@
 					int *addr_len);
 	int			(*bind)(struct sock *sk, 
 					struct sockaddr *uaddr, int addr_len);
+	int			(*getname)(struct sock *sk, struct sockaddr *uaddr,
+					   int *uaddr_len, int peer);
 
 	int			(*backlog_rcv) (struct sock *sk, 
 						struct sk_buff *skb);
@@ -671,12 +715,17 @@
 	int			(*get_port)(struct sock *sk, unsigned short snum);
 
 	char			name[32];
+	int			autobinding;
 
 	struct {
 		int inuse;
 		u8  __pad[SMP_CACHE_BYTES - sizeof(int)];
 	} stats[NR_CPUS];
 };
+
+#define AUTOBIND_DONE       0
+#define AUTOBIND_ALWAYS     1
+#define AUTOBIND_SENDONLY   2
 
 /* Called with local bh disabled */
 static void __inline__ sock_prot_inc_use(struct proto *prot)
diff -ru linux/include/net/transp_v6.h linux-2.3.99-pre5+anep/include/net/transp_v6.h
--- linux/include/net/transp_v6.h	Wed Apr 12 02:33:25 2000
+++ linux-2.3.99-pre5+anep/include/net/transp_v6.h	Thu Apr 27 10:20:45 2000
@@ -12,12 +12,14 @@
 extern struct proto rawv6_prot;
 extern struct proto udpv6_prot;
 extern struct proto tcpv6_prot;
+extern struct proto anep_v6_prot;
 
 struct flowi;
 
 extern void				rawv6_init(void);
 extern void				udpv6_init(void);
 extern void				tcpv6_init(void);
+extern void				anep_v6_init(void);
 
 extern int				udpv6_connect(struct sock *sk,
 						      struct sockaddr *uaddr,
diff -ru linux/net/Config.in linux-2.3.99-pre5+anep/net/Config.in
--- linux/net/Config.in	Mon Mar 27 20:35:56 2000
+++ linux-2.3.99-pre5+anep/net/Config.in	Thu Apr 27 10:20:45 2000
@@ -27,6 +27,10 @@
       if [ "$CONFIG_IPV6" != "n" ]; then
 	 source net/ipv6/Config.in
       fi
+      bool '  The ANEP protocol (EXPERIMENTAL)' CONFIG_ANEP
+      if [ "$CONFIG_ANEP" != "n" ]
+         bool '    Build ANEP over IPv6 only' CONFIG_ANEP_IPV6_ONLY
+      fi 
    fi
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
       source net/khttpd/Config.in
diff -ru linux/net/core/iovec.c linux-2.3.99-pre5+anep/net/core/iovec.c
--- linux/net/core/iovec.c	Sat Jan 22 20:54:57 2000
+++ linux-2.3.99-pre5+anep/net/core/iovec.c	Thu Apr 27 10:20:45 2000
@@ -231,6 +231,35 @@
 	return err;
 }
 
+int memcpy_fromkiovecend(unsigned char *kdata, struct iovec *iov, int offset,
+			int len)
+{
+	int err = -EFAULT;
+
+	/* Skip over the finished iovecs */
+	while(offset >= iov->iov_len)
+	{
+		offset -= iov->iov_len;
+		iov++;
+	}
+
+	while (len > 0)
+	{
+		u8 *base = iov->iov_base + offset;
+		int copy = min(len, iov->iov_len - offset);
+
+		offset = 0;
+		if (memcpy(base, kdata, copy))
+			goto out;
+		len   -= copy;
+		kdata += copy;
+		iov++;
+	}
+	err = 0;
+out:
+	return err;
+}
+
 /*
  *	And now for the all-in-one: copy and checksum from a user iovec
  *	directly to a datagram
@@ -319,3 +348,68 @@
 	err = -EFAULT;
 	goto out;
 }
+
+
+int csum_partial_copy_fromkiovecend(unsigned char *kdata, struct iovec *iov,
+				    int offset, unsigned int len, int *csump)
+{
+	int csum = *csump;
+	int partial_cnt = 0;
+
+	/* Skip over the finished iovecs */
+	for ( ; offset >= iov->iov_len ; offset -= iov->iov_len )
+		iov++;
+
+	while (len > 0) {
+		u8 *base = iov->iov_base + offset;
+		unsigned int copy = min(len, iov->iov_len - offset);
+
+		offset = 0;
+		/* There is a remnant from previous iov. */
+		if (partial_cnt) {
+			int par_len = 4 - partial_cnt;
+
+			/* iov component is too short ... */
+			if (par_len > copy) {
+			    memcpy(kdata, base, copy);
+				kdata += copy;
+				base  += copy;
+				partial_cnt += copy;
+				len   -= copy;
+				iov++;
+				if (len)
+					continue;
+				*csump = csum_partial(kdata - partial_cnt,
+							 partial_cnt, csum);
+				return 0;
+			}
+			memcpy(kdata, base, par_len);
+			csum = csum_partial(kdata - partial_cnt, 4, csum);
+			kdata += par_len;
+			base  += par_len;
+			copy  -= par_len;
+			len   -= par_len;
+			partial_cnt = 0;
+		}
+
+		if (len > copy) {
+			partial_cnt = copy % 4;
+			if (partial_cnt) {
+				copy -= partial_cnt;
+				memcpy(kdata + copy, base + copy, partial_cnt);
+			}
+		}
+
+		if (copy) {
+			// ::TODO:: is there a function to do memcpy + checksum
+			memcpy(kdata, base, copy);
+			csum = csum_partial(kdata, copy, csum);
+		}
+		len   -= copy + partial_cnt;
+		kdata += copy + partial_cnt;
+		iov++;
+	}
+        *csump = csum;
+	return 0;
+}
+
diff -ru linux/net/ipv4/Makefile linux-2.3.99-pre5+anep/net/ipv4/Makefile
--- linux/net/ipv4/Makefile	Thu Jan  6 19:14:36 2000
+++ linux-2.3.99-pre5+anep/net/ipv4/Makefile	Thu Apr 27 10:20:45 2000
@@ -56,6 +56,13 @@
 IPV4_OBJS += ipconfig.o
 endif
 
+ifdef CONFIG_ANEP
+  ifndef CONFIG_ANEP_IPV6_ONLY
+  IPV4_OBJS += anep_common.o
+  endif
+IPV4_OBJS += anep.o
+endif
+
 ifdef CONFIG_INET
 O_OBJS := $(IPV4_OBJS)
 OX_OBJS := $(IPV4X_OBJS)
diff -ru linux/net/ipv4/af_inet.c linux-2.3.99-pre5+anep/net/ipv4/af_inet.c
--- linux/net/ipv4/af_inet.c	Mon Mar 27 20:35:56 2000
+++ linux-2.3.99-pre5+anep/net/ipv4/af_inet.c	Thu Apr 27 10:20:45 2000
@@ -5,7 +5,7 @@
  *
  *		PF_INET protocol family socket handler.
  *
- * Version:	$Id: af_inet.c,v 1.109 2000/03/25 01:55:10 davem Exp $
+ * Version:	$Id: af_inet.c,v 1.8 2000/04/18 11:58:01 sdalu Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -93,6 +93,9 @@
 #include <net/arp.h>
 #include <net/route.h>
 #include <net/tcp.h>
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+#  include <net/anep.h>
+#endif
 #include <net/udp.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
@@ -125,6 +128,9 @@
 extern int afinet_get_info(char *, char **, off_t, int);
 extern int tcp_get_info(char *, char **, off_t, int);
 extern int udp_get_info(char *, char **, off_t, int);
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+extern int anep4_get_info(char *, char **, off_t, int);
+#endif
 extern void ip_mc_drop_socket(struct sock *sk);
 
 #ifdef CONFIG_DLCI
@@ -248,16 +254,32 @@
 
 static int inet_autobind(struct sock *sk)
 {
-	/* We may need to bind the socket. */
+	/* Lock the socket */
 	lock_sock(sk);
-	if (sk->num == 0) {
-		if (sk->prot->get_port(sk, 0) != 0) {
-			release_sock(sk);
-			return -EAGAIN;
-		}
-		sk->sport = htons(sk->num);
-		sk->prot->hash(sk);
+
+	/* Is the binding already done (if not udp/tcp) */
+	if (sk->prot->autobinding == AUTOBIND_DONE)
+		goto out;
+
+	/* Is the binding already done (if udp/tcp) */
+	if (sk->num != 0)
+		goto out;
+
+	/* When it is not possible to autobind (ie we are not using port!!) */
+	if (sk->prot->get_port == NULL) {
+		release_sock(sk);
+		return -EBADFD; // ::TODO:: how to say need to bind (EBADFD)
+	}
+
+	/* Bind it */
+	if (sk->prot->get_port(sk, 0) != 0) {
+		release_sock(sk);
+		return -EAGAIN;
 	}
+	sk->sport = htons(sk->num);
+	sk->prot->hash(sk);
+
+ out:
 	release_sock(sk);
 	return 0;
 }
@@ -326,12 +348,25 @@
 	case SOCK_SEQPACKET:
 		goto free_and_badtype;
 	case SOCK_DGRAM:
-		if (protocol && protocol != IPPROTO_UDP)
+		switch(protocol) {
+		case 0:
+			protocol = IPPROTO_UDP;
+			/* FALL THROUGH */
+		case IPPROTO_UDP:
+			sk->no_check = UDP_CSUM_DEFAULT;
+			prot=&udp_prot;
+			sock->ops = &inet_dgram_ops;
+			break;
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+		case IPPROTO_ANEP:
+			sk->no_check = ANEP_CSUM_DEFAULT;
+			prot=&anep_v4_prot;
+			sock->ops = &inet_dgram_ops;
+			break;
+#endif
+		default:
 			goto free_and_noproto;
-		protocol = IPPROTO_UDP;
-		sk->no_check = UDP_CSUM_DEFAULT;
-		prot=&udp_prot;
-		sock->ops = &inet_dgram_ops;
+		}
 		break;
 	case SOCK_RAW:
 		if (!capable(CAP_NET_RAW))
@@ -488,6 +523,10 @@
 		sk->saddr = 0;  /* Use device */
 
 	/* Make sure we are allowed to bind here. */
+	if (sk->prot->get_port == NULL) {
+		err = -EBADFD;
+		goto out;
+	}
 	if (sk->prot->get_port(sk, snum) != 0) {
 		sk->saddr = sk->rcv_saddr = 0;
 		err = -EADDRINUSE;
@@ -509,12 +548,14 @@
 		       int addr_len, int flags)
 {
 	struct sock *sk=sock->sk;
+	int err;
 
 	if (uaddr->sa_family == AF_UNSPEC)
 		return sk->prot->disconnect(sk, flags);
 
-	if (sk->num==0 && inet_autobind(sk) != 0)
-		return -EAGAIN;
+	if (sk->prot->autobinding == AUTOBIND_ALWAYS)
+		if ((err = inet_autobind(sk)) < 0)
+			return err;
 	return sk->prot->connect(sk, (struct sockaddr *)uaddr, addr_len);
 }
 
@@ -675,6 +716,10 @@
 	struct sock *sk		= sock->sk;
 	struct sockaddr_in *sin	= (struct sockaddr_in *)uaddr;
   
+	/* If the socket has its own bind function then use it. */
+	if(sk->prot->getname)
+		return sk->prot->getname(sk, uaddr, uaddr_len, peer);
+
 	sin->sin_family = AF_INET;
 	if (peer) {
 		if (!sk->dport)
@@ -705,8 +750,8 @@
 	
 	/* We may need to bind the socket. */
 	/* It is pretty strange. I would return error in this case --ANK */
-	if (sk->num==0 && inet_autobind(sk) != 0)
-		return -EAGAIN;
+	if ((err = inet_autobind(sk)) < 0)
+		return err;
 	err = sk->prot->recvmsg(sk, msg, size, flags&MSG_DONTWAIT,
 				flags&~MSG_DONTWAIT, &addr_len);
 	if (err >= 0)
@@ -719,10 +764,12 @@
 		 struct scm_cookie *scm)
 {
 	struct sock *sk = sock->sk;
+	int err;
 
 	/* We may need to bind the socket. */
-	if (sk->num==0 && inet_autobind(sk) != 0)
-		return -EAGAIN;
+	if (sk->prot->autobinding == AUTOBIND_ALWAYS)
+		if ((err = inet_autobind(sk)) < 0)
+			return err;
 
 	return sk->prot->sendmsg(sk, msg, size);
 }
@@ -942,7 +989,9 @@
 
 extern void tcp_init(void);
 extern void tcp_v4_init(struct net_proto_family *);
-
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+extern void anep_v4_init(void);
+#endif
 
 /*
  *	Called by socket.c on kernel startup.  
@@ -997,6 +1046,10 @@
 	/* Setup TCP slab cache for open requests. */
 	tcp_init();
 
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+	/* Setup ANEP */
+	anep_v4_init();
+#endif
 
 	/*
 	 *	Set the ICMP layer up
@@ -1031,5 +1084,8 @@
 	proc_net_create ("sockstat", 0, afinet_get_info);
 	proc_net_create ("tcp", 0, tcp_get_info);
 	proc_net_create ("udp", 0, udp_get_info);
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+	proc_net_create ("anep", 0, anep4_get_info);
+#endif
 #endif		/* CONFIG_PROC_FS */
 }
Only in linux-2.3.99-pre5+anep/net/ipv4: anep.c
Only in linux-2.3.99-pre5+anep/net/ipv4: anep_common.c
diff -ru linux/net/ipv4/proc.c linux-2.3.99-pre5+anep/net/ipv4/proc.c
--- linux/net/ipv4/proc.c	Sat Jan 22 20:54:57 2000
+++ linux-2.3.99-pre5+anep/net/ipv4/proc.c	Thu Apr 27 10:20:45 2000
@@ -7,7 +7,7 @@
  *		PROC file system.  It is mainly used for debugging and
  *		statistics.
  *
- * Version:	$Id: proc.c,v 1.41 2000/01/21 23:45:57 davem Exp $
+ * Version:	$Id: proc.c,v 1.3 2000/03/07 09:53:28 sdalu Exp $
  *
  * Authors:	Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *		Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de>
@@ -49,6 +49,9 @@
 #include <linux/skbuff.h>
 #include <net/sock.h>
 #include <net/raw.h>
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+#  include <net/anep.h>
+#endif
 
 static int fold_prot_inuse(struct proto *proto)
 {
@@ -78,6 +81,10 @@
 		       fold_prot_inuse(&udp_prot));
 	len += sprintf(buffer+len,"RAW: inuse %d\n",
 		       fold_prot_inuse(&raw_prot));
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+	len += sprintf(buffer+len,"ANEP: inuse %d\n",
+		       fold_prot_inuse(&anep_v4_prot));
+#endif
 	if (offset >= len)
 	{
 		*start = buffer;
@@ -136,6 +143,14 @@
 		  "Udp:");
 	for (i=0; i<offsetof(struct udp_mib, __pad)/sizeof(unsigned long); i++)
 		len += sprintf(buffer+len, " %lu", fold_field((unsigned long*)udp_statistics, sizeof(struct udp_mib), i));
+
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+	len += sprintf (buffer + len,
+		"\nAnep: InDatagrams InErrors OutDatagrams NoType Forwarded\n"
+		  "Anep:");
+	for (i=0; i<offsetof(struct anep_mib, __pad)/sizeof(unsigned long); i++)
+		len += sprintf(buffer+len, " %lu", fold_field((unsigned long*)anep_stats_in, sizeof(struct anep_mib), i));
+#endif
 
 	len += sprintf (buffer + len, "\n");
 
diff -ru linux/net/ipv4/protocol.c linux-2.3.99-pre5+anep/net/ipv4/protocol.c
--- linux/net/ipv4/protocol.c	Sun Feb 27 07:34:27 2000
+++ linux-2.3.99-pre5+anep/net/ipv4/protocol.c	Thu Apr 27 10:20:45 2000
@@ -5,7 +5,7 @@
  *
  *		INET protocol dispatch tables.
  *
- * Version:	$Id: protocol.c,v 1.11 2000/02/22 23:54:26 davem Exp $
+ * Version:	$Id: protocol.c,v 1.4 2000/03/07 16:41:45 sdalu Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -43,6 +43,9 @@
 #include <net/sock.h>
 #include <net/icmp.h>
 #include <net/udp.h>
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+#  include <net/anep.h>
+#endif
 #include <net/ipip.h>
 #include <linux/igmp.h>
 
@@ -94,6 +97,21 @@
 #undef  IPPROTO_PREVIOUS
 #define IPPROTO_PREVIOUS &udp_protocol
 
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+static struct inet_protocol anep_v4_protocol = 
+{
+	anep_v4_rcv,		/* ANEP handler		*/
+	anep_v4_err,		/* ANEP error control	*/
+	IPPROTO_PREVIOUS,	/* next			*/
+	IPPROTO_ANEP,		/* protocol ID		*/
+	0,			/* copy			*/
+	NULL,			/* data			*/
+	"ANEP"			/* name			*/
+};
+
+#undef  IPPROTO_PREVIOUS
+#define IPPROTO_PREVIOUS &anep_v4_protocol
+#endif
 
 static struct inet_protocol icmp_protocol = 
 {
diff -ru linux/net/ipv4/raw.c linux-2.3.99-pre5+anep/net/ipv4/raw.c
--- linux/net/ipv4/raw.c	Sat Jan 22 20:54:57 2000
+++ linux-2.3.99-pre5+anep/net/ipv4/raw.c	Thu Apr 27 10:20:45 2000
@@ -5,7 +5,7 @@
  *
  *		RAW - implementation of IP "raw" sockets.
  *
- * Version:	$Id: raw.c,v 1.48 2000/01/18 08:24:15 davem Exp $
+ * Version:	$Id: raw.c,v 1.3 2000/03/07 09:53:28 sdalu Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -661,9 +661,11 @@
 	raw_sendmsg,			/* sendmsg */
 	raw_recvmsg,			/* recvmsg */
 	raw_bind,			/* bind */
+	NULL,				/* getname */
 	raw_rcv_skb,			/* backlog_rcv */
 	raw_v4_hash,			/* hash */
 	raw_v4_unhash,			/* unhash */
 	NULL,				/* get_port */
 	"RAW",				/* name */
+ 	AUTOBIND_ALWAYS,		/* autobinding */
 };
diff -ru linux/net/ipv4/tcp_ipv4.c linux-2.3.99-pre5+anep/net/ipv4/tcp_ipv4.c
--- linux/net/ipv4/tcp_ipv4.c	Mon Mar 27 20:35:57 2000
+++ linux-2.3.99-pre5+anep/net/ipv4/tcp_ipv4.c	Thu Apr 27 10:20:45 2000
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_ipv4.c,v 1.205 2000/03/26 09:16:08 davem Exp $
+ * Version:	$Id: tcp_ipv4.c,v 1.5 2000/04/18 11:58:01 sdalu Exp $
  *
  *		IPv4 specific functions
  *
@@ -2182,11 +2182,13 @@
 	tcp_sendmsg,			/* sendmsg */
 	tcp_recvmsg,			/* recvmsg */
 	NULL,				/* bind */
+	NULL,				/* getname */
 	tcp_v4_do_rcv,			/* backlog_rcv */
 	tcp_v4_hash,			/* hash */
 	tcp_unhash,			/* unhash */
 	tcp_v4_get_port,		/* get_port */
 	"TCP",				/* name */
+ 	AUTOBIND_ALWAYS,		/* autobinding */
 };
 
 
diff -ru linux/net/ipv4/udp.c linux-2.3.99-pre5+anep/net/ipv4/udp.c
--- linux/net/ipv4/udp.c	Mon Feb 28 03:45:10 2000
+++ linux-2.3.99-pre5+anep/net/ipv4/udp.c	Thu Apr 27 10:20:46 2000
@@ -5,7 +5,7 @@
  *
  *		The User Datagram Protocol (UDP).
  *
- * Version:	$Id: udp.c,v 1.80 2000/02/27 19:51:43 davem Exp $
+ * Version:	$Id: udp.c,v 1.5 2000/03/07 16:41:46 sdalu Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -1054,9 +1054,11 @@
 	udp_sendmsg,			/* sendmsg */
 	udp_recvmsg,			/* recvmsg */
 	NULL,				/* bind */
+	NULL,				/* getname */
 	udp_queue_rcv_skb,		/* backlog_rcv */
 	udp_v4_hash,			/* hash */
 	udp_v4_unhash,			/* unhash */
 	udp_v4_get_port,		/* good_socknum */
  	"UDP",				/* name */
+	AUTOBIND_ALWAYS,		/* autobinding */
 };
diff -ru linux/net/ipv6/Config.in linux-2.3.99-pre5+anep/net/ipv6/Config.in
--- linux/net/ipv6/Config.in	Wed Dec 15 05:43:56 1999
+++ linux-2.3.99-pre5+anep/net/ipv6/Config.in	Thu Apr 27 10:20:46 2000
@@ -12,3 +12,4 @@
 fi
 #bool '    IPv6: flow policy support' CONFIG_RT6_POLICY
 #bool '    IPv6: firewall support' CONFIG_IPV6_FIREWALL
+bool '    IPv6: multicast for IPv4 mapped IPv6 addesses (EXPERIMENTAL)' CONFIG_IPV6_MAPPED_MCAST
diff -ru linux/net/ipv6/Makefile linux-2.3.99-pre5+anep/net/ipv6/Makefile
--- linux/net/ipv6/Makefile	Fri Apr 23 04:45:20 1999
+++ linux-2.3.99-pre5+anep/net/ipv6/Makefile	Thu Apr 27 10:20:46 2000
@@ -21,6 +21,13 @@
 #  IPV6_OBJS += ip6_fw.o
 #endif
 
+ifeq ($(CONFIG_ANEP),y)
+  ifdef CONFIG_ANEP_IPV6_ONLY
+  IPV6_OBJS += ../ipv4/anep_common.o
+  endif
+   IPV6_OBJS += anep.o
+endif
+
 O_OBJS := $(IPV6_OBJS)
 
 include $(TOPDIR)/Rules.make
diff -ru linux/net/ipv6/af_inet6.c linux-2.3.99-pre5+anep/net/ipv6/af_inet6.c
--- linux/net/ipv6/af_inet6.c	Mon Feb 28 03:45:10 2000
+++ linux-2.3.99-pre5+anep/net/ipv6/af_inet6.c	Thu Apr 27 10:20:46 2000
@@ -7,7 +7,7 @@
  *
  *	Adapted from linux/net/ipv4/af_inet.c
  *
- *	$Id: af_inet6.c,v 1.55 2000/02/27 19:51:47 davem Exp $
+ *	$Id: af_inet6.c,v 1.7 2000/03/07 16:41:47 sdalu Exp $
  *
  * 	Fixes:
  * 	Hideaki YOSHIFUJI	:	sin6_scope_id support
@@ -49,6 +49,9 @@
 #include <net/ipv6.h>
 #include <net/udp.h>
 #include <net/tcp.h>
+#if defined(CONFIG_ANEP)
+#  include <net/anep.h>
+#endif
 #include <net/ipip.h>
 #include <net/protocol.h>
 #include <net/inet_common.h>
@@ -79,6 +82,9 @@
 extern int raw6_get_info(char *, char **, off_t, int);
 extern int tcp6_get_info(char *, char **, off_t, int);
 extern int udp6_get_info(char *, char **, off_t, int);
+#if defined(CONFIG_ANEP)
+extern int anep6_get_info(char *, char **, off_t, int);
+#endif
 extern int afinet6_get_info(char *, char **, off_t, int);
 extern int afinet6_get_snmp(char *, char **, off_t, int);
 #endif
@@ -118,12 +124,24 @@
 		prot = &tcpv6_prot;
 		sock->ops = &inet6_stream_ops;
 	} else if(sock->type == SOCK_DGRAM) {
-		if (protocol && protocol != IPPROTO_UDP) 
+		switch(protocol) {
+		case 0:
+			protocol = IPPROTO_UDP;
+		case IPPROTO_UDP:
+			sk->no_check = UDP_CSUM_DEFAULT;
+			prot=&udpv6_prot;
+			sock->ops = &inet6_dgram_ops;
+			break;
+#if defined(CONFIG_ANEP)			
+		case IPPROTO_ANEP:
+			sk->no_check = ANEP_CSUM_DEFAULT;
+			prot=&anep_v6_prot;
+			sock->ops = &inet6_dgram_ops;
+			break;
+#endif
+		default:
 			goto free_and_noproto;
-		protocol = IPPROTO_UDP;
-		sk->no_check = UDP_CSUM_DEFAULT;
-		prot=&udpv6_prot;
-		sock->ops = &inet6_dgram_ops;
+		}
 	} else if(sock->type == SOCK_RAW) {
 		if (!capable(CAP_NET_RAW))
 			goto free_and_badperm;
@@ -354,6 +372,10 @@
 	struct sockaddr_in6 *sin=(struct sockaddr_in6 *)uaddr;
 	struct sock *sk = sock->sk;
   
+	/* If the socket has its own bind function then use it. */
+	if(sk->prot->getname)
+		return sk->prot->getname(sk, uaddr, uaddr_len, peer);
+
 	sin->sin6_family = AF_INET6;
 	sin->sin6_flowinfo = 0;
 	sin->sin6_scope_id = 0;
@@ -381,7 +403,7 @@
 	}
 	if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
 		sin->sin6_scope_id = sk->bound_dev_if;
-	*uaddr_len = sizeof(*sin);
+	*uaddr_len = sizeof(*sin);	
 	return(0);
 }
 
@@ -562,12 +584,18 @@
 	/* Init v6 transport protocols. */
 	udpv6_init();
 	tcpv6_init();
+#if defined(CONFIG_ANEP)
+	anep_v6_init();
+#endif
 
 	/* Create /proc/foo6 entries. */
 #ifdef CONFIG_PROC_FS
 	proc_net_create("raw6", 0, raw6_get_info);
 	proc_net_create("tcp6", 0, tcp6_get_info);
 	proc_net_create("udp6", 0, udp6_get_info);
+#if defined(CONFIG_ANEP)
+	proc_net_create("anep6", 0, anep6_get_info);
+#endif
 	proc_net_create("sockstat6", 0, afinet6_get_info);
 	proc_net_create("snmp6", 0, afinet6_get_snmp);
 #endif
@@ -605,6 +633,9 @@
 	proc_net_remove("raw6");
 	proc_net_remove("tcp6");
 	proc_net_remove("udp6");
+#if defined(CONFIG_ANEP)
+	proc_net_remove("anep6");
+#endif
 	proc_net_remove("sockstat6");
 	proc_net_remove("snmp6");
 #endif
Only in linux-2.3.99-pre5+anep/net/ipv6: anep.c
diff -ru linux/net/ipv6/ip6_input.c linux-2.3.99-pre5+anep/net/ipv6/ip6_input.c
--- linux/net/ipv6/ip6_input.c	Mon Feb 28 03:45:10 2000
+++ linux-2.3.99-pre5+anep/net/ipv6/ip6_input.c	Thu Apr 27 10:20:46 2000
@@ -6,7 +6,7 @@
  *	Pedro Roque		<roque@di.fc.ul.pt>
  *	Ian P. Morris		<I.P.Morris@soton.ac.uk>
  *
- *	$Id: ip6_input.c,v 1.17 2000/02/27 19:42:53 davem Exp $
+ *	$Id: ip6_input.c,v 1.3 2000/03/07 16:41:50 sdalu Exp $
  *
  *	Based in linux/net/ipv4/ip_input.c
  *
@@ -137,7 +137,11 @@
 	   It would be stupid to detect for optional headers,
 	   which are missing with probability of 200%
 	 */
-	if (nexthdr != IPPROTO_TCP && nexthdr != IPPROTO_UDP) {
+	if (nexthdr != IPPROTO_TCP && nexthdr != IPPROTO_UDP 
+#if defined(CONFIG_ANEP)
+	    && nexthdr != IPPROTO_ANEP
+#endif
+	    ) {
 		nhptr = ipv6_parse_exthdrs(&skb, nhptr);
 		if (nhptr == NULL)
 			return 0;
@@ -194,7 +198,6 @@
 {
 	return NF_HOOK(PF_INET6,NF_IP6_LOCAL_IN, skb, skb->dev, NULL, ip6_input_finish);
 }
-
 int ip6_mc_input(struct sk_buff *skb)
 {
 	struct ipv6hdr *hdr;	
diff -ru linux/net/ipv6/ipv6_sockglue.c linux-2.3.99-pre5+anep/net/ipv6/ipv6_sockglue.c
--- linux/net/ipv6/ipv6_sockglue.c	Mon Feb 28 03:45:10 2000
+++ linux-2.3.99-pre5+anep/net/ipv6/ipv6_sockglue.c	Thu Apr 27 10:20:46 2000
@@ -7,7 +7,7 @@
  *
  *	Based on linux/net/ipv4/ip_sockglue.c
  *
- *	$Id: ipv6_sockglue.c,v 1.33 2000/02/27 19:42:54 davem Exp $
+ *	$Id: ipv6_sockglue.c,v 1.7 2000/04/21 09:00:25 sdalu Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -36,6 +36,11 @@
 #include <linux/init.h>
 #include <linux/sysctl.h>
 #include <linux/netfilter.h>
+#if defined(CONFIG_IPV6_MAPPED_MCAST)
+#  include <linux/inetdevice.h>
+#  include <linux/in.h>
+#  include <linux/igmp.h>
+#endif
 
 #include <net/sock.h>
 #include <net/snmp.h>
@@ -48,7 +53,9 @@
 #include <net/inet_common.h>
 #include <net/tcp.h>
 #include <net/udp.h>
-
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+#  include <net/anep.h>
+#endif
 #include <asm/uaccess.h>
 
 struct ipv6_mib ipv6_statistics[NR_CPUS*2];
@@ -148,8 +155,12 @@
 			struct ipv6_txoptions *opt;
 			struct sk_buff *pktopt;
 
-			if (sk->protocol != IPPROTO_UDP &&
-			    sk->protocol != IPPROTO_TCP)
+			if (sk->protocol != IPPROTO_UDP 
+			    && sk->protocol != IPPROTO_TCP
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+			    && sk->protocol != IPPROTO_ANEP
+#endif
+			    )
 				break;
 
 			if (sk->state != TCP_ESTABLISHED) {
@@ -165,7 +176,8 @@
 			fl6_free_socklist(sk);
 			ipv6_sock_mc_close(sk);
 
-			if (sk->protocol == IPPROTO_TCP) {
+			switch(sk->protocol) {
+			case IPPROTO_TCP: {
 				struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
 
 				local_bh_disable();
@@ -177,7 +189,10 @@
 				sk->socket->ops = &inet_stream_ops;
 				sk->family = PF_INET;
 				tcp_sync_mss(sk, tp->pmtu_cookie);
-			} else {
+				break;
+			}
+			
+			case IPPROTO_UDP: 
 				local_bh_disable();
 				sock_prot_dec_use(sk->prot);
 				sock_prot_inc_use(&udp_prot);
@@ -185,6 +200,23 @@
 				sk->prot = &udp_prot;
 				sk->socket->ops = &inet_dgram_ops;
 				sk->family = PF_INET;
+				break;
+
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+			case IPPROTO_ANEP: {
+				local_bh_disable();
+				sock_prot_dec_use(sk->prot);
+				sock_prot_inc_use(&anep_v4_prot);
+				local_bh_enable();
+				sk->family               = PF_INET;
+				sk->prot                 = &anep_v4_prot;
+				sk->socket->ops          = &inet_dgram_ops;
+				sk->sk_anep.af_specific  = &anep_v4_specific;
+				break;
+			}
+#endif
+
+			default:
 			}
 			opt = xchg(&np->opt, NULL);
 			if (opt)
@@ -299,6 +331,13 @@
 		if (val > 255 || val < -1)
 			goto e_inval;
 		np->hop_limit = val;
+#if defined(CONFIG_IPV6_MAPPED_MCAST)
+		/* Don't check if it is IPv6 mapped, it's quicker 
+		 * to the job, and it is safe as ipv6 and ipv4
+		 * data don't use the same space (for now)
+		 */
+		sk->protinfo.af_inet.mc_ttl = val;
+#endif
 		retv = 0;
 		break;
 
@@ -308,6 +347,13 @@
 		if (val > 255 || val < -1)
 			goto e_inval;
 		np->mcast_hops = val;
+#if defined(CONFIG_IPV6_MAPPED_MCAST)
+		/* Don't check if it is IPv6 mapped, it's quicker 
+		 * to the job, and it is safe as ipv6 and ipv4
+		 * data don't use the same space (for now)
+		 */
+		sk->protinfo.af_inet.mc_loop = valbool;
+#endif
 		retv = 0;
 		break;
 
@@ -327,6 +373,14 @@
 			break;
 		}
 		np->mcast_oif = val;
+#if defined(CONFIG_IPV6_MAPPED_MCAST)
+		/* Don't check if it is IPv6 mapped, it's quicker 
+		 * to the job, and it is safe as ipv6 and ipv4
+		 * data don't use the same space (for now)
+		 */
+		sk->protinfo.af_inet.mc_index = val;
+		sk->protinfo.af_inet.mc_addr  = 0;
+#endif
 		retv = 0;
 		break;
 	case IPV6_ADD_MEMBERSHIP:
@@ -338,6 +392,20 @@
 		if (copy_from_user(&mreq, optval, sizeof(struct ipv6_mreq)))
 			break;
 
+#if defined(CONFIG_IPV6_MAPPED_MCAST)
+		if (ipv6_addr_type(&mreq.ipv6mr_multiaddr)==IPV6_ADDR_MAPPED) {
+			struct ip_mreqn ipv4_mreq;
+			ipv4_mreq.imr_address.s_addr   = 0;
+			ipv4_mreq.imr_ifindex          = mreq.ipv6mr_ifindex;
+			ipv4_mreq.imr_multiaddr.s_addr = mreq.ipv6mr_multiaddr.s6_addr32[3];
+			if (optname == IPV6_ADD_MEMBERSHIP)
+				retv = ip_mc_join_group(sk, &ipv4_mreq);
+			else
+				retv = ip_mc_leave_group(sk, &ipv4_mreq);
+			break;
+		}
+#endif
+
 		if (optname == IPV6_ADD_MEMBERSHIP)
 			retv = ipv6_sock_mc_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
 		else
@@ -443,6 +511,17 @@
 		len -= msg.msg_controllen;
 		return put_user(len, optlen);
 	}
+#if defined(CONFIG_IPV6_MAPPED_MCAST)
+	case IPV6_MULTICAST_HOPS:
+	  val = np->mcast_hops;
+	  break;
+        case IPV6_MULTICAST_LOOP:
+	  val = np->mc_loop;
+	  break;
+        case IPV6_MULTICAST_IF:
+	  val = np->mcast_oif;
+	  break;               
+#endif
 	case IP_MTU:
 	{
 		struct dst_entry *dst;
diff -ru linux/net/ipv6/proc.c linux-2.3.99-pre5+anep/net/ipv6/proc.c
--- linux/net/ipv6/proc.c	Sun Jan  9 06:36:21 2000
+++ linux-2.3.99-pre5+anep/net/ipv6/proc.c	Thu Apr 27 10:20:46 2000
@@ -7,7 +7,7 @@
  *		PROC file system.  This is very similar to the IPv4 version,
  *		except it reports the sockets in the INET6 address family.
  *
- * Version:	$Id: proc.c,v 1.13 2000/01/09 02:19:55 davem Exp $
+ * Version:	$Id: proc.c,v 1.6 2000/01/13 09:37:33 sdalu Exp $
  *
  * Authors:	David S. Miller (davem@caip.rutgers.edu)
  *
@@ -44,6 +44,10 @@
 		       fold_prot_inuse(&tcpv6_prot));
 	len += sprintf(buffer+len, "UDP6: inuse %d\n",
 		       fold_prot_inuse(&udpv6_prot));
+#if defined(CONFIG_ANEP)
+	len += sprintf(buffer+len, "ANEP6: inuse %d\n",
+		       fold_prot_inuse(&anep_v6_prot));
+#endif
 	len += sprintf(buffer+len, "RAW6: inuse %d\n",
 		       fold_prot_inuse(&rawv6_prot));
 	*start = buffer + offset;
@@ -131,6 +135,16 @@
 	SNMP6_GEN(InErrors),
 	SNMP6_GEN(OutDatagrams)
 #undef SNMP6_GEN
+#if defined(CONFIG_ANEP)
+#define SNMP6_GEN(x) { "Anep6" #x , &anep_stats_in6[0].Anep##x, sizeof(struct anep_mib)/sizeof(unsigned long) }
+	,
+	SNMP6_GEN(InDatagrams),
+	SNMP6_GEN(NoType),
+	SNMP6_GEN(InErrors),
+	SNMP6_GEN(OutDatagrams),
+	SNMP6_GEN(Forwarded)
+#undef SNMP6_GEN
+#endif
 };
 
 static unsigned long fold_field(unsigned long *ptr, int size)
diff -ru linux/net/ipv6/raw.c linux-2.3.99-pre5+anep/net/ipv6/raw.c
--- linux/net/ipv6/raw.c	Mon Feb 28 03:45:10 2000
+++ linux-2.3.99-pre5+anep/net/ipv6/raw.c	Thu Apr 27 10:20:46 2000
@@ -7,7 +7,7 @@
  *
  *	Adapted from linux/net/ipv4/raw.c
  *
- *	$Id: raw.c,v 1.34 2000/02/27 19:51:48 davem Exp $
+ *	$Id: raw.c,v 1.4 2000/03/07 16:41:51 sdalu Exp $
  *
  *	Fixes:
  *	Hideaki YOSHIFUJI	:	sin6_scope_id support
@@ -799,9 +799,11 @@
 	rawv6_sendmsg,			/* sendmsg */
 	rawv6_recvmsg,			/* recvmsg */
 	rawv6_bind,			/* bind */
+	NULL,				/* getname */
 	rawv6_rcv_skb,			/* backlog_rcv */
 	raw_v6_hash,			/* hash */
 	raw_v6_unhash,			/* unhash */
 	NULL,				/* get_port */
 	"RAW",				/* name */
+ 	AUTOBIND_ALWAYS,		/* autobinding */
 };
diff -ru linux/net/ipv6/tcp_ipv6.c linux-2.3.99-pre5+anep/net/ipv6/tcp_ipv6.c
--- linux/net/ipv6/tcp_ipv6.c	Mon Mar 27 20:35:57 2000
+++ linux-2.3.99-pre5+anep/net/ipv6/tcp_ipv6.c	Thu Apr 27 10:20:46 2000
@@ -5,7 +5,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>	
  *
- *	$Id: tcp_ipv6.c,v 1.122 2000/03/25 01:52:11 davem Exp $
+ *	$Id: tcp_ipv6.c,v 1.6 2000/04/18 11:58:02 sdalu Exp $
  *
  *	Based on: 
  *	linux/net/ipv4/tcp.c
@@ -2093,11 +2093,13 @@
 	tcp_sendmsg,			/* sendmsg */
 	tcp_recvmsg,			/* recvmsg */
 	NULL,				/* bind */
+	NULL,				/* getname */
 	tcp_v6_do_rcv,			/* backlog_rcv */
 	tcp_v6_hash,			/* hash */
 	tcp_unhash,			/* unhash */
 	tcp_v6_get_port,		/* get_port */
 	"TCPv6",			/* name */
+	AUTOBIND_ALWAYS,		/* autobinding */
 };
 
 static struct inet6_protocol tcpv6_protocol =
diff -ru linux/net/ipv6/udp.c linux-2.3.99-pre5+anep/net/ipv6/udp.c
--- linux/net/ipv6/udp.c	Mon Feb 28 03:45:10 2000
+++ linux-2.3.99-pre5+anep/net/ipv6/udp.c	Thu Apr 27 10:20:46 2000
@@ -7,7 +7,7 @@
  *
  *	Based on linux/ipv4/udp.c
  *
- *	$Id: udp.c,v 1.51 2000/02/27 19:51:51 davem Exp $
+ *	$Id: udp.c,v 1.5 2000/03/07 16:41:54 sdalu Exp $
  *
  *	Fixes:
  *	Hideaki YOSHIFUJI	:	sin6_scope_id support
@@ -985,11 +985,13 @@
 	udpv6_sendmsg,			/* sendmsg */
 	udpv6_recvmsg,			/* recvmsg */
 	NULL,				/* bind */
+	NULL,				/* getname */
 	udpv6_queue_rcv_skb,		/* backlog_rcv */
 	udp_v6_hash,			/* hash */
 	udp_v6_unhash,			/* unhash */
 	udp_v6_get_port,		/* get_port */
 	"UDP",				/* name */
+ 	AUTOBIND_ALWAYS,		/* autobinding */
 };
 
 void __init udpv6_init(void)
diff -ru linux/net/netsyms.c linux-2.3.99-pre5+anep/net/netsyms.c
--- linux/net/netsyms.c	Mon Mar 27 20:35:57 2000
+++ linux-2.3.99-pre5+anep/net/netsyms.c	Thu Apr 27 10:20:45 2000
@@ -300,14 +300,25 @@
 EXPORT_SYMBOL(tcp_portalloc_lock);
 EXPORT_SYMBOL(udp_hash);
 EXPORT_SYMBOL(udp_hash_lock);
+#if defined(CONFIG_ANEP)
+EXPORT_SYMBOL(anep_hash);
+EXPORT_SYMBOL(anep_hash_lock);
+#endif
 
 EXPORT_SYMBOL(tcp_destroy_sock);
 EXPORT_SYMBOL(ip_queue_xmit);
 EXPORT_SYMBOL(memcpy_fromiovecend);
+EXPORT_SYMBOL(memcpy_fromkiovecend);
 EXPORT_SYMBOL(csum_partial_copy_fromiovecend);
+EXPORT_SYMBOL(csum_partial_copy_fromkiovecend);
 EXPORT_SYMBOL(copy_and_csum_toiovec);
 EXPORT_SYMBOL(tcp_v4_lookup_listener);
 /* UDP/TCP exported functions for TCPv6 */
+#if defined(CONFIG_ANEP) && !defined(CONFIG_ANEP_IPV6_ONLY)
+EXPORT_SYMBOL(anep_v4_connect);
+EXPORT_SYMBOL(anep_v4_sendmsg);
+EXPORT_SYMBOL(anep_v4_specific);
+#endif
 EXPORT_SYMBOL(udp_ioctl);
 EXPORT_SYMBOL(udp_connect);
 EXPORT_SYMBOL(udp_disconnect);
