]> git.sur5r.net Git - i3/i3status/blob - src/print_ip_addr.c
Add IPv6 address when IPv4 isn't available (#247)
[i3/i3status] / src / print_ip_addr.c
1 // vim:ts=4:sw=4:expandtab
2 #include <sys/types.h>
3 #include <sys/socket.h>
4 #include <netinet/in.h>
5
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <netdb.h>
10 #include <ifaddrs.h>
11 #include <net/if.h>
12
13 #include "i3status.h"
14
15 /*
16  * Return the IP address for the given interface or "no IP" if the
17  * interface is up and running but hasn't got an IP address yet
18  *
19  */
20 const char *get_ip_addr(const char *interface, int family) {
21     static char part[512];
22     socklen_t len = 0;
23     if (family == AF_INET)
24         len = sizeof(struct sockaddr_in);
25     else if (family == AF_INET6)
26         len = sizeof(struct sockaddr_in6);
27
28     memset(part, 0, sizeof(part));
29
30     struct ifaddrs *ifaddr, *addrp;
31     bool found = false;
32
33     getifaddrs(&ifaddr);
34
35     if (ifaddr == NULL)
36         return NULL;
37
38     /* Skip until we are at the input family address of interface */
39     for (addrp = ifaddr;
40
41          (addrp != NULL &&
42           (strcmp(addrp->ifa_name, interface) != 0 ||
43            addrp->ifa_addr == NULL ||
44            addrp->ifa_addr->sa_family != family));
45
46          addrp = addrp->ifa_next) {
47         /* Check if the interface is down */
48         if (strcmp(addrp->ifa_name, interface) != 0)
49             continue;
50         found = true;
51         if ((addrp->ifa_flags & IFF_RUNNING) == 0) {
52             freeifaddrs(ifaddr);
53             return NULL;
54         }
55     }
56
57     if (addrp == NULL) {
58         freeifaddrs(ifaddr);
59         return (found ? "no IP" : NULL);
60     }
61
62     int ret;
63     if ((ret = getnameinfo(addrp->ifa_addr, len, part, sizeof(part), NULL, 0, NI_NUMERICHOST)) != 0) {
64         fprintf(stderr, "i3status: getnameinfo(): %s\n", gai_strerror(ret));
65         freeifaddrs(ifaddr);
66         return "no IP";
67     }
68
69     freeifaddrs(ifaddr);
70     return part;
71 }