Re: Linux, IO::Socket::INET and recv'ing broadcasted UDP




Quoth DJ Stunks <DJStunks@xxxxxxxxx>:
On Feb 18, 4:42 pm, Ben Morrow <b...@xxxxxxxxxxxx> wrote:
Quoth DJ Stunks <DJStu...@xxxxxxxxx>:

The DHCPOFFER is broadcasted regardless (Ethernet
destination MAC = ff:ff:ff:ff:ff:ff; destination IP = 255.255.255.255;
destination udp port = 68) but my socket never receives it.

That's... odd. Can you recieve other broadcast datagrams?

Have you tried using a PF_PACKET socket?

I thought it was odd too, but I'm continuing to research (so
frustrated! ;-)) and I think what I'm finding is that it's not that
odd...

Here's a post from Solaris' bug tracker:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4191980.
The originator had a similar problem, but with Java. The response
was:

"The Solaris (& Linux for that matter) behavior is that to be able to
receive broadcasts a UDP socket has to be bound to the wildcard
address (aka anylocal). This has been the defacto standard behavior
since the days of BSD 4.3. Win32 behaviors differs from that. So the
only way to be guaranteed to receive the broadcasts on any platform is
to bind to the wildcard address."

OK. I didn't know that, but it makes some sense.

So I tried changing my IO::Socket::INET constructor to use INADDR_ANY,
but no luck. The constructor seems to ignore PeerAddr => '0.0.0.0';

No, you need LocalAddr => '0.0.0.0'. It's the address of *this* socket
you're setting, not the address you're talking to. For UDP sockets,
PeerAddr sets the default destination for sends.

This page (http://wiki.forum.nokia.com/index.php/
How_to_use_udp_broadcast) shows how to set up a Python socket for UDP
broadcast.

Whoa... that page is about PyS60, otherwise known as 'Python for itty
bitty Symbian phones with rather weird network stacks' :). However, the
code they give is basically the same as on any other platform; here
(FreeBSD) I can send and recieve broadcast datagrams with

#!/usr/bin/perl -l

use warnings;
use strict;

use IO::Socket::INET;

use Data::Dump qw/dump/;

my $port = 8091;

if ($ARGV[0] eq 'recv') {
my $SCK = IO::Socket::INET->new(
Type => SOCK_DGRAM,
Proto => 'udp',
LocalAddr => '0.0.0.0',
LocalPort => $port,
Broadcast => 1,
) or die "socket: $@";

$SCK->recv(my $buf, 512, 0)
or die "recv: $@ $!";

print dump $buf;
}
else {
my $SCK = IO::Socket::INET->new(
Type => SOCK_DGRAM,
Proto => 'udp',
PeerAddr => $ARGV[1],
PeerPort => $port,
Broadcast => 1,
) or die "socket: $!";

my $buf = 'Hello world!';
$SCK->send($buf)
or die "send: $!";
}

__END__

though I find I have to send to 192.168.1.255 (the local net broadcast
addr) rather than 255.255.255.255, which ought to be the same. I don't
know why that is.

So now my question is, how do I set up a Perl socket similarly? Can I
still use IO::Socket::INET to set PF_INET (is that the same as
PF_PACKET?) or do I have to use Socket instead?

No, PF_PACKET isn't the same as PF_INET. PF_INET is the normal Internet
protocol family: basically TCP or UDP over IP, though on most OSen you
can use PF_INET/SOCK_RAW sockets to talk any IP protocol, including
ICMP. In Perl you can use IO::Socket::INET to do anything your OS will
let you do with PF_INET sockets.

PF_PACKET is a Linux-specific protocol family for talking directly to
the network driver; it allows you to send and receive raw Ethernet
frames, for example. Perl has no IO::Socket support for PF_PACKET
(though writing an IO::Socket::PACKET wouldn't be too hard: it's mostly
just packing and unpacking the addresses, which is code you'd need to
write to use these sockets anyway), so if you need these you would have
to use the socket builtins (Socket wouldn't help, here, as that only has
AF_INET/AF_UNIX support).

Ben

.



Relevant Pages

  • Re: SetSockOpt with SO_REUSEADDR parameter
    ... So I create multiple UDP sockets with the same port to send data. ... happening is that you are throwing away the old socket and replacing it with the new ... When the second client is connecting to server, I still get the error code ...
    (microsoft.public.vc.mfc)
  • Re: SetSockOpt with SO_REUSEADDR parameter
    ... The accept call creates a new socket with the same local port number. ... TCP is not UDP. ... And because there can only be one listening socket on a port, ...
    (microsoft.public.vc.mfc)
  • Re: How to uniquely identify a UDP session at Winsock layer?
    ... For UDP, once a send is done, the socket will be auto-bound if it has not ... > Theoretically, I guess, a connection or session in uniquely identified ... > by "Source IP, Source port, Destination IP, Destination port". ...
    (microsoft.public.pocketpc.developer.networking)
  • Re: call is blocked in recvfrom() and no further proceedings in Wi
    ... How is the Windows CE device connected to the network where the desktop ... that won't work with UDP. ... >>> My program has to send request to service through port 5070(in this ... >>> socket ...
    (microsoft.public.windowsce.embedded)
  • Re: UDP broadcast/receive notification system
    ... I haven't yet seen a message I drop on the broadcast address come back on ... He may be also using the GUID to detect duplicated datagrams at the recipient end. ... My recollection is that the sending socket won't get echos, so if that's all he's doing, yes...that's probably overkill. ... Unless you bind to different IP addresses, you wouldn't be able to receive on the same port. ...
    (microsoft.public.dotnet.framework)