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

#include "ftmacros.h"
#include "diag-control.h"

#include <errno.h>		// for the errno variable
#include <string.h>		// for strtok, etc
#include <stdlib.h>		// for malloc(), free(), ...
#include <stdio.h>		// for fprintf(), stderr, FILE etc
#include <pcap.h>		// for PCAP_ERRBUF_SIZE
#include <signal.h>		// for signal()

#include "fmtutils.h"
#include "sockutils.h"		// for socket calls
#include "varattrs.h"		// for _U_
#include "portability.h"
#include "rpcapd.h"
#include "config_params.h"	// configuration file parameters
#include "fileconf.h"		// for the configuration file management
#include "rpcap-protocol.h"
#include "daemon.h"		// the true main() method of this daemon
#include "log.h"

#ifdef HAVE_OPENSSL
#include "sslutils.h"
#endif

#ifdef _WIN32
  #include <process.h>		// for thread stuff
  #include "win32-svc.h"	// for Win32 service stuff
  #include "getopt.h"		// for getopt()-for-Windows
#else
  #include <fcntl.h>		// for open()
  #include <unistd.h>		// for exit()
  #include <sys/wait.h>		// waitpid()
#endif

//
// Element in list of sockets on which we're listening for connections.
//
struct listen_sock {
	struct listen_sock *next;
	SOCKET sock;
};

// Global variables
char hostlist[MAX_HOST_LIST + 1];		//!< Keeps the list of the hosts that are allowed to connect to this server
struct active_pars activelist[MAX_ACTIVE_LIST];	//!< Keeps the list of the hosts (host, port) on which I want to connect to (active mode)
int nullAuthAllowed;				//!< '1' if we permit NULL authentication, '0' otherwise
static struct listen_sock *listen_socks;	//!< sockets on which we listen
char loadfile[MAX_LINE + 1];			//!< Name of the file from which we have to load the configuration
static int passivemode = 1;			//!< '1' if we want to run in passive mode as well
static struct addrinfo mainhints;		//!< temporary struct to keep settings needed to open the new socket
static char address[MAX_LINE + 1];		//!< keeps the network address (either numeric or literal) to bind to
static char port[MAX_LINE + 1];			//!< keeps the network port to bind to
#ifdef _WIN32
static HANDLE state_change_event;		//!< event to signal that a state change should take place
#endif
static volatile sig_atomic_t shutdown_server;	//!< '1' if the server is to shut down
static volatile sig_atomic_t reread_config;	//!< '1' if the server is to re-read its configuration
static int uses_ssl; //!< '1' to use TLS over the data socket

extern char *optarg;	// for getopt()

// Function definition
#ifdef _WIN32
static unsigned __stdcall main_active(void *ptr);
static BOOL WINAPI main_ctrl_event(DWORD);
#else
static void *main_active(void *ptr);
static void main_terminate(int sign);
static void main_reread_config(int sign);
#endif
static void accept_connections(void);
static void accept_connection(SOCKET listen_sock);
#ifndef _WIN32
static void main_reap_children(int sign);
#endif
#ifdef _WIN32
static unsigned __stdcall main_passive_serviceloop_thread(void *ptr);
#endif

#define RPCAP_ACTIVE_WAIT 30		/* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */

/*!
	\brief Prints the usage screen if it is launched in console mode.
*/
static void printusage(FILE * f)
{
	const char *usagetext =
	"USAGE:"
	" "  PROGRAM_NAME " [-b <address>] [-p <port>] [-4] [-l <host_list>] [-a <host,port>]\n"
	"              [-n] [-v] [-d] "
#ifndef _WIN32
	"[-i] "
#endif
        "[-D] [-s <config_file>] [-f <config_file>]\n\n"
	"  -b <address>    the address to bind to (either numeric or literal).\n"
	"                  Default: binds to all local IPv4 and IPv6 addresses\n\n"
	"  -p <port>       the port to bind to.\n"
	"                  Default: binds to port " RPCAP_DEFAULT_NETPORT "\n\n"
	"  -4              use only IPv4.\n"
	"                  Default: use both IPv4 and IPv6 waiting sockets\n\n"
	"  -l <host_list>  a file that contains a list of hosts that are allowed\n"
	"                  to connect to this server (if more than one, list them one\n"
	"                  per line).\n"
	"                  We suggest to use literal names (instead of numeric ones)\n"
	"                  in order to avoid problems with different address families.\n\n"
	"  -n              permit NULL authentication (usually used with '-l')\n\n"
	"  -a <host,port>  run in active mode when connecting to 'host' on port 'port'\n"
	"                  In case 'port' is omitted, the default port (" RPCAP_DEFAULT_NETPORT_ACTIVE ") is used\n\n"
	"  -v              run in active mode only (default: if '-a' is specified, it\n"
	"                  accepts passive connections as well)\n\n"
	"  -d              run in daemon mode (UNIX only) or as a service (Win32 only)\n"
	"                  Warning (Win32): this switch is provided automatically when\n"
	"                  the service is started from the control panel\n\n"
#ifndef _WIN32
	"  -i              run in inetd mode (UNIX only)\n\n"
#endif
	"  -D              log debugging messages\n\n"
#ifdef HAVE_OPENSSL
	"  -S              encrypt all communication with SSL (implements rpcaps://)\n"
	"  -C              enable compression\n"
	"  -K <pem_file>   uses the SSL private key in this file (default: key.pem)\n"
	"  -X <pem_file>   uses the certificate from this file (default: cert.pem)\n"
#endif
	"  -s <config_file> save the current configuration to file\n\n"
	"  -f <config_file> load the current configuration from file; all switches\n"
	"                  specified from the command line are ignored\n\n"
	"  -h              print this help screen\n\n";

	(void)fprintf(f, "RPCAPD, a remote packet capture daemon.\n"
	"Compiled with %s\n", pcap_lib_version());
#if defined(HAVE_OPENSSL) && defined(SSLEAY_VERSION)
	(void)fprintf(f, "Compiled with %s\n", SSLeay_version(SSLEAY_VERSION));
#endif
	(void)fprintf(f, "\n%s", usagetext);
}



//! Program main
int main(int argc, char *argv[])
{
	char savefile[MAX_LINE + 1];		// name of the file on which we have to save the configuration
	int log_to_systemlog = 0;		// Non-zero if we should log to the "system log" rather than the standard error
	int isdaemon = 0;			// Non-zero if the user wants to run this program as a daemon
#ifndef _WIN32
	int isrunbyinetd = 0;			// Non-zero if this is being run by inetd or something inetd-like
#endif
	int log_debug_messages = 0;		// Non-zero if the user wants debug messages logged
	int retval;				// keeps the returning value from several functions
	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
#ifndef _WIN32
	struct sigaction action;
#endif
#ifdef HAVE_OPENSSL
	int enable_compression = 0;
#endif

	savefile[0] = 0;
	loadfile[0] = 0;
	hostlist[0] = 0;

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

	pcap_strlcpy(address, RPCAP_DEFAULT_NETADDR, sizeof (address));
	pcap_strlcpy(port, RPCAP_DEFAULT_NETPORT, sizeof (port));

	// Prepare to open a new server socket
	memset(&mainhints, 0, sizeof(struct addrinfo));

	mainhints.ai_family = PF_UNSPEC;
	mainhints.ai_flags = AI_PASSIVE;	// Ready to a bind() socket
	mainhints.ai_socktype = SOCK_STREAM;

	// Getting the proper command line options
#	ifdef HAVE_OPENSSL
#		define SSL_CLOPTS  "SK:X:C"
#	else
#		define SSL_CLOPTS ""
#	endif

#	define CLOPTS "b:dDhip:4l:na:s:f:v" SSL_CLOPTS

	while ((retval = getopt(argc, argv, CLOPTS)) != -1)
	{
		switch (retval)
		{
			case 'D':
				log_debug_messages = 1;
				rpcapd_log_set(log_to_systemlog, log_debug_messages);
				break;
			case 'b':
				pcap_strlcpy(address, optarg, sizeof (address));
				break;
			case 'p':
				pcap_strlcpy(port, optarg, sizeof (port));
				break;
			case '4':
				mainhints.ai_family = PF_INET;		// IPv4 server only
				break;
			case 'd':
				isdaemon = 1;
				log_to_systemlog = 1;
				rpcapd_log_set(log_to_systemlog, log_debug_messages);
				break;
			case 'i':
#ifdef _WIN32
				printusage(stderr);
				exit(1);
#else
				isrunbyinetd = 1;
				log_to_systemlog = 1;
				rpcapd_log_set(log_to_systemlog, log_debug_messages);
#endif
				break;
			case 'n':
				nullAuthAllowed = 1;
				break;
			case 'v':
				passivemode = 0;
				break;
			case 'l':
			{
				pcap_strlcpy(hostlist, optarg, sizeof(hostlist));
				break;
			}
			case 'a':
			{
				char *tmpaddress, *tmpport;
				char *lasts;
				int i = 0;

				tmpaddress = pcap_strtok_r(optarg, RPCAP_HOSTLIST_SEP, &lasts);

				while ((tmpaddress != NULL) && (i < MAX_ACTIVE_LIST))
				{
					tmpport = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);

					pcap_strlcpy(activelist[i].address, tmpaddress, sizeof (activelist[i].address));

					if ((tmpport == NULL) || (strcmp(tmpport, "DEFAULT") == 0)) // the user choose a custom port
						pcap_strlcpy(activelist[i].port, RPCAP_DEFAULT_NETPORT_ACTIVE, sizeof (activelist[i].port));
					else
						pcap_strlcpy(activelist[i].port, tmpport, sizeof (activelist[i].port));

					tmpaddress = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);

					i++;
				}

				if (i > MAX_ACTIVE_LIST)
					rpcapd_log(LOGPRIO_ERROR, "Only MAX_ACTIVE_LIST active connections are currently supported.");

				// I don't initialize the remaining part of the structure, since
				// it is already zeroed (it is a global var)
				break;
			}
			case 'f':
				pcap_strlcpy(loadfile, optarg, sizeof (loadfile));
				break;
			case 's':
				pcap_strlcpy(savefile, optarg, sizeof (savefile));
				break;
#ifdef HAVE_OPENSSL
			case 'S':
				uses_ssl = 1;
				break;
			case 'C':
				enable_compression = 1;
				break;
			case 'K':
				ssl_set_keyfile(optarg);
				break;
			case 'X':
				ssl_set_certfile(optarg);
				break;
#endif
			case 'h':
				printusage(stdout);
				exit(0);
				/*NOTREACHED*/
			default:
				exit(1);
				/*NOTREACHED*/
		}
	}

#ifndef _WIN32
	if (isdaemon && isrunbyinetd)
	{
		rpcapd_log(LOGPRIO_ERROR, "rpcapd: -d and -i can't be used together");
		exit(1);
	}
#endif

	//
	// We want UTF-8 error messages.
	//
	if (pcap_init(PCAP_CHAR_ENC_UTF_8, errbuf) == -1)
	{
		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
		exit(-1);
	}
	pcap_fmt_set_encoding(PCAP_CHAR_ENC_UTF_8);

	if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
	{
		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
		exit(-1);
	}

	if (savefile[0] && fileconf_save(savefile))
		rpcapd_log(LOGPRIO_DEBUG, "Error when saving the configuration to file");

	// If the file does not exist, it keeps the settings provided by the command line
	if (loadfile[0])
		fileconf_read();

#ifdef _WIN32
	//
	// Create a handle to signal the main loop to tell it to do
	// something.
	//
	state_change_event = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (state_change_event == NULL)
	{
		sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
		    "Can't create state change event");
		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
		exit(2);
	}

	//
	// Catch control signals.
	//
	if (!SetConsoleCtrlHandler(main_ctrl_event, TRUE))
	{
		sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
		    "Can't set control handler");
		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
		exit(2);
	}
#else
	memset(&action, 0, sizeof (action));
	action.sa_handler = main_terminate;
	action.sa_flags = 0;
	sigemptyset(&action.sa_mask);
	sigaction(SIGTERM, &action, NULL);
	memset(&action, 0, sizeof (action));
	action.sa_handler = main_reap_children;
	action.sa_flags = 0;
	sigemptyset(&action.sa_mask);
	sigaction(SIGCHLD, &action, NULL);
	// Ignore SIGPIPE - we'll get EPIPE when trying to write to a closed
	// connection, we don't want to get killed by a signal in that case
	signal(SIGPIPE, SIG_IGN);
#endif

# ifdef HAVE_OPENSSL
	if (uses_ssl) {
		if (ssl_init_once(1, enable_compression, errbuf, PCAP_ERRBUF_SIZE) < 0)
		{
			rpcapd_log(LOGPRIO_ERROR, "Can't initialize SSL: %s",
			    errbuf);
			exit(2);
		}
	}
# endif

#ifndef _WIN32
	if (isrunbyinetd)
	{
		//
		// -i was specified, indicating that this is being run
		// by inetd or something that can run network daemons
		// as if it were inetd (xinetd, launchd, systemd, etc.).
		//
		// We assume that the program that launched us just
		// duplicated a single socket for the connection
		// to our standard input, output, and error, so we
		// can just use the standard input as our control
		// socket.
		//
		int sockctrl;
		int devnull_fd;

		//
		// Duplicate the standard input as the control socket.
		//
		sockctrl = dup(0);
		if (sockctrl == -1)
		{
			sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
			    "Can't dup standard input");
			rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
			exit(2);
		}

		//
		// Try to set the standard input, output, and error
		// to /dev/null.
		//
		devnull_fd = open("/dev/null", O_RDWR);
		if (devnull_fd != -1)
		{
			//
			// If this fails, just drive on.
			//
			(void)dup2(devnull_fd, 0);
			(void)dup2(devnull_fd, 1);
			(void)dup2(devnull_fd, 2);
			close(devnull_fd);
		}

		//
		// Handle this client.
		// This is passive mode, so we don't care whether we were
		// told by the client to close.
		//
		char *hostlist_copy = strdup(hostlist);
		if (hostlist_copy == NULL)
		{
			rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
			exit(0);
		}
		(void)daemon_serviceloop(sockctrl, 0, hostlist_copy,
		    nullAuthAllowed, uses_ssl);

		//
		// Nothing more to do.
		//
		exit(0);
	}
#endif

	if (isdaemon)
	{
		//
		// This is being run as a daemon.
		// On UN*X, it might be manually run, or run from an
		// rc file.
		//
#ifndef _WIN32
		int pid;

		//
		// Daemonize ourselves.
		//
		// Unix Network Programming, pg 336
		//
		if ((pid = fork()) != 0)
			exit(0);		// Parent terminates

		// First child continues
		// Set daemon mode
		setsid();

		// generated under unix with 'kill -HUP', needed to reload the configuration
		memset(&action, 0, sizeof (action));
		action.sa_handler = main_reread_config;
		action.sa_flags = 0;
		sigemptyset(&action.sa_mask);
		sigaction(SIGHUP, &action, NULL);

		if ((pid = fork()) != 0)
			exit(0);		// First child terminates

		// LINUX WARNING: the current linux implementation of pthreads requires a management thread
		// to handle some hidden stuff. So, as soon as you create the first thread, two threads are
		// created. From this point on, the number of threads active are always one more compared
		// to the number you're expecting

		// Second child continues
//		umask(0);
//		chdir("/");
#else
		//
		// This is being run as a service on Windows.
		//
		// If this call succeeds, it is blocking on Win32
		//
		if (!svc_start())
			rpcapd_log(LOGPRIO_DEBUG, "Unable to start the service");

		// When the previous call returns, the entire application has to be stopped.
		exit(0);
#endif
	}
	else	// Console mode
	{
#ifndef _WIN32
		// Enable the catching of Ctrl+C
		memset(&action, 0, sizeof (action));
		action.sa_handler = main_terminate;
		action.sa_flags = 0;
		sigemptyset(&action.sa_mask);
		sigaction(SIGINT, &action, NULL);

		// generated under unix with 'kill -HUP', needed to reload the configuration
		// We do not have this kind of signal in Win32
		memset(&action, 0, sizeof (action));
		action.sa_handler = main_reread_config;
		action.sa_flags = 0;
		sigemptyset(&action.sa_mask);
		sigaction(SIGHUP, &action, NULL);
#endif

		printf("Press CTRL + C to stop the server...\n");
	}

	// If we're a Win32 service, we have already called this function in the service_main
	main_startup();

	// The code should never arrive here (since the main_startup is blocking)
	//  however this avoids a compiler warning
	exit(0);
}

void main_startup(void)
{
	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
	struct addrinfo *addrinfo;		// keeps the addrinfo chain; required to open a new socket
	int i;
#ifdef _WIN32
	HANDLE threadId;			// handle for the subthread
#else
	pid_t pid;
#endif

	i = 0;
	addrinfo = NULL;
	memset(errbuf, 0, sizeof(errbuf));

	// Starts all the active threads
	while ((i < MAX_ACTIVE_LIST) && (activelist[i].address[0] != 0))
	{
		activelist[i].ai_family = mainhints.ai_family;

#ifdef _WIN32
		threadId = (HANDLE)_beginthreadex(NULL, 0, main_active,
		    (void *)&activelist[i], 0, NULL);
		if (threadId == 0)
		{
			rpcapd_log(LOGPRIO_DEBUG, "Error creating the active child threads");
			continue;
		}
		CloseHandle(threadId);
#else
		if ((pid = fork()) == 0)	// I am the child
		{
			main_active((void *) &activelist[i]);
			exit(0);
		}
#endif
		i++;
	}

	/*
	 * The code that manages the active connections is not blocking;
	 * the code that manages the passive connection is blocking.
	 * So, if the user does not want to run in passive mode, we have
	 * to block the main thread here, otherwise the program ends and
	 * all threads are stopped.
	 *
	 * WARNING: this means that in case we have only active mode,
	 * the program does not terminate even if all the child thread
	 * terminates. The user has always to press Ctrl+C (or send a
	 * SIGTERM) to terminate the program.
	 */
	if (passivemode)
	{
		struct addrinfo *tempaddrinfo;

		//
		// Get a list of sockets on which to listen.
		//
		if (sock_initaddress((address[0]) ? address : NULL, port, &mainhints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
		{
			rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
			return;
		}

		for (tempaddrinfo = addrinfo; tempaddrinfo;
		     tempaddrinfo = tempaddrinfo->ai_next)
		{
			SOCKET sock;
			struct listen_sock *sock_info;

			if ((sock = sock_open(NULL, tempaddrinfo, SOCKOPEN_SERVER, SOCKET_MAXCONN, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
			{
				switch (tempaddrinfo->ai_family)
				{
				case AF_INET:
				{
					struct sockaddr_in *in;
					char addrbuf[INET_ADDRSTRLEN];

					in = (struct sockaddr_in *)tempaddrinfo->ai_addr;
					rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for %s:%u: %s",
					    inet_ntop(AF_INET, &in->sin_addr,
						addrbuf, sizeof (addrbuf)),
					    ntohs(in->sin_port),
					    errbuf);
					break;
				}

				case AF_INET6:
				{
					struct sockaddr_in6 *in6;
					char addrbuf[INET6_ADDRSTRLEN];

					in6 = (struct sockaddr_in6 *)tempaddrinfo->ai_addr;
					rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for %s:%u: %s",
					    inet_ntop(AF_INET6, &in6->sin6_addr,
						addrbuf, sizeof (addrbuf)),
					    ntohs(in6->sin6_port),
					    errbuf);
					break;
				}

				default:
					rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for address family %u: %s",
					    tempaddrinfo->ai_family,
					    errbuf);
					break;
				}
				continue;
			}

			sock_info = (struct listen_sock *) malloc(sizeof (struct listen_sock));
			if (sock_info == NULL)
			{
				rpcapd_log(LOGPRIO_ERROR, "Can't allocate structure for listen socket");
				exit(2);
			}
			sock_info->sock = sock;
			sock_info->next = listen_socks;
			listen_socks = sock_info;
		}

		freeaddrinfo(addrinfo);

		if (listen_socks == NULL)
		{
			rpcapd_log(LOGPRIO_ERROR, "Can't listen on any address");
			exit(2);
		}

		//
		// Now listen on all of them, waiting for connections.
		//
		accept_connections();
	}

	//
	// We're done; exit.
	//
	rpcapd_log(LOGPRIO_DEBUG, PROGRAM_NAME " is closing.\n");

#ifndef _WIN32
	//
	// Sends a KILL signal to all the processes in this process's
	// process group; i.e., it kills all the child processes
	// we've created.
	//
	// XXX - that also includes us, so we will be killed as well;
	// that may cause a message to be printed or logged.
	//
	kill(0, SIGKILL);
#endif

	//
	// Just leave.  We shouldn't need to clean up sockets or
	// anything else, and if we try to do so, we'll could end
	// up closing sockets, or shutting Winsock down, out from
	// under service loops, causing all sorts of noisy error
	// messages.
	//
	// We shouldn't need to worry about cleaning up any resources
	// such as handles, sockets, threads, etc. - exit() should
	// terminate the process, causing all those resources to be
	// cleaned up (including the threads; Microsoft claims in the
	// ExitProcess() documentation that, if ExitProcess() is called,
	// "If a thread is waiting on a kernel object, it will not be
	// terminated until the wait has completed.", but claims in the
	// _beginthread()/_beginthreadex() documentation that "All threads
	// are terminated if any thread calls abort, exit, _exit, or
	// ExitProcess." - the latter appears to be the case, even for
	// threads waiting on the event for a pcap_t).
	//
	exit(0);
}

#ifdef _WIN32
static void
send_state_change_event(void)
{
	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed

	if (!SetEvent(state_change_event))
	{
		sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
		    "SetEvent on shutdown event failed");
		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
	}
}

void
send_shutdown_notification(void)
{
	//
	// Indicate that the server should shut down.
	//
	shutdown_server = 1;

	//
	// Send a state change event, to wake up WSAWaitForMultipleEvents().
	//
	send_state_change_event();
}

void
send_reread_configuration_notification(void)
{
	//
	// Indicate that the server should re-read its configuration file.
	//
	reread_config = 1;

	//
	// Send a state change event, to wake up WSAWaitForMultipleEvents().
	//
	send_state_change_event();
}

static BOOL WINAPI main_ctrl_event(DWORD ctrltype)
{
	//
	// ctrltype is one of:
	//
	// CTRL_C_EVENT - we got a ^C; this is like SIGINT
	// CTRL_BREAK_EVENT - we got Ctrl+Break
	// CTRL_CLOSE_EVENT - the console was closed; this is like SIGHUP
	// CTRL_LOGOFF_EVENT - a user is logging off; this is received
	//   only by services
	// CTRL_SHUTDOWN_EVENT - the systemis shutting down; this is
	//   received only by services
	//
	// For now, we treat all but CTRL_LOGOFF_EVENT as indications
	// that we should shut down.
	//
	switch (ctrltype)
	{
		case CTRL_C_EVENT:
		case CTRL_BREAK_EVENT:
		case CTRL_CLOSE_EVENT:
		case CTRL_SHUTDOWN_EVENT:
			//
			// Set a shutdown notification.
			//
			send_shutdown_notification();
			break;

		default:
			break;
	}

	//
	// We handled this.
	//
	return TRUE;
}
#else
static void main_terminate(int sign _U_)
{
	//
	// Note that the server should shut down.
	// select() should get an EINTR error when we return,
	// so it will wake up and know it needs to check the flag.
	//
	shutdown_server = 1;
}

static void main_reread_config(int sign _U_)
{
	//
	// Note that the server should re-read its configuration file.
	// select() should get an EINTR error when we return,
	// so it will wake up and know it needs to check the flag.
	//
	reread_config = 1;
}

static void main_reap_children(int sign _U_)
{
	pid_t pid;
	int exitstat;

	// Reap all child processes that have exited.
	// For reference, Stevens, pg 128

	while ((pid = waitpid(-1, &exitstat, WNOHANG)) > 0)
		rpcapd_log(LOGPRIO_DEBUG, "Child terminated");

	return;
}
#endif

//
// Loop waiting for incoming connections and accepting them.
//
static void
accept_connections(void)
{
#ifdef _WIN32
	struct listen_sock *sock_info;
	DWORD num_events;
	WSAEVENT *events;
	int i;
	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed

	//
	// How big does the set of events need to be?
	// One for the shutdown event, plus one for every socket on which
	// we'll be listening.
	//
	num_events = 1;		// shutdown event
	for (sock_info = listen_socks; sock_info;
	    sock_info = sock_info->next)
	{
		if (num_events == WSA_MAXIMUM_WAIT_EVENTS)
		{
			//
			// WSAWaitForMultipleEvents() doesn't support
			// more than WSA_MAXIMUM_WAIT_EVENTS events
			// on which to wait.
			//
			rpcapd_log(LOGPRIO_ERROR, "Too many sockets on which to listen");
			exit(2);
		}
		num_events++;
	}

	//
	// Allocate the array of events.
	//
	events = (WSAEVENT *) malloc(num_events * sizeof (WSAEVENT));
	if (events == NULL)
	{
		rpcapd_log(LOGPRIO_ERROR, "Can't allocate array of events which to listen");
		exit(2);
	}

	//
	// Fill it in.
	//
	events[0] = state_change_event;	// state change event first
	for (sock_info = listen_socks, i = 1; sock_info;
	    sock_info = sock_info->next, i++)
	{
		WSAEVENT event;

		//
		// Create an event that is signaled if there's a connection
		// to accept on the socket in question.
		//
		event = WSACreateEvent();
		if (event == WSA_INVALID_EVENT)
		{
			sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
			    "Can't create socket event");
			rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
			exit(2);
		}
		if (WSAEventSelect(sock_info->sock, event, FD_ACCEPT) == SOCKET_ERROR)
		{
			sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
			    "Can't setup socket event");
			rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
			exit(2);
		}
		events[i] = event;
	}

	for (;;)
	{
		//
		// Wait for incoming connections.
		//
		DWORD ret;

		ret = WSAWaitForMultipleEvents(num_events, events, FALSE,
		    WSA_INFINITE, FALSE);
		if (ret == WSA_WAIT_FAILED)
		{
			sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
			    "WSAWaitForMultipleEvents failed");
			rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
			exit(2);
		}

		if (ret == WSA_WAIT_EVENT_0)
		{
			//
			// The state change event was set.
			//
			if (shutdown_server)
			{
				//
				// Time to quit. Exit the loop.
				//
				break;
			}
			if (reread_config)
			{
				//
				// We should re-read the configuration
				// file.
				//
				reread_config = 0;	// clear the indicator
				fileconf_read();
			}
		}

		//
		// Check each socket.
		//
		for (sock_info = listen_socks, i = 1; sock_info;
		    sock_info = sock_info->next, i++)
		{
			WSANETWORKEVENTS network_events;

			if (WSAEnumNetworkEvents(sock_info->sock,
			    events[i], &network_events) == SOCKET_ERROR)
			{
				sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
				    "WSAEnumNetworkEvents failed");
				rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
				exit(2);
			}
			if (network_events.lNetworkEvents & FD_ACCEPT)
			{
				//
				// Did an error occur?
				//
				if (network_events.iErrorCode[FD_ACCEPT_BIT] != 0)
				{
					//
					// Yes - report it and keep going.
					//
					sock_fmterrmsg(errbuf,
					    PCAP_ERRBUF_SIZE,
					    network_events.iErrorCode[FD_ACCEPT_BIT],
					    "Socket error");
					rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
					continue;
				}

				//
				// Accept the connection.
				//
				accept_connection(sock_info->sock);
			}
		}
	}
#else
	struct listen_sock *sock_info;
	int num_sock_fds;

	//
	// How big does the bitset of sockets on which to select() have
	// to be?
	//
	num_sock_fds = 0;
	for (sock_info = listen_socks; sock_info; sock_info = sock_info->next)
	{
		if (sock_info->sock + 1 > num_sock_fds)
		{
			if ((unsigned int)(sock_info->sock + 1) >
			    (unsigned int)FD_SETSIZE)
			{
				rpcapd_log(LOGPRIO_ERROR, "Socket FD is too bit for an fd_set");
				exit(2);
			}
			num_sock_fds = sock_info->sock + 1;
		}
	}

	for (;;)
	{
		fd_set sock_fds;
		int ret;

		//
		// Set up an fd_set for all the sockets on which we're
		// listening.
		//
		// This set is modified by select(), so we have to
		// construct it anew each time.
		//
		FD_ZERO(&sock_fds);
		for (sock_info = listen_socks; sock_info;
		    sock_info = sock_info->next)
		{
			FD_SET(sock_info->sock, &sock_fds);
		}

		//
		// Wait for incoming connections.
		//
		ret = select(num_sock_fds, &sock_fds, NULL, NULL, NULL);
		if (ret == -1)
		{
			if (errno == EINTR)
			{
				//
				// If this is a "terminate the
				// server" signal, exit the loop,
				// otherwise just keep trying.
				//
				if (shutdown_server)
				{
					//
					// Time to quit.  Exit the loop.
					//
					break;
				}
				if (reread_config)
				{
					//
					// We should re-read the configuration
					// file.
					//
					reread_config = 0;	// clear the indicator
					fileconf_read();
				}

				//
				// Go back and wait again.
				//
				continue;
			}
			else
			{
				rpcapd_log(LOGPRIO_ERROR, "select failed: %s",
				    strerror(errno));
				exit(2);
			}
		}

		//
		// Check each socket.
		//
		for (sock_info = listen_socks; sock_info;
		    sock_info = sock_info->next)
		{
			if (FD_ISSET(sock_info->sock, &sock_fds))
			{
				//
				// Accept the connection.
				//
				accept_connection(sock_info->sock);
			}
		}
	}
#endif

	//
	// Close all the listen sockets.
	//
	for (sock_info = listen_socks; sock_info; sock_info = sock_info->next)
	{
		closesocket(sock_info->sock);
	}
	sock_cleanup();
}

#ifdef _WIN32
//
// A structure to hold the parameters to the daemon service loop
// thread on Windows.
//
// (On UN*X, there is no need for this explicit copy since the
// fork "inherits" the parent stack.)
//
struct params_copy {
	SOCKET sockctrl;
	char *hostlist;
};
#endif

//
// Accept a connection and start a worker thread, on Windows, or a
// worker process, on UN*X, to handle the connection.
//
static void
accept_connection(SOCKET listen_sock)
{
	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
	SOCKET sockctrl;			// keeps the socket ID for this control connection
	struct sockaddr_storage from;		// generic sockaddr_storage variable
	socklen_t fromlen;			// keeps the length of the sockaddr_storage variable

#ifdef _WIN32
	HANDLE threadId;			// handle for the subthread
	u_long off = 0;
	struct params_copy *params_copy = NULL;
#else
	pid_t pid;
#endif

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

	for (;;)
	{
		// Accept the connection
		fromlen = sizeof(struct sockaddr_storage);

		sockctrl = accept(listen_sock, (struct sockaddr *) &from, &fromlen);

		if (sockctrl != INVALID_SOCKET)
		{
			// Success.
			break;
		}

		// The accept() call can return this error when a signal is caught
		// In this case, we have simply to ignore this error code
		// Stevens, pg 124
#ifdef _WIN32
		if (WSAGetLastError() == WSAEINTR)
#else
		if (errno == EINTR)
#endif
			continue;

		// Don't check for errors here, since the error can be due to the fact that the thread
		// has been killed
		sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, "accept() failed");
		rpcapd_log(LOGPRIO_ERROR, "Accept of control connection from client failed: %s",
		    errbuf);
		return;
	}

#ifdef _WIN32
	//
	// Put the socket back into blocking mode; doing WSAEventSelect()
	// on the listen socket makes that socket non-blocking, and it
	// appears that sockets returned from an accept() on that socket
	// are also non-blocking.
	//
	// First, we have to un-WSAEventSelect() this socket, and then
	// we can turn non-blocking mode off.
	//
	// If this fails, we aren't guaranteed that, for example, any
	// of the error message will be sent - if it can't be put in
	// the socket queue, the send will just fail.
	//
	// So we just log the message and close the connection.
	//
	if (WSAEventSelect(sockctrl, NULL, 0) == SOCKET_ERROR)
	{
		sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
		    "WSAEventSelect() failed");
		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
		sock_close(sockctrl, NULL, 0);
		return;
	}
	if (ioctlsocket(sockctrl, FIONBIO, &off) == SOCKET_ERROR)
	{
		sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
		    "ioctlsocket(FIONBIO) failed");
		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
		sock_close(sockctrl, NULL, 0);
		return;
	}

	//
	// Make a copy of the host list to pass to the new thread, so that
	// if we update it in the main thread, it won't catch us in the
	// middle of updating it.
	//
	// daemon_serviceloop() will free it once it's done with it.
	//
	char *hostlist_copy = strdup(hostlist);
	if (hostlist_copy == NULL)
	{
		rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
		sock_close(sockctrl, NULL, 0);
		return;
	}

	//
	// Allocate a location to hold the values of sockctrl.
	// It will be freed in the newly-created thread once it's
	// finished with it.
	//
	params_copy = malloc(sizeof(*params_copy));
	if (params_copy == NULL)
	{
		rpcapd_log(LOGPRIO_ERROR, "Out of memory allocating the parameter copy structure");
		free(hostlist_copy);
		sock_close(sockctrl, NULL, 0);
		return;
	}
	params_copy->sockctrl = sockctrl;
	params_copy->hostlist = hostlist_copy;

	threadId = (HANDLE)_beginthreadex(NULL, 0,
	    main_passive_serviceloop_thread, (void *) params_copy, 0, NULL);
	if (threadId == 0)
	{
		rpcapd_log(LOGPRIO_ERROR, "Error creating the child thread");
		free(params_copy);
		free(hostlist_copy);
		sock_close(sockctrl, NULL, 0);
		return;
	}
	CloseHandle(threadId);
#else /* _WIN32 */
	pid = fork();
	if (pid == -1)
	{
		rpcapd_log(LOGPRIO_ERROR, "Error creating the child process: %s",
		    strerror(errno));
		sock_close(sockctrl, NULL, 0);
		return;
	}
	if (pid == 0)
	{
		//
		// Child process.
		//
		// Close the socket on which we're listening (must
		// be open only in the parent).
		//
		closesocket(listen_sock);

#if 0
		//
		// Modify thread params so that it can be killed at any time
		// XXX - is this necessary?  This is the main and, currently,
		// only thread in the child process, and nobody tries to
		// cancel us, although *we* may cancel the thread that's
		// handling the capture loop.
		//
		if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL))
			goto end;
		if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL))
			goto end;
#endif

		//
		// Run the service loop.
		// This is passive mode, so we don't care whether we were
		// told by the client to close.
		//
		char *hostlist_copy = strdup(hostlist);
		if (hostlist_copy == NULL)
		{
			rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
			exit(0);
		}
		(void)daemon_serviceloop(sockctrl, 0, hostlist_copy,
		    nullAuthAllowed, uses_ssl);

		exit(0);
	}

	// I am the parent
	// Close the socket for this session (must be open only in the child)
	closesocket(sockctrl);
#endif /* _WIN32 */
}

/*!
	\brief 'true' main of the program in case the active mode is turned on.

	This function loops forever trying to connect to the remote host, until the
	daemon is turned down.

	\param ptr: it keeps the 'activepars' parameters.  It is a 'void *'
	just because the thread APIs want this format.
*/
#ifdef _WIN32
static unsigned __stdcall
#else
static void *
#endif
main_active(void *ptr)
{
	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
	SOCKET sockctrl;			// keeps the socket ID for this control connection
	struct addrinfo hints;			// temporary struct to keep settings needed to open the new socket
	struct addrinfo *addrinfo;		// keeps the addrinfo chain; required to open a new socket
	struct active_pars *activepars;

	activepars = (struct active_pars *) ptr;

	// Prepare to open a new server socket
	memset(&hints, 0, sizeof(struct addrinfo));
						// WARNING Currently it supports only ONE socket family among IPv4 and IPv6
	hints.ai_family = AF_INET;		// PF_UNSPEC to have both IPv4 and IPv6 server
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_family = activepars->ai_family;

	rpcapd_log(LOGPRIO_DEBUG, "Connecting to host %s, port %s, using protocol %s",
	    activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4":
	    (hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified");

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

	// Do the work
	if (sock_initaddress(activepars->address, activepars->port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
	{
		rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
		return 0;
	}

	for (;;)
	{
		int activeclose;

		if ((sockctrl = sock_open(activepars->address, addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
		{
			rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);

			DIAG_OFF_FORMAT_TRUNCATION
			snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error connecting to host %s, port %s, using protocol %s",
					activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4":
					(hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified");
			DIAG_ON_FORMAT_TRUNCATION

			rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);

			sleep_secs(RPCAP_ACTIVE_WAIT);

			continue;
		}

		char *hostlist_copy = strdup(hostlist);
		if (hostlist_copy == NULL)
		{
			rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
			activeclose = 0;
			sock_close(sockctrl, NULL, 0);
		}
		else
		{
			//
			// daemon_serviceloop() will free the copy.
			//
			activeclose = daemon_serviceloop(sockctrl, 1,
			    hostlist_copy, nullAuthAllowed, uses_ssl);
		}

		// If the connection is closed by the user explicitly, don't try to connect to it again
		// just exit the program
		if (activeclose == 1)
			break;
	}

	freeaddrinfo(addrinfo);
	return 0;
}

#ifdef _WIN32
//
// Main routine of a passive-mode service thread.
//
unsigned __stdcall main_passive_serviceloop_thread(void *ptr)
{
	struct params_copy params = *(struct params_copy *)ptr;
	free(ptr);

	//
	// Handle this client.
	// This is passive mode, so we don't care whether we were
	// told by the client to close.
	//
	(void)daemon_serviceloop(params.sockctrl, 0, params.hostlist,
	    nullAuthAllowed, uses_ssl);

	return 0;
}
#endif
