There are updates to this page that haven't been applied because you've entered text. Refresh this page to see updates.
Hide this message.

Share Post

Post stats

Views863

Making Multicast Work on VirtualBox in C#

Jeff KesselmanJeff Kesselman, I know a little bit about a wh... (more)
I've been working on a LAN networking library for my students.  Because I don't have a Windows network, I had to create a virtual one using a couple of VirtualBox VMs.

Although my C# code worked on a real Windows network when tested, it staunchly refused to work on VirtualBox.  It took me about a week of poking around the internet and beating my head against my laptop, but i finally have a virtual multi-cast network working.  I thought I'd lay out the finally successful formula..  There may be other ways, and not all of these steps may really be necessary , but this is what worked for me:

  1. Download and install the latest VirtualBox from Oracle VM VirtualBox   also download and install the Oracle VirtualBox Extension Pack (might not be necessary, but I did.)
  2. Install a copy of Win7 into a VirtualBox VM.
  3. Clone the VM to create a second machine.
  4. Critically Important:  A clone starts with the same MAC address as its parent. This messed me up for a long time. Go into Network Settings->Advanced  for the clone and request that it assign you a new MAC by pressing the circular arrows next to the MAC.  (This only works when the virtual machine is powered down.)
  5. Set the network type setting for both machines to "Internal Network".  (Note that this will isolate them from your host and the internet.)
  6. On the command line of your host, enable dhcp  (this also may not be absolutely necessary but it is what I did.  As an alternative you could also manually config your IP for both machines).  Assuming you used the default internal network name of "intnet", you can do that like this (all on one line):  
    dhcpserver add --netname intnet --ip 10.10.10.1 --netmask 255.255.255.0 --enable --lowerip 10.10.10.10 --upperip 10.10.10.128
  7. Critically Important:  In the environment created by VirtualBox there are multiple NICs that claim to be multicast capable.  However, they are lying.  Furthermore, because of the way VirtualBox assigns metrics, your outgoing socket will get assigned to a liar who will happily gobble up your multicast messages and not send them on.
    The solution is to open an outgoing socket specifically on every NIC that claims to be multicast capable and send your outgoing packets to all of them.  Below is my code that opens the sockets and makes a list.  Just foreach on the list when sending the packet.
      NetworkInterface[] nics =  
                      NetworkInterface.GetAllNetworkInterfaces();
      // Get netowrk info
      int defaultPort = 5050;
      string localName = Dns.GetHostName();

      IPHostEntry hostEntry = new IPHostEntry();
      hostEntry = Dns.GetHostByName(localName);
      IPAddress localAddress = hostEntry.AddressList[0];
       for(int i=0;i<nics.Length;i++){
                if (!nics[i].SupportsMulticast)
                {
                    continue; // skip this one
                }
                Console.WriteLine("Adding socket to nic: " + nics[i].Name);
                // output interface
                Socket mcastSocket = new
                    Socket(AddressFamily.InterNetwork,
                         SocketType.Dgram, ProtocolType.Udp);

                // Bind the socket to default IP address and port.
                mcastSocket.Bind(new IPEndPoint(localAddress,4568+i));

                //Select Adapter for outgoing Multicast packets );

                int optionValue = (int)IPAddress.HostToNetworkOrder(i);

                //Multicast Address - To add membership :
                IPAddress mcastAddress = IPAddress.Parse("224.5.6.7");

                // Port number - Where Multicast members are listening
                int mcastPort = 4567;
                MulticastOption mcastOpt = new
                    MulticastOption(mcastAddress,localAddress);

                 // Add membership to the group.
                mcastSocket.SetSocketOption(SocketOptionLevel.IP,
                    SocketOptionName.AddMembership, mcastOpt);

                // Set the required interface for outgoing multicast packets.
                mcastSocket.SetSocketOption(SocketOptionLevel.IP,
                    SocketOptionName.MulticastInterface, optionValue);

                mcastSocket.Connect(new
                    IPEndPoint(mcastAddress,4567));
               
                // add to transmission list
                transmissionList.Add(mcastSocket);
            }
Comment

Blog

Ramblings, rants and ruminations from an irasci...

Author

Jeff Kesselman
Jeff Kesselman
I know a little bit about a whole lot, and a whole lot about a...