2 votes

Windows ne reçoit pas les paquets IPv6 multicast de toutes les interfaces.

J'essaie de recevoir des paquets multicast IPv6 (envoyés à l'adresse ff02::1) sur Windows en utilisant ce code python 2.7-.

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

J'envoie des paquets depuis un autre ordinateur qui est connecté à mon ordinateur. via Ethernet ; en outre, mon ordinateur dispose également d'une interface WiFi. Bien que je puisse voir les paquets pertinents en reniflant la connexion Ethernet avec Wireshark, les paquets ne sont pas reçus par ce code.

Cependant, quand je désactiver le WiFi carte réseau, les paquets sont reçus. Cela me fait penser que lorsque l'interface WiFi est activée, le code n'écoute que les paquets provenant de cette interface.

J'ai lu que la liaison à "" devrait permettre de recevoir des paquets de toutes les interfaces réseau, mais pour une raison quelconque, cela ne fonctionne pas pour moi.

Quelqu'un a-t-il une idée de ce que j'ai oublié de faire ? ou une autre façon de résoudre ce problème ?

Merci !

2voto

Shir Points 733

Résolu :)

Donc apparemment, IPv6 n'a pas écouter le multicast de toutes les interfaces. Cette syntaxe

mreq = group + struct.pack('@I', 0)

avait tort. Selon ce Le mreq est composé de l'id du groupe et de l'id de l'interface, où 0 est l'interface par défaut (dans mon cas - WiFi). Afin d'écouter le multicast d'autres interfaces, l'index de l'interface réseau doit être spécifié.

L'index de l'interface réseau est le numéro qui apparaît après le nom de l'interface. % dans l'adresse ipv6 lors de l'exécution de ipconfig, et peut également être trouvé en exécutant "route print" dans cmd.

J'ai utilisé ce code pour le trouver sur 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 https://stackoverflow.com/questions/29913516/how-to-get-meaningful-network-interface-names-instead-of-guids-with-netifaces-un
"""
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

Et puis

mreq = group + struct.pack('@I', get_ethernet_ipv6_ifindex())

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X