我有一个带有虚拟网络接口 eth0:1 的系统,我想发送具有该接口源 IP 的多播数据包。但是,我的数据包最终以 eth0 的源 IP 结束。如何在多播数据包中获取正确的源 IP?
用于创建 iface/route 的命令
sudo ifconfig eth0:1 plumb
sudo ifconfig eth0:1 192.168.123.123 netmask 255.255.255.0 up
sudo ip route add 224.1.1.0/24 dev eth0:1 src 192.168.123.123
之后界面看起来像这样;
eth0 Link encap:Ethernet HWaddr fa:16:3e:9d:94:c2
inet addr:14.0.0.2 Bcast:14.0.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
eth0:1 Link encap:Ethernet HWaddr fa:16:3e:9d:94:c2
inet addr:192.168.123.123 Bcast:192.168.123.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
路线看起来像这样;
default via 14.0.0.1 metric 100
14.0.0.0/24 proto kernel scope link src 14.0.0.2
192.168.123.0/24 proto kernel scope link src 192.168.123.123
224.1.1.0/24 dev eth0 scope link src 192.168.123.123
发送到 192.168.123.123:5007 的定向 udp 数据包会获取正确的源 IP 192.168.123.123,但发送到 224.1.1.1:5007 的多播数据包会获取源 IP 14.0.0.2。
我用来生成数据包的 python 脚本是这样的;
MCAST_GRP = '224.1.1.1'
MCAST_PORT = 5007
MY_IP = '192.168.123.123'
def send_mcast():
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
except AttributeError:
pass # Some systems don't support SO_REUSEPORT
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 2)
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(MY_IP))
print "Sending: robot"
sock.sendto("robot", (MCAST_GRP, MCAST_PORT))
def send_direct():
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
except AttributeError:
pass # Some systems don't support SO_REUSEPORT
print "Sending: robot"
sock.sendto("robot", (MY_IP, MCAST_PORT))
答案1
在尝试了几种不同的“ip route add”方法但都不起作用之后,我偶然发现了mac VLAN其工作方式与预期完全一致。以下是设置命令;
sudo ip link add link eth0 mac0 type macvlan
sudo ifconfig mac0 plumb
sudo ifconfig mac0 192.168.123.123 netmask 255.255.255.0 up
sudo ip route add 224.1.1.0/24 dev mac0
这提供了一个界面;
eth0 Link encap:Ethernet HWaddr fa:16:3e:9d:94:c2
inet addr:14.0.0.2 Bcast:14.0.0.255 Mask:255.255.255.0
mac0 Link encap:Ethernet HWaddr 62:c8:10:38:dc:9a
inet addr:192.168.123.123 Bcast:192.168.123.255 Mask:255.255.255.0
和路线;
224.1.1.0/24 dev mac0 scope link
答案2
我相信您需要使用不带端口的 socket.bind(address)。
docs.python.org/2/library/socket.html
另外,我建议在使用子接口时不要使用 eth0 上的地址。将其移动到 0:0
此外,除非您使用 SSM,否则源接口与多播无关。
希望有帮助!