Subject: [magma] IGMPv3 API / RFC3678

From: "Seehofer, Markus" <[email-masked]>
Date: Fri, 20 Jan 2006 11:36:29 +0100

Hello,

i'm curretly doing little research on IGMPv3 and therefore trying to
write some small test applications. I've read the
RFC3678 for the new API. With IGMPv1/IGMPv2 there are no problems at
all. I can JOIN and LEAVE to multicast groups.
Also i have no problems using the Basic (Delta-based) API (Any-Source /
Source Specific Multicast). So i can use both IP_ADD_MEMBERSHIP and
IP_ADD_SOURCE_MEMBERSHIP and the other relevant sockopts.

But when trying to use the Advanced (Full-state) API for
IPv4 i didn't get it to work.

I use both WindowsXP Pro. with ServicePack1 and Linux
(Debian/Mandrake/Gentoo) with Kernel 2.6.12.

Below is some code i use. Starting that application on a Linux box i get
the following error message.

--> "Error in setting filter: Cannot assign requested address"

Maybe anybody has a hint for me what i'm doing wrong and how i can use
the Advanced (Full-state) API on a Windows machine.

Regards,
 Markus

<-----Code BEGIN-------------------------------------------->
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/ioctl.h>

/* Defines */
#define SRC_ADDRESS	"192.168.1.2"
#define MCAST_ADDRESS	"225.1.1.1"
#define UDP_PORT		12345

/* Globals*/
int nsrcs       = 0;
char *sources[] = {};

/* Prototypes */
void set_filter(const unsigned int sockfd, const char *mcastaddr,int
fmode, int nsrcs, char **src);

int main(int argc, char *argv[])
{	
	int sockfd;
	struct sockaddr_in maddr;

	/* Create socket*/
	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("ERROR: Cannot create socket");
		exit(1);
	}

	/* Bind socket */
	bzero((void *) &maddr, sizeof(struct sockaddr_in));
	maddr.sin_family = AF_INET;
	maddr.sin_addr.s_addr = htonl(INADDR_ANY);
	maddr.sin_port = htons(UDP_PORT);

	if (bind(sockfd, (struct sockaddr *) &maddr, 
		 sizeof(struct sockaddr_in)) < 0) {
			 perror("ERROR: Cannot bind socket");
		exit(1);
	}

    /* Set filter */
	set_filter(sockfd, MCAST_ADDRESS, MCAST_EXCLUDE, nsrcs,
sources);

	/* Wait ... seconds*/
	sleep(10);

	/* Close socket */
	close(sockfd);
	return 0;
	
}
	
void set_filter(const unsigned int sockfd, const char *mcastaddr,
		        int fmode, int nsrcs, char **src) {
	unsigned long int maddr = inet_addr(mcastaddr);
	struct ip_msfilter *filter;
	int err, i;
	
	if (fmode!=MCAST_INCLUDE && fmode!=MCAST_EXCLUDE) {
		perror("ERROR: Wrong filter mode.\n");
		return;
	}

	filter = (struct ip_msfilter *)
			malloc(IP_MSFILTER_SIZE(nsrcs));
	if (!filter) {
		perror("ERROR: Not enough memory to reserve for
filter.\n");
		return;
	}

	filter->imsf_multiaddr.s_addr = maddr;
	filter->imsf_interface.s_addr = inet_addr(SRC_ADDRESS);
	filter->imsf_fmode            = fmode;
	filter->imsf_numsrc           = nsrcs;

	for (i=0; i<nsrcs; i++) {
		filter->imsf_slist[i].s_addr = inet_addr(src[i]);
	}

	err = setsockopt(sockfd, IPPROTO_IP, IP_MSFILTER,
			 (char *) filter, IP_MSFILTER_SIZE(nsrcs));
	if (err!=0)
		perror("Error in setting filter");

	return;
}
-------->Code END<------------------------------------------

-----------------------------------------------------------
Markus Seehofer
Automation and Network Solutions / AEI
Hirschmann Automation and Control GmbH
mailto:[email-masked] * http://www.hirschmann.com

_______________________________________________
magma mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/magma

---

From: Stig Venaas <[email-masked]>
Date: Fri, 20 Jan 2006 15:04:04 +0100

> the Advanced (Full-state) API on a Windows machine.

I've had a quick look at your code, and it looks ok. I've written some 
similar code myself and the problem I found on some systems, I think 
Windows and some version of Linux kernel (not sure if 2.6.12), was that 
I had to specify interface.

I've only tried the full state API on Linux, and that was the protocol 
independent API. I believe that was working fine, except for having to 
specify interface on some kernel versions.

Stig