Linux组播源地址

Linux组播源地址

我有一个带有多个接口的Linux系统(内核3.10.62 - 是的,我知道它很旧):

  • eth0——192.168.1.110/24
  • eth1——10.149.1.4/24
  • eth2——10.10.0.99/16

我正在尝试发送到 eth2 接口上的多播地址 (235.0.0.37),并使用该 eth2 接口的源 IP 地址。

我有如下路由表设置:

# ip route
default via 10.10.0.99 dev eth2  scope link
192.168.10.0/24 dev eth0  proto kernel  scope link  src 192.168.10.110
10.149.1.0/24   dev eth1  proto kernel  scope link  src 10.149.1.4
10.10.0.0/16    dev eth2  proto kernel  scope link  src 10.10.0.99
224.0.0.0/4  dev eth0 scope link
235.0.0.0/24 dev eth2  scope link

我有一个测试 python(2.7.3)应用程序(真正的应用程序是 Java 语言的,但是这清楚地显示了问题,并且 Java 应用程序的行为也相同):

# cat test_mc.py
#!/usr/bin/env python

import socket
import struct

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

sock.bind( ( "10.10.0.99", 0 ) )
print "bound to:", sock.getsockname()

sock.setsockopt( socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton("10.10.0.99") )

ifip = sock.getsockopt( socket.IPPROTO_IP, socket.IP_MULTICAST_IF )
print socket.inet_ntoa( struct.pack('<L', ifip) )

sock.sendto(b'hello world', ('235.0.0.37', 9006))


# python test_mc.py
bound to: ('10.10.0.99', 49908)
10.10.0.99
#

请注意,这会将套接字绑定到 eth2 地址并明确设置 IP_MULTICAST_IF。

我期望此消息从 eth2 接口 (10.10.0.99) 发出。它确实这样做了,但数据包的源地址是 eth1 接口 (10.149.1.4)。我已经使用本地主机上的 tcpdump 和外部 PC(连接到 eth2 网络)上的 wireshark 确认了这一点。

# tcpdump -X -n -i eth2 udp port 9006
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth2, link-type EN10MB (Ethernet), capture size 65535 bytes
17:58:10.915720 IP 10.149.1.4.49908 > 235.0.0.37.9006: UDP, length 11
        0x0000:  4500 0027 aa66 4000 0111 d8a1 0a95 0104  E..'.f@.........
        0x0010:  eb00 0025 c2f4 232e 0013 f6e2 6865 6c6c  ...%..#.....hell
        0x0020:  6f20 776f 726c 64                        o.world

有没有办法设置套接字,以便发往该多播地址的数据包看起来来自 eth2 IP(10.10.0.99)?我以为 IP_MULTICAST_IF 会做到这一点。它甚至没有选择默认多播路由(eth0)或默认路由的源地址。有没有办法做到这一点?

相关内容