/*
 * user-mode-linux networking multicast transport
 * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
 *
 * based on the existing uml-networking code, which is
 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
 * James Leu (jleu@mindspring.net).
 * Copyright (C) 2001 by various other people who didn't put their name here.
 *
 * Licensed under the GPL.
 */

#include "linux/kernel.h"
#include "linux/init.h"
#include "linux/netdevice.h"
#include "linux/etherdevice.h"
#include "linux/in.h"
#include "linux/inet.h"
#include "net_kern.h"
#include "net_user.h"
#include "mcast.h"

struct mcast_init {
	char *addr;
	int port;
	int ttl;
};

static void mcast_init(struct net_device *dev, void *data)
{
	struct uml_net_private *pri;
	struct mcast_data *dpri;
	struct mcast_init *init = data;

	pri = dev->priv;
	dpri = (struct mcast_data *) pri->user;
	dpri->addr = init->addr;
	dpri->port = init->port;
	dpri->ttl = init->ttl;
	dpri->dev = dev;

	printk("mcast backend ");
	printk("multicast address: %s:%u, TTL:%u ",
	       dpri->addr, dpri->port, dpri->ttl);

	printk("\n");
}

static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
{
	*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
	if(*skb == NULL) return(-ENOMEM);
	return(net_recvfrom(fd, (*skb)->mac.raw, 
			    (*skb)->dev->mtu + ETH_HEADER_OTHER));
}

static int mcast_write(int fd, struct sk_buff **skb,
			struct uml_net_private *lp)
{
	return mcast_user_write(fd, (*skb)->data, (*skb)->len, 
				 (struct mcast_data *) &lp->user);
}

static const struct net_kern_info mcast_kern_info = {
	.init			= mcast_init,
	.protocol		= eth_protocol,
	.read			= mcast_read,
	.write			= mcast_write,
};

int mcast_setup(char *str, char **mac_out, void *data)
{
	struct mcast_init *init = data;
	char *port_str = NULL, *ttl_str = NULL, *remain;
	char *last;

	*init = ((struct mcast_init)
		{ .addr 	= "239.192.168.1",
		  .port 	= 1102,
		  .ttl 		= 1 });

	remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
			       NULL);
	if(remain != NULL){
		printk(KERN_ERR "mcast_setup - Extra garbage on "
		       "specification : '%s'\n", remain);
		return(0);
	}
	
	if(port_str != NULL){
		init->port = simple_strtoul(port_str, &last, 10);
		if((*last != '\0') || (last == port_str)){
			printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", 
			       port_str);
			return(0);
		}
	}

	if(ttl_str != NULL){
		init->ttl = simple_strtoul(ttl_str, &last, 10);
		if((*last != '\0') || (last == ttl_str)){
			printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n", 
			       ttl_str);
			return(0);
		}
	}

	printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
	       init->port, init->ttl);

	return(1);
}

static struct transport mcast_transport = {
	.list 		= LIST_HEAD_INIT(mcast_transport.list),
	.name 		= "mcast",
	.setup  	= mcast_setup,
	.user 		= &mcast_user_info,
	.kern 		= &mcast_kern_info,
	.private_size 	= sizeof(struct mcast_data),
	.setup_size 	= sizeof(struct mcast_init),
};

static int register_mcast(void)
{
	register_transport(&mcast_transport);
	return 0;
}

late_initcall(register_mcast);
