在Python中发送源IP等于虚拟接口IP的多播数据包

在Python中发送源IP等于虚拟接口IP的多播数据包

我有一个带有虚拟网络接口 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,否则源接口与多播无关。

希望有帮助!

相关内容