I am trying to listen to multicast on all interfaces in system, but responds only on this on which I've received multicast packet.
What I've did is to create a socket for each of the interfaces and here the problems starts.
When I bind interface to INADDR_ANY
it will receive packets for all interfaces and send on default one. If I bind port to specific interface it will not receive multicast packet (but it will be able to send it on correct interface).
I've tried setting options like IP_ADD_MEMBERSHIP
or IP_MULTICAST_IF
but without success.
I think the other options whould be to create one socket to receive on all ifs and senders sockets for all interfaces, but on this approach I have no idea on which ifs packet entered...
Code samples (simplified, without error handling and stuff):
Creating socket:
//here i am looping over all interfaces from getifaddrs
struct sockaddr_in *pAddr = (struct sockaddr_in *)tmp->ifa_addr;
sockets[i] = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
setsockopt(sockets[i], SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
mreq.imr_multiaddr.s_addr=inet_addr(MDNS_ADDRESS);
mreq.imr_interface.s_addr=pAddr->sin_addr.s_addr;
setsockopt(sockets[i], IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
setsockopt(sockets[i], IPPROTO_IP, IP_MULTICAST_IF, &pAddr, sizeof(struct in_addr));
memset(&my_addr, 0, sizeof(struct sockaddr_in));
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = INADDR_ANY; //or pAddr->sin_addr.s_addr;
my_addr.sin_port = htons(port);
bind(sockets[i], (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1);
Receiving and sending:
recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len);
//do some magic and response (response should be a multicast too)
destination.sin_addr.s_addr = inet_addr(MULTICAST_ADDRESS);
destination.sin_family = AF_INET;
destination.sin_port = htons( port );
sendto(sockfd, buffer, len, 0, (struct sockaddr *)&destination, sizeof destination);
I would like to create something similar in work to mDNS so when packet entered on specific interface program should answer on the same if with some data about this if. It should not send this on other ifs as it may not be relevant for them, but it should send it as multicast so any other host in same network will receive the respond.