From: Nadav Har'El <n...@scylladb.com>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master

Fix if_nameindex()

The if_nameindex() implementation we got from Musl is based on various
ioctls explained in netdevice(7). As that manual page explains, these
ioctls "can be used on any socket's file descriptor regardless of the
family or type.". So it was unfortunate that the musl implementation
chose to create a UNIX domain socket, which is not currently supported
in OSv (see issue #355). Just changing the code to use AF_INET instead
of AF_UNIX makes it work correctly.

Signed-off-by: Nadav Har'El <n...@scylladb.com>
Message-Id: <1470780495-10772-1-git-send-email-...@scylladb.com>

---
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -1350,7 +1350,7 @@ musl += network/getservbyname.o
 musl += network/getservbyport_r.o
 musl += network/getservbyport.o
 musl += network/getifaddrs.o
-musl += network/if_nameindex.o
+libc += network/if_nameindex.o
 musl += network/if_freenameindex.o

 musl += prng/rand.o
diff --git a/libc/network/if_nameindex.c b/libc/network/if_nameindex.c
--- a/libc/network/if_nameindex.c
+++ b/libc/network/if_nameindex.c
@@ -0,0 +1,57 @@
+#define _GNU_SOURCE
+#include <net/if.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include "syscall.h"
+
+#include <stdio.h>
+
+static void *do_nameindex(int s, size_t n)
+{
+       size_t i, len, k;
+       struct ifconf conf;
+       struct if_nameindex *idx;
+
+       idx = malloc(n * (sizeof(struct if_nameindex)+sizeof(struct ifreq)));
+       if (!idx) return 0;
+
+       conf.ifc_buf = (void *)&idx[n];
+       conf.ifc_len = len = n * sizeof(struct ifreq);
+       if (ioctl(s, SIOCGIFCONF, &conf) < 0) {
+               free(idx);
+               return 0;
+       }
+       if (conf.ifc_len == len) {
+               free(idx);
+               return (void *)-1;
+       }
+
+       n = conf.ifc_len / sizeof(struct ifreq);
+       for (i=k=0; i<n; i++) {
+               if (ioctl(s, SIOCGIFINDEX, &conf.ifc_req[i]) < 0) {
+                       k++;
+                       continue;
+               }
+               idx[i-k].if_index = conf.ifc_req[i].ifr_ifindex;
+               idx[i-k].if_name = conf.ifc_req[i].ifr_name;
+       }
+       idx[i-k].if_name = 0;
+       idx[i-k].if_index = 0;
+
+       return idx;
+}
+
+struct if_nameindex *if_nameindex()
+{
+       size_t n;
+       void *p = 0;
+       int s = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+       if (s>=0) {
+               for (n=0; (p=do_nameindex(s, n)) == (void *)-1; n++);
+               __syscall(SYS_close, s);
+       }
+       errno = ENOBUFS;
+       return p;
+}

--
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to