/*
 * 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 <errno.h>		// for the errno variable
#include <string.h>		// for strtok, etc
#include <stdlib.h>		// for malloc(), free(), ...
#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 _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

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(void)
{
	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
	"[-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
	"  -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(stderr, "RPCAPD, a remote packet capture daemon.\n"
	"Compiled with %s\n\n", pcap_lib_version());
	printf("%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 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 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

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

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

	if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
	{
		SOCK_DEBUG_MESSAGE(errbuf);
		exit(-1);
	}

	strncpy(address, RPCAP_DEFAULT_NETADDR, MAX_LINE);
	strncpy(port, RPCAP_DEFAULT_NETPORT, MAX_LINE);

	// 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
	while ((retval = getopt(argc, argv, "b:dhip:4l:na:s:f:v")) != -1)
	{
		switch (retval)
		{
			case 'b':
				strncpy(address, optarg, MAX_LINE);
				break;
			case 'p':
				strncpy(port, optarg, MAX_LINE);
				break;
			case '4':
				mainhints.ai_family = PF_INET;		// IPv4 server only
				break;
			case 'd':
				isdaemon = 1;
				break;
			case 'i':
#ifdef _WIN32
				printusage();
				exit(1);
#else
				isrunbyinetd = 1;
#endif
				break;
			case 'n':
				nullAuthAllowed = 1;
				break;
			case 'v':
				passivemode = 0;
				break;
			case 'l':
			{
				strncpy(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);

					strlcpy(activelist[i].address, tmpaddress, MAX_LINE);

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

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

					i++;
				}

				if (i > MAX_ACTIVE_LIST)
					SOCK_DEBUG_MESSAGE("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':
				strlcpy(loadfile, optarg, MAX_LINE);
				break;
			case 's':
				strlcpy(savefile, optarg, MAX_LINE);
				break;
			case 'h':
				printusage();
				exit(0);
				break;
			default:
				exit(1);
				break;
		}
	}

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

	if (savefile[0] && fileconf_save(savefile))
		SOCK_DEBUG_MESSAGE("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_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
		rpcapd_log(LOGPRIO_ERROR, "Can't create state change event: %s",
		    errbuf);
		exit(2);
	}

	//
	// Catch control signals.
	//
	if (!SetConsoleCtrlHandler(main_ctrl_event, TRUE))
	{
		sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
		rpcapd_log(LOGPRIO_ERROR, "Can't set control handler: %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

#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.).
		//
		// Our standard input is the input side of a connection,
		// and our standard output is the output side of a
		// connection.
		//
		int sockctrl_in, sockctrl_out;
		int devnull_fd;

		//
		// Duplicate the standard input and output, making them
		// the input and output side of the control connection.
		//
		sockctrl_in = dup(0);
		if (sockctrl_in == -1)
		{
			sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
			rpcapd_log(LOGPRIO_ERROR, "Can't dup standard input: %s",
			    errbuf);
			exit(2);
		}
		sockctrl_out = dup(1);
		if (sockctrl_out == -1)
		{
			sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
			rpcapd_log(LOGPRIO_ERROR, "Can't dup standard output: %s",
			    errbuf);
			exit(2);
		}

		//
		// Try to set the standard input and output 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);
			close(devnull_fd);
		}

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

		//
		// 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. Fom 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() != 1)
			SOCK_DEBUG_MESSAGE("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)
		{
			SOCK_DEBUG_MESSAGE("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)
		{
			SOCK_DEBUG_MESSAGE(errbuf);
			return;
		}

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

			if ((sock = sock_open(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.
	//
	SOCK_DEBUG_MESSAGE(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_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
		rpcapd_log(LOGPRIO_ERROR, "SetEvent on shutdown event failed: %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)
		SOCK_DEBUG_MESSAGE("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_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
			rpcapd_log(LOGPRIO_ERROR, "Can't create socket event: %s", errbuf);
			exit(2);
		}
		if (WSAEventSelect(sock_info->sock, event, FD_ACCEPT) == SOCKET_ERROR)
		{
			sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
			rpcapd_log(LOGPRIO_ERROR, "Can't setup socket event: %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_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
			rpcapd_log(LOGPRIO_ERROR, "WSAWaitForMultipleEvents failed: %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_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
				rpcapd_log(LOGPRIO_ERROR, "WSAEnumNetworkEvents failed: %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_fmterror(NULL,
					    network_events.iErrorCode[FD_ACCEPT_BIT],
					    errbuf,
					    PCAP_ERRBUF_SIZE);
					rpcapd_log(LOGPRIO_ERROR, "Socket 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();
}

//
// 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;
	SOCKET *sockctrl_temp;
#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 catched
		// 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_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE);
		rpcapd_log(LOGPRIO_ERROR, "Accept of control connection from client failed: %s",
		    errbuf);
		return;
	}

	//
	// We have a connection.
	// Check whether the connecting host is among the ones allowed.
	//
	if (sock_check_hostlist(hostlist, RPCAP_HOSTLIST_SEP, &from, errbuf, PCAP_ERRBUF_SIZE) < 0)
	{
		rpcap_senderror(sockctrl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
		sock_close(sockctrl, NULL, 0);
		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 (WSAEventSelect(sockctrl, NULL, 0) == SOCKET_ERROR)
	{
		sock_geterror("ioctlsocket(FIONBIO): ", errbuf, PCAP_ERRBUF_SIZE);
		rpcap_senderror(sockctrl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
		sock_close(sockctrl, NULL, 0);
		return;
	}
	if (ioctlsocket(sockctrl, FIONBIO, &off) == SOCKET_ERROR)
	{
		sock_geterror("ioctlsocket(FIONBIO): ", errbuf, PCAP_ERRBUF_SIZE);
		rpcap_senderror(sockctrl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
		sock_close(sockctrl, NULL, 0);
		return;
	}

	//
	// Allocate a location to hold the value of sockctrl.
	// It will be freed in the newly-created thread once it's
	// finished with it.
	// I guess we *could* just cast sockctrl to a void *, but that's
	// a bit ugly.
	//
	sockctrl_temp = (SOCKET *)malloc(sizeof (SOCKET));
	if (sockctrl_temp == NULL)
	{
		pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
		    errno, "malloc() failed");
		rpcap_senderror(sockctrl, 0, PCAP_ERR_OPEN, errbuf, NULL);
		sock_close(sockctrl, NULL, 0);
		return;
	}
	*sockctrl_temp = sockctrl;

	threadId = (HANDLE)_beginthreadex(NULL, 0,
	    main_passive_serviceloop_thread, (void *) sockctrl_temp, 0, NULL);
	if (threadId == 0)
	{
		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the child thread");
		rpcap_senderror(sockctrl, 0, PCAP_ERR_OPEN, errbuf, NULL);
		sock_close(sockctrl, NULL, 0);
		free(sockctrl_temp);
		return;
	}
	CloseHandle(threadId);
#else
	pid = fork();
	if (pid == -1)
	{
		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the child process");
		rpcap_senderror(sockctrl, 0, PCAP_ERR_OPEN, errbuf, NULL);
		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.
		//
		(void)daemon_serviceloop(sockctrl, sockctrl, 0,
		    nullAuthAllowed);

		close(sockctrl);

		exit(0);
	}

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

/*!
	\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;

	pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "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");
	SOCK_DEBUG_MESSAGE(errbuf);

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

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

	for (;;)
	{
		int activeclose;

		if ((sockctrl = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
		{
			SOCK_DEBUG_MESSAGE(errbuf);

			pcap_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");

			SOCK_DEBUG_MESSAGE(errbuf);

			sleep_secs(RPCAP_ACTIVE_WAIT);

			continue;
		}

		activeclose = daemon_serviceloop(sockctrl, sockctrl, 1,
		    nullAuthAllowed);

		sock_close(sockctrl, NULL, 0);

		// If the connection is closed by the user explicitely, 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)
{
	SOCKET sockctrl;

	sockctrl = *((SOCKET *)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(sockctrl, sockctrl, 0, nullAuthAllowed);

	sock_close(sockctrl, NULL, 0);

	return 0;
}
#endif
