1
votes

I'm trying to use raw sockets and ICMPv6 to read router advertisement messages on Windows. Through Wireshark, I can see the router (a Cisco 877) sending these messages about every 200 seconds, but my application never receives them.

My code takes the following steps:

1) Create an IPv6 raw socket using ICMPv6 protocol

2) Bind the socket to the IPv6 unspecified address (::)

3) Join the link-local all nodes multicast group at FF02::1

4) Receive router advertisements (... or not :))

The code works fine if I join FF02::16...

I've tried setting other socket options like hop limits, multicast hops, to no avail. Any ideas would be welcome, as I am out of them.

#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),&wsaData);

    // Create a raw socket talking ICMPv6

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

    // Bind to ::

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

    // Join the link-local all nodes multicast group

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

    // Wait for advertisements

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

    closesocket (nSocket);

    WSACleanup ();
}
1

1 Answers

1
votes

It works on FF02::16 because that is what Cisco uses for its broadcasting. See this discussion on Cisco's forums for more details:

IPv6 address FF02::16 Significance