[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
(usagi-users 01917) usagi multicast problem
- To: usagi-users <usagi-users@xxxxxxxxxxxxxx>
- Subject: (usagi-users 01917) usagi multicast problem
- From: Sermed Al-abbasi <sermed@xxxxxxxxx>
- Date: 24 Oct 2002 14:18:17 +0200
- Reply-to: usagi-users@xxxxxxxxxxxxxx
Hi!
I'm working in an ipv6 project where my part involves working with the
ipv6 multicast. I wrote a simple ipv6 multicast chat program to get
familiarized with how multicast work. The program works fine on the
official 2.4.18 kernel (and older)shipped with RedHat. It works fine
when running them on the two redhat machines, once I run the program on
usagi I'm able to send messages which are received on the redhat
machines but the messages are not received by the usagi machines. I
don't know if it's me who is doing something wrong or if there is
something different with the usagi ipv6 API. I've attached the source
code with this mail, I hope there is somebody who can help.
Thanks
P.S. A compiled version can be found on
http://www.al-abbasi.net/download/multichatv3
/* multichat is an IPV6 Multicast chat program
* usage: multichat <interface> <IPv6-address>
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/time.h>
#define HELLO_PORT 5000
#define HELLO_GROUP "FF01:0:0:0:0:0:0:43" //Multicast group
#define MSGBUFSIZE 256
#define MAXDATASIZE 100
typedef unsigned int uint_t;
/*
* read_buf reads the binded socket for new messages
*/
void read_buf(int fd)
{
int nbytes;
char msgbuf[MSGBUFSIZE];
if (nbytes=read(fd,msgbuf,MSGBUFSIZE) < 0) {
perror("recvfrom");
exit(1);
}
printf("%s",msgbuf);
}
/*
* send_msg sends the stdin to the multicast group
*/
int send_msg(int send_fd, struct sockaddr_in6 their_addr)
{
int numbytes;
char msg[MAXDATASIZE];
if (fgets(msg,MAXDATASIZE,stdin) < 0 )
{
perror("gets");
exit(1);
}
if ((numbytes=sendto(send_fd, msg, sizeof(msg), 0, (struct sockaddr *)&their_addr, sizeof(their_addr))) == -1)
{
perror("sendto");
exit(1);
}
return numbytes;
}
main(int argc, char *argv[])
{
struct sockaddr_in6 addr; /* struct for own address */
struct sockaddr_in6 their_addr; /* struct for group address */
struct timeval timeout; /* Timeout for select */
int fd, maxsocks, readsocks, hops=2;
uint_t ifindex;
u_int loop=0; /* The messages will not return to the sender */
struct ipv6_mreq mreq;
char *input;
char *interface, /* The interface name which will handle multicast */
*address; /* The address where the packets will be sent through */
fd_set socks;
interface=argv[1];
address=argv[2];
/* create an IPV6 UDP socket */
if ((fd=socket(AF_INET6,SOCK_DGRAM,0)) < 0) {
perror("socket");
exit(1);
}
/* Setup own address and port*/
addr.sin6_family=AF_INET6;
inet_pton(AF_INET6,address,addr.sin6_addr.s6_addr);
//addr.sin6_addr=in6addr_any;
addr.sin6_port=htons(HELLO_PORT);
/* Setup the group address and port */
their_addr.sin6_family = AF_INET6;
their_addr.sin6_port = htons(HELLO_PORT);
inet_pton(AF_INET6,HELLO_GROUP,their_addr.sin6_addr.s6_addr);
/* convert the interface name to the index number corresponding to the interface */
ifindex = if_nametoindex (interface);
/* Set the Multicast group to join and on which interface */
inet_pton(AF_INET6,HELLO_GROUP,mreq.ipv6mr_multiaddr.s6_addr);
mreq.ipv6mr_interface=ifindex;
/* bind to the multicast interface*/
if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
perror("bind");
exit(1);
}
/* Set the device for outgoing multicast packets on the socket */
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) < 0)
{
perror("setsockopt_IF");
exit(1);
}
/* Disable the multicast loop (default enable) */
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop)) < 0)
{
perror("setsockopt_LOOP");
exit(1);
}
/* Number of HOPS */
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, sizeof(hops)) < 0)
{
perror("setsockopt_LOOP");
exit(1);
}
/* Request that the kernel join a multicast group */
if (setsockopt(fd,IPPROTO_IPV6,IPV6_JOIN_GROUP,&mreq,sizeof(mreq)) < 0) {
perror("setsockopt_JOIN");
exit(1);
}
/* The loop */
while (1) {
FD_ZERO(&socks);
FD_SET(fd,&socks);
FD_SET(0,&socks);
timeout.tv_sec = 1;
timeout.tv_usec = 0;
/* Listen on stdin and fd to read or send */
readsocks = select (maxsocks, &socks, NULL, NULL, &timeout);
if (readsocks < 0) {
perror("select");
exit(EXIT_FAILURE);
}
/* runs when socks have been set */
else
{
/* The binded socket have received a message */
if (FD_ISSET(fd,&socks)) read_buf(fd);
/* You have writen a message that will be sent */
if (FD_ISSET(0,&socks)) send_msg(fd,their_addr);
}
}
}