Google Answers Logo
View Question
 
Q: How to listen for UDP broadcast packets on a specific network interface ( Answered,   0 Comments )
Question  
Subject: How to listen for UDP broadcast packets on a specific network interface
Category: Computers > Programming
Asked by: bigjosh-ga
List Price: $25.00
Posted: 20 Dec 2002 08:01 PST
Expires: 19 Jan 2003 08:01 PST
Question ID: 127329
I have a host with two network interfaces on two independent networks.
I want to recieve UDP broadcast packets that are coming from one of
the two networks - I don't want to recieve any UDP broadcasts that
might be on the other network.

The broadcast packets that I want to recieve have a destination
address of 255.255.255.255 - they are *not* subnet directed
broadcasts.

This is pretty easy to do with *multicast* packets, but I've been
unable to find a way to bind a UDP listen to a specific interface for
recieving broadcast packets.

One idea was to check the source address of incoming packets to see
which network they came from, but this will not work becuase a sender
could spoof the system by forging a source address (the network from
which I do not want to recieve broadcasts is non-secure).

Platform is Java 1.4 on Linux and/or Win2k.

Request for Question Clarification by maniac-ga on 23 Dec 2002 13:24 PST
Hello Bigjosh,

It appears it should be possible on Linux but I can't test it to be
sure. There is an option to setsockopt called SO_BINDTODEVICE
described at
  http://www.ece.queensu.ca/hpages/courses/Elec377/man/man7/socket.7.txt
The specific option is described about 1/2 of the way down the file.
According to this man page, this was added in Linux 2.0.30.

From a couple other sites, this was added to support DHCP servers
which sounds similar to your application. Is this the kind of solution
you were looking for?

  --Maniac
Answer  
Subject: Re: How to listen for UDP broadcast packets on a specific network interface
Answered By: coral-ga on 24 Dec 2002 16:37 PST
 
The builtin class MulticastSocket [1] should satisfy your needs.  It's
an extension of DatagramSocket [2] that adds several features, two of
which you'll need to accomplish your goal.

Your question states that you're trying to use the broadcast address
"255.255.255.255", so we'll create a socket that's ready to receive
and send packets on the "multicast group" 255.255.255.255.

    // basic multicast datagram socket.
    MulticastSocket socket = new MulticastSocket();

Next, we use joinGroup [3] to join the multicast group on a given
interface; this limits the broadcasts received to a specific
interface, as desired.

    // DatagramPacket.send() also takes this network address.
    InetAddress broadcast = InetAddress.getByName("255.255.255.255");

    // get the interface object for interface "1.2.3.4".
    NetworkInterfaceAddr ifaddr = InetAddress.getByName("1.2.3.4");
    NetworkInterface if = NetworkInterface.getByInetAddress(ifaddr);

    // bind the socket's receiving side to "255.255.255.255", on
interface "1.2.3.4".
    socket.joinGroup(broadcast, if);

If you like, you can choose the outgoing interface for given broadcast
packets as well.

    // bind the socket's sending side to interface "1.2.3.4".
    socket.setNetworkInterface(if);

Further information on the classes used above can be found at Sun's
J2SE 1.4 reference [4]; I suggest browsing the methods provided in
classes NetworkInterface [5] and MulticastSocket [1].

[1] http://java.sun.com/j2se/1.4/docs/api/java/net/MulticastSocket.html
[2] http://java.sun.com/j2se/1.4/docs/api/java/net/DatagramInterface.html
[3] http://java.sun.com/j2se/1.4/docs/api/java/net/MulticastSocket.html#joinGroup(java.net.SocketAddress,%20java.net.NetworkInterface)
[4] http://java.sun.com/j2se/1.4/docs/api/overview-summary.html
[5] http://java.sun.com/j2se/1.4/docs/api/java/net/NetworkInterface.html

Much of the information provided in this answer was found through the
following Google search [6] and result URL [7], once I realized that
MulticastSocket could be used to send and receive on the broadcast
address.

[6] ://www.google.com/search?q=multicastsocket+%22255.255.255.255%22
[7] http://www.cee.hw.ac.uk/~mjc/teaching/3ne3/5/13+14.htm

Request for Answer Clarification by bigjosh-ga on 26 Dec 2002 19:43 PST
Unfortunately that does not work. The MulticastSocket stuff only works
with multicast addresses, not broadcast ones, or the problem would be
easy.

If you try the following program...

NetworkInterface netif = NetworkInterface.getByName( "eth0" );
InetAddress INADDR_ANY = InetAddress.getByName("255.255.255.255");
MulticastSocket sock = new MulticastSocket();
sock.joinGroup( new InetSocketAddress(INADDR_ANY, 20560), netif );
byte[] data = new byte[ 1500 ];
DatagramPacket pack = new DatagramPacket( data, data.length );
sock.receive( pack );

You'll get...

Exception in thread "main" java.net.SocketException: Not a multicast
address
        at java.net.MulticastSocket.joinGroup(MulticastSocket.java:350)
        at NetIf.main(NetIf.java:35)

Becuase in the java.net.MulticastSocket.java source it says...

 if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress())
{
            throw new SocketException("Not a multicast address");
        }

Oh well...

Request for Answer Clarification by bigjosh-ga on 26 Dec 2002 19:46 PST
The SO_BINDTODEVICE stuff if interesting and we've been trying to put
together a kernal that will support it. I guess if no Java-possible
solution surfaces, I'll have no choice but to use this stuff with a
magic kernal and JNI. Thanks for the info.

Clarification of Answer by coral-ga on 26 Dec 2002 21:03 PST
Hm, I looked in the source code and found that [1]; thanks for the
error message.  If you overload isMulticastAddress to accept
"255.255.255.255", does it work?  Some example code here, in case it
helps.

    class allowMulticastBroadcasts extends InetAddress {
        public boolean isMulticastAddress () { return (address ==
0xffffffff || ((address & 0xf0000000) == 0xe0000000)); }
    }

[1] http://216.239.39.100/search?q=cache:V9PBMhQTx2cC:guma.ii.fmph.uniba.sk/jdk/java/net/InetAddress.java.html+%22ismulticastaddress%22+%22255.255.255.255%22&hl=en&ie=UTF-8#:107

Request for Answer Clarification by bigjosh-ga on 27 Dec 2002 10:31 PST
That just makes things worse. In the end, multicast and broadcast
listeners are completely different and there is no way to recieve a
broadcast UDP packet on a multicast socket.

Clarification of Answer by coral-ga on 27 Dec 2002 12:54 PST
Alright, time for a different tack; my apologies for the diversion
down the multicast route.

  The constructor for DatagramSocket notes that you have the option to
bind to both a port and a local address on a given machine.  If you
bind your DatagramSocket to the IP of a local interface, and then
.setBroadcast(true), does the socket properly receive and send
broadcast packets only on the given local address?

[1] http://java.sun.com/j2se/1.4/docs/api/java/net/DatagramSocket.html#constructor_summary
Comments  
There are no comments at this time.

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy