Windows 没有从所有接口接收多播 IPv6 数据包
Windows doesn't receive multicast IPv6 packets from all interfaces
我正在尝试使用此 python 2.7 代码-
在 Windows 上接收 IPv6 多播数据包(发送到 ff02::1 地址)
import socket
import win_inet_pton
import struct
socket.IPPROTO_IPV6=41 #because using python 2.7 on wondows
PORT = 1234
UDP_BROADCAST_IPv6 = "ff02::1"
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("",PORT)) # not working with "::" either
# Join multicast group
addrinfo = socket.getaddrinfo(UDP_BROADCAST_IPv6, None)[0]
group = socket.inet_pton(addrinfo[0], addrinfo[4][0])
mreq = group + struct.pack('@I', 0)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
while True:
msg=sock.recv(1024)
print msg
我从另一台连接到我的计算机的计算机通过以太网发送数据包;另外,我的电脑还有一个WiFi接口。虽然我在使用 Wireshark 嗅探以太网连接时能够看到相关数据包,但此代码未接收到数据包。
但是,当我禁用WiFi网卡时,数据包就收到了。
这让我觉得当启用 WiFi 接口时,代码只侦听来自该接口的数据包。
我读到绑定到 ""
应该可以从所有网络接口接收数据包,但由于某些原因它对我不起作用。
有人知道我忘记做的事情吗?或解决这个问题的不同方法?
谢谢!
解决了:)
很明显,IPv6 不会 侦听来自所有接口的多播。此语法
mreq = group + struct.pack('@I', 0)
错了。根据 this,mreq 由组 ID 和接口 ID 组成,其中 0 是默认接口(在我的例子中是 WiFi)。为了从其他接口收听多播,应该指定网络接口索引。
网络接口索引是运行ipconfig时ipv6地址%
后面出现的数字,也可以在cmd中找到运行"route print" .
我用这段代码在 python 上找到它:
import netifaces as ni
import _winreg as wr # use "winreg" in python3
def get_ethernet_ipv6_ifindex():
x=ni.interfaces()
con_names=get_connection_name_from_guid(x)
ethernet_index= con_names.index('Ethernet')
addresses= ni.ifaddresses(x[ethernet_index])
brod_addr=addresses[socket.AF_INET6][-1]["broadcast"]
return int(brod_addr[brod_addr.find("%")+1:])
"""
Taken from the very helpful
"""
def get_connection_name_from_guid(iface_guids):
iface_names = ['(unknown)' for i in range(len(iface_guids))]
reg = wr.ConnectRegistry(None, wr.HKEY_LOCAL_MACHINE)
reg_key = wr.OpenKey(reg, r'SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}')
for i in range(len(iface_guids)):
try:
reg_subkey = wr.OpenKey(reg_key, iface_guids[i] + r'\Connection')
iface_names[i] = wr.QueryValueEx(reg_subkey, 'Name')[0]
except WindowsError:
pass
return iface_names
然后-
mreq = group + struct.pack('@I', get_ethernet_ipv6_ifindex())
我正在尝试使用此 python 2.7 代码-
在 Windows 上接收 IPv6 多播数据包(发送到 ff02::1 地址)import socket
import win_inet_pton
import struct
socket.IPPROTO_IPV6=41 #because using python 2.7 on wondows
PORT = 1234
UDP_BROADCAST_IPv6 = "ff02::1"
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("",PORT)) # not working with "::" either
# Join multicast group
addrinfo = socket.getaddrinfo(UDP_BROADCAST_IPv6, None)[0]
group = socket.inet_pton(addrinfo[0], addrinfo[4][0])
mreq = group + struct.pack('@I', 0)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
while True:
msg=sock.recv(1024)
print msg
我从另一台连接到我的计算机的计算机通过以太网发送数据包;另外,我的电脑还有一个WiFi接口。虽然我在使用 Wireshark 嗅探以太网连接时能够看到相关数据包,但此代码未接收到数据包。
但是,当我禁用WiFi网卡时,数据包就收到了。 这让我觉得当启用 WiFi 接口时,代码只侦听来自该接口的数据包。
我读到绑定到 ""
应该可以从所有网络接口接收数据包,但由于某些原因它对我不起作用。
有人知道我忘记做的事情吗?或解决这个问题的不同方法?
谢谢!
解决了:)
很明显,IPv6 不会 侦听来自所有接口的多播。此语法
mreq = group + struct.pack('@I', 0)
错了。根据 this,mreq 由组 ID 和接口 ID 组成,其中 0 是默认接口(在我的例子中是 WiFi)。为了从其他接口收听多播,应该指定网络接口索引。
网络接口索引是运行ipconfig时ipv6地址%
后面出现的数字,也可以在cmd中找到运行"route print" .
我用这段代码在 python 上找到它:
import netifaces as ni
import _winreg as wr # use "winreg" in python3
def get_ethernet_ipv6_ifindex():
x=ni.interfaces()
con_names=get_connection_name_from_guid(x)
ethernet_index= con_names.index('Ethernet')
addresses= ni.ifaddresses(x[ethernet_index])
brod_addr=addresses[socket.AF_INET6][-1]["broadcast"]
return int(brod_addr[brod_addr.find("%")+1:])
"""
Taken from the very helpful
"""
def get_connection_name_from_guid(iface_guids):
iface_names = ['(unknown)' for i in range(len(iface_guids))]
reg = wr.ConnectRegistry(None, wr.HKEY_LOCAL_MACHINE)
reg_key = wr.OpenKey(reg, r'SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}')
for i in range(len(iface_guids)):
try:
reg_subkey = wr.OpenKey(reg_key, iface_guids[i] + r'\Connection')
iface_names[i] = wr.QueryValueEx(reg_subkey, 'Name')[0]
except WindowsError:
pass
return iface_names
然后-
mreq = group + struct.pack('@I', get_ethernet_ipv6_ifindex())