Broadcasting Without the Broadcast Address


 
Network Programming with Perl
By Lincoln  D.  Stein
Slots : 1
Table of Contents
Chapter  20.   Broadcasting

    Content

Sending and Receiving Broadcasts

Broadcasting a message is simply a matter of sending a UDP message to the broadcast address for your subnet. A simple way to see broadcasts in action is to use the ping program to send an ICMP ping request to the broadcast address. The following example illustrates what happened when I pinged the broadcast address for my office's 143.48.31.0/24 network:

 %  ping 143.48.31.255  PING 143.48.31.255 (143.48.31.255): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=4.9 ms 64 bytes from 143.48.31.46: icmp_seq=0 ttl=255 time=5.4 ms (DUP!) 64 bytes from 143.48.31.52: icmp_seq=0 ttl=255 time=5.9 ms (DUP!) 64 bytes from 143.48.31.47: icmp_seq=0 ttl=255 time=6.4 ms (DUP!) 64 bytes from 143.48.31.48: icmp_seq=0 ttl=255 time=6.9 ms (DUP!) 64 bytes from 143.48.31.30: icmp_seq=0 ttl=255 time=7.4 ms (DUP!) 64 bytes from 143.48.31.40: icmp_seq=0 ttl=255 time=7.9 ms (DUP!) 64 bytes from 143.48.31.33: icmp_seq=0 ttl=255 time=8.4 ms (DUP!) 64 bytes from 143.48.31.39: icmp_seq=0 ttl=255 time=9.0 ms (DUP!) 64 bytes from 143.48.31.31: icmp_seq=0 ttl=255 time=9.5 ms (DUP!) 64 bytes from 143.48.31.35: icmp_seq=0 ttl=255 time=10.0 ms (DUP!) 64 bytes from 143.48.31.36: icmp_seq=0 ttl=255 time=10.5 ms (DUP!) 64 bytes from 143.48.31.32: icmp_seq=0 ttl=255 time=11.0 ms (DUP!) 64 bytes from 143.48.31.37: icmp_seq=0 ttl=255 time=11.6 ms (DUP!) 64 bytes from 143.48.31.43: icmp_seq=0 ttl=255 time=12.1 ms (DUP!) 64 bytes from 143.48.31.57: icmp_seq=0 ttl=255 time=12.6 ms (DUP!) 64 bytes from 143.48.31.55: icmp_seq=0 ttl=255 time=13.1 ms (DUP!) 64 bytes from 143.48.31.58: icmp_seq=0 ttl=255 time=13.6 ms (DUP!) 64 bytes from 143.48.31.254: icmp_seq=0 ttl=255 time=14.1 ms (DUP!) 64 bytes from 143.48.31.45: icmp_seq=0 ttl=255 time=14.6 ms (DUP!) 64 bytes from 143.48.31.34: icmp_seq=0 ttl=255 time=15.1 ms (DUP!) 64 bytes from 143.48.31.38: icmp_seq=0 ttl=255 time=15.6 ms (DUP!) 64 bytes from 143.48.31.59: icmp_seq=0 ttl=60 time=19.1 ms (DUP!) 64 bytes from 143.48.31.60: icmp_seq=0 ttl=128 time=16.6 ms (DUP!) 64 bytes from 143.48.31.251: icmp_seq=0 ttl=255 time=17.1 ms (DUP!) 64 bytes from 143.48.31.252: icmp_seq=0 ttl=255 time=17.6 ms (DUP!) --- 143.48.31.255 ping statistics --- 1 packets transmitted, 1 packets received, +25 duplicates, 0% packet     loss round-trip min/avg/max = 4.9/11.2/17.6 ms 

A total of 26 hosts responded to the single ping packet, including the machine I was pinging from. The machines that replied to the ping include Windows 98 laptops, a laser printer, some Linux workstations, and servers from Sun and Compaq. Every machine on the subnet received the ping packet, and each responded as if it had been pinged individually. Although one of the machines that responded was a router (143.48.31.254), it did not forward the broadcast. We did not see replies from machines outside the subnet.

Interestingly, the host I ran the ping on did not respond via its network interface of 143.48.31.42, but on its loopback interface, 127.0.0.1. This illustrates the fact that the operating system is free to choose the most efficient route to a destination and is not limited to responding to messages on the same interface that it received them on.

Sending Broadcasts

There are four simple steps to sending broadcast packets:

  1. Create a UDP socket. Create a UDP socket in the normal way, either by using Perl's built-in socket() function or with the IO::Socket module.

  2. Set the socket's SO_BROADCAST option. The designers of the socket API wanted to add some protection against programs inadvertently transmitting to the broadcast address, so they required that the SO_BROADCAST socket option be set to true before a socket can be used for broadcasting. Use either the built-in setsockopt() call or the IO::Socket unified sockopt() method.

  3. Discover the broadcast address for your subnet (optional). The broadcast address is different from location to location. You could just hard code the appropriate address for your subnet (or ask the user to enter it at runtime). For portability, however, you might want to discover the appropriate broadcast address programatically. We discuss how to do this later.

  4. Call send() to send data to the broadcast address. Use sockaddr_in() to create a packed destination address with the broadcast address and the port of your choosing. Pass the packed address to send() to broadcast the message throughout the subnet.

Figure 20.2 shows a simple echo client based on the multiplexing client from Chapter 18. It reads user input from STDIN and broadcasts the data to a hard-coded broadcast address. As responses come in, it prints the IP address and port number of each respondent and the length of the data received back.

Figure 20.2. An echo client that sends to the broadcast address

graphics/20fig02.gif

Lines 1 “3: Bring in modules Load definitions from IO::Socket and IO::Select.

Lines 4 “5: Choose an IP address and port We get the address and port from the command line. If not given, we default to a hard-coded broadcast address and the UDP echo service port. We will see in the next section how to discover the appropriate broadcast address automatically.

Lines 6 “8: Create a UDP socket and enable broadcasting We call IO::Socket::INET-new() to create a new UDP protocol socket. No other arguments are necessary. We then notify the operating system that we intend to broadcast over this socket by calling its sockopt() method with SO_BROADCAST set to true.

The last line of this section creates a packed destination address from the port number and the broadcast address.

Lines 9 “16: Select loop The body of the code is a select loop over the socket and STDIN . Each time through the loop, we call do_stdin() if there's data to be read from the user, and do_socket() if there's a message ready to receive on the socket.

Lines 17 “21: Broadcast user data via the socket The do_stdin() function reads some data from STDIN , exiting the script on end of file or other error. We then send the data to the packed broadcast address created in line 8.

Lines 22 “28: Read responses from socket If select() indicates that the socket has messages to read, we call recv() , saving the peer's packed address and the message itself in local variables . We unpack the peer's address, translate the host portion in it into a dotted -quad form, and print a message to standard output.

Here is what I got when I ran this program on the same subnet that we pinged in the previous section:

 %  broadcast_echo_cli.pl 143.48.31.255   hi there  received 9 bytes from 143.48.31.42:7 received 9 bytes from 143.48.31.36:7 received 9 bytes from 143.48.31.34:7 received 9 bytes from 143.48.31.32:7 received 9 bytes from 143.48.31.40:7 received 9 bytes from 143.48.31.60:7 received 9 bytes from 143.48.31.33:7 received 9 bytes from 143.48.31.31:7 received 9 bytes from 143.48.31.39:7 received 9 bytes from 143.48.31.35:7 received 9 bytes from 143.48.31.38:7 received 9 bytes from 143.48.31.37:7  this works  received 11 bytes from 143.48.31.42:7 received 11 bytes from 143.48.31.34:7 received 11 bytes from 143.48.31.32:7 received 11 bytes from 143.48.31.36:7 received 11 bytes from 143.48.31.35:7 received 11 bytes from 143.48.31.33:7 received 11 bytes from 143.48.31.31:7 received 11 bytes from 143.48.31.38:7 received 11 bytes from 143.48.31.37:7 received 11 bytes from 143.48.31.39:7 received 11 bytes from 143.48.31.40:7 received 11 bytes from 143.48.31.60:7 

If you run this example program, replace the address on the command line with the broadcast address suitable for your network. Each time the client broadcasts a message, it receives a dozen responses, each corresponding to an echo server running on a machine in the local subnet. As it happens, the machine that I ran the client program on (143.48.31.42) also runs an echo server, so it is also one of the machines to respond. Broadcast packets always loop back in this way.

The echo service is commonly active on UNIX systems, and in fact all the responses seen here correspond to various UNIX and Linux hosts on my office network. The Windows machines and the laser printer that responded to the ping test do not run the echo server, so they didn't respond.

Receiving Broadcasts

In contrast to sending broadcast messages, you do not need to do anything special to receive them. Any of the UDP servers used as examples in this book, including the earliest ones from Chapter 18, respond to messages directed to the broadcast address. In fact, without resorting to very-low-level tricks, it is impossible to distinguish between UDP messages directed to your program via the broadcast address and those directed to its unicast address.


   
Top


Network Programming with Perl
Network Programming with Perl
ISBN: 0201615711
EAN: 2147483647
Year: 2000
Pages: 173

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net