diff options
-rw-r--r-- | sysdep/linux/sysio.h | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/sysdep/linux/sysio.h b/sysdep/linux/sysio.h index 32bec160..3a29cdc9 100644 --- a/sysdep/linux/sysio.h +++ b/sysdep/linux/sysio.h @@ -23,6 +23,8 @@ set_inaddr(struct in6_addr *ia, ip_addr a) #else +#include <net/if.h> + static inline void set_inaddr(struct in_addr *ia, ip_addr a) { @@ -78,14 +80,18 @@ static inline char *sysio_mcast_join(sock *s) { struct ip_mreqn mreq; char *err; + struct ifreq ifr; if (err = sysio_mcast_setup(s)) return err; + strcpy(ifr.ifr_name, s->iface->name); + if (setsockopt(s->fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) + return "SO_BINDTODEVICE"; mreq.imr_ifindex = s->iface->index; set_inaddr(&mreq.imr_address, s->iface->addr->ip); set_inaddr(&mreq.imr_multiaddr, s->daddr); /* This defines where should we send _outgoing_ multicasts */ - if (setsockopt(s->fd, SOL_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq)) < 0) + if (ipa_nonzero(s->daddr) && setsockopt(s->fd, SOL_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq)) < 0) return "IP_MULTICAST_IF"; /* And this one sets interface for _receiving_ multicasts from */ if (ipa_nonzero(s->saddr) && setsockopt(s->fd, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) @@ -101,8 +107,6 @@ static inline char *sysio_mcast_join(sock *s) * we can use SO_BINDTODEVICE to circumvent this problem. */ -#include <net/if.h> - static inline char *sysio_mcast_join(sock *s) { struct in_addr mreq; @@ -125,7 +129,7 @@ static inline char *sysio_mcast_join(sock *s) #endif set_inaddr(&mreq_add.imr_multiaddr, s->daddr); /* This defines where should we send _outgoing_ multicasts */ - if (setsockopt(s->fd, SOL_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq)) < 0) + if (ipa_nonzero(s->daddr) && setsockopt(s->fd, SOL_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq)) < 0) return "IP_MULTICAST_IF"; /* And this one sets interface for _receiving_ multicasts from */ if (ipa_nonzero(s->saddr) && setsockopt(s->fd, SOL_IP, IP_ADD_MEMBERSHIP, &mreq_add, sizeof(mreq_add)) < 0) |