【问题标题】:Sending IPv6 multicast packets through a specific network interface通过特定网络接口发送 IPv6 多播数据包
【发布时间】:2018-04-15 02:19:15
【问题描述】:

我正在尝试通过 Windows 在 python 中将 IPv6 UDP 数据包发送到本地网段上的所有节点。

我的电脑有几个网络接口,我想知道如何指定发送数据包的网络接口。

我已尝试使用 socket.sendto(未绑定)将数据包发送到多播地址 ff02::1,但数据包发送到错误的网络接口。

知道如何指定网络适配器吗? (我读过 BINDTODEVICE,但它不适用于 windows,以及一些使用绑定广播 IP 地址类的方法,但仅适用于 IPv4)。

谢谢!

【问题讨论】:

    标签: python udp ipv6 multicast


    【解决方案1】:

    这是您的系统配置有问题。操作系统需要配置正确的 IPv6 路由,以确保数据包在正确的接口上发出。这不是由应用程序来决定的,类似于为网络接口分配 IP 地址不是应用程序的工作 - 这完全是操作系统的责任。

    Here is an answer 解释了这是如何在 Linux 下完成的。如果有人知道,请随时添加评论,并附上有关如何在 Windows 上完成的链接。

    【讨论】:

      【解决方案2】:

      根据this 问题的答案 - 使用 ff12::1 进行多播有时比使用 ff02::1 进行多播效果更好。 我试过了,它起作用了——数据包是通过以太网网络接口(如我所愿)发送的,而不是像以前那样在 WiFi 中发送。

      但是,我不知道它为什么会起作用,而且我在 IPv6 RFC 或互联网上的任何其他地方都找不到任何参考。 欢迎解释:)

      【讨论】:

      • 在尝试使用 IPv6 进行多播之前,您需要了解 IPv6 多播使用的标志和范围。例如,ff02::表示由 Internet 号码分配机构 (IANA) 分配的永久分配(‘众所周知的’)多播地址,”在本地链接范围内,但 @ 987654323@“表示非永久分配的('瞬态'或'动态'分配的)多播地址,”在本地链接范围内。这在 RFC 中有解释。
      • 另外,您应该有一个很好的理由来中断 LAN 上的所有主机。由于备受瞩目的违规行为导致企业对 LAN 上发生的事情的审查越来越严格,许多企业拒绝或强制更改广播 (IPv4) 应用程序或以其他方式中断 LAN 上的每台主机。通常有更好的方法来处理它。
      【解决方案3】:

      我不太喜欢以前的解决方案,所以我一直在寻找其他解决方案。

      对我有用的第一个选项是将发送方套接字绑定到特定的网络接口地址。可以使用netifaces 模块找到网络接口地址,我使用this 有用的答案来指定以太网地址。

      另一个可行的选项是 IPV6_MULTICAST_IF 选项-

      #x is the relevant interface index
      sock.setsockopt(socket.IPPROTO_IPV6,socket.IPV6_MULTICAST_IF,x)
      

      在 Windows,python 2.7 中,应该添加一行

      socket.IPPROTO_IPV6=41
      

      在这段代码之前(因为相关的枚举没有很好地定义)。

      更多信息可以在here (Windows) 或here (Linux) 中找到。

      虽然这似乎是一个更简单的解决方案,但我并没有完全做到这一点,并且不确定找到正确接口索引的正确方法是什么(在 Windows 上,Linux 有多种选择)。

      【讨论】:

      • 我在this答案中写了关于找到正确接口索引的正确方法。不过还是更喜欢第一个解决方案:)