Can't send multicast packets in Linux

  • Jason

    I've found my way here from another software package that use JmDNS and I find that this program does not work for me in Linux. I've downloaded version 3.0, and when I run it I receive an exception:

    :~/code/jmdns-3.0 5> java -jar lib/jmdns.jar -browse 
    TYPE: _http._tcp.local. 
    TYPE: _ftp._tcp.local. 
    TYPE: _tftp._tcp.local. 
    TYPE: _ssh._tcp.local. 
    TYPE: _smb._tcp.local. 
    TYPE: _printer._tcp.local. 
    TYPE: _airport._tcp.local. 
    TYPE: _afpovertcp._tcp.local. 
    TYPE: _ichat._tcp.local. 
    TYPE: _eppc._tcp.local. 
    TYPE: _presence._tcp.local. 
    TYPE: _rfb._tcp.local. 
    TYPE: _daap._tcp.local. 
    TYPE: _touchcs._tcp.local. 
    Dec 31, 2009 7:11:34 PM javax.jmdns.impl.tasks.Prober run 
    WARNING: run() exception Network is unreachable 
            at Method) 
            at javax.jmdns.impl.JmDNSImpl.send( 
            at java.util.TimerThread.mainLoop( 
    Dec 31, 2009 7:11:34 PM javax.jmdns.impl.JmDNSImpl recover 
    WARNING: recover() Start services exception  
            at java.lang.Thread.start( 
            at javax.jmdns.impl.JmDNSImpl.start( 
            at javax.jmdns.impl.JmDNSImpl.recover( 
            at java.util.TimerThread.mainLoop( 
    Dec 31, 2009 7:11:34 PM javax.jmdns.impl.JmDNSImpl recover 
    WARNING: recover() We are back!

    I've tracked down to this line of code: ms.send(packet);

    I'm not sure why it can't send the multicast packet. I have double checked, and my interface does support multicast:

    :~# ifconfig eth0 
    eth0      Link encap:Ethernet  HWaddr 00:ad:be:ef:be:eb 
              inet addr:  Bcast:  Mask: 
              inet6 addr: fe80::dcad:beff:feef:beeb/64 Scope:Link 
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1 
              RX packets:569893 errors:0 dropped:0 overruns:0 frame:0 
              TX packets:79695 errors:0 dropped:0 overruns:0 carrier:0 
              collisions:0 txqueuelen:1000 
              RX bytes:172111849 (164.1 MiB)  TX bytes:10089548 (9.6 MiB) 

    Further, I have attempted to ping the multicast address, and my wireless router (a Linksys WRT54GL) responds:

    :~# ping 
    PING ( 56(84) bytes of data. 
    64 bytes from icmp_seq=1 ttl=64 time=0.763 ms 
    64 bytes from icmp_seq=2 ttl=64 time=0.642 ms 
    64 bytes from icmp_seq=3 ttl=64 time=0.670 ms 

    I am stuck at this moment. I've looked up the MulticastSocket documentation, and the DatagramSocket docs, and they do mention that the send() function can throw an IOException, but I don't get sufficient information as to why exactly this is being thrown.

    Thanks for any help you can give.

  • Jason

    I have written a small Java program that shows this problem:


        class multicast
          public static void main(String args) throws IOException
            //Create socket.
            int port=5353;
            MulticastSocket socket=new MulticastSocket(port);
            //Create address structure.
            InetAddress group=InetAddress.getByName("");
            String msg="Hello";
            //Join group.
            //Send datagram.
            DatagramPacket packet = new DatagramPacket(msg.getBytes(), msg.length(), group, port);
            System.out.println("Exception on the next line.");

    This generates an exception every time:

        :~/code/multicast 44> javac && java multicast
        Exception on the next line.
        Exception in thread "main" Network is unreachable
                at Method)
                at multicast.main(

    Also, to prove that this isn't just a configuration issue with my computer, or a hardware problem, I also wrote a C++ program that does work:

        #include <sys/types.h>
        #include <sys/socket.h>
        #include <netdb.h>
        #include <arpa/inet.h>
        #include <iostream>

        int main(int argv, char* argc)
          //Create Socket.
          protoent* protocol=getprotobyname("udp");
          int sock=socket(PF_INET, SOCK_DGRAM, protocol->p_proto);
          if(sock==-1) { std::cout << "Error creating socket\n"; exit(1); }
          //Create address structure.
          sockaddr_in mdns_addr;
          char message="Hello";
          //Join group.
          struct ip_mreq mreq;
          //Send datagram.
          int return_val=sendto(sock, message, sizeof(message), 0, (sockaddr*)&mdns_addr, sizeof(mdns_addr));
          if(return_val==-1) { std::cout << "Error sending message\n"; exit(1); }

    When I run the C++ program it does not generate an error, and a WireShark capture shows that the interface does indeed send out a multicast datagram.

    I have also tried both programs without joining the multicast group, and the Java program still throws an IOException, and the C++ program still works.

    If I haven't said it, I am running Sun's Java 1.6:

        :~/code/multicast 47> javac -version
        javac 1.6.0_12
        :~/code/multicast 48> java -version
        java version "1.6.0_12"
        Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
        Java HotSpot(TM) Client VM (build 11.2-b01, mixed mode, sharing)

    If anyone can help me with this problem, I would appreciate it.

  • Jason

    I have discovered the root cause of this problem. I had IPv6 configured on this computer. Since other devices that I communicate with do not support IPv6, I turned it off. This stopped the IOExceptions in JmDNS.

  • Rick Blair
    Rick Blair

    Glad you are up and running.

      This makes sense.

    Java 1.6 will prefer IPV6 over IPV4.  There is a setting that will
    reverse it.

    I will see what I can dig up.

  • Bruno

    This problems seems to be specific to trying to use an IPv6 multicast address on the loopback interface. This patch should fix this problem, without having to disable IPv6 altogether:

    --- a/src/main/java/javax/jmdns/impl/
    +++ b/src/main/java/javax/jmdns/impl/
    @@ -1537,7 +1537,7 @@ public class JmDNSImpl extends JmDNS implements DNSStatefulObject, DNSTaskStarte
                 final MulticastSocket ms = _socket;
    -            if (ms != null && !ms.isClosed()) {
    +            if (ms != null && !ms.isClosed() && !(_group instanceof Inet6Address && ms.getInterface().isLoopbackAddress())) {