#include <unistd.h>
#include "internal.h"
#include "network.h"
+
+
+#ifdef WIN32
+# define if_nametoindex( str ) atoi( str )
+#else
+# include <unistd.h>
+# include <net/if.h>
+#endif
+
+
#include "os_support.h"
#include "url.h"
return 0;
}
-static int udp_join_multicast_group(int sockfd, struct sockaddr *addr)
+static int udp_join_multicast_group(int sockfd, struct sockaddr *addr, int miface_nr)
{
#ifdef IP_ADD_MEMBERSHIP
if (addr->sa_family == AF_INET) {
struct ip_mreq mreq;
+ struct group_req gr;
mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
mreq.imr_interface.s_addr= INADDR_ANY;
av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP): %s\n", strerror(errno));
return -1;
}
+
+#ifdef MCAST_JOIN_GROUP
+ memset(&gr, 0, sizeof(struct group_req));
+ gr.gr_interface = miface_nr;
+ memcpy(&gr.gr_group, addr, sizeof(struct sockaddr_in));
+ if (setsockopt(sockfd, SOL_IP, MCAST_JOIN_GROUP, &gr, sizeof(struct group_req)) < 0) {
+ av_log(NULL, AV_LOG_ERROR, "setsockopt(MCAST_JOIN_GROUP): %s\n", strerror(errno));
+ return -1;
+ }
+#endif
}
#endif
#if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6)
* option: 'ttl=n' : set the ttl value (for multicast only)
* 'localport=n' : set the local port
* 'pkt_size=n' : set max packet size
+ * 'miface=if' : set multicast input interface
* 'reuse=1' : enable reusing the socket
*
* @param h media file context
struct sockaddr_storage my_addr;
int len;
int reuse_specified = 0;
+ int miface_nr = 0;
h->is_streamed = 1;
h->max_packet_size = 1472;
if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
av_strlcpy(localaddr, buf, sizeof(localaddr));
}
+ if (av_find_info_tag(buf, sizeof(buf), "miface", p)) {
+ miface_nr = if_nametoindex (buf);
+ }
}
/* fill the dest addr */
}
if (h->flags & AVIO_FLAG_READ) {
/* input */
- if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
+ if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr, miface_nr) < 0)
goto fail;
}
}