This document is not a formal how to but a list of steps that I folloed to get a multicast routing Linux box. I will also give some simple source code at the end to get you started in writing multicast programs. Which is what I needed multicast routing for -- to test my code. Please not that mrouted (the multicast router) is not distributed via the normal Linux distribution channels because it's not free software. Read the license that comes with it before you use it. Also note that even though it is not implicitly specified you are expected to become root for most of these operations.
Multicast is protocol that has been around for a while and I recomend that you read over the Multicast-HOWO (referenced in section 5) to learn how it works. I recomend that you do that first or at least know it's there to answer questions this document will not.
You don't need to run the same exact software as I. My list is just a guide.
I started with a custom install of RedHat 6.0. And then installed these from source:
If these files don't exist you can use http://www.tuxfinder.com/ or http://www.filewatcher.org/ to find them.
- kernel 2.2.12:
- mrouted 3.9 beta3-1:
- mrouted Linux patch:
If you have configured the kernel before and are familiar with the tools you can skip over this section -- simply make sure that you have the following items set:
2.1 Installing the kernel sourcetreeMost comonly the source for the kernel are kept in /usr/src/linux -- most distributions put them there. So if you downloaded your linux-2.2.12.tar.gz file to /tmp you may want to do the following:cd /usr/srcAnd now you have the linux source tree. Since the directory created by the last command is /usr/src/linux, I usually rename it to its proper name (including its version) and simply provide a 'linux' symbolic link to the new name to avoid any compatility issues.
mv linux linux-old
tar xvzf /tmp/linux-2.2.12.tar.gzmv linux linux-2.2.12Ok, so now we are ready to configure our kernel.
ln -s linux-2.2.12 linux
2.2 Configuring the kernelThere are four ways of configuring the kernel. The first is fairly crude and I just include it for completeness: editing the .config file ... yuk! The next is not much better: 'make config' -- it's a program that will ask you for a yes/no/module for every one of the 500 options in the kernel. The next two are vary nice menu driven utilities: 'make menuconfig' and 'make xconfig'. As I don't often have X installed on the systems I use I frequently use the curses based menuconfig feature.
You need these features to get multicast routing to work:
And of course you will require some kind of a network interface (I leave that upto you).
- Networking options
- IP: multicasting
- IP: optimize as router not host
- IP: multicast routing
- IP: tunneling
2.3 Compiling and installing the kernelThis may very from system to system. I use a i86 RedHat 6.0 and this is what I do:make bzImage
2.4 Installing LILOYou must modify your LILO to point and boot from the new kernel. To do this edit your /etc/lilo.conf file and make it look like this:boot=/dev/hdaOf course you must specify the correct harddrive device for the 'boot' and 'root' labels. If you have not done this before best to read the Kernel-HOWTO.
Once you have altered your lilo.conf you can reinstall LILO:liloAnd that's it. Reboot.
As mentioned before mrouted is not free -- read the license file.
3.1 Untaring and patching the sourcesOnce again I assume that you have downloaded the files into /tmp and wish to untar them in /usr/src.cd /usr/srcIf everything goes well it should tell you that it patched ~13 files. I get this output:
tar xvzf /tmp/mrouted-3.9-beta3.tar.gz
gunzip /tmp/mrouted_3.9-beta3-1.diff.gz | patch -p0patching file `mrouted-3.9-beta3.orig/Makefile'
patching file `mrouted-3.9-beta3.orig/defs.h'
patching file `mrouted-3.9-beta3.orig/pathnames.h'
patching file `mrouted-3.9-beta3.orig/debian/init.d'
patching file `mrouted-3.9-beta3.orig/debian/changelog'
patching file `mrouted-3.9-beta3.orig/debian/copyright'
patching file `mrouted-3.9-beta3.orig/debian/dirs'
patching file `mrouted-3.9-beta3.orig/debian/control'
patching file `mrouted-3.9-beta3.orig/debian/rules'
patching file `mrouted-3.9-beta3.orig/debian/README.debian'
patching file `mrouted-3.9-beta3.orig/igmp.i'
patching file `mrouted-3.9-beta3.orig/netinet/ip_mroute.h'
patching file `mrouted-3.9-beta3.orig/vers.c'
3.2 CompilingSo now we are ready to compile:cd mrouted-3.9-beta3.orig
3.3 Configuring the routerOnce it compiles let's create a file /etc/mrouted.conf, it will include:phyint eth0 rate_limit 0 igmpv1There is a lot more that you can configure in the mrouted.conf and you should probably read the mrouted.conf example that comes with the sources -- it's well commented. The above 2 lines force the mrouted program to enforce igmp V1 on eth0 and eth1 with no rate limit. More importantly it works for me.
phyint eth1 rate_limit 0 igmpv1
Delbert Matlock, the maintainer of "Multicast and MBONE on Linux", had an incompatibility with mrouted and virtual interfaces. He was able to overcome this by adding the following line (for each of his virtual devices into the /etc/mrouted.conf.phyint eth0:0 disable
3.4 Running the routerThere are a few issues that must be taken care off before we run the router. First we need to have those interfaces that are specified in the configuration. Next we must have a default route setup for the multicast traffic; to do this run:route add -net 220.127.116.11 netmask 240.0.0.0 dev eth0You can use any network device so long as that is where you want the default data to go to.
Finally you can run the mrouted program:mrouted -c /etc/mrouted.conf -dThe '-d' flag is useful the first time to see the 'debug' output more on this in the manpage for mrouted (mrouted.8).
At this point you should be routing multicast packets. Note that multicast routing is not instantatious and sometimes may requires a half a minute to start up. Most important to understand about multicast routing is that if no one requests the packets on network of eth1 they will jump accross from eth0 to eth1.
In this secion I will give a code example for a simple multicast program. As just mentioned the reader must request the packets in order to be garanteed that they are routed towards it. This is called 'joining a group'. And a multicast group is identified by it's IP address. If a socket does not join a multicast group no packets of that group will ever be passed to it by the kernel.
Sending multicast is no different then sending UDP packets. The sender does not even have to join the multicast group in order to send to it. However, it is proper to join the group and inform the mrouted program that we are sending trafic on that multicast group. Even more important for the multicast sender is to set the TTL to something greater then 1 (which is the default). TTL, or time to live, is a counter attached to every sent packet. The TTL value gets decremented at every router and when it reaches 0 is dropped. Thus multicast data will not get very far if the TTL value is 1.
Here is some code to get you going:int main(void)
const int TTL=64;
const int v_off=0, v_on=1;
struct sockaddr_in to;
struct ip_mreq multiaddr;
int sock = socket(AF_INET, SOCK_DGRAM, 0);
// Join a multicast group 18.104.22.168 on all interfaces
multiaddr.imr_multiaddr.s_addr = htonl(0xe0010104); // 22.214.171.124
multiaddr.imr_interface.s_addr = htonl(INADDR_ANY);
setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL,
// setup the destination address of 126.96.36.199 and UDP port 2007
to.sin_family = AF_INET;
to.sin_addr.s_addr = htonl(0xe0010104);
to.sin_port = htons(2007);
// write some data
(const struct sockaddr*)&to,sizeof(to));
// tell router we are no longer interested in this group
Google search on multicast routing on linux yields many good results: