/* * Find suitable IPv6/IPv4 address to bind to based on a numeric port number */ #include #include #include #include #include #include #include #include #include /* int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); void freeaddrinfo(struct addrinfo *res); struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; }; */ int main(int ac, char *av[]) { struct addrinfo *info, *pinfo; struct addrinfo hint; memset(&hint, 0, sizeof hint); if (ac < 2) printf("Usage: %s \n", av[0]), exit(0); hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; int rc = getaddrinfo(NULL, av[1], &hint, &info); if (rc != 0) gai_strerror(rc), exit(-1); char printed_addr[1024]; for (pinfo = info; pinfo; pinfo = pinfo->ai_next) { if (pinfo->ai_protocol != IPPROTO_TCP) continue; switch (pinfo->ai_family) { case AF_INET: { struct sockaddr_in *sa; sa = (struct sockaddr_in *)pinfo->ai_addr; inet_ntop(pinfo->ai_family, (const void *)&sa->sin_addr, printed_addr, sizeof printed_addr); printf("AF_INET: %s\n", printed_addr); break; } case AF_INET6: { struct sockaddr_in6 *sa; sa = (struct sockaddr_in6 *)pinfo->ai_addr; inet_ntop(pinfo->ai_family, (const void *)&sa->sin6_addr, printed_addr, sizeof printed_addr); printf("AF_INET6: %s\n", printed_addr); break; } default: printf("Unknown address family\n"); break; } } freeaddrinfo(info); return 0; }