/* $Id$ */
/* 
 * Copyright (C)2003-2007 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include <pj/sock.h>
#include <pj/assert.h>
#include <pj/errno.h>
#include <pj/ip_helper.h>
#include <pj/os.h>
#include <pj/addr_resolv.h>
#include <pj/string.h>
#include <pj/compat/socket.h>


/*
 * Convert address string with numbers and dots to binary IP address.
 */ 
PJ_DEF(pj_in_addr) pj_inet_addr(const pj_str_t *cp)
{
    pj_in_addr addr;

    pj_inet_aton(cp, &addr);
    return addr;
}

/*
 * Convert address string with numbers and dots to binary IP address.
 */ 
PJ_DEF(pj_in_addr) pj_inet_addr2(const char *cp)
{
    pj_str_t str = pj_str((char*)cp);
    return pj_inet_addr(&str);
}

/*
 * Get text representation.
 */
PJ_DEF(char*) pj_inet_ntop2( int af, const void *src,
			     char *dst, int size)
{
    pj_status_t status;

    status = pj_inet_ntop(af, src, dst, size);
    return (status==PJ_SUCCESS)? dst : NULL;
}

/*
 * Set the IP address of an IP socket address from string address, 
 * with resolving the host if necessary. The string address may be in a
 * standard numbers and dots notation or may be a hostname. If hostname
 * is specified, then the function will resolve the host into the IP
 * address.
 */
PJ_DEF(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr,
					         const pj_str_t *str_addr)
{
    PJ_CHECK_STACK();

    PJ_ASSERT_RETURN(!str_addr || str_addr->slen < PJ_MAX_HOSTNAME, 
                     (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL));

    PJ_SOCKADDR_RESET_LEN(addr);
    addr->sin_family = AF_INET;
    pj_bzero(addr->sin_zero, sizeof(addr->sin_zero));

    if (str_addr && str_addr->slen) {
	addr->sin_addr = pj_inet_addr(str_addr);
	if (addr->sin_addr.s_addr == PJ_INADDR_NONE) {
    	    pj_hostent he;
	    pj_status_t rc;

	    rc = pj_gethostbyname(str_addr, &he);
	    if (rc == 0) {
		addr->sin_addr.s_addr = *(pj_uint32_t*)he.h_addr;
	    } else {
		addr->sin_addr.s_addr = PJ_INADDR_NONE;
		return rc;
	    }
	}

    } else {
	addr->sin_addr.s_addr = 0;
    }

    return PJ_SUCCESS;
}

/* Set address from a name */
PJ_DEF(pj_status_t) pj_sockaddr_set_str_addr(int af,
					     pj_sockaddr *addr,
					     const pj_str_t *str_addr)
{
    pj_status_t status;

    if (af == PJ_AF_INET) {
	return pj_sockaddr_in_set_str_addr(&addr->ipv4, str_addr);
    }

    PJ_ASSERT_RETURN(af==PJ_AF_INET6, PJ_EAFNOTSUP);

    /* IPv6 specific */

    addr->ipv6.sin6_family = PJ_AF_INET6;
    PJ_SOCKADDR_RESET_LEN(addr);

    if (str_addr && str_addr->slen) {
	status = pj_inet_pton(PJ_AF_INET6, str_addr, &addr->ipv6.sin6_addr);
	if (status != PJ_SUCCESS) {
    	    pj_addrinfo ai;
	    unsigned count = 1;

	    status = pj_getaddrinfo(PJ_AF_INET6, str_addr, &count, &ai);
	    if (status==PJ_SUCCESS) {
		pj_memcpy(&addr->ipv6.sin6_addr, &ai.ai_addr.ipv6.sin6_addr,
			  sizeof(pj_sockaddr_in6));
	    }
	}
    } else {
	status = PJ_SUCCESS;
    }

    return status;
}

/*
 * Set the IP address and port of an IP socket address.
 * The string address may be in a standard numbers and dots notation or 
 * may be a hostname. If hostname is specified, then the function will 
 * resolve the host into the IP address.
 */
PJ_DEF(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr,
				         const pj_str_t *str_addr,
					 pj_uint16_t port)
{
    PJ_ASSERT_RETURN(addr, (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL));

    PJ_SOCKADDR_RESET_LEN(addr);
    addr->sin_family = PJ_AF_INET;
    pj_bzero(addr->sin_zero, sizeof(addr->sin_zero));
    pj_sockaddr_in_set_port(addr, port);
    return pj_sockaddr_in_set_str_addr(addr, str_addr);
}

/*
 * Initialize IP socket address based on the address and port info.
 */
PJ_DEF(pj_status_t) pj_sockaddr_init(int af, 
				     pj_sockaddr *addr,
				     const pj_str_t *cp,
				     pj_uint16_t port)
{
    pj_status_t status;

    if (af == PJ_AF_INET) {
	return pj_sockaddr_in_init(&addr->ipv4, cp, port);
    }

    /* IPv6 specific */
    PJ_ASSERT_RETURN(af==PJ_AF_INET6, PJ_EAFNOTSUP);

    pj_bzero(addr, sizeof(pj_sockaddr_in6));
    addr->addr.sa_family = PJ_AF_INET6;
    
    status = pj_sockaddr_set_str_addr(af, addr, cp);
    if (status != PJ_SUCCESS)
	return status;

    addr->ipv6.sin6_port = pj_htons(port);
    return PJ_SUCCESS;
}

/*
 * Get first IP address associated with the hostname.
 */
PJ_DEF(pj_in_addr) pj_gethostaddr(void)
{
    pj_sockaddr_in addr;
    const pj_str_t *hostname = pj_gethostname();

    pj_sockaddr_in_set_str_addr(&addr, hostname);
    return addr.sin_addr;
}

/*
 * Get port number of a pj_sockaddr_in
 */
PJ_DEF(pj_uint16_t) pj_sockaddr_in_get_port(const pj_sockaddr_in *addr)
{
    return pj_ntohs(addr->sin_port);
}

/*
 * Get the address part
 */
PJ_DEF(void*) pj_sockaddr_get_addr(const pj_sockaddr_t *addr)
{
    const pj_sockaddr *a = (const pj_sockaddr*)addr;

    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||
		     a->addr.sa_family == PJ_AF_INET6, NULL);

    if (a->addr.sa_family == PJ_AF_INET6)
	return (void*) &a->ipv6.sin6_addr;
    else
	return (void*) &a->ipv4.sin_addr;
}

/*
 * Check if sockaddr contains a non-zero address
 */
PJ_DEF(pj_bool_t) pj_sockaddr_has_addr(const pj_sockaddr_t *addr)
{
    const pj_sockaddr *a = (const pj_sockaddr*)addr;

    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||
		     a->addr.sa_family == PJ_AF_INET6, PJ_EAFNOTSUP);

    if (a->addr.sa_family == PJ_AF_INET6) {
	pj_uint8_t zero[24];
	pj_bzero(zero, sizeof(zero));
	return pj_memcmp(a->ipv6.sin6_addr.s6_addr, zero, 
			 sizeof(pj_in6_addr)) != 0;
    } else
	return a->ipv4.sin_addr.s_addr != PJ_INADDR_ANY;
}

/*
 * Get port number
 */
PJ_DEF(pj_uint16_t) pj_sockaddr_get_port(const pj_sockaddr_t *addr)
{
    const pj_sockaddr *a = (const pj_sockaddr*) addr;

    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||
		     a->addr.sa_family == PJ_AF_INET6, (pj_uint16_t)0xFFFF);

    return pj_ntohs((pj_uint16_t)(a->addr.sa_family == PJ_AF_INET6 ?
				    a->ipv6.sin6_port : a->ipv4.sin_port));
}

/*
 * Get the length of the address part.
 */
PJ_DEF(unsigned) pj_sockaddr_get_addr_len(const pj_sockaddr_t *addr)
{
    const pj_sockaddr *a = (const pj_sockaddr*) addr;
    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||
		     a->addr.sa_family == PJ_AF_INET6, PJ_EAFNOTSUP);
    return a->addr.sa_family == PJ_AF_INET6 ?
	    sizeof(pj_in6_addr) : sizeof(pj_in_addr);
}

/*
 * Get socket address length.
 */
PJ_DEF(unsigned) pj_sockaddr_get_len(const pj_sockaddr_t *addr)
{
    const pj_sockaddr *a = (const pj_sockaddr*) addr;
    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||
		     a->addr.sa_family == PJ_AF_INET6, PJ_EAFNOTSUP);
    return a->addr.sa_family == PJ_AF_INET6 ?
	    sizeof(pj_sockaddr_in6) : sizeof(pj_sockaddr_in);
}

/*
 * Set port number of pj_sockaddr_in
 */
PJ_DEF(void) pj_sockaddr_in_set_port(pj_sockaddr_in *addr, 
				     pj_uint16_t hostport)
{
    addr->sin_port = pj_htons(hostport);
}

/*
 * Set port number of pj_sockaddr
 */
PJ_DEF(pj_status_t) pj_sockaddr_set_port(pj_sockaddr *addr, 
					 pj_uint16_t hostport)
{
    int af = addr->addr.sa_family;

    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EINVAL);

    if (af == PJ_AF_INET6)
	addr->ipv6.sin6_port = pj_htons(hostport);
    else
	addr->ipv4.sin_port = pj_htons(hostport);

    return PJ_SUCCESS;
}

/*
 * Get IPv4 address
 */
PJ_DEF(pj_in_addr) pj_sockaddr_in_get_addr(const pj_sockaddr_in *addr)
{
    pj_in_addr in_addr;
    in_addr.s_addr = pj_ntohl(addr->sin_addr.s_addr);
    return in_addr;
}

/*
 * Set IPv4 address
 */
PJ_DEF(void) pj_sockaddr_in_set_addr(pj_sockaddr_in *addr,
				     pj_uint32_t hostaddr)
{
    addr->sin_addr.s_addr = pj_htonl(hostaddr);
}

/* Resolve the IP address of local machine */
PJ_DEF(pj_status_t) pj_gethostip(int af, pj_sockaddr *addr)
{
    unsigned count;
    pj_addrinfo ai;
    pj_status_t status;


#ifdef _MSC_VER
    /* Get rid of "uninitialized he variable" with MS compilers */
    pj_bzero(&ai, sizeof(ai));
#endif

    addr->addr.sa_family = (pj_uint16_t)af;
    PJ_SOCKADDR_RESET_LEN(addr);

    /* Try with resolving local hostname first */
    count = 1;
    status = pj_getaddrinfo(af, pj_gethostname(), &count, &ai);
    if (status == PJ_SUCCESS) {
	pj_memcpy(pj_sockaddr_get_addr(addr),
		  pj_sockaddr_get_addr(&ai.ai_addr),
		  pj_sockaddr_get_addr_len(&ai.ai_addr));
    }


    /* If we end up with 127.x.x.x, resolve the IP by getting the default
     * interface to connect to some public host.
     */
    if (status != PJ_SUCCESS || !pj_sockaddr_has_addr(addr) ||
	(af==PJ_AF_INET && (pj_ntohl(addr->ipv4.sin_addr.s_addr) >> 24)==127))
    {
	status = pj_getdefaultipinterface(af, addr);
    }

    /* If failed, get the first available interface */
    if (status != PJ_SUCCESS) {
	pj_sockaddr itf[1];
	unsigned count = PJ_ARRAY_SIZE(itf);

	status = pj_enum_ip_interface(af, &count, itf);
	if (status == PJ_SUCCESS) {
	    itf[0].addr.sa_family = (pj_uint16_t)af;
	    pj_memcpy(pj_sockaddr_get_addr(addr),
		      pj_sockaddr_get_addr(&itf[0]),
		      pj_sockaddr_get_addr_len(&itf[0]));
	}
    }

    /* If else fails, returns loopback interface as the last resort */
    if (status != PJ_SUCCESS) {
	if (af==PJ_AF_INET) {
	    addr->ipv4.sin_addr.s_addr = pj_htonl (0x7f000001);
	} else {
	    pj_in6_addr *s6_addr;

	    s6_addr = (pj_in6_addr*) pj_sockaddr_get_addr(addr);
	    pj_bzero(s6_addr, sizeof(pj_in6_addr));
	    s6_addr->s6_addr[15] = 1;
	}
	status = PJ_SUCCESS;
    }

    return status;
}

/* Get the default IP interface */
PJ_DEF(pj_status_t) pj_getdefaultipinterface(int af, pj_sockaddr *addr)
{
    pj_sock_t fd;
    pj_str_t cp;
    pj_sockaddr a;
    int len;
    pj_uint8_t zero[64];
    pj_status_t status;

    addr->addr.sa_family = (pj_uint16_t)af;

    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &fd);
    if (status != PJ_SUCCESS) {
	return status;
    }

    if (af == PJ_AF_INET) {
	cp = pj_str("1.1.1.1");
    } else {
	cp = pj_str("1::1");
    }
    status = pj_sockaddr_init(af, &a, &cp, 53);
    if (status != PJ_SUCCESS) {
	pj_sock_close(fd);
	return status;
    }

    status = pj_sock_connect(fd, &a, sizeof(a));
    if (status != PJ_SUCCESS) {
	pj_sock_close(fd);
	return status;
    }

    len = sizeof(a);
    status = pj_sock_getsockname(fd, &a, &len);
    if (status != PJ_SUCCESS) {
	pj_sock_close(fd);
	return status;
    }

    pj_sock_close(fd);

    /* Check that the address returned is not zero */
    pj_bzero(zero, sizeof(zero));
    if (pj_memcmp(pj_sockaddr_get_addr(&a), zero,
		  pj_sockaddr_get_addr_len(&a))==0)
    {
	return PJ_ENOTFOUND;
    }

    pj_memcpy(pj_sockaddr_get_addr(addr),
	      pj_sockaddr_get_addr(&a),
	      pj_sockaddr_get_addr_len(&a));

    /* Success */
    return PJ_SUCCESS;
}


/* Only need to implement these in DLL build */
#if defined(PJ_DLL)

PJ_DEF(pj_uint16_t) pj_AF_UNSPEC(void)
{
    return PJ_AF_UNSPEC;
}

PJ_DEF(pj_uint16_t) pj_AF_UNIX(void)
{
    return PJ_AF_UNIX;
}

PJ_DEF(pj_uint16_t) pj_AF_INET(void)
{
    return PJ_AF_INET;
}

PJ_DEF(pj_uint16_t) pj_AF_INET6(void)
{
    return PJ_AF_INET6;
}

PJ_DEF(pj_uint16_t) pj_AF_PACKET(void)
{
    return PJ_AF_PACKET;
}

PJ_DEF(pj_uint16_t) pj_AF_IRDA(void)
{
    return PJ_AF_IRDA;
}

PJ_DEF(int) pj_SOCK_STREAM(void)
{
    return PJ_SOCK_STREAM;
}

PJ_DEF(int) pj_SOCK_DGRAM(void)
{
    return PJ_SOCK_DGRAM;
}

PJ_DEF(int) pj_SOCK_RAW(void)
{
    return PJ_SOCK_RAW;
}

PJ_DEF(int) pj_SOCK_RDM(void)
{
    return PJ_SOCK_RDM;
}

PJ_DEF(pj_uint16_t) pj_SOL_SOCKET(void)
{
    return PJ_SOL_SOCKET;
}

PJ_DEF(pj_uint16_t) pj_SOL_IP(void)
{
    return PJ_SOL_IP;
}

PJ_DEF(pj_uint16_t) pj_SOL_TCP(void)
{
    return PJ_SOL_TCP;
}

PJ_DEF(pj_uint16_t) pj_SOL_UDP(void)
{
    return PJ_SOL_UDP;
}

PJ_DEF(pj_uint16_t) pj_SOL_IPV6(void)
{
    return PJ_SOL_IPV6;
}

PJ_DEF(int) pj_IP_TOS(void)
{
    return PJ_IP_TOS;
}

PJ_DEF(int) pj_IPTOS_LOWDELAY(void)
{
    return PJ_IPTOS_LOWDELAY;
}

PJ_DEF(int) pj_IPTOS_THROUGHPUT(void)
{
    return PJ_IPTOS_THROUGHPUT;
}

PJ_DEF(int) pj_IPTOS_RELIABILITY(void)
{
    return PJ_IPTOS_RELIABILITY;
}

PJ_DEF(int) pj_IPTOS_MINCOST(void)
{
    return PJ_IPTOS_MINCOST;
}

PJ_DEF(pj_uint16_t) pj_SO_TYPE(void)
{
    return PJ_SO_TYPE;
}

PJ_DEF(pj_uint16_t) pj_SO_RCVBUF(void)
{
    return PJ_SO_RCVBUF;
}

PJ_DEF(pj_uint16_t) pj_SO_SNDBUF(void)
{
    return PJ_SO_SNDBUF;
}

PJ_DEF(int) pj_MSG_OOB(void)
{
    return PJ_MSG_OOB;
}

PJ_DEF(int) pj_MSG_PEEK(void)
{
    return PJ_MSG_PEEK;
}

PJ_DEF(int) pj_MSG_DONTROUTE(void)
{
    return PJ_MSG_DONTROUTE;
}

#endif	/* PJ_DLL */

