]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: update Solaris multicast API (BZ#725)
authorChristian Franke <chris@opensourcerouting.org>
Mon, 14 Jan 2013 22:41:57 +0000 (23:41 +0100)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 23 Sep 2016 16:12:16 +0000 (12:12 -0400)
On OpenIndiana/Solaris the build fails with "unsupported multicast API".
It's only in the IPv4 part where setsockopt IP_MULTICAST_IF needs a
local address and not the index (IPv6 wants the index).
The following code walks the list of interfaces until it finds the matching
index and uses the interface's local address for the setsockopt call.
I don't know if it works on Solaris < 10 (I guess yes, but I don't have
any machine to verify it).

[NB: this breaks unnumbered setups that use the same IPv4 address on
multiple interfaces. -- equinox@opensourcerouting.org]

Reported-by: Brian Utterback <brian.utterback@oracle.com>
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Patchwork #762

lib/sockopt.c

index 31b2edbacfef881331e0f37451c8f77e27f6863a..c480cee0d723d08af874fe8c48e1184d56ff5dd8 100644 (file)
  */
 
 #include <zebra.h>
+
+#ifdef SUNOS_5
+#include <ifaddrs.h>
+#endif
+
 #include "log.h"
 #include "sockopt.h"
 #include "sockunion.h"
@@ -346,6 +351,35 @@ setsockopt_ipv4_multicast_if(int sock, struct in_addr if_addr,
 #endif
 
   return setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, (void *)&m, sizeof(m));
+#elif defined(SUNOS_5)
+  char ifname[IF_NAMESIZE];
+  struct ifaddrs *ifa, *ifap;
+  struct in_addr ifaddr;
+
+  if (if_indextoname(ifindex, ifname) == NULL)
+    return -1;
+
+  if (getifaddrs(&ifa) != 0)
+    return -1;
+
+  for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next)
+    {
+      struct sockaddr_in *sa;
+
+      if (strcmp(ifap->ifa_name, ifname) != 0)
+        continue;
+      if (ifap->ifa_addr->sa_family != AF_INET)
+        continue;
+      sa = (struct sockaddr_in*)ifap->ifa_addr;
+      memcpy(&ifaddr, &sa->sin_addr, sizeof(ifaddr));
+      break;
+    }
+
+  freeifaddrs(ifa);
+  if (!ifap) /* This means we did not find an IP */
+    return -1;
+
+  return setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (void *)&ifaddr, sizeof(ifaddr));
 #else
   #error "Unsupported multicast API"
 #endif