broadcast udp packets ...
Wes Peters
wes at softweyr.com
Tue Jul 15 15:48:53 PDT 2003
On Tuesday 15 July 2003 10:09, Matthew Grooms wrote:
> Hmmm,
>
> >What we observed on our embedded system is the packet gets sent on
> > all attached interfaces, with dest IP 255.255.255.255, and a src IP
> > of the local address that has the default route. If there isn't a
> > default route, sending to 255.255.255.255 fails with "no route to
> > host."
>
> Maybe I am confused. When I use a udp socket bound to an interface,
> packets that are generated from that socket get thier dest address
> translated to a network specific broadcast address. Do I understad
> you correctly when you say that you can generate packets destined to
> 255.255.255.255? Am I doing somthing different then you are? ...
>
> int test_sock = socket( PF_INET, SOCK_DGRAM, 0 );
> if( test_sock == -1 )
> return -1;
>
> struct ifreq ifr;
> memset( &ifr, 0, sizeof( struct ifreq ) );
> strcpy( ifr.ifr_name, config.get_service_iface() );
> if( ioctl( test_sock, SIOCGIFADDR, &ifr ) == -1 )
> return -1;
>
> uint32_t value = 1;
> if( setsockopt( test_sock, SOL_SOCKET, SO_BROADCAST,
> (char*) &value, sizeof( uint32_t ) ) == -1
> return -1;
>
> struct sockaddr_in serv_addr;
> memset( &serv_addr, 0, sizeof( struct sockaddr_in ) );
> memcpy( &serv_addr, &ifr.ifr_addr, sizeof( struct sockaddr_in ) );
> serv_addr.sin_family = AF_INET;
> serv_addr.sin_port = htons( config.get_service_port() );
>
> if( bind( test_sock, ( struct sockaddr * ) &serv_addr,
> sizeof( struct sockaddr_in ) ) == - 1)
> return -1;
>
> struct sockaddr_in bcast_addr;
> memset( &bcast_addr, 0, sizeof( struct sockaddr_in ) );
> bcast_addr.sin_family = AF_INET;
> bcast_addr.sin_addr.s_addr = 0xffffffff;
> bcast_addr.sin_port = htons( 100 );
>
> char test_buff[] = { "TEST123TEST123" };
> if( sendto( test_sock, test_buff, sizeof( test_buff ), 0,
> ( const struct sockaddr * ) &bcast_addr,
> sizeof( const struct sockaddr_in ) ) == -1 )
> printf( "failed to generate broadcast packet( %d bytes )\n",
> sizeof( test_buff ) );
> else
> printf( "broadcast packet generated ( %d bytes )\n",
> sizeof( test_buff ) );
>
> >This is bogus, so I propose to change it to a special case, where
> >packets sent to 255.255.255.255 will be sent on each attached
> >interface, with src IP of the interface "primary" address.
>
> When you say attached, do you mean the socket is bound to the ip
> address of that interface or do you mean all configured interfaces on
> that host? Should this be affected by the MSG_DONTROUTE flag? It
> would seem that if you were requesting the packet be routed, that it
> would be emmitted on all network interfaces. If the MSG_DONTROUTE
> were passed, that the packet would only be generated on the interface
> the socket is bound to.
It's a broadcast, the socket isn't bound to an interface. ;^)
The idea is, we have listener on each ethernet interface listening via a
bpf. The listener listens for an 'appliance discovery' packet which is
broadcast by the console application running on the admin's
workstation. When we receive this discovery packet, we're supposed to
reply back with a broadcast packet that says 'here I am' so the console
can get our MAC address. The console application does some special
h0h0 magic of it's own then sends us back another broadcast message
that has IP addresses for all 3 interfaces.
It's a wonderful idea but it doesn't work. This seems in keeping with
the spirit of BOOTP, DHCP, et al, but is explicitly designed to assign
a permanent address to an appliance that cannot know it's boot address
when configured and cannot really predict which of the 3 interfaces it
might receive an address from.
If the answer to this is 'ick, that's just not what IP broadcasting is
supposed to do, get lost' I'm willing to accept that answer, but so far
everyone seems to agree that what I proposed isn't that whacked out.
Tell me if I'm wrong! ;^)
So, in short, the IP address 255.255.255.255 is a special case that
isn't handled as a special case by the ip_output code. I propose to
change the code so that a packet sent to destination address
255.255.255.255 (aka INADDR_BROADCAST) be handled specially. Any such
packet will be sent to destination address 255.255.255.255 on each
interface that is marked UP and BROADCAST, with the ip src address set
to the currently configured primary ip address of the interface, even
if this is 0.0.0.0. This special case will not call rtalloc or do any
other route lookups.
Stop me if I'm violating specifications or even just common sense
here... (I need to read the IP and UDP RFCs in a bit more detail, they
seem pretty vague in this area.) I'd like to implement this if it's a
sensible change, but will tell the application guys to rewrite their
send code to use the BPF if it seems this is wrong. I don't feel the
current implementation is right in any way, but I don't want to make it
more wrong.
--
"Where am I, and what am I doing in this handbasket?"
Wes Peters wes at softweyr.com
More information about the freebsd-net
mailing list