implement if_nameindex and if_freenameindex
authorRich Felker <dalias@aerifal.cx>
Wed, 3 Aug 2011 16:13:13 +0000 (12:13 -0400)
committerRich Felker <dalias@aerifal.cx>
Wed, 3 Aug 2011 16:13:13 +0000 (12:13 -0400)
src/network/if_freenameindex.c [new file with mode: 0644]
src/network/if_nameindex.c [new file with mode: 0644]

diff --git a/src/network/if_freenameindex.c b/src/network/if_freenameindex.c
new file mode 100644 (file)
index 0000000..89bafcc
--- /dev/null
@@ -0,0 +1,7 @@
+#include <net/if.h>
+#include <stdlib.h>
+
+void if_freenameindex(struct if_nameindex *idx)
+{
+       free(idx);
+}
diff --git a/src/network/if_nameindex.c b/src/network/if_nameindex.c
new file mode 100644 (file)
index 0000000..580acce
--- /dev/null
@@ -0,0 +1,58 @@
+#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;
+       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=0; i<n; i++) {
+               if (ioctl(s, SIOCGIFINDEX, &conf.ifc_req[i]) < 0) {
+                       i--;
+                       n--;
+                       continue;
+               }
+               idx[i].if_index = conf.ifc_req[i].ifr_ifindex;
+               idx[i].if_name = conf.ifc_req[i].ifr_name;
+       }
+       idx[i].if_name = 0;
+       idx[i].if_index = 0;
+
+       return idx;
+}
+
+struct if_nameindex *if_nameindex()
+{
+       size_t n;
+       void *p = 0;
+       int s = socket(AF_UNIX, SOCK_DGRAM, 0);
+       if (s>=0) {
+               for (n=0; (p=do_nameindex(s, n)) == (void *)-1; n++);
+               __syscall(SYS_close, s);
+       }
+       errno = ENOBUFS;
+       return p;
+}