ip.c (1632B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <ifaddrs.h> 3 #include <netdb.h> 4 #include <net/if.h> 5 #include <stdio.h> 6 #include <string.h> 7 #if defined(__OpenBSD__) 8 #include <sys/socket.h> 9 #include <sys/types.h> 10 #elif defined(__FreeBSD__) 11 #include <netinet/in.h> 12 #include <sys/socket.h> 13 #endif 14 15 #include "../slstatus.h" 16 #include "../util.h" 17 18 static const char * 19 ip(const char *interface, unsigned short sa_family) 20 { 21 struct ifaddrs *ifaddr, *ifa; 22 int s; 23 char host[NI_MAXHOST]; 24 25 if (getifaddrs(&ifaddr) < 0) { 26 warn("getifaddrs:"); 27 return NULL; 28 } 29 30 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { 31 if (!ifa->ifa_addr) 32 continue; 33 34 s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), 35 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); 36 if (!strcmp(ifa->ifa_name, interface) && 37 (ifa->ifa_addr->sa_family == sa_family)) { 38 freeifaddrs(ifaddr); 39 if (s != 0) { 40 warn("getnameinfo: %s", gai_strerror(s)); 41 return NULL; 42 } 43 return bprintf("%s", host); 44 } 45 } 46 47 freeifaddrs(ifaddr); 48 49 return NULL; 50 } 51 52 const char * 53 ipv4(const char *interface) 54 { 55 return ip(interface, AF_INET); 56 } 57 58 const char * 59 ipv6(const char *interface) 60 { 61 return ip(interface, AF_INET6); 62 } 63 64 const char * 65 up(const char *interface) 66 { 67 struct ifaddrs *ifaddr, *ifa; 68 69 if (getifaddrs(&ifaddr) < 0) { 70 warn("getifaddrs:"); 71 return NULL; 72 } 73 74 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { 75 if (!ifa->ifa_addr) 76 continue; 77 78 if (!strcmp(ifa->ifa_name, interface)) { 79 freeifaddrs(ifaddr); 80 return ifa->ifa_flags & IFF_UP ? "up" : "down"; 81 } 82 } 83 84 freeifaddrs(ifaddr); 85 86 return NULL; 87 }