summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2016-08-04 10:07:26 -0300
committerDonald Sharp <sharpd@cumulusnetwroks.com>2016-08-07 21:05:26 -0400
commit4a3867d0d331ab64311f517bfb39bddfc933c9ee (patch)
treebbfb0e3efa099b216058d16937ec442d1d085a37 /lib
parent288b91e0bdf99bd835ce82905415011f77ce5a62 (diff)
lib: fix setting of IPv4 multicast sockopts on OpenBSD
OpenBSD doesn't support the "ifindex hack" derived from RFC 1724 which allows an ifindex to be encoded in the imr_interface field (in_addr) of the ip_mreq structure. OpenBSD also doesn't support the RFC3678 Protocol-Independent socket API extensions, which allows an interface to be specified by its ifindex. With that said, in OpenBSD we still need to specify an interface by its IP address. This patch adds an exception in the multicast sockopt functions to handle this case. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/sockopt.c19
-rw-r--r--lib/sockopt.h3
2 files changed, 15 insertions, 7 deletions
diff --git a/lib/sockopt.c b/lib/sockopt.c
index 257271bc0b..d8204936f9 100644
--- a/lib/sockopt.c
+++ b/lib/sockopt.c
@@ -219,6 +219,7 @@ setsockopt_ipv6_tclass(int sock, int tclass)
int
setsockopt_ipv4_multicast(int sock,
int optname,
+ struct in_addr if_addr,
unsigned int mcast_addr,
unsigned int ifindex)
{
@@ -279,18 +280,20 @@ setsockopt_ipv4_multicast(int sock,
#elif defined(HAVE_BSD_STRUCT_IP_MREQ_HACK) /* #if OS_TYPE */
/* standard BSD API */
- struct in_addr m;
struct ip_mreq mreq;
int ret;
assert(optname == IP_ADD_MEMBERSHIP || optname == IP_DROP_MEMBERSHIP);
- m.s_addr = htonl(ifindex);
memset (&mreq, 0, sizeof(mreq));
mreq.imr_multiaddr.s_addr = mcast_addr;
- mreq.imr_interface = m;
-
+#if !defined __OpenBSD__
+ mreq.imr_interface.s_addr = htonl (ifindex);
+#else
+ mreq.imr_interface.s_addr = if_addr.s_addr;
+#endif
+
ret = setsockopt (sock, IPPROTO_IP, optname, (void *)&mreq, sizeof(mreq));
if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE))
{
@@ -318,7 +321,7 @@ setsockopt_ipv4_multicast(int sock,
* Set IP_MULTICAST_IF socket option in an OS-dependent manner.
*/
int
-setsockopt_ipv4_multicast_if(int sock,
+setsockopt_ipv4_multicast_if(int sock, struct in_addr if_addr,
unsigned int ifindex)
{
@@ -336,7 +339,11 @@ setsockopt_ipv4_multicast_if(int sock,
#elif defined(HAVE_BSD_STRUCT_IP_MREQ_HACK)
struct in_addr m;
- m.s_addr = htonl(ifindex);
+#if !defined __OpenBSD__
+ m.s_addr = htonl (ifindex);
+#else
+ m.s_addr = if_addr.s_addr;
+#endif
return setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, (void *)&m, sizeof(m));
#else
diff --git a/lib/sockopt.h b/lib/sockopt.h
index cb14efc7ba..a597314c3d 100644
--- a/lib/sockopt.h
+++ b/lib/sockopt.h
@@ -83,9 +83,10 @@ extern int setsockopt_ipv6_tclass (int, int);
(((af) == AF_INET) : SOPT_SIZE_CMSG_IFINDEX_IPV4() \
? SOPT_SIZE_CMSG_PKTINFO_IPV6())
-extern int setsockopt_ipv4_multicast_if(int sock,
+extern int setsockopt_ipv4_multicast_if(int sock, struct in_addr if_addr,
unsigned int ifindex);
extern int setsockopt_ipv4_multicast(int sock, int optname,
+ struct in_addr if_addr,
unsigned int mcast_addr,
unsigned int ifindex);
extern int setsockopt_ipv4_tos(int sock, int tos);