ICMPv6 — не удается прочитать рекламные сообщения маршрутизатора

#c #sockets #winsock #ipv6 #multicast

#c #сокеты #winsock #ipv6 #многоадресная рассылка

Вопрос:

Я пытаюсь использовать необработанные сокеты и ICMPv6 для чтения рекламных сообщений маршрутизатора в Windows. Через Wireshark я вижу, что маршрутизатор (Cisco 877) отправляет эти сообщения примерно каждые 200 секунд, но мое приложение никогда их не получает.

Мой код выполняет следующие шаги:

1) Создайте необработанный сокет IPv6, используя протокол ICMPv6

2) Привязать сокет к неуказанному адресу IPv6 (::)

3) Присоединитесь к группе групповой рассылки link-local all nodes по адресу FF02::1

4) Получать рекламные объявления маршрутизатора (… или нет :))

Код работает нормально, если я присоединюсь к FF02 :: 16…

Я пытался установить другие параметры сокета, такие как ограничения перехода, многоадресные переходы, но безрезультатно. Любые идеи будут приветствоваться, так как у меня их нет.

 #include "stdlib.h"
#include "winsock2.h"
#include "Ws2tcpip.h"

#pragma comment(lib, "ws2_32.lib")

void
main (int argc,char **argv)
{
    WSADATA wsaData;
    SOCKET nSocket;
    struct sockaddr_in6 sockinfo;
    struct ipv6_mreq mreq;
    char strBuffer[1024];
    int nBytes;

    WSAStartup (MAKEWORD (2,2),amp;wsaData);

    // Create a raw socket talking ICMPv6

    if ((nSocket = socket (AF_INET6,SOCK_RAW,IPPROTO_ICMPV6)) == SOCKET_ERROR)
       return;

    // Bind to ::

    ::memset (amp;sockinfo,0,sizeof (sockinfo));
    sockinfo.sin6_family = AF_INET6;
    inet_pton (AF_INET6,"::",amp;sockinfo.sin6_addr);
    if (bind (nSocket,(struct sockaddr *) amp;sockinfo,sizeof (sockinfo)) < 0)
       return;

    // Join the link-local all nodes multicast group

    inet_pton (AF_INET6,"FF02::1",amp;mreq.ipv6mr_multiaddr);
    mreq.ipv6mr_interface = 0;
    if (setsockopt (nSocket,IPPROTO_IPV6,IPV6_ADD_MEMBERSHIP,(char *) amp;mreq,sizeof (mreq)) < 0)
       return;

    // Wait for advertisements

    for (;;)
        nBytes = ::recvfrom (nSocket,strBuffer,sizeof (strBuffer),0,NULL,0);

    closesocket (nSocket);

    WSACleanup ();
}
  

Ответ №1:

Это работает FF02::16 , потому что это то, что Cisco использует для своей трансляции. Смотрите Это обсуждение на форумах Cisco для получения более подробной информации:

Значение адреса IPv6 FF02:: 16