Add syscall tracing support to 'path' calls
[akaros.git] / tools / compilers / gcc-glibc / glibc-2.19-akaros / sysdeps / akaros / ifaddrs.c
1 #define _LARGEFILE64_SOURCE /* needed to use lseek64 */
2
3 #include <stdio.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <parlib/arch/arch.h>
8 #include <unistd.h>
9 #include <errno.h>
10 #include <dirent.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include <dirent.h>
15 #include <arpa/inet.h>
16 #include <sys/socket.h>
17 #include <netdb.h>
18 #include <ifaddrs.h>
19 #include <ros/syscall.h>
20 #include <ros/fs.h>
21
22 int getifaddrs(struct ifaddrs **ifap)
23 {
24         DIR *net;
25         struct dirent *d;
26         int addr;
27         /* 6 is known everywhere, defined nowhere. So is 6 * 2 */
28         char etheraddr[12];
29         struct ifaddrs *ifa = NULL;
30         uint8_t *v;
31         int i;
32
33         *ifap = NULL;
34
35         net = opendir("/net");
36         if (net == NULL) {
37                 fprintf(stderr, "/net: %r");
38                 return -1;
39         }
40
41         for (d = readdir(net); d; d = readdir(net)) {
42                 /*
43                  * For now we only do ethernet MACs.  It's easy to
44                  * change later: just get rid of the following 2
45                  * lines.
46                  */
47                 if (strncmp(d->d_name, "ether", 5))
48                         continue;
49                 sprintf(etheraddr, "/net/%s/addr", d->d_name);
50                 addr = open(etheraddr, O_RDONLY);
51                 if (addr < 0)
52                         continue;
53                 if (read(addr, etheraddr, sizeof(etheraddr)) < sizeof(etheraddr)) {
54                         fprintf(stderr, "Read addr from %s: %r", d->d_name);
55                         close(addr);
56                         continue;
57                 }
58                 /* getifaddrds is a stupid design as it only admits of
59                  * one address per interface.  Don't even bother
60                  * filling in ifa_{addr,netmask}. They're allowed to
61                  * be NULL.  Broadaddr need be set IFF a bit is set
62                  * in the flags field. We don't set either one.
63                  */
64                 if (!ifa) {
65                         ifa = calloc(sizeof(*ifa), 1);
66                         *ifap = ifa;
67                 } else {
68                         ifa->ifa_next = calloc(sizeof(*ifa), 1);
69                         ifa = ifa->ifa_next;
70                 }
71                 ifa->ifa_name = strdup(d->d_name);
72                 /*
73                  * 6 is known everywhere, not defined anywhere.  oh
74                  * yeah, another binary thing. 1976 all over again.
75                  */
76                 v = malloc(6);
77                 for (i = 0; i < 6; i++)
78                         sscanf(&etheraddr[i*2], "%02x", &v[i]);
79                 ifa->ifa_data = v;
80                 close(addr);
81         }
82         closedir(net);
83         return 0;
84 }
85 libc_hidden_def(getifaddrs)
86
87 void freeifaddrs(struct ifaddrs *ifa)
88 {
89         for (; ifa; ifa = ifa->ifa_next)
90                 free(ifa);
91 }
92 libc_hidden_def(freeifaddrs)