#include #include #include #ifdef _WIN32 #include #include #include #else #include #include #include #endif static int isEqualIPv6Addr(const struct sockaddr_in6 *sa, const struct in6_addr in6Addr) { return (memcmp(&(sa->sin6_addr), &in6Addr, sizeof(in6Addr)) == 0) ? 1 : 0; } void sockaddr_show(struct sockaddr *sa) { int family = sa->sa_family; if (family == AF_INET) { char buff[INET_ADDRSTRLEN]; struct sockaddr_in server_addr = *((struct sockaddr_in*) sa); inet_ntop(AF_INET, &server_addr.sin_addr, buff, INET_ADDRSTRLEN); printf("AF_INET IPv4 addr '%s'\n", buff); } else if (family == AF_INET6) { char buff[INET_ADDRSTRLEN]; struct sockaddr_in6 server_addr = *((struct sockaddr_in6*) sa); struct in6_addr mappedAny = IN6ADDR_ANY_INIT; inet_pton(AF_INET6, "::ffff:0.0.0.0", &mappedAny); inet_ntop(AF_INET6, &server_addr.sin6_addr, buff, INET6_ADDRSTRLEN); printf("AF_INET6 IPv6 addr '%s', mappedAny: %d, in6addr_any: %d\n", buff, isEqualIPv6Addr(&server_addr, mappedAny), isEqualIPv6Addr(&server_addr, in6addr_any)); } else { printf("family: %d\n", family); } } void show_addr_info(int family, int flags) { char* hostname = NULL; char* service = "0"; struct addrinfo hints; struct addrinfo *result = NULL, *rp; memset (&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_NUMERICSERV | flags; #ifdef _WIN32 WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); #endif int res = getaddrinfo(hostname, service, &hints, &result); printf("res = %d\n", res); for (rp = result; rp != NULL; rp = rp->ai_next) { sockaddr_show(rp->ai_addr); } printf("\n"); } int main(void) { printf("family: AF_UNSPEC, flags: AI_PASSIVE\n"); show_addr_info(AF_UNSPEC, AI_PASSIVE); printf("family: AF_INET, flags: AI_PASSIVE\n"); show_addr_info(AF_INET, AI_PASSIVE); printf("family: AF_INET6, flags: AI_PASSIVE\n"); show_addr_info(AF_INET6, AI_PASSIVE); printf("family: AF_INET6, flags: AI_PASSIVE | AI_V4MAPPED | AI_ALL\n"); show_addr_info(AF_INET6, AI_PASSIVE | AI_V4MAPPED | AI_ALL); return EXIT_SUCCESS; }