OSDN Git Service

implement sendmmsg and recvmmsg
[android-x86/external-musl-libc.git] / src / network / if_nameindex.c
1 #define _GNU_SOURCE
2 #include <net/if.h>
3 #include <stdlib.h>
4 #include <sys/socket.h>
5 #include <sys/ioctl.h>
6 #include <errno.h>
7 #include "syscall.h"
8
9 static void *do_nameindex(int s, size_t n)
10 {
11         size_t i, len, k;
12         struct ifconf conf;
13         struct if_nameindex *idx;
14
15         idx = malloc(n * (sizeof(struct if_nameindex)+sizeof(struct ifreq)));
16         if (!idx) return 0;
17
18         conf.ifc_buf = (void *)&idx[n];
19         conf.ifc_len = len = n * sizeof(struct ifreq);
20         if (ioctl(s, SIOCGIFCONF, &conf) < 0) {
21                 free(idx);
22                 return 0;
23         }
24         if (conf.ifc_len == len) {
25                 free(idx);
26                 return (void *)-1;
27         }
28
29         n = conf.ifc_len / sizeof(struct ifreq);
30         for (i=k=0; i<n; i++) {
31                 if (ioctl(s, SIOCGIFINDEX, &conf.ifc_req[i]) < 0) {
32                         k++;
33                         continue;
34                 }
35                 idx[i-k].if_index = conf.ifc_req[i].ifr_ifindex;
36                 idx[i-k].if_name = conf.ifc_req[i].ifr_name;
37         }
38         idx[i-k].if_name = 0;
39         idx[i-k].if_index = 0;
40
41         return idx;
42 }
43
44 struct if_nameindex *if_nameindex()
45 {
46         size_t n;
47         void *p = 0;
48         int s = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
49         if (s>=0) {
50                 for (n=0; (p=do_nameindex(s, n)) == (void *)-1; n++);
51                 __syscall(SYS_close, s);
52         }
53         errno = ENOBUFS;
54         return p;
55 }