cnping

Minimal Graphical Ping Tool
git clone https://git.sinitax.com/cnlohr/cnping
Log | Files | Refs | Submodules | README | LICENSE | sfeed.txt

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}