port/linux/ipadapter: fix multicast config
* Set scope_id into outgoing message for each
interface in oc_send_discovery_request().
* Iterate through all interfaces to add IPv6
multicast membership inside
add_mcast_sock_to_ipv6_multicast_group().
@@ -527,6 +527,7 @@ oc_send_discovery_request(oc_message_t *message)
errno);
goto done;
}
+ message->endpoint.addr.ipv6.scope = mif;
oc_send_buffer(message);
}
#ifdef OC_IPV4
@@ -659,14 +660,30 @@ connectivity_ipv4_init(ip_context_t *dev)
static int
add_mcast_sock_to_ipv6_multicast_group(int sock, const uint8_t *addr)
{
+ struct ifaddrs *ifs = NULL, *interface = NULL;
+ if (getifaddrs(&ifs) < 0) {
+ OC_ERR("querying interfaces: %d\n", errno);
+ return -1;
+ }
+ for (interface = ifs; interface != NULL; interface = interface->ifa_next) {
+ if (!interface->ifa_flags & IFF_UP || interface->ifa_flags & IFF_LOOPBACK)
+ continue;
+ struct sockaddr_in6 *if_addr = (struct sockaddr_in6 *)interface->ifa_addr;
+ if (IN6_IS_ADDR_LINKLOCAL(&if_addr->sin6_addr)) {
struct ipv6_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
memcpy(mreq.ipv6mr_multiaddr.s6_addr, addr, 16);
+ mreq.ipv6mr_interface = if_addr->sin6_scope_id;
+
if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq,
sizeof(mreq)) == -1) {
OC_ERR("joining IPv6 multicast group %d\n", errno);
+ freeifaddrs(ifs);
return -1;
}
+ }
+ }
+ freeifaddrs(ifs);
return 0;
}
