resolve.c (1820B)
1#include "resolve.h" 2 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6#include "error_handling.h" 7 8#ifdef WIN32 9 #include <ws2tcpip.h> 10#else // !WIN32 11 #include <arpa/inet.h> // inet_pton (parsing ipv4 and ipv6 notation) 12 13 #include <sys/types.h> 14 #include <sys/socket.h> 15 #include <netdb.h> 16#endif 17 18int resolveName(struct sockaddr* addr, socklen_t* addr_len, const char* hostname, int family) 19{ 20 int result; 21 struct addrinfo* res = NULL; 22 23 // zero addr 24 memset(addr, 0, *addr_len); 25 26 // try to parse ipv4 27 if(family == AF_UNSPEC || family == AF_INET) { 28 result = inet_pton(AF_INET, hostname, &((struct sockaddr_in*) addr)->sin_addr); 29 if(result == 1) 30 { 31 addr->sa_family = AF_INET; 32 *addr_len = sizeof(struct sockaddr_in); 33 return 1; 34 } 35 } 36 37 // try to parse ipv6 38 if(family == AF_UNSPEC || family == AF_INET6) { 39 result = inet_pton(AF_INET6, hostname, &((struct sockaddr_in6*) addr)->sin6_addr); 40 if(result == 1) 41 { 42 addr->sa_family = AF_INET6; 43 *addr_len = sizeof(struct sockaddr_in6); 44 return 1; 45 } 46 } 47 48 // try to resolve DNS 49 struct addrinfo hints; 50 memset(&hints, 0, sizeof(struct addrinfo)); 51 hints.ai_family = family; // AF_UNSPEC, AF_INET, AF_INET6 52 hints.ai_socktype = 0; // 0 = any, SOCK_STREAM, SOCK_DGRAM 53 hints.ai_protocol = 0; // 0 = any 54 hints.ai_flags = 0; // no flags 55 56 result = getaddrinfo(hostname, NULL, &hints, &res); 57 if( result != 0) 58 { 59 ERRM( "Error: cannot resolve hostname %s: %s\n", hostname, gai_strerror(result) ); 60 exit( -1 ); 61 } 62 63 if(res->ai_addrlen > *addr_len) 64 { 65 // error - this should not happen 66 ERRM( "Error addr is to short. required length: %d, available length: %d", res->ai_addrlen, *addr_len ); 67 freeaddrinfo(res); 68 exit( -1 ); 69 } 70 memcpy(addr, res->ai_addr, res->ai_addrlen); 71 *addr_len = res->ai_addrlen; 72 73 freeaddrinfo(res); 74 return 1; 75}