2010-06-18 11 views
7

Sto cercando di capire come fare l'equivalente di una trasmissione IPV4 usando IPV6.IPV6 link multicasting locale

Sto creando un socket UDP IPV6 non bloccante.

Dal broadcasting parte sto letteralmente solo facendo un sendto "FF02 :: 1" sulla porta 12346.

Sul lato ascoltare ho scoperto che ho bisogno di unirsi al gruppo così ho fatto la seguente:

ipv6_mreq membership; 
    memset(&membership.ipv6mr_multiaddr, 0, sizeof(in6_addr)); 
    membership.ipv6mr_multiaddr.u.Word[0] = htons(0xff02); 
    membership.ipv6mr_multiaddr.u.Word[7] = htons(0x0001); 
    membership.ipv6mr_interface    = 0; 

    if(enable) 
    { 
     if (0 != setsockopt(m_Socket, SOL_SOCKET, IPV6_JOIN_GROUP, (char*)&membership, sizeof(ipv6_mreq))) 
     { 
      DisplayError(); 
      return false; 
     } 
    } 

Tuttavia setockopt restituisce sempre "WSAENOPROTOOPT". Perché? Qualcuno può aiutarmi su questo? Sono completamente perso.

Modifica: cambio il livello in "IPPROTO_IPV6", ma ora ho un "WSAEINVAL".

+0

@bdonlan: Acclamazioni. Era Gonan farlo da solo ma ho dimenticato :) – Goz

risposta

4

l'interfaccia deve essere impostato per ambito locale IPv6 perché gli indirizzi sono unici solo per l'interfaccia. In termini più semplici la fe80 indirizzo :: 1 può appartenere sia eth0 e eth1 ma sono completamente separati.

Quindi questo significa hai bisogno di t o inviare esplicitamente un pacchetto multicast su ogni all'interfaccia che supporta il multicast o fornire all'utente un mezzo per specificare una particolare interfaccia.

(edit) Se serve si può verificare il codice multicast qui,

http://code.google.com/p/openpgm/source/browse/trunk/openpgm/pgm/

+0

Quindi, per dirmi che ho bisogno di eseguire il binding all'indirizzo fe80 :: 1/random port prima di fare l'IPV6_JOIN_GROUP? – Goz

+0

Esegui l'output di GetAdapterAddresses() e per ogni indice di interfaccia univoco con un indirizzo IPv6 chiama IPV6_JOIN_GROUP. –

+0

In realtà ho legato PRIMA di unirmi al gruppo e il join è andato bene ... È perfetto :) – Goz

1

Penso che il problema è che si sta lasciando il valore ipv6mr_interface a zero, il che non è abbastanza buono se si desidera utilizzare un indirizzo multicast di tipo link-scope come ff02 :: 1. È necessario impostare il valore ipv6mr_interface sul numero corrispondente all'interfaccia di rete locale su cui si desidera che i pacchetti vengano inviati/ricevuti. (Puoi scoprire quali indici di interfaccia sono disponibili sul computer corrente chiamando getaddrinfo() e leggendo i valori di syn6_addr.s6_addr fuori dalla (struct sockaddr_in6 *) che ti consegna)

(Se a questo punto che stai pensando a te stesso, non sarebbe molto più facile se l'interfaccia zero fungesse da impostazione "tutte le interfacce" ... sì, lo sarebbe. Ahimè, IPv6 non lo fa per qualche motivo :()

+0

Ahimè sotto Windows ho visto che l'indice della zona era 5 per il mio adattatore principale. Quindi ho provato quell'indice. Ho anche 1 e ancora non ho avuto fortuna ... L'indice di interfaccia è lo stesso dell'indice di zona? – Goz

+0

vedere anche: http://msdn.microsoft.com/en-us/library/ms738655(VS.85).aspx – Goz

+0

Sono sicuro al 99% che l'indice di zona e l'indice di interfaccia sono la stessa cosa; quindi potrebbe essere che anche qualcos'altro sia il problema. In Windows è possibile chiamare GetAdaptersAddresses() per accedere al campo Ipv6IfIndex della struttura PIP_ADAPTER_ADDRESSES di ogni adattatore. GetAdaptersAddresses() è ancora più divertente della funzione getaddrinfo() di Posix ... controlla le righe 1034-1124 (e in particolare la riga 1097) del seguente file per vedere il mio utilizzo di tale funzione: www.lcscanada.com/muscle/ muscle/util/NetworkUtilityFunctions.cpp –