/* Address manipulation */

#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/socket.h>

#include "addr.h"


uint32_t
sock_addr_ip4byname(char *hostname) {
	struct hostent *host;
	uint32_t ip;

	if (! hostname[0])
		return INADDR_ANY;

	host = gethostbyname(hostname);
	if (! host)
		return 0;

	ip = ((struct in_addr *) host->h_addr)->s_addr;

	return ip;
}

addr_t *
sock_addr_del(addr_t *addr) {
	if (! addr)
		return NULL;

	if (addr->addr)
		free(addr->addr);

	free(addr);

	return NULL;
}

addr_t *
sock_addr_get(int af, struct sockaddr *saddr, int addrlen) {
	addr_t *addr = malloc(sizeof(addr_t));

	if (! addr)
		return NULL;

	addr->af = af;
	addr->addr = malloc(addrlen);
	addr->addrlen = addrlen;

	if (! addr->addr)
		return sock_addr_del(addr);

	memcpy(addr->addr, saddr, addrlen);

	return addr;
}

addr_t *
sock_addr_get4(uint32_t ip, int port) {
	struct sockaddr_in addr_in;

	memset((char *)&addr_in, 0, sizeof(addr_in));
	addr_in.sin_family = AF_INET;
	addr_in.sin_addr.s_addr = ip;
	addr_in.sin_port = htons(port);

	return sock_addr_get(AF_INET, (struct sockaddr *)&addr_in, sizeof(addr_in));
}

addr_t *
sock_addr_getbyname(char *name, int port) {
	return sock_addr_get4(sock_addr_ip4byname(name), port);
}
