implement dn_skipname (legacy resolver function)
[musl] / 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 #include <stdio.h>
10
11 static void *do_nameindex(int s, size_t n)
12 {
13         size_t i, len, k;
14         struct ifconf conf;
15         struct if_nameindex *idx;
16
17         idx = malloc(n * (sizeof(struct if_nameindex)+sizeof(struct ifreq)));
18         if (!idx) return 0;
19
20         conf.ifc_buf = (void *)&idx[n];
21         conf.ifc_len = len = n * sizeof(struct ifreq);
22         if (ioctl(s, SIOCGIFCONF, &conf) < 0) {
23                 free(idx);
24                 return 0;
25         }
26         if (conf.ifc_len == len) {
27                 free(idx);
28                 return (void *)-1;
29         }
30
31         n = conf.ifc_len / sizeof(struct ifreq);
32         for (i=k=0; i<n; i++) {
33                 if (ioctl(s, SIOCGIFINDEX, &conf.ifc_req[i]) < 0) {
34                         k++;
35                         continue;
36                 }
37                 idx[i-k].if_index = conf.ifc_req[i].ifr_ifindex;
38                 idx[i-k].if_name = conf.ifc_req[i].ifr_name;
39         }
40         idx[i-k].if_name = 0;
41         idx[i-k].if_index = 0;
42
43         return idx;
44 }
45
46 struct if_nameindex *if_nameindex()
47 {
48         size_t n;
49         void *p = 0;
50         int s = socket(AF_UNIX, SOCK_DGRAM, 0);
51         if (s>=0) {
52                 for (n=0; (p=do_nameindex(s, n)) == (void *)-1; n++);
53                 __syscall(SYS_close, s);
54         }
55         errno = ENOBUFS;
56         return p;
57 }