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

