Skip to Content.
Sympa Menu

wg-multicast - Re: example of proper use of igmp v3 SSM setsockopt on Linux 2.6 kernel?

Subject: All things related to multicast

List archive

Re: example of proper use of igmp v3 SSM setsockopt on Linux 2.6 kernel?


Chronological Thread 
  • From: Stig Venaas <>
  • To: Alan Crosswell <>
  • Cc: wg-multicast <>
  • Subject: Re: example of proper use of igmp v3 SSM setsockopt on Linux 2.6 kernel?
  • Date: Tue, 16 Nov 2004 23:55:17 +0100

I didn't look much at your code. Here's my variant of openSSM() that I
just wrote. I believe it works with both IPv4 and IPv6 on recent Linux
kernels. I tested with 2.6.7. Some more error checking should be done
and the reporting improved. Attached is the complete source I used.

I tested the program by running it with strace and while it sleeps
doing "cat /proc/net/mcfilter" and "netstat -a". In my case I then
see:

Idx Device MCA SRC INC EXC
4 ath0 0xe0010203 0x9e263fc8 1 0

udp 0 0 224.1.2.3:5001 *:*

So I think it works.

Note that I have interface ath0 while you probably have eth0. In the
attached source it's eth0. In 2.6.9 I think perhaps you can leave
interface unspecified. It also includes more header files than is
needed.

Let me know if there are any problems.

Stig
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#ifndef MCAST_JOIN_SOURCE_GROUP
struct group_source_req {
uint32_t gsr_interface; /* interface index */
struct sockaddr_storage gsr_group; /* group address */
struct sockaddr_storage gsr_source; /* source address */
};
#define MCAST_JOIN_SOURCE_GROUP 46
#define MCAST_LEAVE_SOURCE_GROUP 47
#endif

int openSSM(source, group, port)
char *source;
char *group;
char *port;
{
int e, s, slevel;
struct addrinfo hints, *res;
struct group_source_req gsreq;

/* Should be possible to use "0" for interface or take interface
name as argument */
gsreq.gsr_interface = if_nametoindex("eth0");

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;

if ((e = getaddrinfo(source, NULL, &hints, &res))) {
fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(e));
return -1;
}

/* We only use first value, a name might resolve to multiple */
if ((s = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
return -1;

memcpy(&gsreq.gsr_source, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);

if ((e = getaddrinfo(group, port, &hints, &res))) {
fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(e));
return -1;
}
/* We only use first value, a name might resolve to multiple */
slevel = res->ai_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
memcpy(&gsreq.gsr_group, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);

if (bind(s, res->ai_addr, res->ai_addrlen) < 0)
return -1;

if (setsockopt(s, slevel, MCAST_JOIN_SOURCE_GROUP,
(char *)&gsreq, sizeof(gsreq)) == -1)
return -1;
return 0;
}

int main() {
int i;

i = openSSM("158.38.63.200", "224.1.2.3", "5001");
sleep(30);
return i;
}



Archive powered by MHonArc 2.6.16.

Top of Page