/*
 * 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.
 */

#include <config.h>

#include "ftmacros.h"
#include "varattrs.h"

#include <errno.h>		// for the errno variable
#include <stdlib.h>		// for malloc(), free(), ...
#include <string.h>		// for strlen(), ...
#include <limits.h>		// for INT_MAX

#ifdef _WIN32
  #include <process.h>		// for threads
#else
  #include <unistd.h>
  #include <pthread.h>
  #include <signal.h>
  #include <sys/time.h>
  #include <sys/types.h>	// for select() and such
  #include <pwd.h>		// for password management
#endif

#ifdef HAVE_GETSPNAM
#include <shadow.h>		// for password management
#endif

#include <pcap.h>		// for libpcap/WinPcap calls

#include "fmtutils.h"
#include "sockutils.h"		// for socket calls
#include "portability.h"
#include "rpcap-protocol.h"
#include "daemon.h"
#include "log.h"

#ifdef HAVE_OPENSSL
#include <openssl/ssl.h>
#include "sslutils.h"
#endif

//
// Timeout, in seconds, when we're waiting for a client to send us an
// authentication request; if they don't send us a request within that
// interval, we drop the connection, so we don't stay stuck forever.
//
#define RPCAP_TIMEOUT_INIT 90

//
// Timeout, in seconds, when we're waiting for an authenticated client
// to send us a request, if a capture isn't in progress; if they don't
// send us a request within that interval, we drop the connection, so
// we don't stay stuck forever.
//
#define RPCAP_TIMEOUT_RUNTIME 180

//
// Time, in seconds, that we wait after a failed authentication attempt
// before processing the next request; this prevents a client from
// rapidly trying different accounts or passwords.
//
#define RPCAP_SUSPEND_WRONGAUTH 1

// Parameters for the service loop.
struct daemon_slpars
{
	PCAP_SOCKET sockctrl;	//!< PCAP_SOCKET ID of the control connection
	SSL *ssl;		//!< Optional SSL handler for the controlling sockets
	int isactive;		//!< Not null if the daemon has to run in active mode
	int nullAuthAllowed;	//!< '1' if we permit NULL authentication, '0' otherwise
};

//
// Data for a session managed by a thread.
// It includes both a Boolean indicating whether we *have* a thread,
// and a platform-dependent (UN*X vs. Windows) identifier for the
// thread; on Windows, we could use an invalid handle to indicate
// that we don't have a thread, but there *is* no portable "no thread"
// value for a pthread_t on UN*X.
//
struct session {
	PCAP_SOCKET sockctrl;
	PCAP_SOCKET sockdata;
	SSL *ctrl_ssl, *data_ssl; // optional SSL handlers for sockctrl and sockdata.
	uint8 protocol_version;
	pcap_t *fp;
	unsigned int TotCapt;
	int	have_thread;
#ifdef _WIN32
	HANDLE thread;
#else
	pthread_t thread;
#endif
};

// Locally defined functions
static int daemon_msg_err(PCAP_SOCKET sockctrl, SSL *, uint32 plen);
static int daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen);
static int daemon_AuthUserPwd(char *username, char *password, char *errbuf);

static int daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars,
    uint32 plen);

static int daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars,
    uint32 plen, char *source, size_t sourcelen);
static int daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars,
    uint32 plen, char *source, struct session **sessionp,
    struct rpcap_sampling *samp_param, int uses_ssl);
static int daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars,
    struct session *session);

static int daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars,
    struct session *session, uint32 plen);
static int daemon_unpackapplyfilter(PCAP_SOCKET sockctrl, SSL *, struct session *session, uint32 *plenp, char *errbuf);

static int daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars,
    struct session *session, uint32 plen, struct pcap_stat *stats,
    unsigned int svrcapt);

static int daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars,
    uint32 plen, struct rpcap_sampling *samp_param);

static void daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *sockaddrout);
#ifdef _WIN32
static unsigned __stdcall daemon_thrdatamain(void *ptr);
#else
static void *daemon_thrdatamain(void *ptr);
static void noop_handler(int sign);
#endif

static int rpcapd_recv_msg_header(PCAP_SOCKET sock, SSL *, struct rpcap_header *headerp);
static int rpcapd_recv(PCAP_SOCKET sock, SSL *, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf);
static int rpcapd_discard(PCAP_SOCKET sock, SSL *, uint32 len);
static void session_close(struct session *);

//
// TLS record layer header; used when processing the first message from
// the client, in case we aren't doing TLS but they are.
//
struct tls_record_header {
	uint8 type;		// ContentType - will be 22, for Handshake
	uint8 version_major;	// TLS protocol major version
	uint8 version_injor;	// TLS protocol minor version
	// This is *not* aligned on a 2-byte boundary; we just
	// declare it as two bytes.  Don't assume any particular
	// compiler's mechanism for saying "packed"!
	uint8 length_hi;	// Upper 8 bits of payload length
	uint8 length_lo;	// Low 8 bits of payload length
};

#define TLS_RECORD_HEADER_LEN	5	// Don't use sizeof in case it's padded

#define TLS_RECORD_TYPE_ALERT		21
#define TLS_RECORD_TYPE_HANDSHAKE	22

//
// TLS alert message.
//
struct tls_alert {
	uint8 alert_level;
	uint8 alert_description;
};

#define TLS_ALERT_LEN			2

#define TLS_ALERT_LEVEL_FATAL		2
#define TLS_ALERT_HANDSHAKE_FAILURE	40

static int is_url(const char *source);

/*
 * Maximum sizes for fixed-bit-width values.
 */
#ifndef UINT16_MAX
#define UINT16_MAX	65535U
#endif

#ifndef UINT32_MAX
#define UINT32_MAX	4294967295U
#endif

int
daemon_serviceloop(PCAP_SOCKET sockctrl, int isactive, char *passiveClients,
    int nullAuthAllowed, int uses_ssl)
{
	uint8 first_octet;
	struct tls_record_header tls_header;
	struct tls_alert tls_alert;
	struct daemon_slpars pars;		// service loop parameters
	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
	char errmsgbuf[PCAP_ERRBUF_SIZE + 1];	// buffer for errors to send to the client
	int host_port_check_status;
	SSL *ssl = NULL;
	int nrecv;
	struct rpcap_header header;		// RPCAP message general header
	uint32 plen;				// payload length from header
	int authenticated = 0;			// 1 if the client has successfully authenticated
	char source[PCAP_BUF_SIZE+1];		// keeps the string that contains the interface to open
	int got_source = 0;			// 1 if we've gotten the source from an open request
#ifndef _WIN32
	struct sigaction action;
#endif
	struct session *session = NULL;		// struct session main variable
	const char *msg_type_string;		// string for message type
	int client_told_us_to_close = 0;	// 1 if the client told us to close the capture

	// needed to save the values of the statistics
	struct pcap_stat stats;
	unsigned int svrcapt;

	struct rpcap_sampling samp_param;	// in case sampling has been requested

	// Structures needed for the select() call
	fd_set rfds;				// set of socket descriptors we have to check
	struct timeval tv;			// maximum time the select() can block waiting for data
	int retval;				// select() return value

	*errbuf = 0;	// Initialize errbuf

	//
	// Peek into the socket to determine whether the client sent us
	// a TLS handshake message or a non-TLS rpcapd message.
	//
	// The first byte of an rpcapd request is the version number;
	// the first byte of a TLS handshake message is 22.  The
	// first request to an rpcapd server must be an authentication
	// request or a close request, and must have a version number
	// of 0, so it will be possible to distinguish between an
	// initial plaintext request to a server and an initial TLS
	// handshake message.
	//
	nrecv = sock_recv(sockctrl, NULL, (char *)&first_octet, 1,
	    SOCK_EOF_ISNT_ERROR|SOCK_MSG_PEEK, errbuf, PCAP_ERRBUF_SIZE);
	if (nrecv == -1)
	{
		// Fatal error.
		rpcapd_log(LOGPRIO_ERROR, "Peek from client failed: %s", errbuf);
		goto end;
	}
	if (nrecv == 0)
	{
		// Client closed the connection.
		goto end;
	}

#ifdef HAVE_OPENSSL
	//
	// We have to upgrade to TLS as soon as possible, so that the
	// whole protocol goes through the encrypted tunnel, including
	// early error messages.
	//
	// Even in active mode, the other end has to initiate the TLS
	// handshake as we still are the server as far as TLS is concerned,
	// so we don't check isactive.
	//
	if (uses_ssl)
	{
		//
		// We're expecting a TLS handshake message.  If this
		// isn't one, assume it's a non-TLS rpcapd message.
		//
		// The first octet of a TLS handshake is
		// TLS_RECORD_TYPE_HANDSHAKE.
		//
		if (first_octet != TLS_RECORD_TYPE_HANDSHAKE)
		{
			//
			// We assume this is a non-TLS rpcapd message.
			//
			// Read the message header from the client.
			//
			nrecv = rpcapd_recv_msg_header(sockctrl, NULL, &header);
			if (nrecv == -1)
			{
				// Fatal error.
				goto end;
			}
			if (nrecv == -2)
			{
				// Client closed the connection.
				goto end;
			}
			plen = header.plen;

			// Discard the rest of the message.
			if (rpcapd_discard(sockctrl, NULL, plen) == -1)
			{
				// Network error.
				goto end;
			}

			//
			// Send an authentication error, indicating
			// that we require TLS.
			//
			if (rpcap_senderror(sockctrl, NULL, header.ver,
			    PCAP_ERR_TLS_REQUIRED,
			    "TLS is required by this server", errbuf) == -1)
			{
				// That failed; log a message and give up.
				rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
				goto end;
			}

			// Shut the session down.
			goto end;
		}
		ssl = ssl_promotion(1, sockctrl, errbuf, PCAP_ERRBUF_SIZE);
		if (! ssl)
		{
			rpcapd_log(LOGPRIO_ERROR, "TLS handshake on control connection failed: %s",
			    errbuf);
			goto end;
		}
	}
	else
#endif
	{
		//
		// We're expecting a non-TLS rpcapd message.  If this
		// looks, instead, like a TLS handshake message, send
		// a TLS handshake_failed alert.
		//
		// The first octet of a TLS handshake is
		// TLS_RECORD_TYPE_HANDSHAKE.
		//
		if (first_octet == TLS_RECORD_TYPE_HANDSHAKE)
		{
			//
			// TLS handshake.
			// Read the record header.
			//
			nrecv = sock_recv(sockctrl, ssl, (char *) &tls_header,
			    sizeof tls_header, SOCK_RECEIVEALL_YES|SOCK_EOF_ISNT_ERROR,
			    errbuf, PCAP_ERRBUF_SIZE);
			if (nrecv == -1)
			{
				// Network error.
				rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
				goto end;
			}
			if (nrecv == 0)
			{
				// Immediate EOF
				goto end;
			}
			plen = (tls_header.length_hi << 8U) | tls_header.length_lo;

			// Discard the rest of the message.
			if (rpcapd_discard(sockctrl, NULL, plen) == -1)
			{
				// Network error.
				goto end;
			}

			//
			// Send a TLS handshake failure alert.
			// Use the same version the client sent us.
			//
			tls_header.type = TLS_RECORD_TYPE_ALERT;
			tls_header.length_hi = 0;
			tls_header.length_lo = TLS_ALERT_LEN;

			if (sock_send(sockctrl, NULL, (char *) &tls_header,
			    TLS_RECORD_HEADER_LEN, errbuf, PCAP_ERRBUF_SIZE) == -1)
			{
				// That failed; log a message and give up.
				rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
				goto end;
			}

			tls_alert.alert_level = TLS_ALERT_LEVEL_FATAL;
			tls_alert.alert_description = TLS_ALERT_HANDSHAKE_FAILURE;
			if (sock_send(sockctrl, NULL, (char *) &tls_alert,
			    TLS_ALERT_LEN, errbuf, PCAP_ERRBUF_SIZE) == -1)
			{
				// That failed; log a message and give up.
				rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
				goto end;
			}
			//
			// Give up anyway.
			//
			goto end;
		}
	}

	// Set parameters structure
	pars.sockctrl = sockctrl;
	pars.ssl = ssl;
	pars.isactive = isactive;		// active mode
	pars.nullAuthAllowed = nullAuthAllowed;

	//
	// We have a connection.
	//
	// If it's a passive mode connection, check whether the connecting
	// host is among the ones allowed.
	//
	// In either case, we were handed a copy of the host list; free it
	// as soon as we're done with it.
	//
	if (pars.isactive)
	{
		// Nothing to do.
		free(passiveClients);
		passiveClients = NULL;
	}
	else
	{
		struct sockaddr_storage from;
		socklen_t fromlen;

		//
		// Get the address of the other end of the connection.
		//
		fromlen = sizeof(struct sockaddr_storage);
		if (getpeername(pars.sockctrl, (struct sockaddr *)&from,
		    &fromlen) == -1)
		{
			sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
			    "getpeername() failed");
			if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1)
				rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
			goto end;
		}

		//
		// Are they in the list of host/port combinations we allow?
		//
		host_port_check_status = sock_check_hostlist(passiveClients, RPCAP_HOSTLIST_SEP, &from, errmsgbuf, PCAP_ERRBUF_SIZE);
		free(passiveClients);
		passiveClients = NULL;
		if (host_port_check_status < 0)
		{
			if (host_port_check_status == -2) {
				//
				// We got an error; log it.
				//
				rpcapd_log(LOGPRIO_ERROR, "%s", errmsgbuf);
			}

			//
			// Sorry, we can't let you in.
			//
			if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_HOSTNOAUTH, errmsgbuf, errbuf) == -1)
				rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
			goto end;
		}
	}

#ifndef _WIN32
	//
	// Catch SIGUSR1, but do nothing.  We use it to interrupt the
	// capture thread to break it out of a loop in which it's
	// blocked waiting for packets to arrive.
	//
	// We don't want interrupted system calls to restart, so that
	// the read routine for the pcap_t gets EINTR rather than
	// restarting if it's blocked in a system call.
	//
	memset(&action, 0, sizeof (action));
	action.sa_handler = noop_handler;
	action.sa_flags = 0;
	sigemptyset(&action.sa_mask);
	sigaction(SIGUSR1, &action, NULL);
#endif

	//
	// The client must first authenticate; loop until they send us a
	// message with a version we support and credentials we accept,
	// they send us a close message indicating that they're giving up,
	// or we get a network error or other fatal error.
	//
	while (!authenticated)
	{
		//
		// If we're not in active mode, we use select(), with a
		// timeout, to wait for an authentication request; if
		// the timeout expires, we drop the connection, so that
		// a client can't just connect to us and leave us
		// waiting forever.
		//
		if (!pars.isactive)
		{
			FD_ZERO(&rfds);
			// We do not have to block here
			tv.tv_sec = RPCAP_TIMEOUT_INIT;
			tv.tv_usec = 0;

			FD_SET(pars.sockctrl, &rfds);

			retval = select((int)pars.sockctrl + 1, &rfds, NULL, NULL, &tv);
			if (retval == -1)
			{
				sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
				    "select() failed");
				if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1)
					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
				goto end;
			}

			// The timeout has expired
			// So, this was a fake connection. Drop it down
			if (retval == 0)
			{
				if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_INITTIMEOUT, "The RPCAP initial timeout has expired", errbuf) == -1)
					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
				goto end;
			}
		}

		//
		// Read the message header from the client.
		//
		nrecv = rpcapd_recv_msg_header(pars.sockctrl, pars.ssl, &header);
		if (nrecv == -1)
		{
			// Fatal error.
			goto end;
		}
		if (nrecv == -2)
		{
			// Client closed the connection.
			goto end;
		}

		plen = header.plen;

		//
		// While we're in the authentication phase, all requests
		// must use version 0.
		//
		if (header.ver != 0)
		{
			//
			// Send it back to them with their version.
			//
			if (rpcap_senderror(pars.sockctrl, pars.ssl, header.ver,
			    PCAP_ERR_WRONGVER,
			    "RPCAP version in requests in the authentication phase must be 0",
			    errbuf) == -1)
			{
				// That failed; log a message and give up.
				rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
				goto end;
			}

			// Discard the rest of the message and drop the
			// connection.
			(void)rpcapd_discard(pars.sockctrl, pars.ssl, plen);
			goto end;
		}

		switch (header.type)
		{
			case RPCAP_MSG_AUTH_REQ:
				retval = daemon_msg_auth_req(&pars, plen);
				if (retval == -1)
				{
					// Fatal error; a message has
					// been logged, so just give up.
					goto end;
				}
				if (retval == -2)
				{
					// Non-fatal error; we sent back
					// an error message, so let them
					// try again.
					continue;
				}

				// OK, we're authenticated; we sent back
				// a reply, so start serving requests.
				authenticated = 1;
				break;

			case RPCAP_MSG_CLOSE:
				//
				// The client is giving up.
				// Discard the rest of the message, if
				// there is anything more.
				//
				(void)rpcapd_discard(pars.sockctrl, pars.ssl, plen);
				// We're done with this client.
				goto end;

			case RPCAP_MSG_ERROR:
				// Log this and close the connection?
				// XXX - is this what happens in active
				// mode, where *we* initiate the
				// connection, and the client gives us
				// an error message rather than a "let
				// me log in" message, indicating that
				// we're not allowed to connect to them?
				(void)daemon_msg_err(pars.sockctrl, pars.ssl, plen);
				goto end;

			case RPCAP_MSG_FINDALLIF_REQ:
			case RPCAP_MSG_OPEN_REQ:
			case RPCAP_MSG_STARTCAP_REQ:
			case RPCAP_MSG_UPDATEFILTER_REQ:
			case RPCAP_MSG_STATS_REQ:
			case RPCAP_MSG_ENDCAP_REQ:
			case RPCAP_MSG_SETSAMPLING_REQ:
				//
				// These requests can't be sent until
				// the client is authenticated.
				//
				msg_type_string = rpcap_msg_type_string(header.type);
				if (msg_type_string != NULL)
				{
					snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "%s request sent before authentication was completed", msg_type_string);
				}
				else
				{
					snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message of type %u sent before authentication was completed", header.type);
				}
				if (rpcap_senderror(pars.sockctrl, pars.ssl,
				    header.ver, PCAP_ERR_WRONGMSG,
				    errmsgbuf, errbuf) == -1)
				{
					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
					goto end;
				}
				// Discard the rest of the message.
				if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1)
				{
					// Network error.
					goto end;
				}
				break;

			case RPCAP_MSG_PACKET:
			case RPCAP_MSG_FINDALLIF_REPLY:
			case RPCAP_MSG_OPEN_REPLY:
			case RPCAP_MSG_STARTCAP_REPLY:
			case RPCAP_MSG_UPDATEFILTER_REPLY:
			case RPCAP_MSG_AUTH_REPLY:
			case RPCAP_MSG_STATS_REPLY:
			case RPCAP_MSG_ENDCAP_REPLY:
			case RPCAP_MSG_SETSAMPLING_REPLY:
				//
				// These are server-to-client messages.
				//
				msg_type_string = rpcap_msg_type_string(header.type);
				if (msg_type_string != NULL)
				{
					snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message %s received from client", msg_type_string);
				}
				else
				{
					snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type);
				}
				if (rpcap_senderror(pars.sockctrl, pars.ssl,
				    header.ver, PCAP_ERR_WRONGMSG,
				    errmsgbuf, errbuf) == -1)
				{
					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
					goto end;
				}
				// Discard the rest of the message.
				if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1)
				{
					// Fatal error.
					goto end;
				}
				break;

			default:
				//
				// Unknown message type.
				//
				snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type);
				if (rpcap_senderror(pars.sockctrl, pars.ssl,
				    header.ver, PCAP_ERR_WRONGMSG,
				    errmsgbuf, errbuf) == -1)
				{
					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
					goto end;
				}
				// Discard the rest of the message.
				if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1)
				{
					// Fatal error.
					goto end;
				}
				break;
		}
	}

	//
	// OK, the client has authenticated itself, and we can start
	// processing regular requests from it.
	//

	//
	// We don't have any statistics yet.
	//
	stats.ps_ifdrop = 0;
	stats.ps_recv = 0;
	stats.ps_drop = 0;
	svrcapt = 0;

	//
	// Service requests.
	//
	for (;;)
	{
		errbuf[0] = 0;	// clear errbuf

		// Avoid zombies connections; check if the connection is opens but no commands are performed
		// from more than RPCAP_TIMEOUT_RUNTIME
		// Conditions:
		// - I have to be in normal mode (no active mode)
		// - if the device is open, I don't have to be in the middle of a capture (session->sockdata)
		// - if the device is closed, I have always to check if a new command arrives
		//
		// Be carefully: the capture can have been started, but an error occurred (so session != NULL, but
		//  sockdata is 0
		if ((!pars.isactive) && (session == NULL || session->sockdata == 0))
		{
			// Check for the initial timeout
			FD_ZERO(&rfds);
			// We do not have to block here
			tv.tv_sec = RPCAP_TIMEOUT_RUNTIME;
			tv.tv_usec = 0;

			FD_SET(pars.sockctrl, &rfds);
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
			retval = 1;
#else
			retval = select((int)pars.sockctrl + 1, &rfds, NULL, NULL, &tv);
#endif
			if (retval == -1)
			{
				sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
				    "select() failed");
				if (rpcap_senderror(pars.sockctrl, pars.ssl,
				    0, PCAP_ERR_NETW,
				    errmsgbuf, errbuf) == -1)
					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
				goto end;
			}

			// The timeout has expired
			// So, this was a fake connection. Drop it down
			if (retval == 0)
			{
				if (rpcap_senderror(pars.sockctrl, pars.ssl,
				    0, PCAP_ERR_INITTIMEOUT,
				    "The RPCAP initial timeout has expired",
				    errbuf) == -1)
					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
				goto end;
			}
		}

		//
		// Read the message header from the client.
		//
		nrecv = rpcapd_recv_msg_header(pars.sockctrl, pars.ssl, &header);
		if (nrecv == -1)
		{
			// Fatal error.
			goto end;
		}
		if (nrecv == -2)
		{
			// Client closed the connection.
			goto end;
		}

		plen = header.plen;

		//
		// Did the client specify a protocol version that we
		// support?
		//
		if (!RPCAP_VERSION_IS_SUPPORTED(header.ver))
		{
			//
			// Tell them it's not a supported version.
			// Send the error message with their version,
			// so they don't reject it as having the wrong
			// version.
			//
			if (rpcap_senderror(pars.sockctrl, pars.ssl,
			    header.ver, PCAP_ERR_WRONGVER,
			    "RPCAP version in message isn't supported by the server",
			    errbuf) == -1)
			{
				// That failed; log a message and give up.
				rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
				goto end;
			}

			// Discard the rest of the message.
			(void)rpcapd_discard(pars.sockctrl, pars.ssl, plen);
			// Give up on them.
			goto end;
		}

		switch (header.type)
		{
			case RPCAP_MSG_ERROR:		// The other endpoint reported an error
			{
				(void)daemon_msg_err(pars.sockctrl, pars.ssl, plen);
				// Do nothing; just exit; the error code is already into the errbuf
				// XXX - actually exit....
				break;
			}

			case RPCAP_MSG_FINDALLIF_REQ:
			{
				if (daemon_msg_findallif_req(header.ver, &pars, plen) == -1)
				{
					// Fatal error; a message has
					// been logged, so just give up.
					goto end;
				}
				break;
			}

			case RPCAP_MSG_OPEN_REQ:
			{
				//
				// Process the open request, and keep
				// the source from it, for use later
				// when the capture is started.
				//
				// XXX - we don't care if the client sends
				// us multiple open requests, the last
				// one wins.
				//
				retval = daemon_msg_open_req(header.ver, &pars,
				    plen, source, sizeof(source));
				if (retval == -1)
				{
					// Fatal error; a message has
					// been logged, so just give up.
					goto end;
				}
				got_source = 1;
				break;
			}

			case RPCAP_MSG_STARTCAP_REQ:
			{
				if (!got_source)
				{
					// They never told us what device
					// to capture on!
					if (rpcap_senderror(pars.sockctrl, pars.ssl,
					    header.ver,
					    PCAP_ERR_STARTCAPTURE,
					    "No capture device was specified",
					    errbuf) == -1)
					{
						// Fatal error; log an
						// error and  give up.
						rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
						goto end;
					}
					if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1)
					{
						goto end;
					}
					break;
				}

				if (daemon_msg_startcap_req(header.ver, &pars,
				    plen, source, &session, &samp_param,
				    uses_ssl) == -1)
				{
					// Fatal error; a message has
					// been logged, so just give up.
					goto end;
				}
				break;
			}

			case RPCAP_MSG_UPDATEFILTER_REQ:
			{
				if (session)
				{
					if (daemon_msg_updatefilter_req(header.ver,
					    &pars, session, plen) == -1)
					{
						// Fatal error; a message has
						// been logged, so just give up.
						goto end;
					}
				}
				else
				{
					if (rpcap_senderror(pars.sockctrl, pars.ssl,
					    header.ver,
					    PCAP_ERR_UPDATEFILTER,
					    "Device not opened. Cannot update filter",
					    errbuf) == -1)
					{
						// That failed; log a message and give up.
						rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
						goto end;
					}
				}
				break;
			}

			case RPCAP_MSG_CLOSE:		// The other endpoint close the pcap session
			{
				//
				// Indicate to our caller that the client
				// closed the control connection.
				// This is used only in case of active mode.
				//
				client_told_us_to_close = 1;
				rpcapd_log(LOGPRIO_DEBUG, "The other end system asked to close the connection.");
				goto end;
			}

			case RPCAP_MSG_STATS_REQ:
			{
				if (daemon_msg_stats_req(header.ver, &pars,
				    session, plen, &stats, svrcapt) == -1)
				{
					// Fatal error; a message has
					// been logged, so just give up.
					goto end;
				}
				break;
			}

			case RPCAP_MSG_ENDCAP_REQ:		// The other endpoint close the current capture session
			{
				if (session)
				{
					// Save statistics (we can need them in the future)
					if (pcap_stats(session->fp, &stats))
					{
						svrcapt = session->TotCapt;
					}
					else
					{
						stats.ps_ifdrop = 0;
						stats.ps_recv = 0;
						stats.ps_drop = 0;
						svrcapt = 0;
					}

					if (daemon_msg_endcap_req(header.ver,
					    &pars, session) == -1)
					{
						free(session);
						session = NULL;
						// Fatal error; a message has
						// been logged, so just give up.
						goto end;
					}
					free(session);
					session = NULL;
				}
				else
				{
					rpcap_senderror(pars.sockctrl, pars.ssl,
					    header.ver,
					    PCAP_ERR_ENDCAPTURE,
					    "Device not opened. Cannot close the capture",
					    errbuf);
				}
				break;
			}

			case RPCAP_MSG_SETSAMPLING_REQ:
			{
				if (daemon_msg_setsampling_req(header.ver,
				    &pars, plen, &samp_param) == -1)
				{
					// Fatal error; a message has
					// been logged, so just give up.
					goto end;
				}
				break;
			}

			case RPCAP_MSG_AUTH_REQ:
			{
				//
				// We're already authenticated; you don't
				// get to reauthenticate.
				//
				rpcapd_log(LOGPRIO_INFO, "The client sent an RPCAP_MSG_AUTH_REQ message after authentication was completed");
				if (rpcap_senderror(pars.sockctrl, pars.ssl,
				    header.ver,
				    PCAP_ERR_WRONGMSG,
				    "RPCAP_MSG_AUTH_REQ request sent after authentication was completed",
				    errbuf) == -1)
				{
					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
					goto end;
				}
				// Discard the rest of the message.
				if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1)
				{
					// Fatal error.
					goto end;
				}
				goto end;

			case RPCAP_MSG_PACKET:
			case RPCAP_MSG_FINDALLIF_REPLY:
			case RPCAP_MSG_OPEN_REPLY:
			case RPCAP_MSG_STARTCAP_REPLY:
			case RPCAP_MSG_UPDATEFILTER_REPLY:
			case RPCAP_MSG_AUTH_REPLY:
			case RPCAP_MSG_STATS_REPLY:
			case RPCAP_MSG_ENDCAP_REPLY:
			case RPCAP_MSG_SETSAMPLING_REPLY:
				//
				// These are server-to-client messages.
				//
				msg_type_string = rpcap_msg_type_string(header.type);
				if (msg_type_string != NULL)
				{
					rpcapd_log(LOGPRIO_INFO, "The client sent a %s server-to-client message", msg_type_string);
					snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message %s received from client", msg_type_string);
				}
				else
				{
					rpcapd_log(LOGPRIO_INFO, "The client sent a server-to-client message of type %u", header.type);
					snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type);
				}
				if (rpcap_senderror(pars.sockctrl, pars.ssl,
				    header.ver, PCAP_ERR_WRONGMSG,
				    errmsgbuf, errbuf) == -1)
				{
					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
					goto end;
				}
				// Discard the rest of the message.
				if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1)
				{
					// Fatal error.
					goto end;
				}
				goto end;

			default:
				//
				// Unknown message type.
				//
				rpcapd_log(LOGPRIO_INFO, "The client sent a message of type %u", header.type);
				snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type);
				if (rpcap_senderror(pars.sockctrl, pars.ssl,
				    header.ver, PCAP_ERR_WRONGMSG,
				    errbuf, errmsgbuf) == -1)
				{
					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
					goto end;
				}
				// Discard the rest of the message.
				if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1)
				{
					// Fatal error.
					goto end;
				}
				goto end;
			}
		}
	}

end:
	// The service loop is finishing up.
	// If we have a capture session running, close it.
	if (session)
	{
		session_close(session);
		free(session);
		session = NULL;
	}

	if (passiveClients) {
		free(passiveClients);
	}
	//
	// Finish using the SSL handle for the control socket, if we
	// have an SSL connection, and close the control socket.
	//
#ifdef HAVE_OPENSSL
	if (ssl)
	{
		// Finish using the SSL handle for the socket.
		// This must be done *before* the socket is closed.
		ssl_finish(ssl);
	}
#endif
	sock_close(sockctrl, NULL, 0);

	// Print message and return
	rpcapd_log(LOGPRIO_DEBUG, "I'm exiting from the child loop");

	return client_told_us_to_close;
}

/*
 * This handles the RPCAP_MSG_ERR message.
 */
static int
daemon_msg_err(PCAP_SOCKET sockctrl, SSL *ssl, uint32 plen)
{
	char errbuf[PCAP_ERRBUF_SIZE];
	char remote_errbuf[PCAP_ERRBUF_SIZE];

	if (plen >= PCAP_ERRBUF_SIZE)
	{
		/*
		 * Message is too long; just read as much of it as we
		 * can into the buffer provided, and discard the rest.
		 */
		if (sock_recv(sockctrl, ssl, remote_errbuf, PCAP_ERRBUF_SIZE - 1,
		    SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
		    PCAP_ERRBUF_SIZE) == -1)
		{
			// Network error.
			rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
			return -1;
		}
		if (rpcapd_discard(sockctrl, ssl, plen - (PCAP_ERRBUF_SIZE - 1)) == -1)
		{
			// Network error.
			return -1;
		}

		/*
		 * Null-terminate it.
		 */
		remote_errbuf[PCAP_ERRBUF_SIZE - 1] = '\0';
	}
	else if (plen == 0)
	{
		/* Empty error string. */
		remote_errbuf[0] = '\0';
	}
	else
	{
		if (sock_recv(sockctrl, ssl, remote_errbuf, plen,
		    SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
		    PCAP_ERRBUF_SIZE) == -1)
		{
			// Network error.
			rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
			return -1;
		}

		/*
		 * Null-terminate it.
		 */
		remote_errbuf[plen] = '\0';
	}
	// Log the message
	rpcapd_log(LOGPRIO_ERROR, "Error from client: %s", remote_errbuf);
	return 0;
}

/*
 * This handles the RPCAP_MSG_AUTH_REQ message.
 * It checks if the authentication credentials supplied by the user are valid.
 *
 * This function is called if the daemon receives a RPCAP_MSG_AUTH_REQ
 * message in its authentication loop.  It reads the body of the
 * authentication message from the network and checks whether the
 * credentials are valid.
 *
 * \param sockctrl: the socket for the control connection.
 *
 * \param nullAuthAllowed: '1' if the NULL authentication is allowed.
 *
 * \param errbuf: a user-allocated buffer in which the error message
 * (if one) has to be written.  It must be at least PCAP_ERRBUF_SIZE
 * bytes long.
 *
 * \return '0' if everything is fine, '-1' if an unrecoverable error occurred,
 * or '-2' if the authentication failed.  For errors, an error message is
 * returned in the 'errbuf' variable; this gives a message for the
 * unrecoverable error or for the authentication failure.
 */
static int
daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen)
{
	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
	char errmsgbuf[PCAP_ERRBUF_SIZE];	// buffer for errors to send to the client
	int status;
	struct rpcap_auth auth;			// RPCAP authentication header
	char sendbuf[RPCAP_NETBUF_SIZE];	// temporary buffer in which data to be sent is buffered
	int sendbufidx = 0;			// index which keeps the number of bytes currently buffered
	struct rpcap_authreply *authreply;	// authentication reply message

	status = rpcapd_recv(pars->sockctrl, pars->ssl, (char *) &auth, sizeof(struct rpcap_auth), &plen, errmsgbuf);
	if (status == -1)
	{
		return -1;
	}
	if (status == -2)
	{
		goto error;
	}

	switch (ntohs(auth.type))
	{
		case RPCAP_RMTAUTH_NULL:
		{
			if (!pars->nullAuthAllowed)
			{
				// Send the client an error reply.
				snprintf(errmsgbuf, PCAP_ERRBUF_SIZE,
				    "Authentication failed; NULL authentication not permitted.");
				if (rpcap_senderror(pars->sockctrl, pars->ssl,
				    0, PCAP_ERR_AUTH_FAILED, errmsgbuf, errbuf) == -1)
				{
					// That failed; log a message and give up.
					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
					return -1;
				}
				goto error_noreply;
			}
			break;
		}

		case RPCAP_RMTAUTH_PWD:
		{
			char *username, *passwd;
			uint32 usernamelen, passwdlen;

			usernamelen = ntohs(auth.slen1);
			username = (char *) malloc (usernamelen + 1);
			if (username == NULL)
			{
				pcapint_fmt_errmsg_for_errno(errmsgbuf,
				    PCAP_ERRBUF_SIZE, errno, "malloc() failed");
				goto error;
			}
			status = rpcapd_recv(pars->sockctrl, pars->ssl, username, usernamelen, &plen, errmsgbuf);
			if (status == -1)
			{
				free(username);
				return -1;
			}
			if (status == -2)
			{
				free(username);
				goto error;
			}
			username[usernamelen] = '\0';

			passwdlen = ntohs(auth.slen2);
			passwd = (char *) malloc (passwdlen + 1);
			if (passwd == NULL)
			{
				pcapint_fmt_errmsg_for_errno(errmsgbuf,
				    PCAP_ERRBUF_SIZE, errno, "malloc() failed");
				free(username);
				goto error;
			}
			status = rpcapd_recv(pars->sockctrl, pars->ssl, passwd, passwdlen, &plen, errmsgbuf);
			if (status == -1)
			{
				free(username);
				free(passwd);
				return -1;
			}
			if (status == -2)
			{
				free(username);
				free(passwd);
				goto error;
			}
			passwd[passwdlen] = '\0';

			if (daemon_AuthUserPwd(username, passwd, errmsgbuf))
			{
				//
				// Authentication failed.  Let the client
				// know.
				//
				free(username);
				free(passwd);
				if (rpcap_senderror(pars->sockctrl, pars->ssl,
				    0, PCAP_ERR_AUTH_FAILED, errmsgbuf, errbuf) == -1)
				{
					// That failed; log a message and give up.
					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
					return -1;
				}

				//
				// Suspend for 1 second, so that they can't
				// hammer us with repeated tries with an
				// attack such as a dictionary attack.
				//
				// WARNING: this delay is inserted only
				// at this point; if the client closes the
				// connection and reconnects, the suspension
				// time does not have any effect.
				//
				sleep_secs(RPCAP_SUSPEND_WRONGAUTH);
				goto error_noreply;
			}

			free(username);
			free(passwd);
			break;
			}

		default:
			snprintf(errmsgbuf, PCAP_ERRBUF_SIZE,
			    "Authentication type not recognized.");
			if (rpcap_senderror(pars->sockctrl, pars->ssl,
			    0, PCAP_ERR_AUTH_TYPE_NOTSUP, errmsgbuf, errbuf) == -1)
			{
				// That failed; log a message and give up.
				rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
				return -1;
			}
			goto error_noreply;
	}

	// The authentication succeeded; let the client know.
	if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
	    RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	rpcap_createhdr((struct rpcap_header *) sendbuf, 0,
	    RPCAP_MSG_AUTH_REPLY, 0, sizeof(struct rpcap_authreply));

	authreply = (struct rpcap_authreply *) &sendbuf[sendbufidx];

	if (sock_bufferize(NULL, sizeof(struct rpcap_authreply), NULL, &sendbufidx,
	    RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	//
	// Indicate to our peer what versions we support and what our
	// version of the byte-order magic is (which will tell the
	// client whether our byte order differs from theirs, in which
	// case they will need to byte-swap some fields in some
	// link-layer types' headers).
	//
	memset(authreply, 0, sizeof(struct rpcap_authreply));
	authreply->minvers = RPCAP_MIN_VERSION;
	authreply->maxvers = RPCAP_MAX_VERSION;
	authreply->byte_order_magic = RPCAP_BYTE_ORDER_MAGIC;

	// Send the reply.
	if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
	{
		// That failed; log a message and give up.
		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
		return -1;
	}

	// Check if all the data has been read; if not, discard the data in excess
	if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1)
	{
		return -1;
	}

	return 0;

error:
	if (rpcap_senderror(pars->sockctrl, pars->ssl, 0, PCAP_ERR_AUTH,
	    errmsgbuf, errbuf) == -1)
	{
		// That failed; log a message and give up.
		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
		return -1;
	}

error_noreply:
	// Check if all the data has been read; if not, discard the data in excess
	if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1)
	{
		return -1;
	}

	return -2;
}

static int
daemon_AuthUserPwd(char *username, char *password, char *errbuf)
{
#ifdef _WIN32
	/*
	 * Warning: the user which launches the process must have the
	 * SE_TCB_NAME right.
	 * This corresponds to have the "Act as part of the Operating System"
	 * turned on (administrative tools, local security settings, local
	 * policies, user right assignment)
	 * However, it seems to me that if you run it as a service, this
	 * right should be provided by default.
	 *
	 * XXX - hopefully, this returns errors such as ERROR_LOGON_FAILURE,
	 * which merely indicates that the user name or password is
	 * incorrect, not whether it's the user name or the password
	 * that's incorrect, so a client that's trying to brute-force
	 * accounts doesn't know whether it's the user name or the
	 * password that's incorrect, so it doesn't know whether to
	 * stop trying to log in with a given user name and move on
	 * to another user name.
	 */
	DWORD error;
	HANDLE Token;
	char errmsgbuf[PCAP_ERRBUF_SIZE];	// buffer for errors to log

	if (LogonUser(username, ".", password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &Token) == 0)
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed");
		error = GetLastError();
		if (error != ERROR_LOGON_FAILURE)
		{
			// Some error other than an authentication error;
			// log it.
			pcapint_fmt_errmsg_for_win32_err(errmsgbuf,
			    PCAP_ERRBUF_SIZE, error, "LogonUser() failed");
			rpcapd_log(LOGPRIO_ERROR, "%s", errmsgbuf);
		}
		return -1;
	}

	// This call should change the current thread to the selected user.
	// I didn't test it.
	if (ImpersonateLoggedOnUser(Token) == 0)
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed");
		pcapint_fmt_errmsg_for_win32_err(errmsgbuf, PCAP_ERRBUF_SIZE,
		    GetLastError(), "ImpersonateLoggedOnUser() failed");
		rpcapd_log(LOGPRIO_ERROR, "%s", errmsgbuf);
		CloseHandle(Token);
		return -1;
	}

	CloseHandle(Token);
	return 0;

#else
	/*
	 * See
	 *
	 *	https://www.unixpapa.com/incnote/passwd.html
	 *
	 * We use the Solaris/Linux shadow password authentication if
	 * we have getspnam(), otherwise we just do traditional
	 * authentication, which, on some platforms, might work, even
	 * with shadow passwords, if we're running as root.  Traditional
	 * authentication won't work if we're not running as root, as
	 * I think these days all UN*Xes either won't return the password
	 * at all with getpwnam() or will only do so if you're root.
	 *
	 * XXX - perhaps what we *should* be using is PAM, if we have
	 * it.  That might hide all the details of username/password
	 * authentication, whether it's done with a visible-to-root-
	 * only password database or some other authentication mechanism,
	 * behind its API.
	 */
	int error;
	struct passwd *user;
	char *user_password;
#ifdef HAVE_GETSPNAM
	struct spwd *usersp;
#endif
	char *crypt_password;

	// This call is needed to get the uid
	if ((user = getpwnam(username)) == NULL)
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed");
		return -1;
	}

#ifdef HAVE_GETSPNAM
	// This call is needed to get the password; otherwise 'x' is returned
	if ((usersp = getspnam(username)) == NULL)
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed");
		return -1;
	}
	user_password = usersp->sp_pwdp;
#else
	/*
	 * XXX - what about other platforms?
	 * The unixpapa.com page claims this Just Works on *BSD if you're
	 * running as root - it's from 2000, so it doesn't indicate whether
	 * macOS (which didn't come out until 2001, under the name Mac OS
	 * X) behaves like the *BSDs or not, and might also work on AIX.
	 * HP-UX does something else.
	 *
	 * Again, hopefully PAM hides all that.
	 */
	user_password = user->pw_passwd;
#endif

	//
	// The Single UNIX Specification says that if crypt() fails it
	// sets errno, but some implementations that haven't been run
	// through the SUS test suite might not do so.
	//
	errno = 0;
	crypt_password = crypt(password, user_password);
	if (crypt_password == NULL)
	{
		error = errno;
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed");
		if (error == 0)
		{
			// It didn't set errno.
			rpcapd_log(LOGPRIO_ERROR, "crypt() failed");
		}
		else
		{
			rpcapd_log(LOGPRIO_ERROR, "crypt() failed: %s",
			    strerror(error));
		}
		return -1;
	}
	if (strcmp(user_password, crypt_password) != 0)
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed");
		return -1;
	}

	if (setuid(user->pw_uid))
	{
		error = errno;
		pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
		    error, "setuid");
		rpcapd_log(LOGPRIO_ERROR, "setuid() failed: %s",
		    strerror(error));
		return -1;
	}

/*	if (setgid(user->pw_gid))
	{
		error = errno;
		pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
		    errno, "setgid");
		rpcapd_log(LOGPRIO_ERROR, "setgid() failed: %s",
		    strerror(error));
		return -1;
	}
*/
	return 0;

#endif

}

/*
 * Make sure that the reply length won't overflow 32 bits if we add the
 * specified amount to it.  If it won't, add that amount to it.
 *
 * We check whether replylen + itemlen > UINT32_MAX, but subtract itemlen
 * from both sides, to prevent overflow.
 */
#define CHECK_AND_INCREASE_REPLY_LEN(itemlen) \
	if (replylen > UINT32_MAX - (itemlen)) { \
		pcapint_strlcpy(errmsgbuf, "Reply length doesn't fit in 32 bits", \
		    sizeof (errmsgbuf)); \
		goto error; \
	} \
	replylen += (uint32)(itemlen)

static int
daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen)
{
	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
	char errmsgbuf[PCAP_ERRBUF_SIZE];	// buffer for errors to send to the client
	char sendbuf[RPCAP_NETBUF_SIZE];	// temporary buffer in which data to be sent is buffered
	int sendbufidx = 0;			// index which keeps the number of bytes currently buffered
	pcap_if_t *alldevs = NULL;		// pointer to the header of the interface chain
	pcap_if_t *d;				// temp pointer needed to scan the interface chain
	struct pcap_addr *address;		// pcap structure that keeps a network address of an interface
	uint32 replylen;			// length of reply payload
	uint16 nif = 0;				// counts the number of interface listed

	// Discard the rest of the message; there shouldn't be any payload.
	if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1)
	{
		// Network error.
		return -1;
	}

	// Retrieve the device list
	if (pcap_findalldevs(&alldevs, errmsgbuf) == -1)
		goto error;

	if (alldevs == NULL)
	{
		if (rpcap_senderror(pars->sockctrl, pars->ssl, ver,
			PCAP_ERR_NOREMOTEIF,
			"No interfaces found! Make sure libpcap/WinPcap is properly installed"
			" and you have the right to access to the remote device.",
			errbuf) == -1)
		{
			rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
			return -1;
		}
		return 0;
	}

	// This checks the number of interfaces and computes the total
	// length of the payload.
	replylen = 0;
	for (d = alldevs; d != NULL; d = d->next)
	{
		nif++;

		if (d->description) {
			size_t stringlen = strlen(d->description);
			if (stringlen > UINT16_MAX) {
				pcapint_strlcpy(errmsgbuf,
				    "Description length doesn't fit in 16 bits",
				    sizeof (errmsgbuf));
				goto error;
			}
			CHECK_AND_INCREASE_REPLY_LEN(stringlen);
		}
		if (d->name) {
			size_t stringlen = strlen(d->name);
			if (stringlen > UINT16_MAX) {
				pcapint_strlcpy(errmsgbuf,
				    "Name length doesn't fit in 16 bits",
				    sizeof (errmsgbuf));
				goto error;
			}
			CHECK_AND_INCREASE_REPLY_LEN(stringlen);
		}

		CHECK_AND_INCREASE_REPLY_LEN(sizeof(struct rpcap_findalldevs_if));

		uint16_t naddrs = 0;
		for (address = d->addresses; address != NULL; address = address->next)
		{
			/*
			 * Send only IPv4 and IPv6 addresses over the wire.
			 */
			switch (address->addr->sa_family)
			{
			case AF_INET:
#ifdef AF_INET6
			case AF_INET6:
#endif
				CHECK_AND_INCREASE_REPLY_LEN(sizeof(struct rpcap_sockaddr) * 4);
				if (naddrs == UINT16_MAX) {
					pcapint_strlcpy(errmsgbuf,
					    "Number of interfaces doesn't fit in 16 bits",
					    sizeof (errmsgbuf));
					goto error;
				}
				naddrs++;
				break;

			default:
				break;
			}
		}
	}

	// RPCAP findalldevs reply
	if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
	    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf,
	    PCAP_ERRBUF_SIZE) == -1)
		goto error;

	rpcap_createhdr((struct rpcap_header *) sendbuf, ver,
	    RPCAP_MSG_FINDALLIF_REPLY, nif, replylen);

	// send the interface list
	for (d = alldevs; d != NULL; d = d->next)
	{
		uint16 lname, ldescr;

		// Note: the findalldevs_if entries are *not* neatly
		// aligned on 4-byte boundaries, because they're
		// preceded by strings that aren't padded to 4-byte
		// boundaries, so we cannot just cast output buffer
		// boundaries to struct rpcap_findalldevs_if pointers
		// and store into them - we must fill in a structure and
		// then copy the structure to the buffer, as not all
		// systems support unaligned access (some, such as
		// SPARC, crash; others, such as Arm, may just ignore
		// the lower-order bits).
		struct rpcap_findalldevs_if findalldevs_if;

		/*
		 * We've already established that the string lengths
		 * fit in 16 bits.
		 */
		if (d->description)
			ldescr = (uint16) strlen(d->description);
		else
			ldescr = 0;
		if (d->name)
			lname = (uint16) strlen(d->name);
		else
			lname = 0;

		findalldevs_if.desclen = htons(ldescr);
		findalldevs_if.namelen = htons(lname);
		findalldevs_if.flags = htonl(d->flags);

		uint16_t naddrs = 0;
		for (address = d->addresses; address != NULL; address = address->next)
		{
			/*
			 * Send only IPv4 and IPv6 addresses over the wire.
			 */
			switch (address->addr->sa_family)
			{
			case AF_INET:
#ifdef AF_INET6
			case AF_INET6:
#endif
				naddrs++;
				break;

			default:
				break;
			}
		}
		findalldevs_if.naddr = htons(naddrs);
		findalldevs_if.dummy = 0;

		if (sock_bufferize(&findalldevs_if, sizeof(struct rpcap_findalldevs_if), sendbuf,
		    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errmsgbuf,
		    PCAP_ERRBUF_SIZE) == -1)
			goto error;

		if (sock_bufferize(d->name, lname, sendbuf, &sendbufidx,
		    RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errmsgbuf,
		    PCAP_ERRBUF_SIZE) == -1)
			goto error;

		if (sock_bufferize(d->description, ldescr, sendbuf, &sendbufidx,
		    RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errmsgbuf,
		    PCAP_ERRBUF_SIZE) == -1)
			goto error;

		// send all addresses
		for (address = d->addresses; address != NULL; address = address->next)
		{
			struct rpcap_sockaddr *sockaddr;

			/*
			 * Send only IPv4 and IPv6 addresses over the wire.
			 */
			switch (address->addr->sa_family)
			{
			case AF_INET:
#ifdef AF_INET6
			case AF_INET6:
#endif
				sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx];
				if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL,
				    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
					goto error;
				daemon_seraddr((struct sockaddr_storage *) address->addr, sockaddr);

				sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx];
				if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL,
				    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
					goto error;
				daemon_seraddr((struct sockaddr_storage *) address->netmask, sockaddr);

				sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx];
				if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL,
				    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
					goto error;
				daemon_seraddr((struct sockaddr_storage *) address->broadaddr, sockaddr);

				sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx];
				if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL,
				    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
					goto error;
				daemon_seraddr((struct sockaddr_storage *) address->dstaddr, sockaddr);
				break;

			default:
				break;
			}
		}
	}

	// We no longer need the device list. Free it.
	pcap_freealldevs(alldevs);

	// Send a final command that says "now send it!"
	if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
	{
		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
		return -1;
	}

	return 0;

error:
	if (alldevs)
		pcap_freealldevs(alldevs);

	if (rpcap_senderror(pars->sockctrl, pars->ssl, ver,
	    PCAP_ERR_FINDALLIF, errmsgbuf, errbuf) == -1)
	{
		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
		return -1;
	}
	return 0;
}

/*
	\param plen: the length of the current message (needed in order to be able
	to discard excess data in the message, if present)
*/
static int
daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
    char *source, size_t sourcelen)
{
	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
	char errmsgbuf[PCAP_ERRBUF_SIZE];	// buffer for errors to send to the client
	pcap_t *fp;				// pcap_t main variable
	int nread;
	char sendbuf[RPCAP_NETBUF_SIZE];	// temporary buffer in which data to be sent is buffered
	int sendbufidx = 0;			// index which keeps the number of bytes currently buffered
	struct rpcap_openreply *openreply;	// open reply message

	if (plen > sourcelen - 1)
	{
		snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Source string too long");
		goto error;
	}

	nread = sock_recv(pars->sockctrl, pars->ssl, source, plen,
	    SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE);
	if (nread == -1)
	{
		rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
		return -1;
	}
	source[nread] = '\0';
	plen -= nread;

	// Is this a URL rather than a device?
	// If so, reject it.
	if (is_url(source))
	{
		snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Source string refers to a remote device");
		goto error;
	}

	// Open the selected device
	// This is a fake open, since we do that only to get the needed parameters, then we close the device again
	if ((fp = pcap_open_live(source,
			1500 /* fake snaplen */,
			0 /* no promisc */,
			1000 /* fake timeout */,
			errmsgbuf)) == NULL)
		goto error;

	// Now, I can send a RPCAP open reply message
	if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
	    RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	rpcap_createhdr((struct rpcap_header *) sendbuf, ver,
	    RPCAP_MSG_OPEN_REPLY, 0, sizeof(struct rpcap_openreply));

	openreply = (struct rpcap_openreply *) &sendbuf[sendbufidx];

	if (sock_bufferize(NULL, sizeof(struct rpcap_openreply), NULL, &sendbufidx,
	    RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	memset(openreply, 0, sizeof(struct rpcap_openreply));
	openreply->linktype = htonl(pcap_datalink(fp));
	/*
	 * This is always 0 for live captures; we no longer support it
	 * as something we read from capture files and supply to
	 * clients, but we have to send it over the wire, as open
	 * replies are expected to have 8 bytes of payload by
	 * existing clients.
	 */
	openreply->tzoff = 0;

	// We're done with the pcap_t.
	pcap_close(fp);

	// Send the reply.
	if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
	{
		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
		return -1;
	}
	return 0;

error:
	if (rpcap_senderror(pars->sockctrl, pars->ssl, ver, PCAP_ERR_OPEN,
	    errmsgbuf, errbuf) == -1)
	{
		// That failed; log a message and give up.
		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
		return -1;
	}

	// Check if all the data has been read; if not, discard the data in excess
	if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1)
	{
		return -1;
	}
	return 0;
}

/*
	\param plen: the length of the current message (needed in order to be able
	to discard excess data in the message, if present)
*/
static int
daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
    char *source, struct session **sessionp,
    struct rpcap_sampling *samp_param _U_, int uses_ssl)
{
	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
	char errmsgbuf[PCAP_ERRBUF_SIZE];	// buffer for errors to send to the client
	char portdata[PCAP_BUF_SIZE];		// temp variable needed to derive the data port
	char peerhost[PCAP_BUF_SIZE];		// temp variable needed to derive the host name of our peer
	struct session *session = NULL;		// saves state of session
	int status;
	char sendbuf[RPCAP_NETBUF_SIZE];	// temporary buffer in which data to be sent is buffered
	int sendbufidx = 0;			// index which keeps the number of bytes currently buffered

	// socket-related variables
	struct addrinfo hints;			// temp, needed to open a socket connection
	struct addrinfo *addrinfo;		// temp, needed to open a socket connection
	struct sockaddr_storage saddr;		// temp, needed to retrieve the network data port chosen on the local machine
	socklen_t saddrlen;			// temp, needed to retrieve the network data port chosen on the local machine
	int ret;				// return value from functions

	// RPCAP-related variables
	struct rpcap_startcapreq startcapreq;		// start capture request message
	struct rpcap_startcapreply *startcapreply;	// start capture reply message
	int serveropen_dp;							// keeps who is going to open the data connection

	addrinfo = NULL;

	status = rpcapd_recv(pars->sockctrl, pars->ssl, (char *) &startcapreq,
	    sizeof(struct rpcap_startcapreq), &plen, errmsgbuf);
	if (status == -1)
	{
		goto fatal_error;
	}
	if (status == -2)
	{
		goto error;
	}

	startcapreq.flags = ntohs(startcapreq.flags);

	// Check that the client does not ask for UDP is the server has been asked
	// to enforce encryption, as SSL is not supported yet with UDP:
	if (uses_ssl && (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM))
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE,
		    "SSL not supported with UDP forward of remote packets");
		goto error;
	}

	// Create a session structure
	session = malloc(sizeof(struct session));
	if (session == NULL)
	{
		snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Can't allocate session structure");
		goto error;
	}

	session->sockdata = INVALID_SOCKET;
	session->ctrl_ssl = session->data_ssl = NULL;
	// We don't have a thread yet.
	session->have_thread = 0;
	//
	// We *shouldn't* have to initialize the thread indicator
	// itself, because the compiler *should* realize that we
	// only use this if have_thread isn't 0, but we *do* have
	// to do it, because not all compilers *do* realize that.
	//
	// There is no "invalid thread handle" value for a UN*X
	// pthread_t, so we just zero it out.
	//
#ifdef _WIN32
	session->thread = INVALID_HANDLE_VALUE;
#else
	memset(&session->thread, 0, sizeof(session->thread));
#endif

	// Open the selected device
	if ((session->fp = pcap_open_live(source,
			ntohl(startcapreq.snaplen),
			(startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_PROMISC) ? 1 : 0 /* local device, other flags not needed */,
			ntohl(startcapreq.read_timeout),
			errmsgbuf)) == NULL)
		goto error;

#if 0
	// Apply sampling parameters
	fp->rmt_samp.method = samp_param->method;
	fp->rmt_samp.value = samp_param->value;
#endif

	/*
	We're in active mode if:
	- we're using TCP, and the user wants us to be in active mode
	- we're using UDP
	*/
	serveropen_dp = (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_SERVEROPEN) || (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM) || pars->isactive;

	/*
	Gets the sockaddr structure referred to the other peer in the ctrl connection

	We need that because:
	- if we're in passive mode, we need to know the address family we want to use
	(the same used for the ctrl socket)
	- if we're in active mode, we need to know the network address of the other host
	we want to connect to
	*/
	saddrlen = sizeof(struct sockaddr_storage);
	if (getpeername(pars->sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
	{
		sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
		    "getpeername() failed");
		goto error;
	}

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_socktype = (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM) ? SOCK_DGRAM : SOCK_STREAM;
	hints.ai_family = saddr.ss_family;

	// Now we have to create a new socket to send packets
	if (serveropen_dp)		// Data connection is opened by the server toward the client
	{
		snprintf(portdata, sizeof portdata, "%d", ntohs(startcapreq.portdata));

		// Get the name of the other peer (needed to connect to that specific network address)
		if (getnameinfo((struct sockaddr *) &saddr, saddrlen, peerhost,
				sizeof(peerhost), NULL, 0, NI_NUMERICHOST))
		{
			sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
			    "getnameinfo() failed");
			goto error;
		}

		addrinfo = sock_initaddress(peerhost, portdata, &hints,
		    errmsgbuf, PCAP_ERRBUF_SIZE);
		if (addrinfo == NULL)
			goto error;

		if ((session->sockdata = sock_open(peerhost, addrinfo, SOCKOPEN_CLIENT, 0, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
			goto error;
	}
	else		// Data connection is opened by the client toward the server
	{
		hints.ai_flags = AI_PASSIVE;

		// Make the server socket pick up a free network port for us
		addrinfo = sock_initaddress(NULL, NULL, &hints, errmsgbuf,
		    PCAP_ERRBUF_SIZE);
		if (addrinfo == NULL)
			goto error;

		if ((session->sockdata = sock_open(NULL, addrinfo, SOCKOPEN_SERVER, 1 /* max 1 connection in queue */, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
			goto error;

		// get the complete sockaddr structure used in the data connection
		saddrlen = sizeof(struct sockaddr_storage);
		if (getsockname(session->sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1)
		{
			sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
			    "getsockname() failed");
			goto error;
		}

		// Get the local port the system picked up
		if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL,
				0, portdata, sizeof(portdata), NI_NUMERICSERV))
		{
			sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
			    "getnameinfo() failed");
			goto error;
		}
	}

	// addrinfo is no longer used
	freeaddrinfo(addrinfo);
	addrinfo = NULL;

	// Needed to send an error on the ctrl connection
	session->sockctrl = pars->sockctrl;
	session->ctrl_ssl = pars->ssl;
	session->protocol_version = ver;

	// Now I can set the filter
	ret = daemon_unpackapplyfilter(pars->sockctrl, pars->ssl, session, &plen, errmsgbuf);
	if (ret == -1)
	{
		// Fatal error.  A message has been logged; just give up.
		goto fatal_error;
	}
	if (ret == -2)
	{
		// Non-fatal error.  Send an error message to the client.
		goto error;
	}

	// Now, I can send a RPCAP start capture reply message
	if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
	    RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	rpcap_createhdr((struct rpcap_header *) sendbuf, ver,
	    RPCAP_MSG_STARTCAP_REPLY, 0, sizeof(struct rpcap_startcapreply));

	startcapreply = (struct rpcap_startcapreply *) &sendbuf[sendbufidx];

	if (sock_bufferize(NULL, sizeof(struct rpcap_startcapreply), NULL,
	    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	memset(startcapreply, 0, sizeof(struct rpcap_startcapreply));
	startcapreply->bufsize = htonl(pcap_bufsize(session->fp));

	if (!serveropen_dp)
	{
		unsigned short port = (unsigned short)strtoul(portdata,NULL,10);
		startcapreply->portdata = htons(port);
	}

	if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
	{
		// That failed; log a message and give up.
		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
		goto fatal_error;
	}

	if (!serveropen_dp)
	{
		PCAP_SOCKET socktemp;	// We need another socket, since we're going to accept() a connection

		// Connection creation
		saddrlen = sizeof(struct sockaddr_storage);

		socktemp = accept(session->sockdata, (struct sockaddr *) &saddr, &saddrlen);

		if (socktemp == INVALID_SOCKET)
		{
			sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
			   "accept() failed");
			rpcapd_log(LOGPRIO_ERROR, "Accept of data connection failed: %s",
			    errbuf);
			goto error;
		}

		// Now that I accepted the connection, the server socket is no longer needed
		sock_close(session->sockdata, NULL, 0);
		session->sockdata = socktemp;
	}

	SSL *ssl = NULL;
	if (uses_ssl)
	{
#ifdef HAVE_OPENSSL
		/* In both active or passive cases, wait for the client to initiate the
		 * TLS handshake. Yes during that time the control socket will not be
		 * served, but the same was true from the above call to accept(). */
		ssl = ssl_promotion(1, session->sockdata, errbuf, PCAP_ERRBUF_SIZE);
		if (! ssl)
		{
			rpcapd_log(LOGPRIO_ERROR, "TLS handshake failed: %s", errbuf);
			goto error;
		}
#endif
	}
	session->data_ssl = ssl;

	// Now we have to create a new thread to receive packets
#ifdef _WIN32
	session->thread = (HANDLE)_beginthreadex(NULL, 0, daemon_thrdatamain,
	    (void *) session, 0, NULL);
	if (session->thread == 0)
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the data thread");
		goto error;
	}
#else
	ret = pthread_create(&session->thread, NULL, daemon_thrdatamain,
	    (void *) session);
	if (ret != 0)
	{
		pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
		    ret, "Error creating the data thread");
		goto error;
	}
#endif
	session->have_thread = 1;

	// Check if all the data has been read; if not, discard the data in excess
	if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1)
		goto fatal_error;

	*sessionp = session;
	return 0;

error:
	//
	// Not a fatal error, so send the client an error message and
	// keep serving client requests.
	//
	*sessionp = NULL;

	if (addrinfo)
		freeaddrinfo(addrinfo);

	if (session)
	{
		session_close(session);
		free(session);
	}

	if (rpcap_senderror(pars->sockctrl, pars->ssl, ver,
	    PCAP_ERR_STARTCAPTURE, errmsgbuf, errbuf) == -1)
	{
		// That failed; log a message and give up.
		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
		return -1;
	}

	// Check if all the data has been read; if not, discard the data in excess
	if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1)
	{
		// Network error.
		return -1;
	}

	return 0;

fatal_error:
	//
	// Fatal network error, so don't try to communicate with
	// the client, just give up.
	//
	*sessionp = NULL;

	if (session)
	{
		session_close(session);
		free(session);
	}

	return -1;
}

static int
daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars,
    struct session *session)
{
	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
	struct rpcap_header header;

	session_close(session);

	rpcap_createhdr(&header, ver, RPCAP_MSG_ENDCAP_REPLY, 0, 0);

	if (sock_send(pars->sockctrl, pars->ssl, (char *) &header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
	{
		// That failed; log a message and give up.
		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
		return -1;
	}

	return 0;
}

//
// We impose a limit on the filter program size, so that, on Windows,
// where there's only one server process with multiple threads, it's
// harder to eat all the server address space by sending larger filter
// programs.  (This isn't an issue on UN*X, where there are multiple
// server processes, one per client connection.)
//
// We pick a value that limits each filter to 64K; that value is twice
// the in-kernel limit for Linux and 16 times the in-kernel limit for
// *BSD and macOS.
//
// It also prevents an overflow on 32-bit platforms when calculating
// the total size of the filter program.  (It's not an issue on 64-bit
// platforms with a 64-bit size_t, as the filter size is 32 bits.)
//
#define RPCAP_BPF_MAXINSNS	8192

static int
daemon_unpackapplyfilter(PCAP_SOCKET sockctrl, SSL *ctrl_ssl, struct session *session, uint32 *plenp, char *errmsgbuf)
{
	int status;
	struct rpcap_filter filter;
	struct rpcap_filterbpf_insn insn;
	struct bpf_insn *bf_insn;
	struct bpf_program bf_prog;
	unsigned int i;

	status = rpcapd_recv(sockctrl, ctrl_ssl, (char *) &filter,
	    sizeof(struct rpcap_filter), plenp, errmsgbuf);
	if (status == -1)
	{
		return -1;
	}
	if (status == -2)
	{
		return -2;
	}

	bf_prog.bf_len = ntohl(filter.nitems);

	if (ntohs(filter.filtertype) != RPCAP_UPDATEFILTER_BPF)
	{
		snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Only BPF/NPF filters are currently supported");
		return -2;
	}

	if (bf_prog.bf_len > RPCAP_BPF_MAXINSNS)
	{
		snprintf(errmsgbuf, PCAP_ERRBUF_SIZE,
		    "Filter program is larger than the maximum size of %d instructions",
		    RPCAP_BPF_MAXINSNS);
		return -2;
	}
	bf_insn = (struct bpf_insn *) malloc (sizeof(struct bpf_insn) * bf_prog.bf_len);
	if (bf_insn == NULL)
	{
		pcapint_fmt_errmsg_for_errno(errmsgbuf, PCAP_ERRBUF_SIZE,
		    errno, "malloc() failed");
		return -2;
	}

	bf_prog.bf_insns = bf_insn;

	for (i = 0; i < bf_prog.bf_len; i++)
	{
		status = rpcapd_recv(sockctrl, ctrl_ssl, (char *) &insn,
		    sizeof(struct rpcap_filterbpf_insn), plenp, errmsgbuf);
		if (status == -1)
		{
			return -1;
		}
		if (status == -2)
		{
			return -2;
		}

		bf_insn->code = ntohs(insn.code);
		bf_insn->jf = insn.jf;
		bf_insn->jt = insn.jt;
		bf_insn->k = ntohl(insn.k);

		bf_insn++;
	}

	//
	// XXX - pcap_setfilter() should do the validation for us.
	//
	if (bpf_validate(bf_prog.bf_insns, bf_prog.bf_len) == 0)
	{
		snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "The filter contains bogus instructions");
		return -2;
	}

	if (pcap_setfilter(session->fp, &bf_prog))
	{
		snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "RPCAP error: %s", pcap_geterr(session->fp));
		return -2;
	}

	return 0;
}

static int
daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars,
    struct session *session, uint32 plen)
{
	char errbuf[PCAP_ERRBUF_SIZE];
	char errmsgbuf[PCAP_ERRBUF_SIZE];	// buffer for errors to send to the client
	int ret;				// status of daemon_unpackapplyfilter()
	struct rpcap_header header;		// keeps the answer to the updatefilter command

	ret = daemon_unpackapplyfilter(pars->sockctrl, pars->ssl, session, &plen, errmsgbuf);
	if (ret == -1)
	{
		// Fatal error.  A message has been logged; just give up.
		return -1;
	}
	if (ret == -2)
	{
		// Non-fatal error.  Send an error reply to the client.
		goto error;
	}

	// Check if all the data has been read; if not, discard the data in excess
	if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1)
	{
		// Network error.
		return -1;
	}

	// A response is needed, otherwise the other host does not know that everything went well
	rpcap_createhdr(&header, ver, RPCAP_MSG_UPDATEFILTER_REPLY, 0, 0);

	if (sock_send(pars->sockctrl, pars->ssl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE))
	{
		// That failed; log a message and give up.
		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
		return -1;
	}

	return 0;

error:
	if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1)
	{
		return -1;
	}
	rpcap_senderror(pars->sockctrl, pars->ssl, ver, PCAP_ERR_UPDATEFILTER,
	    errmsgbuf, NULL);

	return 0;
}

/*!
	\brief Received the sampling parameters from remote host and it stores in the pcap_t structure.
*/
static int
daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
    struct rpcap_sampling *samp_param)
{
	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
	char errmsgbuf[PCAP_ERRBUF_SIZE];
	struct rpcap_header header;
	struct rpcap_sampling rpcap_samp;
	int status;

	status = rpcapd_recv(pars->sockctrl, pars->ssl, (char *) &rpcap_samp, sizeof(struct rpcap_sampling), &plen, errmsgbuf);
	if (status == -1)
	{
		return -1;
	}
	if (status == -2)
	{
		goto error;
	}

	// Save these settings in the pcap_t
	samp_param->method = rpcap_samp.method;
	samp_param->value = ntohl(rpcap_samp.value);

	// A response is needed, otherwise the other host does not know that everything went well
	rpcap_createhdr(&header, ver, RPCAP_MSG_SETSAMPLING_REPLY, 0, 0);

	if (sock_send(pars->sockctrl, pars->ssl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
	{
		// That failed; log a message and give up.
		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
		return -1;
	}

	if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1)
	{
		return -1;
	}

	return 0;

error:
	if (rpcap_senderror(pars->sockctrl, pars->ssl, ver, PCAP_ERR_SETSAMPLING,
	    errmsgbuf, errbuf) == -1)
	{
		// That failed; log a message and give up.
		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
		return -1;
	}

	// Check if all the data has been read; if not, discard the data in excess
	if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1)
	{
		return -1;
	}

	return 0;
}

static int
daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars,
    struct session *session, uint32 plen, struct pcap_stat *stats,
    unsigned int svrcapt)
{
	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
	char errmsgbuf[PCAP_ERRBUF_SIZE];	// buffer for errors to send to the client
	char sendbuf[RPCAP_NETBUF_SIZE];	// temporary buffer in which data to be sent is buffered
	int sendbufidx = 0;			// index which keeps the number of bytes currently buffered
	struct rpcap_stats *netstats;		// statistics sent on the network

	// Checks that the header does not contain other data; if so, discard it
	if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1)
	{
		// Network error.
		return -1;
	}

	if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
	    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	rpcap_createhdr((struct rpcap_header *) sendbuf, ver,
	    RPCAP_MSG_STATS_REPLY, 0, (uint16) sizeof(struct rpcap_stats));

	netstats = (struct rpcap_stats *) &sendbuf[sendbufidx];

	if (sock_bufferize(NULL, sizeof(struct rpcap_stats), NULL,
	    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	if (session && session->fp)
	{
		if (pcap_stats(session->fp, stats) == -1)
		{
			snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "%s", pcap_geterr(session->fp));
			goto error;
		}

		netstats->ifdrop = htonl(stats->ps_ifdrop);
		netstats->ifrecv = htonl(stats->ps_recv);
		netstats->krnldrop = htonl(stats->ps_drop);
		netstats->svrcapt = htonl(session->TotCapt);
	}
	else
	{
		// We have to keep compatibility with old applications,
		// which ask for statistics also when the capture has
		// already stopped.
		netstats->ifdrop = htonl(stats->ps_ifdrop);
		netstats->ifrecv = htonl(stats->ps_recv);
		netstats->krnldrop = htonl(stats->ps_drop);
		netstats->svrcapt = htonl(svrcapt);
	}

	// Send the packet
	if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
	{
		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
		return -1;
	}

	return 0;

error:
	rpcap_senderror(pars->sockctrl, pars->ssl, ver, PCAP_ERR_GETSTATS,
	    errmsgbuf, NULL);
	return 0;
}

#ifdef _WIN32
static unsigned __stdcall
#else
static void *
#endif
daemon_thrdatamain(void *ptr)
{
	char errbuf[PCAP_ERRBUF_SIZE + 1];	// error buffer
	struct session *session;		// pointer to the struct session for this session
	int retval;							// general variable used to keep the return value of other functions
	struct rpcap_pkthdr *net_pkt_header;// header of the packet
	struct pcap_pkthdr *pkt_header;		// pointer to the buffer that contains the header of the current packet
	u_char *pkt_data;					// pointer to the buffer that contains the current packet
	size_t sendbufsize;			// size for the send buffer
	char *sendbuf;						// temporary buffer in which data to be sent is buffered
	int sendbufidx;						// index which keeps the number of bytes currently buffered
	int status;
#ifndef _WIN32
	sigset_t sigusr1;			// signal set with just SIGUSR1
#endif

	session = (struct session *) ptr;

	session->TotCapt = 0;			// counter which is incremented each time a packet is received

	// Initialize errbuf
	memset(errbuf, 0, sizeof(errbuf));

	//
	// We need a buffer large enough to hold a buffer large enough
	// for a maximum-size packet for this pcap_t.
	//
	if (pcap_snapshot(session->fp) < 0)
	{
		//
		// The snapshot length is negative.
		// This "should not happen".
		//
		rpcapd_log(LOGPRIO_ERROR,
		    "Unable to allocate the buffer for this child thread: snapshot length of %d is negative",
		        pcap_snapshot(session->fp));
		sendbuf = NULL;	// we can't allocate a buffer, so nothing to free
		goto error;
	}
	//
	// size_t is unsigned, and the result of pcap_snapshot() is signed;
	// on no platform that we support is int larger than size_t.
	// This means that, unless the extra information we prepend to
	// a maximum-sized packet is impossibly large, the sum of the
	// snapshot length and the size of that extra information will
	// fit in a size_t.
	//
	// So we don't need to make sure that sendbufsize will overflow.
	//
	// However, we *do* need to make sure its value fits in an int,
	// because sock_send() can't send more than INT_MAX bytes (it could
	// do so on 64-bit UN*Xes, but can't do so on Windows, not even
	// 64-bit Windows, as the send() buffer size argument is an int
	// in Winsock).
	//
	sendbufsize = sizeof(struct rpcap_header) + sizeof(struct rpcap_pkthdr) + pcap_snapshot(session->fp);
	if (sendbufsize > INT_MAX)
	{
		rpcapd_log(LOGPRIO_ERROR,
		    "Buffer size for this child thread would be larger than %d",
		    INT_MAX);
		sendbuf = NULL;	// we haven't allocated a buffer, so nothing to free
		goto error;
	}
	sendbuf = (char *) malloc (sendbufsize);
	if (sendbuf == NULL)
	{
		rpcapd_log(LOGPRIO_ERROR,
		    "Unable to allocate the buffer for this child thread");
		goto error;
	}

#ifndef _WIN32
	//
	// Set the signal set to include just SIGUSR1, and block that
	// signal; we only want it unblocked when we're reading
	// packets - we dn't want any other system calls, such as
	// ones being used to send to the client or to log messages,
	// to be interrupted.
	//
	sigemptyset(&sigusr1);
	sigaddset(&sigusr1, SIGUSR1);
	pthread_sigmask(SIG_BLOCK, &sigusr1, NULL);
#endif

	// Retrieve the packets
	for (;;)
	{
#ifndef _WIN32
		//
		// Unblock SIGUSR1 while we might be waiting for packets.
		//
		pthread_sigmask(SIG_UNBLOCK, &sigusr1, NULL);
#endif
		retval = pcap_next_ex(session->fp, &pkt_header, (const u_char **) &pkt_data);	// cast to avoid a compiler warning
#ifndef _WIN32
		//
		// Now block it again.
		//
		pthread_sigmask(SIG_BLOCK, &sigusr1, NULL);
#endif
		if (retval < 0)
			break;		// error
		if (retval == 0)	// Read timeout elapsed
			continue;

		sendbufidx = 0;

		// Bufferize the general header
		if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
		    &sendbufidx, (int)sendbufsize, SOCKBUF_CHECKONLY, errbuf,
		    PCAP_ERRBUF_SIZE) == -1)
		{
			rpcapd_log(LOGPRIO_ERROR,
			    "sock_bufferize() error sending packet message: %s",
			    errbuf);
			goto error;
		}

		rpcap_createhdr((struct rpcap_header *) sendbuf,
		    session->protocol_version, RPCAP_MSG_PACKET, 0,
		    (uint16) (sizeof(struct rpcap_pkthdr) + pkt_header->caplen));

		net_pkt_header = (struct rpcap_pkthdr *) &sendbuf[sendbufidx];

		// Bufferize the pkt header
		if (sock_bufferize(NULL, sizeof(struct rpcap_pkthdr), NULL,
		    &sendbufidx, (int)sendbufsize, SOCKBUF_CHECKONLY, errbuf,
		    PCAP_ERRBUF_SIZE) == -1)
		{
			rpcapd_log(LOGPRIO_ERROR,
			    "sock_bufferize() error sending packet message: %s",
			    errbuf);
			goto error;
		}

		net_pkt_header->caplen = htonl(pkt_header->caplen);
		net_pkt_header->len = htonl(pkt_header->len);
		net_pkt_header->npkt = htonl(++(session->TotCapt));
		//
		// This protocol needs to be updated with a new version
		// before 2038-01-19 03:14:07 UTC.
		//
		net_pkt_header->timestamp_sec = htonl((uint32)pkt_header->ts.tv_sec);
		net_pkt_header->timestamp_usec = htonl((uint32)pkt_header->ts.tv_usec);

		// Bufferize the pkt data
		if (sock_bufferize((char *) pkt_data, pkt_header->caplen,
		    sendbuf, &sendbufidx, (int)sendbufsize, SOCKBUF_BUFFERIZE,
		    errbuf, PCAP_ERRBUF_SIZE) == -1)
		{
			rpcapd_log(LOGPRIO_ERROR,
			    "sock_bufferize() error sending packet message: %s",
			    errbuf);
			goto error;
		}

		// Send the packet
		// If the client dropped the connection, don't report an
		// error, just quit.
		status = sock_send(session->sockdata, session->data_ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE);
		if (status < 0)
		{
			if (status == -1)
			{
				//
				// Error other than "client closed the
				// connection out from under us"; report
				// it.
				//
				rpcapd_log(LOGPRIO_ERROR,
				    "Send of packet to client failed: %s",
				    errbuf);
			}

			//
			// Give up in either case.
			//
			goto error;
		}
	}

	if (retval < 0 && retval != PCAP_ERROR_BREAK)
	{
		//
		// Failed with an error other than "we were told to break
		// out of the loop".
		//
		// The latter just means that the client told us to stop
		// capturing, so there's no error to report.
		//
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error reading the packets: %s", pcap_geterr(session->fp));
		rpcap_senderror(session->sockctrl, session->ctrl_ssl, session->protocol_version,
		    PCAP_ERR_READEX, errbuf, NULL);
	}

error:
	//
	// The main thread will clean up the session structure.
	//
	free(sendbuf);

	return 0;
}

#ifndef _WIN32
//
// Do-nothing handler for SIGUSR1; the sole purpose of SIGUSR1 is to
// interrupt the data thread if it's blocked in a system call waiting
// for packets to arrive.
//
static void noop_handler(int sign _U_)
{
}
#endif

/*!
	\brief It serializes a network address.

	It accepts a 'sockaddr_storage' structure as input, and it converts it appropriately into a format
	that can be used to be sent on the network. Basically, it applies all the hton()
	conversion required to the input variable.

	\param sockaddrin a 'sockaddr_storage' pointer to the variable that has to be
	serialized. This variable can be both a 'sockaddr_in' and 'sockaddr_in6'.

	\param sockaddrout an 'rpcap_sockaddr' pointer to the variable that will contain
	the serialized data. This variable has to be allocated by the user.

	\warning This function supports only AF_INET and AF_INET6 address families.
*/
static void
daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *sockaddrout)
{
	memset(sockaddrout, 0, sizeof(struct sockaddr_storage));

	// There can be the case in which the sockaddrin is not available
	if (sockaddrin == NULL) return;

	// Warning: we support only AF_INET and AF_INET6
	//
	// Note: as noted above, the output structures are not
	// neatly aligned on 4-byte boundaries, so we must fill
	// in an aligned structure and then copy it to the output
	// buffer with memcpy().
	switch (sockaddrin->ss_family)
	{
	case AF_INET:
		{
		struct sockaddr_in *sockaddrin_ipv4;
		struct rpcap_sockaddr_in sockaddrout_ipv4;

		sockaddrin_ipv4 = (struct sockaddr_in *) sockaddrin;

		sockaddrout_ipv4.family = htons(RPCAP_AF_INET);
		sockaddrout_ipv4.port = htons(sockaddrin_ipv4->sin_port);
		memcpy(&sockaddrout_ipv4.addr, &sockaddrin_ipv4->sin_addr, sizeof(sockaddrout_ipv4.addr));
		memset(sockaddrout_ipv4.zero, 0, sizeof(sockaddrout_ipv4.zero));
		memcpy(sockaddrout, &sockaddrout_ipv4, sizeof(struct rpcap_sockaddr_in));
		break;
		}

#ifdef AF_INET6
	case AF_INET6:
		{
		struct sockaddr_in6 *sockaddrin_ipv6;
		struct rpcap_sockaddr_in6 sockaddrout_ipv6;

		sockaddrin_ipv6 = (struct sockaddr_in6 *) sockaddrin;

		sockaddrout_ipv6.family = htons(RPCAP_AF_INET6);
		sockaddrout_ipv6.port = htons(sockaddrin_ipv6->sin6_port);
		sockaddrout_ipv6.flowinfo = htonl(sockaddrin_ipv6->sin6_flowinfo);
		memcpy(&sockaddrout_ipv6.addr, &sockaddrin_ipv6->sin6_addr, sizeof(sockaddrout_ipv6.addr));
		sockaddrout_ipv6.scope_id = htonl(sockaddrin_ipv6->sin6_scope_id);
		memcpy(sockaddrout, &sockaddrout_ipv6, sizeof(struct rpcap_sockaddr_in6));
		break;
		}
#endif
	}
}


/*!
	\brief Suspends a thread for secs seconds.
*/
void sleep_secs(int secs)
{
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
#ifdef _WIN32
	Sleep(secs*1000);
#else
	unsigned secs_remaining;

	if (secs <= 0)
		return;
	secs_remaining = secs;
	while (secs_remaining != 0)
		secs_remaining = sleep(secs_remaining);
#endif
#endif
}

/*
 * Read the header of a message.
 */
static int
rpcapd_recv_msg_header(PCAP_SOCKET sock, SSL *ssl, struct rpcap_header *headerp)
{
	int nread;
	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors

	nread = sock_recv(sock, ssl, (char *) headerp, sizeof(struct rpcap_header),
	    SOCK_RECEIVEALL_YES|SOCK_EOF_ISNT_ERROR, errbuf, PCAP_ERRBUF_SIZE);
	if (nread == -1)
	{
		// Network error.
		rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
		return -1;
	}
	if (nread == 0)
	{
		// Immediate EOF; that's treated like a close message.
		return -2;
	}
	headerp->plen = ntohl(headerp->plen);
	return 0;
}

/*
 * Read data from a message.
 * If we're trying to read more data that remains, puts an error
 * message into errmsgbuf and returns -2.  Otherwise, tries to read
 * the data and, if that succeeds, subtracts the amount read from
 * the number of bytes of data that remains.
 * Returns 0 on success, logs a message and returns -1 on a network
 * error.
 */
static int
rpcapd_recv(PCAP_SOCKET sock, SSL *ssl, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf)
{
	int nread;
	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors

	if (toread > *plen)
	{
		// Tell the client and continue.
		snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message payload is too short");
		return -2;
	}
	nread = sock_recv(sock, ssl, buffer, toread,
	    SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE);
	if (nread == -1)
	{
		rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
		return -1;
	}
	*plen -= nread;
	return 0;
}

/*
 * Discard data from a connection.
 * Mostly used to discard wrong-sized messages.
 * Returns 0 on success, logs a message and returns -1 on a network
 * error.
 */
static int
rpcapd_discard(PCAP_SOCKET sock, SSL *ssl, uint32 len)
{
	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed

	if (len != 0)
	{
		if (sock_discard(sock, ssl, len, errbuf, PCAP_ERRBUF_SIZE) == -1)
		{
			// Network error.
			rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
			return -1;
		}
	}
	return 0;
}

//
// Shut down any packet-capture thread associated with the session,
// close the SSL handle for the data socket if we have one, close
// the data socket if we have one, and close the underlying packet
// capture handle if we have one.
//
// We do not, of course, touch the controlling socket that's also
// copied into the session, as the service loop might still use it.
//
static void session_close(struct session *session)
{
	if (session->have_thread)
	{
		//
		// Tell the data connection thread main capture loop to
		// break out of that loop.
		//
		// This may be sufficient to wake up a blocked thread,
		// but it's not guaranteed to be sufficient.
		//
		pcap_breakloop(session->fp);

#ifdef _WIN32
		//
		// Set the event on which a read would block, so that,
		// if it's currently blocked waiting for packets to
		// arrive, it'll wake up, so it can see the "break
		// out of the loop" indication.  (pcap_breakloop()
		// might do this, but older versions don't.  Setting
		// it twice should, at worst, cause an extra wakeup,
		// which shouldn't be a problem.)
		//
		// XXX - what about modules other than NPF?
		//
		SetEvent(pcap_getevent(session->fp));

		//
		// Wait for the thread to exit, so we don't close
		// sockets out from under it.
		//
		// XXX - have a timeout, so we don't wait forever?
		//
		WaitForSingleObject(session->thread, INFINITE);

		//
		// Release the thread handle, as we're done with
		// it.
		//
		CloseHandle(session->thread);
		session->have_thread = 0;
		session->thread = INVALID_HANDLE_VALUE;
#else
		//
		// Send a SIGUSR1 signal to the thread, so that, if
		// it's currently blocked waiting for packets to arrive,
		// it'll wake up (we've turned off SA_RESTART for
		// SIGUSR1, so that the system call in which it's blocked
		// should return EINTR rather than restarting).
		//
		pthread_kill(session->thread, SIGUSR1);

		//
		// Wait for the thread to exit, so we don't close
		// sockets out from under it.
		//
		// XXX - have a timeout, so we don't wait forever?
		//
		pthread_join(session->thread, NULL);
		session->have_thread = 0;
		memset(&session->thread, 0, sizeof(session->thread));
#endif
	}

#ifdef HAVE_OPENSSL
	if (session->data_ssl)
	{
		// Finish using the SSL handle for the socket.
		// This must be done *before* the socket is closed.
		ssl_finish(session->data_ssl);
		session->data_ssl = NULL;
	}
#endif

	if (session->sockdata != INVALID_SOCKET)
	{
		sock_close(session->sockdata, NULL, 0);
		session->sockdata = INVALID_SOCKET;
	}

	if (session->fp)
	{
		pcap_close(session->fp);
		session->fp = NULL;
	}
}

//
// Check whether a capture source string is a URL or not.
// This includes URLs that refer to a local device; a scheme, followed
// by ://, followed by *another* scheme and ://, is just silly, and
// anybody who supplies that will get an error.
//
static int
is_url(const char *source)
{
	char *colonp;

	/*
	 * RFC 3986 says:
	 *
	 *   URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
	 *
	 *   hier-part   = "//" authority path-abempty
	 *               / path-absolute
	 *               / path-rootless
	 *               / path-empty
	 *
	 *   authority   = [ userinfo "@" ] host [ ":" port ]
	 *
	 *   userinfo    = *( unreserved / pct-encoded / sub-delims / ":" )
	 *
	 * Step 1: look for the ":" at the end of the scheme.
	 * A colon in the source is *NOT* sufficient to indicate that
	 * this is a URL, as interface names on some platforms might
	 * include colons (e.g., I think some Solaris interfaces
	 * might).
	 */
	colonp = strchr(source, ':');
	if (colonp == NULL)
	{
		/*
		 * The source is the device to open.  It's not a URL.
		 */
		return (0);
	}

	/*
	 * All schemes must have "//" after them, i.e. we only support
	 * hier-part   = "//" authority path-abempty, not
	 * hier-part   = path-absolute
	 * hier-part   = path-rootless
	 * hier-part   = path-empty
	 *
	 * We need that in order to distinguish between a local device
	 * name that happens to contain a colon and a URI.
	 */
	if (strncmp(colonp + 1, "//", 2) != 0)
	{
		/*
		 * The source is the device to open.  It's not a URL.
		 */
		return (0);
	}

	/*
	 * It's a URL.
	 */
	return (1);
}
