Last update: January 21, 2002

A Host Implementation of IGMPv3 on FreeBSD


Introduction

As part of a project within KPN Research, I worked on an implementation of IGMPv3 on FreeBSD, at the ICSI in Berkeley. Please feel free to give it a try and provide me with feedback.
If you're looking for an implementation of IGMPv3 on Linux, try the implementation of SprintLabs.

IP Multicast

There are several applications that require the same data to be delivered to multiple destinations at approximately the same time. Instead of each sender having to send every packet to every destination, the senders could also send the data to a group. IP multicast is all about making this concept of a group possible on the Internet. Steven Deering described the standard IP multicast model in RFC1112. In this RFC, the Internet Group Membership Protocol (IGMP) is used to deal with membership of these groups. Work is going on to standardize the 3rd version of this protocol, IGMPv3.

The Implementation

The TCP/IP networking code within FreeBSD (referred to as Net/3) is very well-structured, and documentation can be found in "TCP/IP Illustrated, Volume 2; The Implementation", by Gary R. Wright and W. Richard Stevens -- no need to say more.

The goal of this implementation is to be a full implementation of IGMPv3. Full includes compatibility with IGMPv1 and IGMPv2, support for the protocol independent API and merged reports. The sources have been tested and are used at several places. Since IGMPv3 is still a draft, it is very likeley there will be some updates. Bugs, of course ... they are also a reason to update the sources. I will update this site and the bundle whenever I update the sources.

The implementation consisted of several stages:

  1. Changes to the socket API (See: Socket Interface Extensions for Multicast Source Filters draft-ietf-idmr-msf-api-01.txt)
  2. Changes to the sockets layer to associated filter lists
  3. Changes to the interface data structure to keep a filter list per interface/ip-address
  4. Changes to the protocol (Eg. reports, compatibility with older versions, ...)
  5. Filtering of incoming data to 'subscribed' sockets

Download and Install

The files that had to be modified are:

Installation using the patches:

FreeBSD 4.0 patches:
igmpv3/freebsd_4.0_igmpv3_src.patch
igmpv3/freebsd_4.0_igmpv3_inc.patch

FreeBSD 4.1 patches:
igmpv3/freebsd_4.1_igmpv3_src.patch
igmpv3/freebsd_4.1_igmpv3_inc.patch

FreeBSD 4.2 patches: I fixed this patch at 03/16/2001 (the previous patch undid some 4.1-4.2 changes)
igmpv3/freebsd_4.2_igmpv3_src.patch
igmpv3/freebsd_4.2_igmpv3_inc.patch

To install, store these files in some directory, assuming it's your home directory. Now execute these commands as superuser:

cd /usr/src/
patch -p < ~/*src.patch
cd /usr/include/
patch -p < ~/*inc.patch

Building the kernel:

To build the kernel, assuming your workstation is has the i386 architecture inside, execute the commands:

cd /usr/src/sys/i386/conf
cp GENERIC IGMPV3
/usr/sbin/config -g IGMPV3
cd /usr/src/sys/compile/IGMPV3
make depend && make
make install


Examples and Testing

I changed Steve Deering's mtest.c into pmsft.c, in order to support source filters and be able to read commands from a file. At this moment, I'm working together with SprintLabs to create a host stack test document and test cases. This file will be used to run the test cases on different platforms, including Linux and Solaris. When I get my hands on Microsoft's implementation I will modify try to make it work on Win32 too.

The application can be started without arguments. Entering the command '?' will display a list of commands, similar to 'mtest.c'. It includes several new commands in order to specify source filters. Examples of these commands are:

# join a the group 230.0.0.0 on the default interface (0)
j 230.0.0.10 0
# block traffic on that group from 192.168.0.12
b 230.0.0.10 0 192.168.0.12
# also block traffic from 192.168.0.14
b 230.0.0.10 0 192.168.0.14
# show the source filter of this group, at most 5 sources
g 230.0.0.10 0 5
# now allow traffic from 192.168.0.12 again
t 230.0.0.10 0 192.168.0.12
# leave the group
l 230.0.0.10 0
# read commands from file t1.txt (see below)
f t1.txt

The commands return the error as returned by the API. If the arguments for the command are not as expected, the application returns '-1' (which simplified parsing to me).
As shown above, it's also possible to read commands from a file, which proved to be useful to me in order to automate testing. Such a file could look like:

# Join a group in include mode, with 2 sources
i 230.0.0.12 0 2
192.168.0.12
192.168.0.14
# show the filter mode of this group, and retrieve at most 1 source
g 230.0.0.12 0 2
# wait for 1 second
s 1
# block traffic from 192.168.0.14
b 230.0.0.12 0 192.168.0.14
# quit
q

IGMPv3 is rather complex if compared to IGMPv1 and IGMPv2. An example file that could (depending on your luck because of timing issues) is this file. The file itself shows 3 igmp messages that could be generated. Below you can find an source file that can dump IGMP reports (if started as root).

Here are some other source files that might be useful to you:

pmsft.c pmsft [file] As described above, using the Protocl Independent API. Compiles on FreeBSD and Linux.
msft.c
msft.exe
msft [file] The same kind of application as pmsft using the protocol dependent (IPv4) API instead. The good news, however, is that it compiles on those Windows vesions that support IGMPv3. At this moment that's the successor of W2K (Whistler) only.
mshow.c mshow <group> <port> <mode[e|i]> *[ip adresses] Join a multicast group using a source filter and receive and display a line of text.
ctalk.c ctalk <ip group> <port> +<message> Send a message to that group on the (udp) port. Compiles (and works) on Windows too.
UDPSend.java java UDPSend <ip group> <port> <message> Send a message to that group on the (udp) port.
qi3.c qi3 Generate IGMP queries, either v1, v2 or v3. It will ask you for the version, the group and in v3 a number of sources. (Unfortunately the generated addresses are still hardcoded.)


Tcpdump nowadays includes support for IGMPv3. You can download tcpdump at www.tcpdump.org. To see full IGMPv3 messages, you can start it like this:
tcpdump -vvv ip proto 2


Denial of Service (IGMPv3)

This implementation includes a protection against an IGMPv3 DoS attack using successive Group-and-Source-Specific queries. With successive, I mean a set of queries that result in one answer, because of the delayed response. It is possible for a host on the same network to store a lot of state in kernel memory through IGMPv3. How ?
  1. Generate a general IGMPv3 query
  2. Listen for the replies, and select a subscribed group from the host you want to attack
  3. Now send a number of group-and-source specific queries for this memership, with large source lists (which could change per query) for this membership and set the Maximum Response Time to 255, during about 25 seconds.
I created a simple application you could use to see if an IGMPv3 host stack can deal with large successive Group-And-Source-Specific queries. It's called igmpgass.c.

This implementation has 2 restrictions on group-and-source specific queries that will be accepted. The first restriction is the number of successive group-and-source specific queries. (This value defaults to 16.) The second is the number of sources that will be recorded because of group-and-source specific queries. (This value defaults to 64.) You can set these values using sysctl. To disable these restrictions you can set them to a value of 0 or some negative value. The commands would be:

sysctl -w net.inet.igmp.max_gass_queries=0
sysctl -w net.inet.igmp.max_rec_sources=0


On Going Work: IGMPv3 Proxy (igmppd)

Bil Fenner is working on a draft titled IGMP-based Multicast Forwarding.. I once started to work on such a proxy, but I dropped it. Abdelkader Lahmadi did implement an IGMP proxy at LORIA, and you can find details here .


References and Contacts

References:

Contacts:

Whenever you want more information on this implementation, or want to provide feedback, please contact me: wilbert@kloosterhof.com