2010-06-18 17 views
7

Próbuję dowiedzieć się, jak zrobić ekwiwalent emisji IPV4 za pomocą IPV6.Lokalny multicast IPV6

Tworzę nieblokujące gniazdo UDP IPV6.

Z nadawania stronie jestem dosłownie robi sendto „FF02 :: 1” na porcie 12346.

Na stronie słuchać odkryłem muszę dołączyć do grupy tak zrobiłem następujące:

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; 
     } 
    } 

Jednak setsockopt zawsze zwraca "WSAENOPROTOOPT". Czemu? Czy ktoś może mi pomóc w tej sprawie? Mam całkowitą stratę.

Edytuj: Zmieniam poziom na "IPPROTO_IPV6", ale teraz otrzymuję "WSAEINVAL".

+0

@bdonlan: Na zdrowie. Czy gonan zrobił to sam, ale zapomniał :) – Goz

Odpowiedz

4

interfejs musi być ustawiony lokalnie scoped IPv6, ponieważ adresy są unikalne tylko do interfejsu. W prostszych słowach adres FE80 :: 1 może należeć do obu eth0 i eth1, ale są całkowicie oddzielne.

Więc to oznacza potrzebujesz t o jawnie wysyłaj pakiet multiemisji na każdy interfejs do, który obsługuje multiemisję lub podaj użytkownikowi sposób określania określonego interfejsu.

(edit) Jeśli to pomaga można sprawdzić kod multicast Tutaj

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

+0

Więc mówię, że muszę połączyć adres fe80 :: 1/losowy port przed wykonaniem IPV6_JOIN_GROUP? – Goz

+0

Przebiegnij dane wyjściowe GetAdapterAddresses() i dla każdego unikalnego indeksu interfejsu z adresem IPv6 IPV6_JOIN_GROUP. –

+0

Właściwie to związałem PRZED dołączeniem do grupy, a dołączenie poszło dobrze ... To jest idealne :) – Goz

1

Myślę, że problem polega na tym, że pozostawiasz wartość ipv6mr_interface na poziomie zero, co nie jest wystarczająco dobre, jeśli chcesz używać adresu multiemisji łącza, takiego jak ff02 :: 1. Musisz ustawić wartość ipv6mr_interface na numer odpowiadający interfejsowi sieci lokalnej, w której chcesz, aby pakiety były wysyłane/odbierane. (Możesz dowiedzieć się, jakie wskaźniki interfejsu są dostępne na bieżącym komputerze, wywołując metodę getaddrinfo() i odczytując wartości sin6_addr.s6_addr z wartości (struct sockaddr_in6 *), które przekazuje użytkownikowi)

(Jeśli w tym momencie punkt, który myślisz sobie, czy nie byłoby o wiele łatwiej, gdyby interfejs zerowy działał jako ustawienie "wszystkie interfejsy" ... tak, byłoby to. Niestety, IPv6 tego nie robi z jakiegoś powodu :()

+0

Niestety pod oknami widziałem, że indeks strefy wynosił 5 dla mojego głównego adaptera. Więc spróbowałem tego indeksu. Ja też 1 i nadal nie miałem szczęścia ... Czy wskaźnik interfejsu jest taki sam jak indeks strefy? – Goz

+0

Zobacz także: http://msdn.microsoft.com/en-us/library/ms738655(VS.85).aspx – Goz

+0

Jestem w 99% pewien, że indeks stref i indeks interfejsu to to samo; więc może być tak, że problemem jest także coś innego. W systemie Windows można wywołać funkcję GetAdaptersAddresses(), aby przejść do pola Ipv6IfIndex w strukturze PIP_ADAPTER_ADDRESSES każdego adaptera. GetAdaptersAddresses() jest jeszcze bardziej zabawny niż funkcja getaddrinfo() Posixa ... sprawdź linie 1034-1124 (a szczególnie linię 1097) poniższego pliku, aby zobaczyć, jak wykorzystuję tę funkcję: www.lcscanada.com/muscle/ muscle/util/NetworkUtilityFunctions.cpp –