IP Multicasting with Socat

IP Multicasting with Socat
使用 Socat 进行 IP 多播

Introduction 介绍

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.
多播(以及本文中讨论的广播)提供了一种将单个数据包定向到多个主机的方法。为此目的定义了特殊地址,并由网络适配器、网络硬件和 IP 栈特殊处理。

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.
IPv4 规范提供了广播和多播;IPv6 提供了多播,但通过特殊的多播模式替代了广播。UNIX 域套接字不了解广播或多播。

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.
以下示例仅使用 UDP/IPv4。但是,它们可以很容易地适应原始 IPv4 套接字。IPv6 多播尚未成功地与 socat 一起使用;如果您有积极的经验或超出 IPV6_ADD_MEMBERSHIP 的想法,请与作者联系。

All multicast examples presented in this document use multicast address 224.1.0.1; it can be replaced by any valid IPv4 multicast address (except all-systems).
本文档中提供的所有组播示例均使用组播地址 224.1.0.1;可以用任何有效的 IPv4 组播地址(除了 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.
我们假设一个具有地址 192.168.10.0 和掩码 255.255.255.0 的本地网络;一个可能的“客户端”具有 192.168.10.1,示例“服务器”和示例对等体在所有示例中均具有 192.168.10.2。将这些地址和掩码更改为符合您需求的内容。

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).
除非另有通知,所有以下示例均可双向工作。对于“客户端”,我们只使用 STDIO ,对于“服务器”,我们使用 EXEC:hostname ,它忽略其输入但显示我们收到回复的主机。将这些 socat 地址替换为适合您需求的内容(例如,shell 脚本调用)。端口 6666 可以替换为任何其他端口(但对于端口<1024,可能需要 root 权限)。

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.
存在不同类型的广播地址:255.255.255.255 仅用于本地网络;对于 IPv4 网络 192.168.10.0/24,"官方" 广播地址是 192.168.10.255;网络地址 192.168.10.0 也被一些主机解释为广播。后两种形式由网关路由。在以下示例中,我们仅使用广播地址 192.168.10.255。

Example 1: Multicast client and servers
示例 1:多播客户端和服务器

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=224.1.0.1:192.168.10.2,fork EXEC:hostname

This command receives multicast packets addressed to 224.1.0.1 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.
此命令接收寻址为 224.1.0.1 的多播数据包,并为每个数据包派生一个子进程。子进程可以向特定发送者发送一个或多个回复数据包。192.168.10.2 表示应接收多播的接口地址。在多台主机上运行此命令,它们将并行响应。

Multicast client: 多播客户端:

socat STDIO UDP4-DATAGRAM:224.1.0.1: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:
此过程将数据从标准输入传输到多播地址,并将从本地网络接收到的数据包传输到标准输出。第一批数据传递的方向并不重要。如果网络中的数据包被我们的套接字接受,则会被 IP 栈接受。

Of these packets, socat handles only those matching the following criteria:
在这些数据包中,socat 仅处理符合以下条件的数据包:

Example 2: Broadcast client and servers
示例 2:广播客户端和服务器

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:
此过程将数据从标准输入传输到广播地址,并将从本地网络接收到的数据包传输到标准输出。第一批数据传输的方向并不重要。如果网络中的数据包满足以下条件,则会被 IP 栈接受到我们的套接字中:

Of these packets, socat handles only those matching the following criteria:
在这些数据包中,socat 仅处理符合以下条件的数据包:

The broadcast option is only required for sending or receiving local broadcasts.
broadcast ”选项仅在发送或接收本地广播时才需要。

Example 3: Multicast peers
示例 3:多播对等方

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 地址中。这样可以在本地网络上的不同主机上启动进程,使它们可以对称通信,因此每个进程都可以发送消息,而所有其他进程都会接收到这些消息。

socat STDIO UDP4-DATAGRAM:224.1.0.1:6666,bind=:6666,range=192.168.10.0/24,ip-add-membership=224.1.0.1: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.
此命令适用于主机 192.168.10.2;请根据主机的特定接口地址调整此地址。

Starting this process opens a socket on port 6666 that will receive packets directed to multicast address 224.1.0.1. 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 224.1.0.1:6666 and have a source address of 192.168.10.2:6666, matching the accept criteria of the peers on the local network.
启动此过程会在端口 6666 上打开一个套接字,用于接收定向到多播地址 224.1.0.1 的数据包。只有源地址和源端口为 6666 的数据包才会被处理。当此过程向网络发送数据时,数据包将被寻址为 224.1.0.1:6666,并具有源地址 192.168.10.2:6666,符合本地网络上对等体的接受标准。

Note: this command receives the packets it just has sent; add option ip-multicast-loop=0 if this in undesired.
注意:此命令接收它刚刚发送的数据包;如果这是不希望的,请添加选项 ip-multicast-loop=0

Example 4: Broadcast peers
示例 4:广播对等体

Just as with multicast, it is possible to combine broadcast sender and receiver in one socat address.
就像多播一样,可以在一个 socat 地址中组合广播发送器和接收器。

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.
启动此进程会在端口 6666 上打开一个套接字,用于接收定向到本地广播地址的数据包。但只有源地址和源端口为 6666 的数据包才会被处理。当此进程向网络发送数据时,数据包将被寻址为 255.255.255.255:6666,并具有源地址 192.168.10.2:6666,与本地网络上的对等方的接受标准相匹配。

Note: this command receives the packets it just has sent; there does not seem to exist a simple way to prevent this.
注意:此命令接收它刚刚发送的数据包;似乎没有简单的方法来阻止这种情况发生。

Troubleshooting 故障排除

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.
如果在操作过程中没有收到错误消息,但数据包未到达目标进程,请使用 tcpdump 查看数据包是否具有正确的源和目标地址和端口,并且它们是否按预期离开和进入主机。

The following subsections discuss some typical sources of trouble.
下面的小节讨论了一些典型的故障源。

IP filters IP 过滤器

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.
如果您无法接收多播或广播数据包,请检查接收或发送主机上是否激活了 iptables。它们可能被配置为禁止此流量。

Do not bind() 不要绑定()

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.
在使用多播通信时,不应将套接字绑定到特定的 IP 地址。似乎(Linux)IP 栈将目标地址与绑定地址进行比较,而不考虑传入数据包的多播属性。

Routing 路由

When you receive an error like:
当您收到类似错误时:

... E sendto(3, 0x80c2e44, 4, 0, AF=2 224.1.0.1: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.
您可能遇到了路由问题。 (Linux) IP 栈在确定多播地址的路由(接口和网关)时似乎与单播地址一样处理,即路由表需要有一个条目与目标地址匹配。

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):
使用以下命令设置多播/广播路由(Linux):

route add -net 224.0.0.0/3 gw 192.168.10.2

ALL-SYSTEMS multicast address
ALL-SYSTEMS 多播地址

224.0.0.1 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).
224.0.0.1 是所有系统的多播地址:所有数据报套接字似乎自动成为此组的成员,出现在所有接口上。在 Linux 上无法取消此成员身份(您需要使用 iptables 来过滤数据包)。

(In)Security (不)安全

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.
当您使用上述示例时,应了解所有数据报套接字无一例外地接受所有直接寻址到它们的数据包;多播和广播接收功能只是此功能的扩展。socat 目前无法处理传入数据包的方式,无论它们是寻址到单播、多播还是广播地址。但是,对于执行的脚本,socat 可以在环境变量中提供此信息。

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.
很容易伪造 UDP(或原始 IP)数据包的源地址。您应该了解您的网络是否受到地址欺骗攻击的保护。

Broadcast and multicast traffic can trivially be received by any host on the local network.
广播和组播流量可以轻松地被本地网络上的任何主机接收。

History 历史

Starting with version 1.5.0, socat provides a set of address types that allow various operations on datagram oriented sockets:
从版本 1.5.0 开始,socat 提供了一组地址类型,允许在数据报导向套接字上执行各种操作:
SENDTO 发送至
send packets to a remote socket and receive packet from this remote socket only
发送数据包到远程套接字,并仅从该远程套接字接收数据包
RECV 接收
receive all packets that arrive on the local socket, but do not reply
接收到所有到达本地套接字的数据包,但不回复
RECVFROM 接收来自
receive all packets that arrive on the local socket, and reply using child processes
接收到所有到达本地套接字的数据包,并使用子进程进行回复

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.
这些模式已经可以实现多种不同的客户端/服务器操作。此外,SENDTO 地址可以发送到多播和广播地址(后者需要 broadcast 选项)。RECV 和 RECVFROM 也可以接收发送到本地广播地址的数据包(使用选项 broadcast )或所有系统的多播地址。

These address types had, however, two major caveats:
这些地址类型有两个主要的注意事项:

New Features in socat 1.6.0
socat 1.6.0 中的新功能

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.
socat 版本 1.6.0 解决了这些问题,并提供了一个新的更通用的数据报地址类型 (*-DATAGRAM) 和新的地址选项 IP-ADD-MEMBERSHIP。

Please note that multicasting on IPv6 requires a patch that has been introduced past version 1.7.3.2! Use option like ipv6-join-group=[ff02::d]:eth0.
请注意,IPv6 上的多播需要一个补丁,该补丁在版本 1.7.3.2 之后引入!使用选项如 ipv6-join-group=[ff02::d]:eth0

New Features in socat 1.7.0
socat 1.7.0 中的新功能

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.
socat 版本 1.7.0 帮助查找有关传入数据包的更多信息,这些信息可以在由 socat 调用的脚本或程序中使用环境变量。选项 ip-pktinfo (在非 BSD 系统上)或 ip-recvdstaddr (在 BSD 系统上)需要获取有关传入数据包的基本信息。

Example: Start a receiver of the following form (tried on Linux):
示例:启动以下形式的接收器(在 Linux 上尝试):

socat -u UDP-RECVFROM:8888,reuseaddr,ip-add-membership=224.1.0.1:192.168.10.2,ip-pktinfo,fork SYSTEM:export

Then send a multicast packet from the client:
然后从客户端发送一个多播数据包:

echo |socat -u STDIO UDP-DATAGRAM:224.1.0.1:8888

On the server the following text should appear (only interesting lines shown):
在服务器上应该显示以下文本(仅显示有趣的行):

export SOCAT_IP_DSTADDR="224.1.0.1"
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.
SOCAT_IP_IF 显示数据包进入服务器的接口; SOCAT_IP_LOCADDR 显示此接口的 IP 地址; SOCAT_IP_DSTADDR 显示数据包的目标地址; SOCAT_PEERADDRSOCAT_PEERPORT 是客户端套接字的值。

More info about socat datagrams
有关 socat 数据报的更多信息

Links regarding this tutorial
有关本教程的链接

address UDP4-DATAGRAM 地址 UDP4-DATAGRAM
address UDP4-RECVFROM 地址 UDP4-RECVFROM
option range 选项范围
option broadcast 选项广播
option ip-add-membership
选项 IP 添加成员

option fork 选项分叉
option bind 选项绑定

Other datagram addresses
其他数据报地址

address UDP4-RECV: pure datagram receiver
地址 UDP4-RECV:纯数据报接收器

address UDP4-SENDTO: communicate with one peer address
地址 UDP4-SENDTO:与一个对等地址通信

address UDP4-LISTEN: pseudo stream server
地址 UDP4-LISTEN:伪流服务器

address UDP4-CONNECT: pseudo stream client
地址 UDP4-CONNECT:伪流客户端

Related socat option groups
相关的 socat 选项组

IP options IP 选项
socket options 套接字选项
file descriptor options 文件描述符选项
range options 范围选项
child process options 子进程选项

References 参考资料

socat home page socat 主页
socat man page socat 手册页面
multicasting on Wikipedia
维基百科上的多播

broadcasting on Wikipedia
维基百科上的广播

This document was last modified in May 2009.
该文档最后修改于 2009 年 5 月。

Copyright: Gerhard Rieger 2007-2009
版权所有:Gerhard Rieger 2007-2009

License: GNU Free Documentation License (FDL)
许可证:GNU 自由文档许可证(FDL)