| /* This file is part of the UCB release of Plan 9. It is subject to the license | 
 |  * terms in the LICENSE file found in the top-level directory of this | 
 |  * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No | 
 |  * part of the UCB release of Plan 9, including this file, may be copied, | 
 |  * modified, propagated, or distributed except according to the terms contained | 
 |  * in the LICENSE file. */ | 
 |  | 
 | #include <stdlib.h> | 
 | #include <stdio.h> | 
 | #include <parlib/parlib.h> | 
 | #include <unistd.h> | 
 | #include <signal.h> | 
 | #include <iplib/iplib.h> | 
 | #include <iplib/icmp.h> | 
 | #include <ctype.h> | 
 | #include <pthread.h> | 
 | #include <parlib/spinlock.h> | 
 | #include <parlib/timing.h> | 
 | #include <parlib/tsc-compat.h> | 
 | #include <parlib/printf-ext.h> | 
 | #include <parlib/alarm.h> | 
 | #include <ndblib/ndb.h> | 
 | #include <ifaddrs.h> | 
 | #include <netpacket/packet.h> | 
 | #include <arpa/inet.h> | 
 |  | 
 | static void print_eth(struct ifaddrs *ifa) | 
 | { | 
 | 	struct sockaddr_ll *sa_ll = (struct sockaddr_ll*)ifa->ifa_addr; | 
 |  | 
 | 	printf("\tAddr: "); | 
 | 	for (int i = 0; i < sa_ll->sll_halen; i++) { | 
 | 		printf("%02x", sa_ll->sll_addr[i]); | 
 | 		if (i < sa_ll->sll_halen - 1) | 
 | 			printf(":"); | 
 | 	} | 
 | 	printf("\n"); | 
 | 	printf("\tNIC %d\n", sa_ll->sll_ifindex); | 
 | } | 
 |  | 
 | static void print_inet(struct ifaddrs *ifa) | 
 | { | 
 | 	struct sockaddr_in *sa_in = (struct sockaddr_in*)ifa->ifa_addr; | 
 | 	struct sockaddr_in *mask_in = (struct sockaddr_in*)ifa->ifa_netmask; | 
 | 	char buf[INET_ADDRSTRLEN]; | 
 |  | 
 | 	printf("\tAddr: %s\n", inet_ntop(AF_INET, &sa_in->sin_addr, buf, | 
 | 	                                 sizeof(buf))); | 
 | 	if (mask_in) | 
 | 		printf("\tMask: %s\n", inet_ntop(AF_INET, &mask_in->sin_addr, | 
 | 						 buf, sizeof(buf))); | 
 | } | 
 |  | 
 | static void print_inet6(struct ifaddrs *ifa) | 
 | { | 
 | 	struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6*)ifa->ifa_addr; | 
 | 	char buf[INET6_ADDRSTRLEN]; | 
 |  | 
 | 	printf("\tAddr: %s\n", inet_ntop(AF_INET6, &sa_in6->sin6_addr, buf, | 
 | 	                                 sizeof(buf))); | 
 | } | 
 |  | 
 | int main(int argc, char **argv) | 
 | { | 
 | 	int family; | 
 | 	struct ifaddrs *ifaddrs, *ifa; | 
 |  | 
 | 	if (getifaddrs(&ifaddrs) != 0) { | 
 | 		perror("getifaddr"); | 
 | 		exit(-1); | 
 | 	} | 
 |  | 
 | 	for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) { | 
 | 		printf("%s: ", ifa->ifa_name); | 
 | 		if (!ifa->ifa_addr) { | 
 | 			printf("No addr\n"); | 
 | 			continue; | 
 | 		} else { | 
 | 			printf("\n"); | 
 | 		} | 
 | 		family = ifa->ifa_addr->sa_family; | 
 | 		printf("\tFamily: %s\n", (family == AF_PACKET) ? "AF_PACKET" : | 
 | 		                         (family == AF_INET) ? "AF_INET" : | 
 | 		                         (family == AF_INET6) ? "AF_INET6" : | 
 | 		                         "Unknown"); | 
 | 		switch (family) { | 
 | 		case AF_PACKET: | 
 | 			print_eth(ifa); | 
 | 			break; | 
 | 		case AF_INET: | 
 | 			print_inet(ifa); | 
 | 			break; | 
 | 		case AF_INET6: | 
 | 			print_inet6(ifa); | 
 | 			break; | 
 | 		} | 
 | 	} | 
 | 	freeifaddrs(ifaddrs); | 
 | } |