ipaddr.c (1501B)
1 #define _DEFAULT_SOURCE 2 3 #include "config.h" 4 5 #include <arpa/inet.h> 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 9 #if HAVE_ERR 10 #include <err.h> 11 #endif 12 #include <ifaddrs.h> 13 #include <netdb.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 18 int 19 main(int argc, char **argv) 20 { 21 struct ifaddrs *ifaddr, *iter; 22 size_t sa_size; 23 int status; 24 char host[NI_MAXHOST + 1], *iface; 25 26 #if HAVE_PLEDGE 27 if (pledge("stdio") == -1) 28 err(1, "pledge"); 29 #endif 30 31 if (argc != 3) { 32 if (argc > 3) 33 warnx("too many arguments: %s", argv[3]); 34 goto usage; 35 } 36 37 if (argv[1][0] != '-') { 38 warnx("invalid argument"); 39 goto usage; 40 } 41 42 switch (argv[1][1]) { 43 case '4': 44 sa_size = sizeof(struct sockaddr_in); 45 break; 46 case '6': 47 sa_size = sizeof(struct sockaddr_in6); 48 break; 49 default: 50 warnx("invalid argument"); 51 case 'h': 52 goto usage; 53 } 54 55 iface = argv[2]; 56 57 if (getifaddrs(&ifaddr) == -1) 58 err(1, "getifaddrs"); 59 60 for (iter = ifaddr; iter != NULL; iter = iter->ifa_next) { 61 if (iter->ifa_addr == NULL) 62 continue; 63 64 status = getnameinfo(iter->ifa_addr, sa_size, host, NI_MAXHOST, 65 NULL, 0, NI_NUMERICHOST); 66 67 if ((strncmp(iter->ifa_name, iface, strlen(iface)) == 0) 68 && (iter->ifa_addr->sa_family == AF_INET)) { 69 if (status != 0) 70 errx(1, "getnameinfo: %s", 71 gai_strerror(status)); 72 printf("%s %s\n", iter->ifa_name, host); 73 break; 74 } 75 } 76 77 freeifaddrs(ifaddr); 78 79 return 0; 80 usage: 81 fprintf(stderr, "usage: %s [-4 | -6] interface\n", getprogname()); 82 83 return 1; 84 }