hi ,

Here the first realise of patch for multicast support in RTnet , This realise 
support :
* IGMP V2

I have only adapt the NIC drivers for :
*RT_8139too  : Tested
*RT_eepro100  : Not Tested

-HOW TO USE IT ;
     1- Apply the patch to rtnet : (0.8.1 - 0.8.2 - 0.8.3)
     2- Patch the NIC driver 
     3- Execute the autogen.sh scritp to generate a new configure file. (a new  
  
config option will added "--enable-multicast" )
     4-execute configure   "./configure --with-rtai=<RTAI-DIR> 
--enable-multicast "

Now in your application if you want to receive multicast packets  you must use 
setsockopt  " RT_IP_ADD_MEMBERSHIP " , to stop the reception of multicast 
packet you can use "RT_IP_DROP_MEMBERSHIP"

Don't forget when sending multicast packet to specify the local IP adress,  
don't use INADDR_ANY (Only way I've fount to locate the device) .

for more detail about use of multicast in RTNET please see the sample attached 
to this mail.

I hope if any body can test this patch ,and if you have any idea to improve 
it. 

Im working now on a new realize of this patch , I will  add :
* the possiblity to modify the TLL value( new IOCTL in the socketopt).
* IGMP V1 Support.
* A random response to the query request (IGMP  V1 & V2).



-- 
EL HEDADI Amine
R&D 
phone : 
Email : [EMAIL PROTECTED]
/***
 *
 *  examples/round_trip_time/sever/rt_server.c
 *
 *  module that demonstrates an echo message scenario
 *  Copyright (C) 2002 Ulrich Marx <[EMAIL PROTECTED]>
 *                2004 Jan Kiszka <[EMAIL PROTECTED]>
 *
 *  RTnet - real-time networking example
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <net/ip.h>
#include <rtnet_sys.h>
#include <rtdm_driver.h>
#include <rtnet.h>


#define MIN_LENGTH_IPv4 7
#define MAX_LENGTH_IPv4 15
static char *local_ip_s  = "10.0.1.33";
static char *client_ip_s = "239.10.1.1";

MODULE_PARM(local_ip_s ,"s");
MODULE_PARM(client_ip_s,"s");
MODULE_PARM_DESC(local_ip_s, "local ip-addr");
MODULE_PARM_DESC(client_ip_s, "client ip-addr");

MODULE_LICENSE("GPL");

#define RCV_PORT	1234
#define SRV_PORT	5999

static struct sockaddr_in client_addr;
static struct sockaddr_in local_addr;
struct ip_mreq mreq;
static int sock;
int  cmd0 = 2;
int  cmd1 = 4;
#define BUFSIZE 1400
unsigned char buffer[BUFSIZE];
static nanosecs_t tx_time;

void echo_rcv(struct rtdm_dev_context *context, void *arg)
{
    int                 ret;
    struct msghdr       msg;
    struct iovec        iov,*iov1;
    struct sockaddr_in  addr;
    int i;
    rtos_time_t time;

    /* get time        */
    rtos_get_time(&time);
    tx_time = rtos_time_to_nanosecs(&time);
    rtf_put(cmd1, &tx_time, sizeof(tx_time));

    /* initialize */
    iov.iov_base=&buffer;
    iov.iov_len=BUFSIZE;
    msg.msg_name=&addr;
    msg.msg_namelen=sizeof(addr);
    msg.msg_iov=&iov;
    msg.msg_iovlen=1;
    msg.msg_control=NULL;
    msg.msg_controllen=0;
    /* Read Message from socket */
    ret = context->ops->recvmsg_rt(context, 0, &msg, 0);
    if (ret > 0) { 
        rtf_put(cmd0,&buffer,ret);
    
    }

}



int init_module(void)
{
    int                     ret;
    unsigned int            local_ip;
    unsigned int            client_ip = rt_inet_aton(client_ip_s);
    struct rtnet_callback   callback  = {echo_rcv, NULL};

    if (strlen(local_ip_s) != 0)
        local_ip = rt_inet_aton(local_ip_s);
    else
        local_ip = INADDR_ANY;
    /* ip_mreq structure  */
    mreq.imr_multiaddr.s_addr=client_ip;
    mreq.imr_interface.s_addr=local_ip;
    
    
    printk("local  ip address %s=%08x\n", local_ip_s, mreq.imr_interface.s_addr);
    printk("client ip address %s=%08x\n", client_ip_s,mreq.imr_multiaddr.s_addr);
    /* create rt-socket */
    printk("create rtsocket\n");
    if ((sock = socket_rt(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        printk("socket not created\n");
        return -ENOMEM;
    }

    /* bind the rt-socket to local_addr */
    printk("bind rtsocket to local address:port\n");
    memset(&local_addr, 0, sizeof(struct sockaddr_in));
    local_addr.sin_family = AF_INET;
    local_addr.sin_port = htons(RCV_PORT);
    local_addr.sin_addr.s_addr = local_ip;
    if ((ret = bind_rt(sock, (struct sockaddr *)&local_addr,
                       sizeof(struct sockaddr_in))) < 0) {
        printk("can't bind rtsocket\n");
        close_rt(sock);
        return ret;
    }

    /* set client-addr */
    printk("connect rtsocket to client address:port\n");
    memset(&client_addr, 0, sizeof(struct sockaddr_in));
    client_addr.sin_family = AF_INET;
    client_addr.sin_port = htons(SRV_PORT);
    client_addr.sin_addr.s_addr = client_ip;
/*
    if ((ret = connect_rt(sock, (struct sockaddr *)&client_addr,
                          sizeof(struct sockaddr_in))) < 0) {
        printk("can't connect rtsocket\n");
        close_rt(sock);
        return ret;
    }
*/
   
    ret= ioctl_rt(sock, RT_IP_ADD_MEMBERSHIP, &mreq);
    if(ret !=0)
	    printk("error ioctl\n");
    
    
    ioctl_rt(sock, RTNET_RTIOC_CALLBACK, &callback);
    
    /* rt fifo */
    //rtos_fifo_create(&print_fifo, PRINT_FIFO, 8000);
    rtf_create(cmd0,2000000);
    rtf_create(cmd1,1000);
    return 0;
}




void cleanup_module(void)
{
    
    ioctl_rt(sock, RT_IP_DROP_MEMBERSHIP, &mreq);
    
    while (close_rt(sock) == -EAGAIN) {
        set_current_state(TASK_UNINTERRUPTIBLE);
        schedule_timeout(1*HZ); /* wait a second */
    }
    rtf_destroy(cmd0);
    rtf_destroy(cmd1);
}

Attachment: patch-rtnet-multicast-rc0.tar.gz
Description: application/tgz

Reply via email to