+static int
+interface_socket_setup6(struct interface *iface)
+{
+ struct ipv6_mreq mreq;
+ int ttl = 255;
+ int yes = 1;
+ int no = 0;
+ struct sockaddr_in6 sa = { 0 };
+ int fd = iface->fd.fd;
+
+ sa.sin6_family = AF_INET6;
+ sa.sin6_port = htons(MCAST_PORT);
+ inet_pton(AF_INET6, MCAST_ADDR6, &sa.sin6_addr);
+
+ memset(&mreq, 0, sizeof(mreq));
+ mreq.ipv6mr_multiaddr = sa.sin6_addr;
+ mreq.ipv6mr_interface = iface->ifindex;
+
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) < 0)
+ fprintf(stderr, "ioctl failed: IPV6_MULTICAST_HOPS\n");
+
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) < 0)
+ fprintf(stderr, "ioctl failed: IPV6_UNICAST_HOPS\n");
+
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
+ fprintf(stderr, "ioctl failed: SO_REUSEADDR\n");
+
+ setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq, sizeof(mreq));
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
+ fprintf(stderr, "failed to join multicast group: %s\n", strerror(errno));
+ close(fd);
+ fd = -1;
+ return -1;
+ }
+
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &yes, sizeof(yes)) < 0)
+ fprintf(stderr, "ioctl failed: IPV6_RECVPKTINFO\n");
+
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &yes, sizeof(yes)) < 0)
+ fprintf(stderr, "ioctl failed: IPV6_RECVHOPLIMIT\n");
+
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &no, sizeof(no)) < 0)
+ fprintf(stderr, "ioctl failed: IPV6_MULTICAST_LOOP\n");
+
+ return 0;
+}
+