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); }
patch-rtnet-multicast-rc0.tar.gz
Description: application/tgz