2005-04-16 15:20:36 -07:00
/*
* 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 ;
} ;
2006-02-01 03:06:29 -08:00
static void mcast_init ( struct net_device * dev , void * data )
2005-04-16 15:20:36 -07:00
{
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 " ) ;
2006-02-01 03:06:23 -08:00
printk ( " multicast address: %s:%u, TTL:%u " ,
2005-04-16 15:20:36 -07:00
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 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 ) {
2005-05-20 13:59:09 -07:00
init - > port = simple_strtoul ( port_str , & last , 10 ) ;
2005-04-16 15:20:36 -07:00
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 ) ;
2006-03-31 02:30:10 -08:00
return 0 ;
2005-04-16 15:20:36 -07:00
}
__initcall ( register_mcast ) ;