]> git.sur5r.net Git - i3/i3status/blob - src/print_ip_addr.c
Show IP address when address has a label
[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     int interface_len = strlen(interface);
33
34     getifaddrs(&ifaddr);
35
36     if (ifaddr == NULL)
37         return NULL;
38
39     /* Skip until we are at the input family address of interface */
40     for (addrp = ifaddr;
41
42          (addrp != NULL &&
43           (strncmp(addrp->ifa_name, interface, interface_len) != 0 ||
44            addrp->ifa_addr == NULL ||
45            addrp->ifa_addr->sa_family != family));
46
47          addrp = addrp->ifa_next) {
48         /* Check if the interface is down */
49         if (strncmp(addrp->ifa_name, interface, interface_len) != 0)
50             continue;
51         found = true;
52         if ((addrp->ifa_flags & IFF_RUNNING) == 0) {
53             freeifaddrs(ifaddr);
54             return NULL;
55         }
56     }
57
58     if (addrp == NULL) {
59         freeifaddrs(ifaddr);
60         return (found ? "no IP" : NULL);
61     }
62
63     int ret;
64     if ((ret = getnameinfo(addrp->ifa_addr, len, part, sizeof(part), NULL, 0, NI_NUMERICHOST)) != 0) {
65         fprintf(stderr, "i3status: getnameinfo(): %s\n", gai_strerror(ret));
66         freeifaddrs(ifaddr);
67         return "no IP";
68     }
69
70     freeifaddrs(ifaddr);
71     return part;
72 }