Receiving the Multicast Listener Report
Hello.
I'd like to receive the multicast listener report that is sent as a reply to the Multicast listener query. My code however doesn't accept anything. I'd really appreciate any help.
Here is the wireshark screenshot. I am sending the query, getting the reply but cannot catch it with my program. At least one of them would be nice.
Code:
//...
//creating the socket
int ndpResFdLMNR = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
if (ndpResFdLMNR == -1)
{
std::cerr << "Cannot create the listening socket!";
return FAIL_EXIT;
}
//not sure if I have to do this but joining the ff02::c mcast group :-)
struct ipv6_mreq mreq;
mreq.ipv6mr_interface = if_nametoindex(interfaceName);
inet_pton(AF_INET6, "ff02::c",&(mreq.ipv6mr_multiaddr));
setsockopt(ndpResFdLMNR, IPPROTO_RAW, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)); //EDIT: I noticed that IPPROTO_RAW returns error here, changed to IPPROTO_IPV6 but still not working
//setting the timeout
setsockopt(ndpResFdLMNR, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
//setting the reuse
int one = 1;
setsockopt(ndpResFdLMNR,SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
//binding
struct sockaddr_in6 sa6LMNR;
sa6LMNR.sin6_family = AF_INET6;
sa6LMNR.sin6_port = 0;
sa6LMNR.sin6_flowinfo = 0;
sa6LMNR.sin6_scope_id = 0; //EDIT2: Also tried to put if_nametoindex(interfaceName) here
inet_pton(AF_INET6, "ff02::c",&(sa6LMNR.sin6_addr));
bind(ndpResFdLMNR, (struct sockaddr*)&sa6LMNR, sizeof(sa6LMNR));
while (1)
{
retVal6 = recvfrom(ndpResFdLMNR, &r, sizeof(lqPck), 0, (struct sockaddr*)&sourceRes, &len);
if (retVal6 < 0)
break;
addIPv6(sourceRes);
}
I am sorry if I'm missing something basic but I don't know where to look anymore :D. Have a nice day!
Re: Receiving the Multicast Listener Report
Quote:
Code:
inet_pton(AF_INET6, "ff02::c",&(mreq.ipv6mr_multiaddr));
setsockopt(ndpResFdLMNR, IPPROTO_RAW, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)); //EDIT: I noticed that IPPROTO_RAW returns error here, changed to IPPROTO_IPV6 but still not working
i
You have to check the exact error code/description to understans the reason of the problem.
And you should do it for every API/C-runtime function you are using.
Re: Receiving the Multicast Listener Report
Quote:
Originally Posted by
VictorN
You have to check the exact error code/description to understans the reason of the problem.
And you should do it for every API/C-runtime function you are using.
Thank you for the advice! I have tried to check every call there but no luck. It should work right now I think.
I am starting to think there is some flaw in my logic. Is it OK to join those specific multicast groups like ff02::c?
Re: Receiving the Multicast Listener Report
I only can say you that this address looks like a valid one. You could check it in https://www.helpsystems.com/intermap...ess-validation
or some similar sites checking the IPv6 address validity.
Re: Receiving the Multicast Listener Report
Thanks for the effort. I'm still playing with the code but really no idea what's wrong here.
Re: Receiving the Multicast Listener Report
What does the setsockopt return? If it is SOCKET_ERROR then why don't you call the WSAGetLastError to get the error status?
Re: Receiving the Multicast Listener Report
I am using Linux.
I did some edits to the code so it looks like this now:
Code:
int ipv6RawFdRcv = socket(AF_INET6, SOCK_RAW, IPPROTO_IPV6);
if (ipv6RawFdRcv == -1)
{
std::cerr << "Cannot create the IPV6 RAW listening socket!";
return FAIL_EXIT;
}
int retVal = 0;
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 20000;
struct sockaddr_in6 sa6Lq;
sa6Lq.sin6_family = AF_INET6;
sa6Lq.sin6_port = 0;
sa6Lq.sin6_scope_id = interfaceIndex;
sa6Lq.sin6_addr = in6addr_any;
struct ipv6_mreq mreq;
mreq.ipv6mr_interface = interfaceIndex;
struct sockaddr_in6 s;
inet_pton(AF_INET6, "ff02::c",(&s.sin6_addr));
copyIpv6(s.sin6_addr.s6_addr, mreq.ipv6mr_multiaddr.s6_addr);
retVal = setsockopt(ipv6RawFdRcv, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq));
std::cerr << retVal;
retVal = setsockopt(ipv6RawFdRcv, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
std::cerr << retVal;
int one = 1;
retVal = setsockopt(ipv6RawFdRcv,SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
std::cerr << retVal;
retVal = bind(ipv6RawFdRcv, (struct sockaddr*)&sa6Lq, sizeof(sa6Lq));
std::cerr << retVal;
len = sizeof(senderIp);
bzero(&senderIp, sizeof(senderIp));
struct lqPck r;
while (1)
{
retVal = recvfrom(ipv6RawFdRcv, &r, sizeof(lqPck), 0, (struct sockaddr*)&senderIp, &len);
if (retVal < 0)
break;
addIPv6(senderIp);
std::cerr<< "Packet!"<< std::endl;
}
What I get is: 0000
I am starting to think that the Linux kernel is filtering those packets preventing my application to get them :D
Re: Receiving the Multicast Listener Report
Quote:
Originally Posted by
Hitokage
I am using Linux.
I did some edits to the code so it looks like this now:
...
What I get is: 0000
I am starting to think that the Linux kernel is filtering those packets preventing my application to get them :D
Do you mean all of the socket functions you call here succeeded?
Re: Receiving the Multicast Listener Report
Quote:
Originally Posted by
VictorN
Do you mean all of the socket functions you call here succeeded?
It seems so.
Re: Receiving the Multicast Listener Report
So I have found a solution to my problem. Even though I still don't know why the code above doesn't work (as I said I suspect that those packets are somehow filtered since they are on a special purpose multicast addresses, I'd appreciate any explanation if somebody knows the reason though) I managed to catch them in a different way.
What I did is that I simply started accepting all packets and I am choosing the ones I need by checking the ethernet type value and then the IPV6 header info.
So basically using a socket like this:
Code:
socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))