Multicasting (and broadcasting which is also discussed in this article) provides a means to direct a single packet to more than one host. Special addresses are defined for this purpose and are handled specially by network adapters, networking hardware, and IP stacks.
IPv4 specifications provide broadcasting and multicasting; IPv6 provides multicasting but replaces broadcasting by special multicast modes. UNIX domain sockets do not know broadcasting or multicasting.
The following examples use UDP/IPv4 only. However, they can easily be adapted for raw IPv4 sockets. IPv6 multicasting has not yet been successfully used with socat; please contact the author if you have positive experiences or ideas that go beyond IPV6_ADD_MEMBERSHIP.
All multicast examples presented in this document use multicast address 220.127.116.11; it can be replaced by any valid IPv4 multicast address (except all-systems).
We assume a local network with address 192.168.10.0 and mask 255.255.255.0; an eventual "client" has 192.168.10.1, example "server" and example peer have 192.168.10.2 in all examples. Change these addresses and mask to your own requirements.
All the following examples work bidirectionally except when otherwise noticed. For "clients" we just use STDIO, and for "servers" we use EXEC:hostname which ingores its input but shows us which host the reply comes from. Replace these socat addresses with what is appropriate for your needs (e.g. shell script invocations). Port 6666 can be replaced with any other port (but for ports < 1024 root privilege might be required).
Different kinds of broadcast addresses exist: 255.255.255.255 is local network only; for the IPv4 network 192.168.10.0/24 the "official" broadcast address is 192.168.10.255; the network address 192.168.10.0 is also interpreted as broadcast by some hosts. The two latter forms are routed by gateways. In the following examples we only use broadcast address 192.168.10.255.
This example builds something like a "supervisor" or "client" that communicates with a set of "servers". The supervisor may send packets to the multicast address, and the servers may send response packets. Note that the servers would also respond to other clients' requests.
Multicast server:socat UDP4-RECVFROM:6666,ip-add-membership=18.104.22.168:192.168.10.2,fork EXEC:hostname
This command receives multicast packets addressed to 22.214.171.124 and forks a child process for each. The child processes may each send one or more reply packets back to the particular sender. 192.168.10.2 means the address of the interface where multicasts should be received. Run this command on a number of hosts, and they will all respond in parallel.
Multicast client:socat STDIO UDP4-DATAGRAM:126.96.36.199:6666,range=192.168.10.0/24
This process transfers data from stdin to the multicast address, and transfers packets received from the local network to stdout. It does not matter in which direction the first data is passed. A packet from the network is accepted by the IP stack for our socket if:
Broadcast server:socat UDP4-RECVFROM:6666,broadcast,fork EXEC:hostname
This command receives packets addressed to a local broadcast address and forks a child process for each. The child processes may each send one or more reply packets back to the particular sender. Run this command on a number of hosts, and they will all respond in parallel.
Broadcast client:socat STDIO UDP4-DATAGRAM:192.168.10.255:6666,broadcast,range=192.168.10.0/24
This process transfers data from stdin to the broadcast address, and transfers packets received from the local network to stdout. It does not matter in which direction the first data is passed. A packet from the network is accepted by the IP stack for our socket if:
The broadcast option is only required for sending or receiving local broadcasts.
It is possible to combine multicast sender and receiver in one socat address. This allows to start processes on different hosts on the local network that will communicate symmetrically, so each process can send messages that are received by all the other ones.socat STDIO UDP4-DATAGRAM:188.8.131.52:6666,bind=:6666,range=192.168.10.0/24,ip-add-membership=184.108.40.206:192.168.10.2
This command is valid for host 192.168.10.2; adapt this address to the particular interface addresses of the hosts.
Starting this process opens a socket on port 6666 that will receive packets directed to multicast address 220.127.116.11. Only packets with matching source address and source port 6666 will be handled though. When this process sends data to the network the packets will be addressed to 18.104.22.168:6666 and have a source address of 192.168.10.2:6666, matching the accept criteria of the peers on the local network.
Note: this command receives the packets it just has sent; add option ip-multicast-loop=0 if this in undesired.
Just as with multicast, it is possible to combine broadcast sender and receiver in one socat address.socat STDIO UDP4-DATAGRAM:255.255.255.255:6666,bind=:6666,range=192.168.10.0/24,broadcast
Starting this process opens a socket on port 6666 that will receive packets directed to a local broadcast addresses. Only packets with matching source address and source port 6666 will be handled though. When this process sends data to the network the packets will be addressed to 255.255.255.255:6666 and have a source address of 192.168.10.2:6666, matching the accept criteria of the peers on the local network.
Note: this command receives the packets it just has sent; there does not seem to exist a simple way to prevent this.
If you do not get an error message during operation, but the packets do not reach the target processes, use tcpdump to see if the packets have the correct source and destination addresses and ports, and if they leave and enter the hosts as expected.
The following subsections discuss some typical sources of trouble.
If you do not succeed in receiving multicast or broadcast packets, check if iptables are activated on the receiving or sending host. They might be configured to disallow this traffic.
When using multicast communications, you should not bind the sockets to a specific IP address. It seems that the (Linux) IP stack compares the destination address with the bind address, not taking care of the multicast property of the incoming packet.
When you receive an error like:
|... E sendto(3, 0x80c2e44, 4, 0, AF=2 22.214.171.124:6666, 16): Network is unreachable|
you have a routing problem. The (Linux) IP stack seems to handle multicast addresses just like unicast addresses when determining their route (interface and gateway), i.e. the routing table needs an entry that somehow matches the target address.
For the same reason, multicast packets will probably leave your host on the interface with the default route if it is specified.
Set a multicast/broadcast route with the following command (Linux):route add -net 126.96.36.199/3 gw 192.168.10.2
188.8.131.52 is the all-systems multicast address: all datagram sockets appear to be automatically member of this group on all interfaces. This membership cannot be dropped on Linux (you need iptables to filter packets).
When you use the above examples you should understand that all datagram sockets without exception accept all packets that are directly addressed to them; the multi- and broadcast receiving features are just extensions to this functionality. socat currently has no means to handle incoming packets differently whether they are addressed to unicast, multicast, or broadcast addresses. However, for EXEC'd scripts socat can provide this info in environment variables.
Authentication or encryption are not available.
It is very easy to fake the source address of UDP (or raw IP) packets. You should understand whether your network is protected from address spoofing attacks.
Broadcast and multicast traffic can trivially be received by any host on the local network.
These modes already enable several different client/server oriented operations. Moreover, the SENDTO addresses can send to multicast and broadcast addresses (the latter requires the broadcast option though). RECV and RECVFROM also would accept packets addressed to a local broadcast address (with option broadcast) or the all-systems multicast address.
These address types had, however, two major caveats:
socat version 1.6.0 addresses these problems and provides a new more generic datagram address type (*-DATAGRAM) and the new address option IP-ADD-MEMBERSHIP.
Please note that multicasting on IPv6 requires a patch that has been introduced past version 184.108.40.206! Use option like ipv6-join-group=[ff02::d]:eth0.
socat version 1.7.0 helps to find more information about incoming packets in environment variables that can be used in scripts or programs invoked by socat. The option ip-pktinfo (on non-BSD systems) or ip-recvdstaddr (on BSD systems) is required to get basic information about incoming packets.
Example: Start a receiver of the following form (tried on Linux):socat -u UDP-RECVFROM:8888,reuseaddr,ip-add-membership=220.127.116.11:192.168.10.2,ip-pktinfo,fork SYSTEM:export
Then send a multicast packet from the client:echo |socat -u STDIO UDP-DATAGRAM:18.104.22.168:8888
On the server the following text should appear (only interesting lines shown):
export SOCAT_IP_DSTADDR="22.214.171.124" export SOCAT_IP_IF="eth0" export SOCAT_IP_LOCADDR="192.168.10.2" export SOCAT_PEERADDR="192.168.10.1" export SOCAT_PEERPORT="41159"
SOCAT_IP_IF shows the interface where the packet entered the server; SOCAT_IP_LOCADDR shows the IP address of this interface; SOCAT_IP_DSTADDR shows the target address of the packet; SOCAT_PEERADDR and SOCAT_PEERPORT are the client socket values.
This document was last modified in May 2009.
Copyright: Gerhard Rieger 2007-2009
License: GNU Free Documentation License (FDL)