/*
 * Copyright (c) 2002 - 2003
 * NetGroup, Politecnico di Torino (Italy)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Politecnico di Torino nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/*
 * \file sockutils.c
 *
 * The goal of this file is to provide a common set of primitives for socket
 * manipulation.
 *
 * Although the socket interface defined in the RFC 2553 (and its updates)
 * is excellent, there are still differences between the behavior of those
 * routines on UN*X and Windows, and between UN*Xes.
 *
 * These calls provide an interface similar to the socket interface, but
 * that hides the differences between operating systems.  It does not
 * attempt to significantly improve on the socket interface in other
 * ways.
 */

#include "ftmacros.h"

#include <string.h>
#include <errno.h>	/* for the errno variable */
#include <stdio.h>	/* for the stderr file */
#include <stdlib.h>	/* for malloc() and free() */
#include <limits.h>	/* for INT_MAX */

#include "pcap-int.h"

#include "sockutils.h"
#include "portability.h"

#ifdef _WIN32
  /*
   * Winsock initialization.
   *
   * Ask for Winsock 2.2.
   */
  #define WINSOCK_MAJOR_VERSION 2
  #define WINSOCK_MINOR_VERSION 2

  static int sockcount = 0;	/*!< Variable that allows calling the WSAStartup() only one time */
#endif

/* Some minor differences between UNIX and Win32 */
#ifdef _WIN32
  #define SHUT_WR SD_SEND	/* The control code for shutdown() is different in Win32 */
#endif

/* Size of the buffer that has to keep error messages */
#define SOCK_ERRBUF_SIZE 1024

/* Constants; used in order to keep strings here */
#define SOCKET_NO_NAME_AVAILABLE "No name available"
#define SOCKET_NO_PORT_AVAILABLE "No port available"
#define SOCKET_NAME_NULL_DAD "Null address (possibly DAD Phase)"

/*
 * On UN*X, send() and recv() return ssize_t.
 *
 * On Windows, send() and recv() return an int.
 *
 *   Wth MSVC, there *is* no ssize_t.
 *
 *   With MinGW, there is an ssize_t type; it is either an int (32 bit)
 *   or a long long (64 bit).
 *
 * So, on Windows, if we don't have ssize_t defined, define it as an
 * int, so we can use it, on all platforms, as the type of variables
 * that hold the return values from send() and recv().
 */
#if defined(_WIN32) && !defined(_SSIZE_T_DEFINED)
typedef int ssize_t;
#endif

/****************************************************
 *                                                  *
 * Locally defined functions                        *
 *                                                  *
 ****************************************************/

static int sock_ismcastaddr(const struct sockaddr *saddr);

/****************************************************
 *                                                  *
 * Function bodies                                  *
 *                                                  *
 ****************************************************/

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
const uint8_t *fuzzBuffer;
size_t fuzzSize;
size_t fuzzPos;

void sock_initfuzz(const uint8_t *Data, size_t Size) {
	fuzzPos = 0;
	fuzzSize = Size;
	fuzzBuffer = Data;
}

static int fuzz_recv(char *bufp, int remaining) {
	if (remaining > fuzzSize - fuzzPos) {
		remaining = fuzzSize - fuzzPos;
	}
	if (fuzzPos < fuzzSize) {
		memcpy(bufp, fuzzBuffer + fuzzPos, remaining);
	}
	fuzzPos += remaining;
	return remaining;
}
#endif

/*
 * Format an error message given an errno value (UN*X) or a Winsock error
 * (Windows).
 */
void sock_fmterror(const char *caller, int errcode, char *errbuf, int errbuflen)
{
	if (errbuf == NULL)
		return;

#ifdef _WIN32
	pcap_fmt_errmsg_for_win32_err(errbuf, errbuflen, errcode,
	    "%s", caller);
#else
	pcap_fmt_errmsg_for_errno(errbuf, errbuflen, errcode,
	    "%s", caller);
#endif
}

/*
 * \brief It retrieves the error message after an error occurred in the socket interface.
 *
 * This function is defined because of the different way errors are returned in UNIX
 * and Win32. This function provides a consistent way to retrieve the error message
 * (after a socket error occurred) on all the platforms.
 *
 * \param caller: a pointer to a user-allocated string which contains a message that has
 * to be printed *before* the true error message. It could be, for example, 'this error
 * comes from the recv() call at line 31'.
 *
 * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
 * error message. This buffer has to be at least 'errbuflen' in length.
 * It can be NULL; in this case the error cannot be printed.
 *
 * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
 * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
 *
 * \return No return values. The error message is returned in the 'string' parameter.
 */
void sock_geterror(const char *caller, char *errbuf, int errbuflen)
{
#ifdef _WIN32
	sock_fmterror(caller, GetLastError(), errbuf, errbuflen);
#else
	sock_fmterror(caller, errno, errbuf, errbuflen);
#endif
}

/*
 * \brief This function initializes the socket mechanism if it hasn't
 * already been initialized or reinitializes it after it has been
 * cleaned up.
 *
 * On UN*Xes, it doesn't need to do anything; on Windows, it needs to
 * initialize Winsock.
 *
 * \param errbuf: a pointer to an user-allocated buffer that will contain
 * the complete error message. This buffer has to be at least 'errbuflen'
 * in length. It can be NULL; in this case no error message is supplied.
 *
 * \param errbuflen: length of the buffer that will contains the error.
 * The error message cannot be larger than 'errbuflen - 1' because the
 * last char is reserved for the string terminator.
 *
 * \return '0' if everything is fine, '-1' if some errors occurred. The
 * error message is returned in the buffer pointed to by 'errbuf' variable.
 */
#ifdef _WIN32
int sock_init(char *errbuf, int errbuflen)
{
	if (sockcount == 0)
	{
		WSADATA wsaData;			/* helper variable needed to initialize Winsock */

		if (WSAStartup(MAKEWORD(WINSOCK_MAJOR_VERSION,
		    WINSOCK_MINOR_VERSION), &wsaData) != 0)
		{
			if (errbuf)
				snprintf(errbuf, errbuflen, "Failed to initialize Winsock\n");

			WSACleanup();

			return -1;
		}
	}

	sockcount++;
	return 0;
}
#else
int sock_init(char *errbuf _U_, int errbuflen _U_)
{
	/*
	 * Nothing to do on UN*Xes.
	 */
	return 0;
}
#endif

/*
 * \brief This function cleans up the socket mechanism if we have no
 * sockets left open.
 *
 * On UN*Xes, it doesn't need to do anything; on Windows, it needs
 * to clean up Winsock.
 *
 * \return No error values.
 */
void sock_cleanup(void)
{
#ifdef _WIN32
	sockcount--;

	if (sockcount == 0)
		WSACleanup();
#endif
}

/*
 * \brief It checks if the sockaddr variable contains a multicast address.
 *
 * \return '0' if the address is multicast, '-1' if it is not.
 */
static int sock_ismcastaddr(const struct sockaddr *saddr)
{
	if (saddr->sa_family == PF_INET)
	{
		struct sockaddr_in *saddr4 = (struct sockaddr_in *) saddr;
		if (IN_MULTICAST(ntohl(saddr4->sin_addr.s_addr))) return 0;
		else return -1;
	}
	else
	{
		struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) saddr;
		if (IN6_IS_ADDR_MULTICAST(&saddr6->sin6_addr)) return 0;
		else return -1;
	}
}

/*
 * \brief It initializes a network connection both from the client and the server side.
 *
 * In case of a client socket, this function calls socket() and connect().
 * In the meanwhile, it checks for any socket error.
 * If an error occurs, it writes the error message into 'errbuf'.
 *
 * In case of a server socket, the function calls socket(), bind() and listen().
 *
 * This function is usually preceded by the sock_initaddress().
 *
 * \param addrinfo: pointer to an addrinfo variable which will be used to
 * open the socket and such. This variable is the one returned by the previous call to
 * sock_initaddress().
 *
 * \param server: '1' if this is a server socket, '0' otherwise.
 *
 * \param nconn: number of the connections that are allowed to wait into the listen() call.
 * This value has no meanings in case of a client socket.
 *
 * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
 * error message. This buffer has to be at least 'errbuflen' in length.
 * It can be NULL; in this case the error cannot be printed.
 *
 * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
 * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
 *
 * \return the socket that has been opened (that has to be used in the following sockets calls)
 * if everything is fine, INVALID_SOCKET if some errors occurred. The error message is returned
 * in the 'errbuf' variable.
 */
SOCKET sock_open(struct addrinfo *addrinfo, int server, int nconn, char *errbuf, int errbuflen)
{
	SOCKET sock;
#if defined(SO_NOSIGPIPE) || defined(IPV6_V6ONLY) || defined(IPV6_BINDV6ONLY)
	int on = 1;
#endif

	sock = socket(addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol);
	if (sock == INVALID_SOCKET)
	{
		sock_geterror("socket()", errbuf, errbuflen);
		return INVALID_SOCKET;
	}

	/*
	 * Disable SIGPIPE, if we have SO_NOSIGPIPE.  We don't want to
	 * have to deal with signals if the peer closes the connection,
	 * especially in client programs, which may not even be aware that
	 * they're sending to sockets.
	 */
#ifdef SO_NOSIGPIPE
	if (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (char *)&on,
	    sizeof (int)) == -1)
	{
		sock_geterror("setsockopt(SO_NOSIGPIPE)", errbuf, errbuflen);
		closesocket(sock);
		return INVALID_SOCKET;
	}
#endif

	/* This is a server socket */
	if (server)
	{
		/*
		 * Allow a new server to bind the socket after the old one
		 * exited, even if lingering sockets are still present.
		 *
		 * Don't treat an error as a failure.
		 */
		int optval = 1;
		(void)setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
		    (char *)&optval, sizeof (optval));

#if defined(IPV6_V6ONLY) || defined(IPV6_BINDV6ONLY)
		/*
		 * Force the use of IPv6-only addresses.
		 *
		 * RFC 3493 indicates that you can support IPv4 on an
		 * IPv6 socket:
		 *
		 *    https://tools.ietf.org/html/rfc3493#section-3.7
		 *
		 * and that this is the default behavior.  This means
		 * that if we first create an IPv6 socket bound to the
		 * "any" address, it is, in effect, also bound to the
		 * IPv4 "any" address, so when we create an IPv4 socket
		 * and try to bind it to the IPv4 "any" address, it gets
		 * EADDRINUSE.
		 *
		 * Not all network stacks support IPv4 on IPv6 sockets;
		 * pre-NT 6 Windows stacks don't support it, and the
		 * OpenBSD stack doesn't support it for security reasons
		 * (see the OpenBSD inet6(4) man page).  Therefore, we
		 * don't want to rely on this behavior.
		 *
		 * So we try to disable it, using either the IPV6_V6ONLY
		 * option from RFC 3493:
		 *
		 *    https://tools.ietf.org/html/rfc3493#section-5.3
		 *
		 * or the IPV6_BINDV6ONLY option from older UN*Xes.
		 */
#ifndef IPV6_V6ONLY
  /* For older systems */
  #define IPV6_V6ONLY IPV6_BINDV6ONLY
#endif /* IPV6_V6ONLY */
		if (addrinfo->ai_family == PF_INET6)
		{
			if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
			    (char *)&on, sizeof (int)) == -1)
			{
				if (errbuf)
					snprintf(errbuf, errbuflen, "setsockopt(IPV6_V6ONLY)");
				closesocket(sock);
				return INVALID_SOCKET;
			}
		}
#endif /* defined(IPV6_V6ONLY) || defined(IPV6_BINDV6ONLY) */

		/* WARNING: if the address is a mcast one, I should place the proper Win32 code here */
		if (bind(sock, addrinfo->ai_addr, (int) addrinfo->ai_addrlen) != 0)
		{
			sock_geterror("bind()", errbuf, errbuflen);
			closesocket(sock);
			return INVALID_SOCKET;
		}

		if (addrinfo->ai_socktype == SOCK_STREAM)
			if (listen(sock, nconn) == -1)
			{
				sock_geterror("listen()", errbuf, errbuflen);
				closesocket(sock);
				return INVALID_SOCKET;
			}

		/* server side ended */
		return sock;
	}
	else	/* we're the client */
	{
		struct addrinfo *tempaddrinfo;
		char *errbufptr;
		size_t bufspaceleft;

		tempaddrinfo = addrinfo;
		errbufptr = errbuf;
		bufspaceleft = errbuflen;
		*errbufptr = 0;

		/*
		 * We have to loop though all the addinfo returned.
		 * For instance, we can have both IPv6 and IPv4 addresses, but the service we're trying
		 * to connect to is unavailable in IPv6, so we have to try in IPv4 as well
		 */
		while (tempaddrinfo)
		{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
			break;
#endif
			if (connect(sock, tempaddrinfo->ai_addr, (int) tempaddrinfo->ai_addrlen) == -1)
			{
				size_t msglen;
				char TmpBuffer[100];
				char SocketErrorMessage[SOCK_ERRBUF_SIZE];

				/*
				 * We have to retrieve the error message before any other socket call completes, otherwise
				 * the error message is lost
				 */
				sock_geterror("Connect to socket failed",
				    SocketErrorMessage, sizeof(SocketErrorMessage));

				/* Returns the numeric address of the host that triggered the error */
				sock_getascii_addrport((struct sockaddr_storage *) tempaddrinfo->ai_addr, TmpBuffer, sizeof(TmpBuffer), NULL, 0, NI_NUMERICHOST, TmpBuffer, sizeof(TmpBuffer));

				snprintf(errbufptr, bufspaceleft,
				    "Is the server properly installed on %s?  %s", TmpBuffer, SocketErrorMessage);

				/* In case more then one 'connect' fails, we manage to keep all the error messages */
				msglen = strlen(errbufptr);

				errbufptr[msglen] = ' ';
				errbufptr[msglen + 1] = 0;

				bufspaceleft = bufspaceleft - (msglen + 1);
				errbufptr += (msglen + 1);

				tempaddrinfo = tempaddrinfo->ai_next;
			}
			else
				break;
		}

		/*
		 * Check how we exit from the previous loop
		 * If tempaddrinfo is equal to NULL, it means that all the connect() failed.
		 */
		if (tempaddrinfo == NULL)
		{
			closesocket(sock);
			return INVALID_SOCKET;
		}
		else
			return sock;
	}
}

/*
 * \brief Closes the present (TCP and UDP) socket connection.
 *
 * This function sends a shutdown() on the socket in order to disable send() calls
 * (while recv() ones are still allowed). Then, it closes the socket.
 *
 * \param sock: the socket identifier of the connection that has to be closed.
 *
 * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
 * error message. This buffer has to be at least 'errbuflen' in length.
 * It can be NULL; in this case the error cannot be printed.
 *
 * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
 * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
 *
 * \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned
 * in the 'errbuf' variable.
 */
int sock_close(SOCKET sock, char *errbuf, int errbuflen)
{
	/*
	 * SHUT_WR: subsequent calls to the send function are disallowed.
	 * For TCP sockets, a FIN will be sent after all data is sent and
	 * acknowledged by the Server.
	 */
	if (shutdown(sock, SHUT_WR))
	{
		sock_geterror("shutdown()", errbuf, errbuflen);
		/* close the socket anyway */
		closesocket(sock);
		return -1;
	}

	closesocket(sock);
	return 0;
}

/*
 * gai_errstring() has some problems:
 *
 * 1) on Windows, Microsoft explicitly says it's not thread-safe;
 * 2) on UN*X, the Single UNIX Specification doesn't say it *is*
 *    thread-safe, so an implementation might use a static buffer
 *    for unknown error codes;
 * 3) the error message for the most likely error, EAI_NONAME, is
 *    truly horrible on several platforms ("nodename nor servname
 *    provided, or not known"?  It's typically going to be "not
 *    known", not "oopsie, I passed null pointers for the host name
 *    and service name", not to mention they forgot the "neither");
 *
 * so we roll our own.
 */
static void
get_gai_errstring(char *errbuf, int errbuflen, const char *prefix, int err,
    const char *hostname, const char *portname)
{
	char hostport[PCAP_ERRBUF_SIZE];

	if (hostname != NULL && portname != NULL)
		snprintf(hostport, PCAP_ERRBUF_SIZE, "%s:%s",
		    hostname, portname);
	else if (hostname != NULL)
		snprintf(hostport, PCAP_ERRBUF_SIZE, "%s",
		    hostname);
	else if (portname != NULL)
		snprintf(hostport, PCAP_ERRBUF_SIZE, ":%s",
		    portname);
	else
		snprintf(hostport, PCAP_ERRBUF_SIZE, "<no host or port!>");
	switch (err)
	{
#ifdef EAI_ADDRFAMILY
		case EAI_ADDRFAMILY:
			snprintf(errbuf, errbuflen,
			    "%sAddress family for %s not supported",
			    prefix, hostport);
			break;
#endif

		case EAI_AGAIN:
			snprintf(errbuf, errbuflen,
			    "%s%s could not be resolved at this time",
			    prefix, hostport);
			break;

		case EAI_BADFLAGS:
			snprintf(errbuf, errbuflen,
			    "%sThe ai_flags parameter for looking up %s had an invalid value",
			    prefix, hostport);
			break;

		case EAI_FAIL:
			snprintf(errbuf, errbuflen,
			    "%sA non-recoverable error occurred when attempting to resolve %s",
			    prefix, hostport);
			break;

		case EAI_FAMILY:
			snprintf(errbuf, errbuflen,
			    "%sThe address family for looking up %s was not recognized",
			    prefix, hostport);
			break;

		case EAI_MEMORY:
			snprintf(errbuf, errbuflen,
			    "%sOut of memory trying to allocate storage when looking up %s",
			    prefix, hostport);
			break;

		/*
		 * RFC 2553 had both EAI_NODATA and EAI_NONAME.
		 *
		 * RFC 3493 has only EAI_NONAME.
		 *
		 * Some implementations define EAI_NODATA and EAI_NONAME
		 * to the same value, others don't.  If EAI_NODATA is
		 * defined and isn't the same as EAI_NONAME, we handle
		 * EAI_NODATA.
		 */
#if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME
		case EAI_NODATA:
			snprintf(errbuf, errbuflen,
			    "%sNo address associated with %s",
			    prefix, hostport);
			break;
#endif

		case EAI_NONAME:
			snprintf(errbuf, errbuflen,
			    "%sThe host name %s couldn't be resolved",
			    prefix, hostport);
			break;

		case EAI_SERVICE:
			snprintf(errbuf, errbuflen,
			    "%sThe service value specified when looking up %s as not recognized for the socket type",
			    prefix, hostport);
			break;

		case EAI_SOCKTYPE:
			snprintf(errbuf, errbuflen,
			    "%sThe socket type specified when looking up %s as not recognized",
			    prefix, hostport);
			break;

#ifdef EAI_SYSTEM
		case EAI_SYSTEM:
			/*
			 * Assumed to be UN*X.
			 */
			pcap_fmt_errmsg_for_errno(errbuf, errbuflen, errno,
			    "%sAn error occurred when looking up %s",
			    prefix, hostport);
			break;
#endif

#ifdef EAI_BADHINTS
		case EAI_BADHINTS:
			snprintf(errbuf, errbuflen,
			    "%sInvalid value for hints when looking up %s",
			    prefix, hostport);
			break;
#endif

#ifdef EAI_PROTOCOL
		case EAI_PROTOCOL:
			snprintf(errbuf, errbuflen,
			    "%sResolved protocol when looking up %s is unknown",
			    prefix, hostport);
			break;
#endif

#ifdef EAI_OVERFLOW
		case EAI_OVERFLOW:
			snprintf(errbuf, errbuflen,
			    "%sArgument buffer overflow when looking up %s",
			    prefix, hostport);
			break;
#endif

		default:
			snprintf(errbuf, errbuflen,
			    "%sgetaddrinfo() error %d when looking up %s",
			    prefix, err, hostport);
			break;
	}
}

/*
 * \brief Checks that the address, port and flags given are valids and it returns an 'addrinfo' structure.
 *
 * This function basically calls the getaddrinfo() calls, and it performs a set of sanity checks
 * to control that everything is fine (e.g. a TCP socket cannot have a mcast address, and such).
 * If an error occurs, it writes the error message into 'errbuf'.
 *
 * \param host: a pointer to a string identifying the host. It can be
 * a host name, a numeric literal address, or NULL or "" (useful
 * in case of a server socket which has to bind to all addresses).
 *
 * \param port: a pointer to a user-allocated buffer containing the network port to use.
 *
 * \param hints: an addrinfo variable (passed by reference) containing the flags needed to create the
 * addrinfo structure appropriately.
 *
 * \param addrinfo: it represents the true returning value. This is a pointer to an addrinfo variable
 * (passed by reference), which will be allocated by this function and returned back to the caller.
 * This variable will be used in the next sockets calls.
 *
 * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
 * error message. This buffer has to be at least 'errbuflen' in length.
 * It can be NULL; in this case the error cannot be printed.
 *
 * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
 * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
 *
 * \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned
 * in the 'errbuf' variable. The addrinfo variable that has to be used in the following sockets calls is
 * returned into the addrinfo parameter.
 *
 * \warning The 'addrinfo' variable has to be deleted by the programmer by calling freeaddrinfo() when
 * it is no longer needed.
 *
 * \warning This function requires the 'hints' variable as parameter. The semantic of this variable is the same
 * of the one of the corresponding variable used into the standard getaddrinfo() socket function. We suggest
 * the programmer to look at that function in order to set the 'hints' variable appropriately.
 */
int sock_initaddress(const char *host, const char *port,
    struct addrinfo *hints, struct addrinfo **addrinfo, char *errbuf, int errbuflen)
{
	int retval;

	retval = getaddrinfo(host, port, hints, addrinfo);
	if (retval != 0)
	{
		if (errbuf)
		{
			get_gai_errstring(errbuf, errbuflen, "", retval,
			    host, port);
		}
		return -1;
	}
	/*
	 * \warning SOCKET: I should check all the accept() in order to bind to all addresses in case
	 * addrinfo has more han one pointers
	 */

	/*
	 * This software only supports PF_INET and PF_INET6.
	 *
	 * XXX - should we just check that at least *one* address is
	 * either PF_INET or PF_INET6, and, when using the list,
	 * ignore all addresses that are neither?  (What, no IPX
	 * support? :-))
	 */
	if (((*addrinfo)->ai_family != PF_INET) &&
	    ((*addrinfo)->ai_family != PF_INET6))
	{
		if (errbuf)
			snprintf(errbuf, errbuflen, "getaddrinfo(): socket type not supported");
		freeaddrinfo(*addrinfo);
		*addrinfo = NULL;
		return -1;
	}

	/*
	 * You can't do multicast (or broadcast) TCP.
	 */
	if (((*addrinfo)->ai_socktype == SOCK_STREAM) &&
	    (sock_ismcastaddr((*addrinfo)->ai_addr) == 0))
	{
		if (errbuf)
			snprintf(errbuf, errbuflen, "getaddrinfo(): multicast addresses are not valid when using TCP streams");
		freeaddrinfo(*addrinfo);
		*addrinfo = NULL;
		return -1;
	}

	return 0;
}

/*
 * \brief It sends the amount of data contained into 'buffer' on the given socket.
 *
 * This function basically calls the send() socket function and it checks that all
 * the data specified in 'buffer' (of size 'size') will be sent. If an error occurs,
 * it writes the error message into 'errbuf'.
 * In case the socket buffer does not have enough space, it loops until all data
 * has been sent.
 *
 * \param socket: the connected socket currently opened.
 *
 * \param buffer: a char pointer to a user-allocated buffer in which data is contained.
 *
 * \param size: number of bytes that have to be sent.
 *
 * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
 * error message. This buffer has to be at least 'errbuflen' in length.
 * It can be NULL; in this case the error cannot be printed.
 *
 * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
 * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
 *
 * \return '0' if everything is fine, '-1' if an error other than
 * "connection reset" or "peer has closed the receive side" occurred,
 * '-2' if we got one of those errors.
 * For errors, an error message is returned in the 'errbuf' variable.
 */
int sock_send(SOCKET sock, SSL *ssl _U_NOSSL_, const char *buffer, size_t size,
    char *errbuf, int errbuflen)
{
	int remaining;
	ssize_t nsent;

	if (size > INT_MAX)
	{
		if (errbuf)
		{
			snprintf(errbuf, errbuflen,
			    "Can't send more than %u bytes with sock_send",
			    INT_MAX);
		}
		return -1;
	}
	remaining = (int)size;

	do {
#ifdef HAVE_OPENSSL
		if (ssl) return ssl_send(ssl, buffer, remaining, errbuf, errbuflen);
#endif

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
		nsent = remaining;
#else
#ifdef MSG_NOSIGNAL
		/*
		 * Send with MSG_NOSIGNAL, so that we don't get SIGPIPE
		 * on errors on stream-oriented sockets when the other
		 * end breaks the connection.
		 * The EPIPE error is still returned.
		 */
		nsent = send(sock, buffer, remaining, MSG_NOSIGNAL);
#else
		nsent = send(sock, buffer, remaining, 0);
#endif
#endif //FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION

		if (nsent == -1)
		{
			/*
			 * If the client closed the connection out from
			 * under us, there's no need to log that as an
			 * error.
			 */
			int errcode;

#ifdef _WIN32
			errcode = GetLastError();
			if (errcode == WSAECONNRESET ||
			    errcode == WSAECONNABORTED)
			{
				/*
				 * WSAECONNABORTED appears to be the error
				 * returned in Winsock when you try to send
				 * on a connection where the peer has closed
				 * the receive side.
				 */
				return -2;
			}
			sock_fmterror("send()", errcode, errbuf, errbuflen);
#else
			errcode = errno;
			if (errcode == ECONNRESET || errcode == EPIPE)
			{
				/*
				 * EPIPE is what's returned on UN*X when
				 * you try to send on a connection when
				 * the peer has closed the receive side.
				 */
				return -2;
			}
			sock_fmterror("send()", errcode, errbuf, errbuflen);
#endif
			return -1;
		}

		remaining -= nsent;
		buffer += nsent;
	} while (remaining != 0);

	return 0;
}

/*
 * \brief It copies the amount of data contained into 'buffer' into 'tempbuf'.
 * and it checks for buffer overflows.
 *
 * This function basically copies 'size' bytes of data contained into 'buffer'
 * into 'tempbuf', starting at offset 'offset'. Before that, it checks that the
 * resulting buffer will not be larger	than 'totsize'. Finally, it updates
 * the 'offset' variable in order to point to the first empty location of the buffer.
 *
 * In case the function is called with 'checkonly' equal to 1, it does not copy
 * the data into the buffer. It only checks for buffer overflows and it updates the
 * 'offset' variable. This mode can be useful when the buffer already contains the
 * data (maybe because the producer writes directly into the target buffer), so
 * only the buffer overflow check has to be made.
 * In this case, both 'buffer' and 'tempbuf' can be NULL values.
 *
 * This function is useful in case the userland application does not know immediately
 * all the data it has to write into the socket. This function provides a way to create
 * the "stream" step by step, appending the new data to the old one. Then, when all the
 * data has been bufferized, the application can call the sock_send() function.
 *
 * \param buffer: a char pointer to a user-allocated buffer that keeps the data
 * that has to be copied.
 *
 * \param size: number of bytes that have to be copied.
 *
 * \param tempbuf: user-allocated buffer (of size 'totsize') in which data
 * has to be copied.
 *
 * \param offset: an index into 'tempbuf' which keeps the location of its first
 * empty location.
 *
 * \param totsize: total size of the buffer in which data is being copied.
 *
 * \param checkonly: '1' if we do not want to copy data into the buffer and we
 * want just do a buffer ovreflow control, '0' if data has to be copied as well.
 *
 * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
 * error message. This buffer has to be at least 'errbuflen' in length.
 * It can be NULL; in this case the error cannot be printed.
 *
 * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
 * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
 *
 * \return '0' if everything is fine, '-1' if some errors occurred. The error message
 * is returned in the 'errbuf' variable. When the function returns, 'tempbuf' will
 * have the new string appended, and 'offset' will keep the length of that buffer.
 * In case of 'checkonly == 1', data is not copied, but 'offset' is updated in any case.
 *
 * \warning This function assumes that the buffer in which data has to be stored is
 * large 'totbuf' bytes.
 *
 * \warning In case of 'checkonly', be carefully to call this function *before* copying
 * the data into the buffer. Otherwise, the control about the buffer overflow is useless.
 */
int sock_bufferize(const char *buffer, int size, char *tempbuf, int *offset, int totsize, int checkonly, char *errbuf, int errbuflen)
{
	if ((*offset + size) > totsize)
	{
		if (errbuf)
			snprintf(errbuf, errbuflen, "Not enough space in the temporary send buffer.");
		return -1;
	}

	if (!checkonly)
		memcpy(tempbuf + (*offset), buffer, size);

	(*offset) += size;

	return 0;
}

/*
 * \brief It waits on a connected socket and it manages to receive data.
 *
 * This function basically calls the recv() socket function and it checks that no
 * error occurred. If that happens, it writes the error message into 'errbuf'.
 *
 * This function changes its behavior according to the 'receiveall' flag: if we
 * want to receive exactly 'size' byte, it loops on the recv()	until all the requested
 * data is arrived. Otherwise, it returns the data currently available.
 *
 * In case the socket does not have enough data available, it cycles on the recv()
 * until the requested data (of size 'size') is arrived.
 * In this case, it blocks until the number of bytes read is equal to 'size'.
 *
 * \param sock: the connected socket currently opened.
 *
 * \param buffer: a char pointer to a user-allocated buffer in which data has to be stored
 *
 * \param size: size of the allocated buffer. WARNING: this indicates the number of bytes
 * that we are expecting to be read.
 *
 * \param flags:
 *
 *   SOCK_RECEIVALL_XXX:
 *
 * 	if SOCK_RECEIVEALL_NO, return as soon as some data is ready
 *	if SOCK_RECEIVALL_YES, wait until 'size' data has been
 *	    received (in case the socket does not have enough data available).
 *
 *   SOCK_EOF_XXX:
 *
 *	if SOCK_EOF_ISNT_ERROR, if the first read returns 0, just return 0,
 *	    and return an error on any subsequent read that returns 0;
 *	if SOCK_EOF_IS_ERROR, if any read returns 0, return an error.
 *
 * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
 * error message. This buffer has to be at least 'errbuflen' in length.
 * It can be NULL; in this case the error cannot be printed.
 *
 * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
 * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
 *
 * \return the number of bytes read if everything is fine, '-1' if some errors occurred.
 * The error message is returned in the 'errbuf' variable.
 */

int sock_recv(SOCKET sock, SSL *ssl _U_NOSSL_, void *buffer, size_t size,
    int flags, char *errbuf, int errbuflen)
{
	int recv_flags = 0;
	char *bufp = buffer;
	int remaining;
	ssize_t nread;

	if (size == 0)
	{
		return 0;
	}
	if (size > INT_MAX)
	{
		if (errbuf)
		{
			snprintf(errbuf, errbuflen,
			    "Can't read more than %u bytes with sock_recv",
			    INT_MAX);
		}
		return -1;
	}

	if (flags & SOCK_MSG_PEEK)
		recv_flags |= MSG_PEEK;

	bufp = (char *) buffer;
	remaining = (int) size;

	/*
	 * We don't use MSG_WAITALL because it's not supported in
	 * Win32.
	 */
	for (;;) {
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
		nread = fuzz_recv(bufp, remaining);
#elif defined(HAVE_OPENSSL)
		if (ssl)
		{
			/*
			 * XXX - what about MSG_PEEK?
			 */
			nread = ssl_recv(ssl, bufp, remaining, errbuf, errbuflen);
			if (nread == -2) return -1;
		}
		else
			nread = recv(sock, bufp, remaining, recv_flags);
#else
		nread = recv(sock, bufp, remaining, recv_flags);
#endif

		if (nread == -1)
		{
#ifndef _WIN32
			if (errno == EINTR)
				return -3;
#endif
			sock_geterror("recv()", errbuf, errbuflen);
			return -1;
		}

		if (nread == 0)
		{
			if ((flags & SOCK_EOF_IS_ERROR) ||
			    (remaining != (int) size))
			{
				/*
				 * Either we've already read some data,
				 * or we're always supposed to return
				 * an error on EOF.
				 */
				if (errbuf)
				{
					snprintf(errbuf, errbuflen,
					    "The other host terminated the connection.");
				}
				return -1;
			}
			else
				return 0;
		}

		/*
		 * Do we want to read the amount requested, or just return
		 * what we got?
		 */
		if (!(flags & SOCK_RECEIVEALL_YES))
		{
			/*
			 * Just return what we got.
			 */
			return (int) nread;
		}

		bufp += nread;
		remaining -= nread;

		if (remaining == 0)
			return (int) size;
	}
}

/*
 * Receives a datagram from a socket.
 *
 * Returns the size of the datagram on success or -1 on error.
 */
int sock_recv_dgram(SOCKET sock, SSL *ssl _U_NOSSL_, void *buffer, size_t size,
    char *errbuf, int errbuflen)
{
	ssize_t nread;
#ifndef _WIN32
	struct msghdr message;
	struct iovec iov;
#endif

	if (size == 0)
	{
		return 0;
	}
	if (size > INT_MAX)
	{
		if (errbuf)
		{
			snprintf(errbuf, errbuflen,
			    "Can't read more than %u bytes with sock_recv_dgram",
			    INT_MAX);
		}
		return -1;
	}

#ifdef HAVE_OPENSSL
	// TODO: DTLS
	if (ssl)
	{
		snprintf(errbuf, errbuflen, "DTLS not implemented yet");
		return -1;
	}
#endif

	/*
	 * This should be a datagram socket, so we should get the
	 * entire datagram in one recv() or recvmsg() call, and
	 * don't need to loop.
	 */
#ifdef _WIN32
	nread = recv(sock, buffer, (int)size, 0);
	if (nread == SOCKET_ERROR)
	{
		/*
		 * To quote the MSDN documentation for recv(),
		 * "If the datagram or message is larger than
		 * the buffer specified, the buffer is filled
		 * with the first part of the datagram, and recv
		 * generates the error WSAEMSGSIZE. For unreliable
		 * protocols (for example, UDP) the excess data is
		 * lost..."
		 *
		 * So if the message is bigger than the buffer
		 * supplied to us, the excess data is discarded,
		 * and we'll report an error.
		 */
		sock_geterror("recv()", errbuf, errbuflen);
		return -1;
	}
#else /* _WIN32 */
	/*
	 * The Single UNIX Specification says that a recv() on
	 * a socket for a message-oriented protocol will discard
	 * the excess data.  It does *not* indicate that the
	 * receive will fail with, for example, EMSGSIZE.
	 *
	 * Therefore, we use recvmsg(), which appears to be
	 * the only way to get a "message truncated" indication
	 * when receiving a message for a message-oriented
	 * protocol.
	 */
	message.msg_name = NULL;	/* we don't care who it's from */
	message.msg_namelen = 0;
	iov.iov_base = buffer;
	iov.iov_len = size;
	message.msg_iov = &iov;
	message.msg_iovlen = 1;
#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
	message.msg_control = NULL;	/* we don't care about control information */
	message.msg_controllen = 0;
#endif
#ifdef HAVE_STRUCT_MSGHDR_MSG_FLAGS
	message.msg_flags = 0;
#endif
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
	nread = fuzz_recv(buffer, size);
#else
	nread = recvmsg(sock, &message, 0);
#endif
	if (nread == -1)
	{
		if (errno == EINTR)
			return -3;
		sock_geterror("recv()", errbuf, errbuflen);
		return -1;
	}
#ifdef HAVE_STRUCT_MSGHDR_MSG_FLAGS
	/*
	 * XXX - Solaris supports this, but only if you ask for the
	 * X/Open version of recvmsg(); should we use that, or will
	 * that cause other problems?
	 */
	if (message.msg_flags & MSG_TRUNC)
	{
		/*
		 * Message was bigger than the specified buffer size.
		 *
		 * Report this as an error, as the Microsoft documentation
		 * implies we'd do in a similar case on Windows.
		 */
		snprintf(errbuf, errbuflen, "recv(): Message too long");
		return -1;
	}
#endif /* HAVE_STRUCT_MSGHDR_MSG_FLAGS */
#endif /* _WIN32 */

	/*
	 * The size we're reading fits in an int, so the return value
	 * will fit in an int.
	 */
	return (int)nread;
}

/*
 * \brief It discards N bytes that are currently waiting to be read on the current socket.
 *
 * This function is useful in case we receive a message we cannot understand (e.g.
 * wrong version number when receiving a network packet), so that we have to discard all
 * data before reading a new message.
 *
 * This function will read 'size' bytes from the socket and discard them.
 * It defines an internal buffer in which data will be copied; however, in case
 * this buffer is not large enough, it will cycle in order to read everything as well.
 *
 * \param sock: the connected socket currently opened.
 *
 * \param size: number of bytes that have to be discarded.
 *
 * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
 * error message. This buffer has to be at least 'errbuflen' in length.
 * It can be NULL; in this case the error cannot be printed.
 *
 * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
 * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
 *
 * \return '0' if everything is fine, '-1' if some errors occurred.
 * The error message is returned in the 'errbuf' variable.
 */
int sock_discard(SOCKET sock, SSL *ssl, int size, char *errbuf, int errbuflen)
{
#define TEMP_BUF_SIZE 32768

	char buffer[TEMP_BUF_SIZE];		/* network buffer, to be used when the message is discarded */

	/*
	 * A static allocation avoids the need of a 'malloc()' each time we want to discard a message
	 * Our feeling is that a buffer if 32KB is enough for most of the application;
	 * in case this is not enough, the "while" loop discards the message by calling the
	 * sockrecv() several times.
	 * We do not want to create a bigger variable because this causes the program to exit on
	 * some platforms (e.g. BSD)
	 */
	while (size > TEMP_BUF_SIZE)
	{
		if (sock_recv(sock, ssl, buffer, TEMP_BUF_SIZE, SOCK_RECEIVEALL_YES, errbuf, errbuflen) == -1)
			return -1;

		size -= TEMP_BUF_SIZE;
	}

	/*
	 * If there is still data to be discarded
	 * In this case, the data can fit into the temporary buffer
	 */
	if (size)
	{
		if (sock_recv(sock, ssl, buffer, size, SOCK_RECEIVEALL_YES, errbuf, errbuflen) == -1)
			return -1;
	}

	return 0;
}

/*
 * \brief Checks that one host (identified by the sockaddr_storage structure) belongs to an 'allowed list'.
 *
 * This function is useful after an accept() call in order to check if the connecting
 * host is allowed to connect to me. To do that, we have a buffer that keeps the list of the
 * allowed host; this function checks the sockaddr_storage structure of the connecting host
 * against this host list, and it returns '0' is the host is included in this list.
 *
 * \param hostlist: pointer to a string that contains the list of the allowed host.
 *
 * \param sep: a string that keeps the separators used between the hosts (for example the
 * space character) in the host list.
 *
 * \param from: a sockaddr_storage structure, as it is returned by the accept() call.
 *
 * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
 * error message. This buffer has to be at least 'errbuflen' in length.
 * It can be NULL; in this case the error cannot be printed.
 *
 * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
 * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
 *
 * \return It returns:
 * - '1' if the host list is empty
 * - '0' if the host belongs to the host list (and therefore it is allowed to connect)
 * - '-1' in case the host does not belong to the host list (and therefore it is not allowed to connect
 * - '-2' in case or error. The error message is returned in the 'errbuf' variable.
 */
int sock_check_hostlist(char *hostlist, const char *sep, struct sockaddr_storage *from, char *errbuf, int errbuflen)
{
	/* checks if the connecting host is among the ones allowed */
	if ((hostlist) && (hostlist[0]))
	{
		char *token;					/* temp, needed to separate items into the hostlist */
		struct addrinfo *addrinfo, *ai_next;
		char *temphostlist;
		char *lasts;
		int getaddrinfo_failed = 0;

		/*
		 * The problem is that strtok modifies the original variable by putting '0' at the end of each token
		 * So, we have to create a new temporary string in which the original content is kept
		 */
		temphostlist = strdup(hostlist);
		if (temphostlist == NULL)
		{
			sock_geterror("sock_check_hostlist(), malloc() failed", errbuf, errbuflen);
			return -2;
		}

		token = pcap_strtok_r(temphostlist, sep, &lasts);

		/* it avoids a warning in the compilation ('addrinfo used but not initialized') */
		addrinfo = NULL;

		while (token != NULL)
		{
			struct addrinfo hints;
			int retval;

			addrinfo = NULL;
			memset(&hints, 0, sizeof(struct addrinfo));
			hints.ai_family = PF_UNSPEC;
			hints.ai_socktype = SOCK_STREAM;

			retval = getaddrinfo(token, NULL, &hints, &addrinfo);
			if (retval != 0)
			{
				if (errbuf)
					get_gai_errstring(errbuf, errbuflen,
					    "Allowed host list error: ",
					    retval, token, NULL);

				/*
				 * Note that at least one call to getaddrinfo()
				 * failed.
				 */
				getaddrinfo_failed = 1;

				/* Get next token */
				token = pcap_strtok_r(NULL, sep, &lasts);
				continue;
			}

			/* ai_next is required to preserve the content of addrinfo, in order to deallocate it properly */
			ai_next = addrinfo;
			while (ai_next)
			{
				if (sock_cmpaddr(from, (struct sockaddr_storage *) ai_next->ai_addr) == 0)
				{
					free(temphostlist);
					freeaddrinfo(addrinfo);
					return 0;
				}

				/*
				 * If we are here, it means that the current address does not matches
				 * Let's try with the next one in the header chain
				 */
				ai_next = ai_next->ai_next;
			}

			freeaddrinfo(addrinfo);
			addrinfo = NULL;

			/* Get next token */
			token = pcap_strtok_r(NULL, sep, &lasts);
		}

		if (addrinfo)
		{
			freeaddrinfo(addrinfo);
			addrinfo = NULL;
		}

		free(temphostlist);

		if (getaddrinfo_failed) {
			/*
			 * At least one getaddrinfo() call failed;
			 * treat that as an error, so rpcapd knows
			 * that it should log it locally as well
			 * as telling the client about it.
			 */
			return -2;
		} else {
			/*
			 * All getaddrinfo() calls succeeded, but
			 * the host wasn't in the list.
			 */
			if (errbuf)
				snprintf(errbuf, errbuflen, "The host is not in the allowed host list. Connection refused.");
			return -1;
		}
	}

	/* No hostlist, so we have to return 'empty list' */
	return 1;
}

/*
 * \brief Compares two addresses contained into two sockaddr_storage structures.
 *
 * This function is useful to compare two addresses, given their internal representation,
 * i.e. an sockaddr_storage structure.
 *
 * The two structures do not need to be sockaddr_storage; you can have both 'sockaddr_in' and
 * sockaddr_in6, properly acsted in order to be compliant to the function interface.
 *
 * This function will return '0' if the two addresses matches, '-1' if not.
 *
 * \param first: a sockaddr_storage structure, (for example the one that is returned by an
 * accept() call), containing the first address to compare.
 *
 * \param second: a sockaddr_storage structure containing the second address to compare.
 *
 * \return '0' if the addresses are equal, '-1' if they are different.
 */
int sock_cmpaddr(struct sockaddr_storage *first, struct sockaddr_storage *second)
{
	if (first->ss_family == second->ss_family)
	{
		if (first->ss_family == AF_INET)
		{
			if (memcmp(&(((struct sockaddr_in *) first)->sin_addr),
				&(((struct sockaddr_in *) second)->sin_addr),
				sizeof(struct in_addr)) == 0)
				return 0;
		}
		else /* address family is AF_INET6 */
		{
			if (memcmp(&(((struct sockaddr_in6 *) first)->sin6_addr),
				&(((struct sockaddr_in6 *) second)->sin6_addr),
				sizeof(struct in6_addr)) == 0)
				return 0;
		}
	}

	return -1;
}

/*
 * \brief It gets the address/port the system picked for this socket (on connected sockets).
 *
 * It is used to return the address and port the server picked for our socket on the local machine.
 * It works only on:
 * - connected sockets
 * - server sockets
 *
 * On unconnected client sockets it does not work because the system dynamically chooses a port
 * only when the socket calls a send() call.
 *
 * \param sock: the connected socket currently opened.
 *
 * \param address: it contains the address that will be returned by the function. This buffer
 * must be properly allocated by the user. The address can be either literal or numeric depending
 * on the value of 'Flags'.
 *
 * \param addrlen: the length of the 'address' buffer.
 *
 * \param port: it contains the port that will be returned by the function. This buffer
 * must be properly allocated by the user.
 *
 * \param portlen: the length of the 'port' buffer.
 *
 * \param flags: a set of flags (the ones defined into the getnameinfo() standard socket function)
 * that determine if the resulting address must be in numeric / literal form, and so on.
 *
 * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
 * error message. This buffer has to be at least 'errbuflen' in length.
 * It can be NULL; in this case the error cannot be printed.
 *
 * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
 * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
 *
 * \return It returns '-1' if this function succeeds, '0' otherwise.
 * The address and port corresponding are returned back in the buffers 'address' and 'port'.
 * In any case, the returned strings are '0' terminated.
 *
 * \warning If the socket is using a connectionless protocol, the address may not be available
 * until I/O occurs on the socket.
 */
int sock_getmyinfo(SOCKET sock, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen)
{
	struct sockaddr_storage mysockaddr;
	socklen_t sockaddrlen;


	sockaddrlen = sizeof(struct sockaddr_storage);

	if (getsockname(sock, (struct sockaddr *) &mysockaddr, &sockaddrlen) == -1)
	{
		sock_geterror("getsockname()", errbuf, errbuflen);
		return 0;
	}

	/* Returns the numeric address of the host that triggered the error */
	return sock_getascii_addrport(&mysockaddr, address, addrlen, port, portlen, flags, errbuf, errbuflen);
}

/*
 * \brief It retrieves two strings containing the address and the port of a given 'sockaddr' variable.
 *
 * This function is basically an extended version of the inet_ntop(), which does not exist in
 * Winsock because the same result can be obtained by using the getnameinfo().
 * However, differently from inet_ntop(), this function is able to return also literal names
 * (e.g. 'localhost') dependently from the 'Flags' parameter.
 *
 * The function accepts a sockaddr_storage variable (which can be returned by several functions
 * like bind(), connect(), accept(), and more) and it transforms its content into a 'human'
 * form. So, for instance, it is able to translate an hex address (stored in binary form) into
 * a standard IPv6 address like "::1".
 *
 * The behavior of this function depends on the parameters we have in the 'Flags' variable, which
 * are the ones allowed in the standard getnameinfo() socket function.
 *
 * \param sockaddr: a 'sockaddr_in' or 'sockaddr_in6' structure containing the address that
 * need to be translated from network form into the presentation form. This structure must be
 * zero-ed prior using it, and the address family field must be filled with the proper value.
 * The user must cast any 'sockaddr_in' or 'sockaddr_in6' structures to 'sockaddr_storage' before
 * calling this function.
 *
 * \param address: it contains the address that will be returned by the function. This buffer
 * must be properly allocated by the user. The address can be either literal or numeric depending
 * on the value of 'Flags'.
 *
 * \param addrlen: the length of the 'address' buffer.
 *
 * \param port: it contains the port that will be returned by the function. This buffer
 * must be properly allocated by the user.
 *
 * \param portlen: the length of the 'port' buffer.
 *
 * \param flags: a set of flags (the ones defined into the getnameinfo() standard socket function)
 * that determine if the resulting address must be in numeric / literal form, and so on.
 *
 * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
 * error message. This buffer has to be at least 'errbuflen' in length.
 * It can be NULL; in this case the error cannot be printed.
 *
 * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
 * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
 *
 * \return It returns '-1' if this function succeeds, '0' otherwise.
 * The address and port corresponding to the given SockAddr are returned back in the buffers 'address'
 * and 'port'.
 * In any case, the returned strings are '0' terminated.
 */
int sock_getascii_addrport(const struct sockaddr_storage *sockaddr, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen)
{
	socklen_t sockaddrlen;
	int retval;					/* Variable that keeps the return value; */

	retval = -1;

#ifdef _WIN32
	if (sockaddr->ss_family == AF_INET)
		sockaddrlen = sizeof(struct sockaddr_in);
	else
		sockaddrlen = sizeof(struct sockaddr_in6);
#else
	sockaddrlen = sizeof(struct sockaddr_storage);
#endif

	if ((flags & NI_NUMERICHOST) == 0)	/* Check that we want literal names */
	{
		if ((sockaddr->ss_family == AF_INET6) &&
			(memcmp(&((struct sockaddr_in6 *) sockaddr)->sin6_addr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(struct in6_addr)) == 0))
		{
			if (address)
				pcap_strlcpy(address, SOCKET_NAME_NULL_DAD, addrlen);
			return retval;
		}
	}

	if (getnameinfo((struct sockaddr *) sockaddr, sockaddrlen, address, addrlen, port, portlen, flags) != 0)
	{
		/* If the user wants to receive an error message */
		if (errbuf)
		{
			sock_geterror("getnameinfo()", errbuf, errbuflen);
			errbuf[errbuflen - 1] = 0;
		}

		if (address)
		{
			pcap_strlcpy(address, SOCKET_NO_NAME_AVAILABLE, addrlen);
			address[addrlen - 1] = 0;
		}

		if (port)
		{
			pcap_strlcpy(port, SOCKET_NO_PORT_AVAILABLE, portlen);
			port[portlen - 1] = 0;
		}

		retval = 0;
	}

	return retval;
}

/*
 * \brief It translates an address from the 'presentation' form into the 'network' form.
 *
 * This function basically replaces inet_pton(), which does not exist in Winsock because
 * the same result can be obtained by using the getaddrinfo().
 * An additional advantage is that 'Address' can be both a numeric address (e.g. '127.0.0.1',
 * like in inet_pton() ) and a literal name (e.g. 'localhost').
 *
 * This function does the reverse job of sock_getascii_addrport().
 *
 * \param address: a zero-terminated string which contains the name you have to
 * translate. The name can be either literal (e.g. 'localhost') or numeric (e.g. '::1').
 *
 * \param sockaddr: a user-allocated sockaddr_storage structure which will contains the
 * 'network' form of the requested address.
 *
 * \param addr_family: a constant which can assume the following values:
 * - 'AF_INET' if we want to ping an IPv4 host
 * - 'AF_INET6' if we want to ping an IPv6 host
 * - 'AF_UNSPEC' if we do not have preferences about the protocol used to ping the host
 *
 * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
 * error message. This buffer has to be at least 'errbuflen' in length.
 * It can be NULL; in this case the error cannot be printed.
 *
 * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
 * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
 *
 * \return '-1' if the translation succeeded, '-2' if there was some non critical error, '0'
 * otherwise. In case it fails, the content of the SockAddr variable remains unchanged.
 * A 'non critical error' can occur in case the 'Address' is a literal name, which can be mapped
 * to several network addresses (e.g. 'foo.bar.com' => '10.2.2.2' and '10.2.2.3'). In this case
 * the content of the SockAddr parameter will be the address corresponding to the first mapping.
 *
 * \warning The sockaddr_storage structure MUST be allocated by the user.
 */
int sock_present2network(const char *address, struct sockaddr_storage *sockaddr, int addr_family, char *errbuf, int errbuflen)
{
	int retval;
	struct addrinfo *addrinfo;
	struct addrinfo hints;

	memset(&hints, 0, sizeof(hints));

	hints.ai_family = addr_family;

	if ((retval = sock_initaddress(address, "22222" /* fake port */, &hints, &addrinfo, errbuf, errbuflen)) == -1)
		return 0;

	if (addrinfo->ai_family == PF_INET)
		memcpy(sockaddr, addrinfo->ai_addr, sizeof(struct sockaddr_in));
	else
		memcpy(sockaddr, addrinfo->ai_addr, sizeof(struct sockaddr_in6));

	if (addrinfo->ai_next != NULL)
	{
		freeaddrinfo(addrinfo);

		if (errbuf)
			snprintf(errbuf, errbuflen, "More than one socket requested; using the first one returned");
		return -2;
	}

	freeaddrinfo(addrinfo);
	return -1;
}
