Home | History | Annotate | Line # | Download | only in rpcapd
rpcapd.c revision 1.1.1.3
      1 /*
      2  * Copyright (c) 2002 - 2003
      3  * NetGroup, Politecnico di Torino (Italy)
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  *
     10  * 1. Redistributions of source code must retain the above copyright
     11  * notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  * notice, this list of conditions and the following disclaimer in the
     14  * documentation and/or other materials provided with the distribution.
     15  * 3. Neither the name of the Politecnico di Torino nor the names of its
     16  * contributors may be used to endorse or promote products derived from
     17  * this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  *
     31  */
     32 
     33 #ifdef HAVE_CONFIG_H
     34 #include <config.h>
     35 #endif
     36 
     37 #include "ftmacros.h"
     38 #include "diag-control.h"
     39 
     40 #include <errno.h>		// for the errno variable
     41 #include <string.h>		// for strtok, etc
     42 #include <stdlib.h>		// for malloc(), free(), ...
     43 #include <stdio.h>		// for fprintf(), stderr, FILE etc
     44 #include <pcap.h>		// for PCAP_ERRBUF_SIZE
     45 #include <signal.h>		// for signal()
     46 
     47 #include "fmtutils.h"
     48 #include "sockutils.h"		// for socket calls
     49 #include "varattrs.h"		// for _U_
     50 #include "portability.h"
     51 #include "rpcapd.h"
     52 #include "config_params.h"	// configuration file parameters
     53 #include "fileconf.h"		// for the configuration file management
     54 #include "rpcap-protocol.h"
     55 #include "daemon.h"		// the true main() method of this daemon
     56 #include "log.h"
     57 
     58 #ifdef HAVE_OPENSSL
     59 #include "sslutils.h"
     60 #endif
     61 
     62 #ifdef _WIN32
     63   #include <process.h>		// for thread stuff
     64   #include "win32-svc.h"	// for Win32 service stuff
     65   #include "getopt.h"		// for getopt()-for-Windows
     66 #else
     67   #include <fcntl.h>		// for open()
     68   #include <unistd.h>		// for exit()
     69   #include <sys/wait.h>		// waitpid()
     70 #endif
     71 
     72 //
     73 // Element in list of sockets on which we're listening for connections.
     74 //
     75 struct listen_sock {
     76 	struct listen_sock *next;
     77 	SOCKET sock;
     78 };
     79 
     80 // Global variables
     81 char hostlist[MAX_HOST_LIST + 1];		//!< Keeps the list of the hosts that are allowed to connect to this server
     82 struct active_pars activelist[MAX_ACTIVE_LIST];	//!< Keeps the list of the hosts (host, port) on which I want to connect to (active mode)
     83 int nullAuthAllowed;				//!< '1' if we permit NULL authentication, '0' otherwise
     84 static struct listen_sock *listen_socks;	//!< sockets on which we listen
     85 char loadfile[MAX_LINE + 1];			//!< Name of the file from which we have to load the configuration
     86 static int passivemode = 1;			//!< '1' if we want to run in passive mode as well
     87 static struct addrinfo mainhints;		//!< temporary struct to keep settings needed to open the new socket
     88 static char address[MAX_LINE + 1];		//!< keeps the network address (either numeric or literal) to bind to
     89 static char port[MAX_LINE + 1];			//!< keeps the network port to bind to
     90 #ifdef _WIN32
     91 static HANDLE state_change_event;		//!< event to signal that a state change should take place
     92 #endif
     93 static volatile sig_atomic_t shutdown_server;	//!< '1' if the server is to shut down
     94 static volatile sig_atomic_t reread_config;	//!< '1' if the server is to re-read its configuration
     95 static int uses_ssl; //!< '1' to use TLS over the data socket
     96 
     97 extern char *optarg;	// for getopt()
     98 
     99 // Function definition
    100 #ifdef _WIN32
    101 static unsigned __stdcall main_active(void *ptr);
    102 static BOOL WINAPI main_ctrl_event(DWORD);
    103 #else
    104 static void *main_active(void *ptr);
    105 static void main_terminate(int sign);
    106 static void main_reread_config(int sign);
    107 #endif
    108 static void accept_connections(void);
    109 static void accept_connection(SOCKET listen_sock);
    110 #ifndef _WIN32
    111 static void main_reap_children(int sign);
    112 #endif
    113 #ifdef _WIN32
    114 static unsigned __stdcall main_passive_serviceloop_thread(void *ptr);
    115 #endif
    116 
    117 #define RPCAP_ACTIVE_WAIT 30		/* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */
    118 
    119 /*!
    120 	\brief Prints the usage screen if it is launched in console mode.
    121 */
    122 static void printusage(FILE * f)
    123 {
    124 	const char *usagetext =
    125 	"USAGE:"
    126 	" "  PROGRAM_NAME " [-b <address>] [-p <port>] [-4] [-l <host_list>] [-a <host,port>]\n"
    127 	"              [-n] [-v] [-d] "
    128 #ifndef _WIN32
    129 	"[-i] "
    130 #endif
    131         "[-D] [-s <config_file>] [-f <config_file>]\n\n"
    132 	"  -b <address>    the address to bind to (either numeric or literal).\n"
    133 	"                  Default: binds to all local IPv4 and IPv6 addresses\n\n"
    134 	"  -p <port>       the port to bind to.\n"
    135 	"                  Default: binds to port " RPCAP_DEFAULT_NETPORT "\n\n"
    136 	"  -4              use only IPv4.\n"
    137 	"                  Default: use both IPv4 and IPv6 waiting sockets\n\n"
    138 	"  -l <host_list>  a file that contains a list of hosts that are allowed\n"
    139 	"                  to connect to this server (if more than one, list them one\n"
    140 	"                  per line).\n"
    141 	"                  We suggest to use literal names (instead of numeric ones)\n"
    142 	"                  in order to avoid problems with different address families.\n\n"
    143 	"  -n              permit NULL authentication (usually used with '-l')\n\n"
    144 	"  -a <host,port>  run in active mode when connecting to 'host' on port 'port'\n"
    145 	"                  In case 'port' is omitted, the default port (" RPCAP_DEFAULT_NETPORT_ACTIVE ") is used\n\n"
    146 	"  -v              run in active mode only (default: if '-a' is specified, it\n"
    147 	"                  accepts passive connections as well)\n\n"
    148 	"  -d              run in daemon mode (UNIX only) or as a service (Win32 only)\n"
    149 	"                  Warning (Win32): this switch is provided automatically when\n"
    150 	"                  the service is started from the control panel\n\n"
    151 #ifndef _WIN32
    152 	"  -i              run in inetd mode (UNIX only)\n\n"
    153 #endif
    154 	"  -D              log debugging messages\n\n"
    155 #ifdef HAVE_OPENSSL
    156 	"  -S              encrypt all communication with SSL (implements rpcaps://)\n"
    157 	"  -C              enable compression\n"
    158 	"  -K <pem_file>   uses the SSL private key in this file (default: key.pem)\n"
    159 	"  -X <pem_file>   uses the certificate from this file (default: cert.pem)\n"
    160 #endif
    161 	"  -s <config_file> save the current configuration to file\n\n"
    162 	"  -f <config_file> load the current configuration from file; all switches\n"
    163 	"                  specified from the command line are ignored\n\n"
    164 	"  -h              print this help screen\n\n";
    165 
    166 	(void)fprintf(f, "RPCAPD, a remote packet capture daemon.\n"
    167 	"Compiled with %s\n", pcap_lib_version());
    168 #if defined(HAVE_OPENSSL) && defined(SSLEAY_VERSION)
    169 	(void)fprintf(f, "Compiled with %s\n", SSLeay_version(SSLEAY_VERSION));
    170 #endif
    171 	(void)fprintf(f, "\n%s", usagetext);
    172 }
    173 
    174 
    175 
    176 //! Program main
    177 int main(int argc, char *argv[])
    178 {
    179 	char savefile[MAX_LINE + 1];		// name of the file on which we have to save the configuration
    180 	int log_to_systemlog = 0;		// Non-zero if we should log to the "system log" rather than the standard error
    181 	int isdaemon = 0;			// Non-zero if the user wants to run this program as a daemon
    182 #ifndef _WIN32
    183 	int isrunbyinetd = 0;			// Non-zero if this is being run by inetd or something inetd-like
    184 #endif
    185 	int log_debug_messages = 0;		// Non-zero if the user wants debug messages logged
    186 	int retval;				// keeps the returning value from several functions
    187 	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
    188 #ifndef _WIN32
    189 	struct sigaction action;
    190 #endif
    191 #ifdef HAVE_OPENSSL
    192 	int enable_compression = 0;
    193 #endif
    194 
    195 	savefile[0] = 0;
    196 	loadfile[0] = 0;
    197 	hostlist[0] = 0;
    198 
    199 	// Initialize errbuf
    200 	memset(errbuf, 0, sizeof(errbuf));
    201 
    202 	pcap_strlcpy(address, RPCAP_DEFAULT_NETADDR, sizeof (address));
    203 	pcap_strlcpy(port, RPCAP_DEFAULT_NETPORT, sizeof (port));
    204 
    205 	// Prepare to open a new server socket
    206 	memset(&mainhints, 0, sizeof(struct addrinfo));
    207 
    208 	mainhints.ai_family = PF_UNSPEC;
    209 	mainhints.ai_flags = AI_PASSIVE;	// Ready to a bind() socket
    210 	mainhints.ai_socktype = SOCK_STREAM;
    211 
    212 	// Getting the proper command line options
    213 #	ifdef HAVE_OPENSSL
    214 #		define SSL_CLOPTS  "SK:X:C"
    215 #	else
    216 #		define SSL_CLOPTS ""
    217 #	endif
    218 
    219 #	define CLOPTS "b:dDhip:4l:na:s:f:v" SSL_CLOPTS
    220 
    221 	while ((retval = getopt(argc, argv, CLOPTS)) != -1)
    222 	{
    223 		switch (retval)
    224 		{
    225 			case 'D':
    226 				log_debug_messages = 1;
    227 				rpcapd_log_set(log_to_systemlog, log_debug_messages);
    228 				break;
    229 			case 'b':
    230 				pcap_strlcpy(address, optarg, sizeof (address));
    231 				break;
    232 			case 'p':
    233 				pcap_strlcpy(port, optarg, sizeof (port));
    234 				break;
    235 			case '4':
    236 				mainhints.ai_family = PF_INET;		// IPv4 server only
    237 				break;
    238 			case 'd':
    239 				isdaemon = 1;
    240 				log_to_systemlog = 1;
    241 				rpcapd_log_set(log_to_systemlog, log_debug_messages);
    242 				break;
    243 			case 'i':
    244 #ifdef _WIN32
    245 				printusage(stderr);
    246 				exit(1);
    247 #else
    248 				isrunbyinetd = 1;
    249 				log_to_systemlog = 1;
    250 				rpcapd_log_set(log_to_systemlog, log_debug_messages);
    251 #endif
    252 				break;
    253 			case 'n':
    254 				nullAuthAllowed = 1;
    255 				break;
    256 			case 'v':
    257 				passivemode = 0;
    258 				break;
    259 			case 'l':
    260 			{
    261 				pcap_strlcpy(hostlist, optarg, sizeof(hostlist));
    262 				break;
    263 			}
    264 			case 'a':
    265 			{
    266 				char *tmpaddress, *tmpport;
    267 				char *lasts;
    268 				int i = 0;
    269 
    270 				tmpaddress = pcap_strtok_r(optarg, RPCAP_HOSTLIST_SEP, &lasts);
    271 
    272 				while ((tmpaddress != NULL) && (i < MAX_ACTIVE_LIST))
    273 				{
    274 					tmpport = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
    275 
    276 					pcap_strlcpy(activelist[i].address, tmpaddress, sizeof (activelist[i].address));
    277 
    278 					if ((tmpport == NULL) || (strcmp(tmpport, "DEFAULT") == 0)) // the user choose a custom port
    279 						pcap_strlcpy(activelist[i].port, RPCAP_DEFAULT_NETPORT_ACTIVE, sizeof (activelist[i].port));
    280 					else
    281 						pcap_strlcpy(activelist[i].port, tmpport, sizeof (activelist[i].port));
    282 
    283 					tmpaddress = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
    284 
    285 					i++;
    286 				}
    287 
    288 				if (i > MAX_ACTIVE_LIST)
    289 					rpcapd_log(LOGPRIO_ERROR, "Only MAX_ACTIVE_LIST active connections are currently supported.");
    290 
    291 				// I don't initialize the remaining part of the structure, since
    292 				// it is already zeroed (it is a global var)
    293 				break;
    294 			}
    295 			case 'f':
    296 				pcap_strlcpy(loadfile, optarg, sizeof (loadfile));
    297 				break;
    298 			case 's':
    299 				pcap_strlcpy(savefile, optarg, sizeof (savefile));
    300 				break;
    301 #ifdef HAVE_OPENSSL
    302 			case 'S':
    303 				uses_ssl = 1;
    304 				break;
    305 			case 'C':
    306 				enable_compression = 1;
    307 				break;
    308 			case 'K':
    309 				ssl_set_keyfile(optarg);
    310 				break;
    311 			case 'X':
    312 				ssl_set_certfile(optarg);
    313 				break;
    314 #endif
    315 			case 'h':
    316 				printusage(stdout);
    317 				exit(0);
    318 				/*NOTREACHED*/
    319 			default:
    320 				exit(1);
    321 				/*NOTREACHED*/
    322 		}
    323 	}
    324 
    325 #ifndef _WIN32
    326 	if (isdaemon && isrunbyinetd)
    327 	{
    328 		rpcapd_log(LOGPRIO_ERROR, "rpcapd: -d and -i can't be used together");
    329 		exit(1);
    330 	}
    331 #endif
    332 
    333 	//
    334 	// We want UTF-8 error messages.
    335 	//
    336 	if (pcap_init(PCAP_CHAR_ENC_UTF_8, errbuf) == -1)
    337 	{
    338 		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
    339 		exit(-1);
    340 	}
    341 	pcap_fmt_set_encoding(PCAP_CHAR_ENC_UTF_8);
    342 
    343 	if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
    344 	{
    345 		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
    346 		exit(-1);
    347 	}
    348 
    349 	if (savefile[0] && fileconf_save(savefile))
    350 		rpcapd_log(LOGPRIO_DEBUG, "Error when saving the configuration to file");
    351 
    352 	// If the file does not exist, it keeps the settings provided by the command line
    353 	if (loadfile[0])
    354 		fileconf_read();
    355 
    356 #ifdef _WIN32
    357 	//
    358 	// Create a handle to signal the main loop to tell it to do
    359 	// something.
    360 	//
    361 	state_change_event = CreateEvent(NULL, FALSE, FALSE, NULL);
    362 	if (state_change_event == NULL)
    363 	{
    364 		sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
    365 		    "Can't create state change event");
    366 		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
    367 		exit(2);
    368 	}
    369 
    370 	//
    371 	// Catch control signals.
    372 	//
    373 	if (!SetConsoleCtrlHandler(main_ctrl_event, TRUE))
    374 	{
    375 		sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
    376 		    "Can't set control handler");
    377 		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
    378 		exit(2);
    379 	}
    380 #else
    381 	memset(&action, 0, sizeof (action));
    382 	action.sa_handler = main_terminate;
    383 	action.sa_flags = 0;
    384 	sigemptyset(&action.sa_mask);
    385 	sigaction(SIGTERM, &action, NULL);
    386 	memset(&action, 0, sizeof (action));
    387 	action.sa_handler = main_reap_children;
    388 	action.sa_flags = 0;
    389 	sigemptyset(&action.sa_mask);
    390 	sigaction(SIGCHLD, &action, NULL);
    391 	// Ignore SIGPIPE - we'll get EPIPE when trying to write to a closed
    392 	// connection, we don't want to get killed by a signal in that case
    393 	signal(SIGPIPE, SIG_IGN);
    394 #endif
    395 
    396 # ifdef HAVE_OPENSSL
    397 	if (uses_ssl) {
    398 		if (ssl_init_once(1, enable_compression, errbuf, PCAP_ERRBUF_SIZE) < 0)
    399 		{
    400 			rpcapd_log(LOGPRIO_ERROR, "Can't initialize SSL: %s",
    401 			    errbuf);
    402 			exit(2);
    403 		}
    404 	}
    405 # endif
    406 
    407 #ifndef _WIN32
    408 	if (isrunbyinetd)
    409 	{
    410 		//
    411 		// -i was specified, indicating that this is being run
    412 		// by inetd or something that can run network daemons
    413 		// as if it were inetd (xinetd, launchd, systemd, etc.).
    414 		//
    415 		// We assume that the program that launched us just
    416 		// duplicated a single socket for the connection
    417 		// to our standard input, output, and error, so we
    418 		// can just use the standard input as our control
    419 		// socket.
    420 		//
    421 		int sockctrl;
    422 		int devnull_fd;
    423 
    424 		//
    425 		// Duplicate the standard input as the control socket.
    426 		//
    427 		sockctrl = dup(0);
    428 		if (sockctrl == -1)
    429 		{
    430 			sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
    431 			    "Can't dup standard input");
    432 			rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
    433 			exit(2);
    434 		}
    435 
    436 		//
    437 		// Try to set the standard input, output, and error
    438 		// to /dev/null.
    439 		//
    440 		devnull_fd = open("/dev/null", O_RDWR);
    441 		if (devnull_fd != -1)
    442 		{
    443 			//
    444 			// If this fails, just drive on.
    445 			//
    446 			(void)dup2(devnull_fd, 0);
    447 			(void)dup2(devnull_fd, 1);
    448 			(void)dup2(devnull_fd, 2);
    449 			close(devnull_fd);
    450 		}
    451 
    452 		//
    453 		// Handle this client.
    454 		// This is passive mode, so we don't care whether we were
    455 		// told by the client to close.
    456 		//
    457 		char *hostlist_copy = strdup(hostlist);
    458 		if (hostlist_copy == NULL)
    459 		{
    460 			rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
    461 			exit(0);
    462 		}
    463 		(void)daemon_serviceloop(sockctrl, 0, hostlist_copy,
    464 		    nullAuthAllowed, uses_ssl);
    465 
    466 		//
    467 		// Nothing more to do.
    468 		//
    469 		exit(0);
    470 	}
    471 #endif
    472 
    473 	if (isdaemon)
    474 	{
    475 		//
    476 		// This is being run as a daemon.
    477 		// On UN*X, it might be manually run, or run from an
    478 		// rc file.
    479 		//
    480 #ifndef _WIN32
    481 		int pid;
    482 
    483 		//
    484 		// Daemonize ourselves.
    485 		//
    486 		// Unix Network Programming, pg 336
    487 		//
    488 		if ((pid = fork()) != 0)
    489 			exit(0);		// Parent terminates
    490 
    491 		// First child continues
    492 		// Set daemon mode
    493 		setsid();
    494 
    495 		// generated under unix with 'kill -HUP', needed to reload the configuration
    496 		memset(&action, 0, sizeof (action));
    497 		action.sa_handler = main_reread_config;
    498 		action.sa_flags = 0;
    499 		sigemptyset(&action.sa_mask);
    500 		sigaction(SIGHUP, &action, NULL);
    501 
    502 		if ((pid = fork()) != 0)
    503 			exit(0);		// First child terminates
    504 
    505 		// LINUX WARNING: the current linux implementation of pthreads requires a management thread
    506 		// to handle some hidden stuff. So, as soon as you create the first thread, two threads are
    507 		// created. From this point on, the number of threads active are always one more compared
    508 		// to the number you're expecting
    509 
    510 		// Second child continues
    511 //		umask(0);
    512 //		chdir("/");
    513 #else
    514 		//
    515 		// This is being run as a service on Windows.
    516 		//
    517 		// If this call succeeds, it is blocking on Win32
    518 		//
    519 		if (!svc_start())
    520 			rpcapd_log(LOGPRIO_DEBUG, "Unable to start the service");
    521 
    522 		// When the previous call returns, the entire application has to be stopped.
    523 		exit(0);
    524 #endif
    525 	}
    526 	else	// Console mode
    527 	{
    528 #ifndef _WIN32
    529 		// Enable the catching of Ctrl+C
    530 		memset(&action, 0, sizeof (action));
    531 		action.sa_handler = main_terminate;
    532 		action.sa_flags = 0;
    533 		sigemptyset(&action.sa_mask);
    534 		sigaction(SIGINT, &action, NULL);
    535 
    536 		// generated under unix with 'kill -HUP', needed to reload the configuration
    537 		// We do not have this kind of signal in Win32
    538 		memset(&action, 0, sizeof (action));
    539 		action.sa_handler = main_reread_config;
    540 		action.sa_flags = 0;
    541 		sigemptyset(&action.sa_mask);
    542 		sigaction(SIGHUP, &action, NULL);
    543 #endif
    544 
    545 		printf("Press CTRL + C to stop the server...\n");
    546 	}
    547 
    548 	// If we're a Win32 service, we have already called this function in the service_main
    549 	main_startup();
    550 
    551 	// The code should never arrive here (since the main_startup is blocking)
    552 	//  however this avoids a compiler warning
    553 	exit(0);
    554 }
    555 
    556 void main_startup(void)
    557 {
    558 	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
    559 	struct addrinfo *addrinfo;		// keeps the addrinfo chain; required to open a new socket
    560 	int i;
    561 #ifdef _WIN32
    562 	HANDLE threadId;			// handle for the subthread
    563 #else
    564 	pid_t pid;
    565 #endif
    566 
    567 	i = 0;
    568 	addrinfo = NULL;
    569 	memset(errbuf, 0, sizeof(errbuf));
    570 
    571 	// Starts all the active threads
    572 	while ((i < MAX_ACTIVE_LIST) && (activelist[i].address[0] != 0))
    573 	{
    574 		activelist[i].ai_family = mainhints.ai_family;
    575 
    576 #ifdef _WIN32
    577 		threadId = (HANDLE)_beginthreadex(NULL, 0, main_active,
    578 		    (void *)&activelist[i], 0, NULL);
    579 		if (threadId == 0)
    580 		{
    581 			rpcapd_log(LOGPRIO_DEBUG, "Error creating the active child threads");
    582 			continue;
    583 		}
    584 		CloseHandle(threadId);
    585 #else
    586 		if ((pid = fork()) == 0)	// I am the child
    587 		{
    588 			main_active((void *) &activelist[i]);
    589 			exit(0);
    590 		}
    591 #endif
    592 		i++;
    593 	}
    594 
    595 	/*
    596 	 * The code that manages the active connections is not blocking;
    597 	 * the code that manages the passive connection is blocking.
    598 	 * So, if the user does not want to run in passive mode, we have
    599 	 * to block the main thread here, otherwise the program ends and
    600 	 * all threads are stopped.
    601 	 *
    602 	 * WARNING: this means that in case we have only active mode,
    603 	 * the program does not terminate even if all the child thread
    604 	 * terminates. The user has always to press Ctrl+C (or send a
    605 	 * SIGTERM) to terminate the program.
    606 	 */
    607 	if (passivemode)
    608 	{
    609 		struct addrinfo *tempaddrinfo;
    610 
    611 		//
    612 		// Get a list of sockets on which to listen.
    613 		//
    614 		if (sock_initaddress((address[0]) ? address : NULL, port, &mainhints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
    615 		{
    616 			rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
    617 			return;
    618 		}
    619 
    620 		for (tempaddrinfo = addrinfo; tempaddrinfo;
    621 		     tempaddrinfo = tempaddrinfo->ai_next)
    622 		{
    623 			SOCKET sock;
    624 			struct listen_sock *sock_info;
    625 
    626 			if ((sock = sock_open(NULL, tempaddrinfo, SOCKOPEN_SERVER, SOCKET_MAXCONN, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
    627 			{
    628 				switch (tempaddrinfo->ai_family)
    629 				{
    630 				case AF_INET:
    631 				{
    632 					struct sockaddr_in *in;
    633 					char addrbuf[INET_ADDRSTRLEN];
    634 
    635 					in = (struct sockaddr_in *)tempaddrinfo->ai_addr;
    636 					rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for %s:%u: %s",
    637 					    inet_ntop(AF_INET, &in->sin_addr,
    638 						addrbuf, sizeof (addrbuf)),
    639 					    ntohs(in->sin_port),
    640 					    errbuf);
    641 					break;
    642 				}
    643 
    644 				case AF_INET6:
    645 				{
    646 					struct sockaddr_in6 *in6;
    647 					char addrbuf[INET6_ADDRSTRLEN];
    648 
    649 					in6 = (struct sockaddr_in6 *)tempaddrinfo->ai_addr;
    650 					rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for %s:%u: %s",
    651 					    inet_ntop(AF_INET6, &in6->sin6_addr,
    652 						addrbuf, sizeof (addrbuf)),
    653 					    ntohs(in6->sin6_port),
    654 					    errbuf);
    655 					break;
    656 				}
    657 
    658 				default:
    659 					rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for address family %u: %s",
    660 					    tempaddrinfo->ai_family,
    661 					    errbuf);
    662 					break;
    663 				}
    664 				continue;
    665 			}
    666 
    667 			sock_info = (struct listen_sock *) malloc(sizeof (struct listen_sock));
    668 			if (sock_info == NULL)
    669 			{
    670 				rpcapd_log(LOGPRIO_ERROR, "Can't allocate structure for listen socket");
    671 				exit(2);
    672 			}
    673 			sock_info->sock = sock;
    674 			sock_info->next = listen_socks;
    675 			listen_socks = sock_info;
    676 		}
    677 
    678 		freeaddrinfo(addrinfo);
    679 
    680 		if (listen_socks == NULL)
    681 		{
    682 			rpcapd_log(LOGPRIO_ERROR, "Can't listen on any address");
    683 			exit(2);
    684 		}
    685 
    686 		//
    687 		// Now listen on all of them, waiting for connections.
    688 		//
    689 		accept_connections();
    690 	}
    691 
    692 	//
    693 	// We're done; exit.
    694 	//
    695 	rpcapd_log(LOGPRIO_DEBUG, PROGRAM_NAME " is closing.\n");
    696 
    697 #ifndef _WIN32
    698 	//
    699 	// Sends a KILL signal to all the processes in this process's
    700 	// process group; i.e., it kills all the child processes
    701 	// we've created.
    702 	//
    703 	// XXX - that also includes us, so we will be killed as well;
    704 	// that may cause a message to be printed or logged.
    705 	//
    706 	kill(0, SIGKILL);
    707 #endif
    708 
    709 	//
    710 	// Just leave.  We shouldn't need to clean up sockets or
    711 	// anything else, and if we try to do so, we'll could end
    712 	// up closing sockets, or shutting Winsock down, out from
    713 	// under service loops, causing all sorts of noisy error
    714 	// messages.
    715 	//
    716 	// We shouldn't need to worry about cleaning up any resources
    717 	// such as handles, sockets, threads, etc. - exit() should
    718 	// terminate the process, causing all those resources to be
    719 	// cleaned up (including the threads; Microsoft claims in the
    720 	// ExitProcess() documentation that, if ExitProcess() is called,
    721 	// "If a thread is waiting on a kernel object, it will not be
    722 	// terminated until the wait has completed.", but claims in the
    723 	// _beginthread()/_beginthreadex() documentation that "All threads
    724 	// are terminated if any thread calls abort, exit, _exit, or
    725 	// ExitProcess." - the latter appears to be the case, even for
    726 	// threads waiting on the event for a pcap_t).
    727 	//
    728 	exit(0);
    729 }
    730 
    731 #ifdef _WIN32
    732 static void
    733 send_state_change_event(void)
    734 {
    735 	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
    736 
    737 	if (!SetEvent(state_change_event))
    738 	{
    739 		sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
    740 		    "SetEvent on shutdown event failed");
    741 		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
    742 	}
    743 }
    744 
    745 void
    746 send_shutdown_notification(void)
    747 {
    748 	//
    749 	// Indicate that the server should shut down.
    750 	//
    751 	shutdown_server = 1;
    752 
    753 	//
    754 	// Send a state change event, to wake up WSAWaitForMultipleEvents().
    755 	//
    756 	send_state_change_event();
    757 }
    758 
    759 void
    760 send_reread_configuration_notification(void)
    761 {
    762 	//
    763 	// Indicate that the server should re-read its configuration file.
    764 	//
    765 	reread_config = 1;
    766 
    767 	//
    768 	// Send a state change event, to wake up WSAWaitForMultipleEvents().
    769 	//
    770 	send_state_change_event();
    771 }
    772 
    773 static BOOL WINAPI main_ctrl_event(DWORD ctrltype)
    774 {
    775 	//
    776 	// ctrltype is one of:
    777 	//
    778 	// CTRL_C_EVENT - we got a ^C; this is like SIGINT
    779 	// CTRL_BREAK_EVENT - we got Ctrl+Break
    780 	// CTRL_CLOSE_EVENT - the console was closed; this is like SIGHUP
    781 	// CTRL_LOGOFF_EVENT - a user is logging off; this is received
    782 	//   only by services
    783 	// CTRL_SHUTDOWN_EVENT - the systemis shutting down; this is
    784 	//   received only by services
    785 	//
    786 	// For now, we treat all but CTRL_LOGOFF_EVENT as indications
    787 	// that we should shut down.
    788 	//
    789 	switch (ctrltype)
    790 	{
    791 		case CTRL_C_EVENT:
    792 		case CTRL_BREAK_EVENT:
    793 		case CTRL_CLOSE_EVENT:
    794 		case CTRL_SHUTDOWN_EVENT:
    795 			//
    796 			// Set a shutdown notification.
    797 			//
    798 			send_shutdown_notification();
    799 			break;
    800 
    801 		default:
    802 			break;
    803 	}
    804 
    805 	//
    806 	// We handled this.
    807 	//
    808 	return TRUE;
    809 }
    810 #else
    811 static void main_terminate(int sign _U_)
    812 {
    813 	//
    814 	// Note that the server should shut down.
    815 	// select() should get an EINTR error when we return,
    816 	// so it will wake up and know it needs to check the flag.
    817 	//
    818 	shutdown_server = 1;
    819 }
    820 
    821 static void main_reread_config(int sign _U_)
    822 {
    823 	//
    824 	// Note that the server should re-read its configuration file.
    825 	// select() should get an EINTR error when we return,
    826 	// so it will wake up and know it needs to check the flag.
    827 	//
    828 	reread_config = 1;
    829 }
    830 
    831 static void main_reap_children(int sign _U_)
    832 {
    833 	pid_t pid;
    834 	int exitstat;
    835 
    836 	// Reap all child processes that have exited.
    837 	// For reference, Stevens, pg 128
    838 
    839 	while ((pid = waitpid(-1, &exitstat, WNOHANG)) > 0)
    840 		rpcapd_log(LOGPRIO_DEBUG, "Child terminated");
    841 
    842 	return;
    843 }
    844 #endif
    845 
    846 //
    847 // Loop waiting for incoming connections and accepting them.
    848 //
    849 static void
    850 accept_connections(void)
    851 {
    852 #ifdef _WIN32
    853 	struct listen_sock *sock_info;
    854 	DWORD num_events;
    855 	WSAEVENT *events;
    856 	int i;
    857 	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
    858 
    859 	//
    860 	// How big does the set of events need to be?
    861 	// One for the shutdown event, plus one for every socket on which
    862 	// we'll be listening.
    863 	//
    864 	num_events = 1;		// shutdown event
    865 	for (sock_info = listen_socks; sock_info;
    866 	    sock_info = sock_info->next)
    867 	{
    868 		if (num_events == WSA_MAXIMUM_WAIT_EVENTS)
    869 		{
    870 			//
    871 			// WSAWaitForMultipleEvents() doesn't support
    872 			// more than WSA_MAXIMUM_WAIT_EVENTS events
    873 			// on which to wait.
    874 			//
    875 			rpcapd_log(LOGPRIO_ERROR, "Too many sockets on which to listen");
    876 			exit(2);
    877 		}
    878 		num_events++;
    879 	}
    880 
    881 	//
    882 	// Allocate the array of events.
    883 	//
    884 	events = (WSAEVENT *) malloc(num_events * sizeof (WSAEVENT));
    885 	if (events == NULL)
    886 	{
    887 		rpcapd_log(LOGPRIO_ERROR, "Can't allocate array of events which to listen");
    888 		exit(2);
    889 	}
    890 
    891 	//
    892 	// Fill it in.
    893 	//
    894 	events[0] = state_change_event;	// state change event first
    895 	for (sock_info = listen_socks, i = 1; sock_info;
    896 	    sock_info = sock_info->next, i++)
    897 	{
    898 		WSAEVENT event;
    899 
    900 		//
    901 		// Create an event that is signaled if there's a connection
    902 		// to accept on the socket in question.
    903 		//
    904 		event = WSACreateEvent();
    905 		if (event == WSA_INVALID_EVENT)
    906 		{
    907 			sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
    908 			    "Can't create socket event");
    909 			rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
    910 			exit(2);
    911 		}
    912 		if (WSAEventSelect(sock_info->sock, event, FD_ACCEPT) == SOCKET_ERROR)
    913 		{
    914 			sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
    915 			    "Can't setup socket event");
    916 			rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
    917 			exit(2);
    918 		}
    919 		events[i] = event;
    920 	}
    921 
    922 	for (;;)
    923 	{
    924 		//
    925 		// Wait for incoming connections.
    926 		//
    927 		DWORD ret;
    928 
    929 		ret = WSAWaitForMultipleEvents(num_events, events, FALSE,
    930 		    WSA_INFINITE, FALSE);
    931 		if (ret == WSA_WAIT_FAILED)
    932 		{
    933 			sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
    934 			    "WSAWaitForMultipleEvents failed");
    935 			rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
    936 			exit(2);
    937 		}
    938 
    939 		if (ret == WSA_WAIT_EVENT_0)
    940 		{
    941 			//
    942 			// The state change event was set.
    943 			//
    944 			if (shutdown_server)
    945 			{
    946 				//
    947 				// Time to quit. Exit the loop.
    948 				//
    949 				break;
    950 			}
    951 			if (reread_config)
    952 			{
    953 				//
    954 				// We should re-read the configuration
    955 				// file.
    956 				//
    957 				reread_config = 0;	// clear the indicator
    958 				fileconf_read();
    959 			}
    960 		}
    961 
    962 		//
    963 		// Check each socket.
    964 		//
    965 		for (sock_info = listen_socks, i = 1; sock_info;
    966 		    sock_info = sock_info->next, i++)
    967 		{
    968 			WSANETWORKEVENTS network_events;
    969 
    970 			if (WSAEnumNetworkEvents(sock_info->sock,
    971 			    events[i], &network_events) == SOCKET_ERROR)
    972 			{
    973 				sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
    974 				    "WSAEnumNetworkEvents failed");
    975 				rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
    976 				exit(2);
    977 			}
    978 			if (network_events.lNetworkEvents & FD_ACCEPT)
    979 			{
    980 				//
    981 				// Did an error occur?
    982 				//
    983 				if (network_events.iErrorCode[FD_ACCEPT_BIT] != 0)
    984 				{
    985 					//
    986 					// Yes - report it and keep going.
    987 					//
    988 					sock_fmterrmsg(errbuf,
    989 					    PCAP_ERRBUF_SIZE,
    990 					    network_events.iErrorCode[FD_ACCEPT_BIT],
    991 					    "Socket error");
    992 					rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
    993 					continue;
    994 				}
    995 
    996 				//
    997 				// Accept the connection.
    998 				//
    999 				accept_connection(sock_info->sock);
   1000 			}
   1001 		}
   1002 	}
   1003 #else
   1004 	struct listen_sock *sock_info;
   1005 	int num_sock_fds;
   1006 
   1007 	//
   1008 	// How big does the bitset of sockets on which to select() have
   1009 	// to be?
   1010 	//
   1011 	num_sock_fds = 0;
   1012 	for (sock_info = listen_socks; sock_info; sock_info = sock_info->next)
   1013 	{
   1014 		if (sock_info->sock + 1 > num_sock_fds)
   1015 		{
   1016 			if ((unsigned int)(sock_info->sock + 1) >
   1017 			    (unsigned int)FD_SETSIZE)
   1018 			{
   1019 				rpcapd_log(LOGPRIO_ERROR, "Socket FD is too bit for an fd_set");
   1020 				exit(2);
   1021 			}
   1022 			num_sock_fds = sock_info->sock + 1;
   1023 		}
   1024 	}
   1025 
   1026 	for (;;)
   1027 	{
   1028 		fd_set sock_fds;
   1029 		int ret;
   1030 
   1031 		//
   1032 		// Set up an fd_set for all the sockets on which we're
   1033 		// listening.
   1034 		//
   1035 		// This set is modified by select(), so we have to
   1036 		// construct it anew each time.
   1037 		//
   1038 		FD_ZERO(&sock_fds);
   1039 		for (sock_info = listen_socks; sock_info;
   1040 		    sock_info = sock_info->next)
   1041 		{
   1042 			FD_SET(sock_info->sock, &sock_fds);
   1043 		}
   1044 
   1045 		//
   1046 		// Wait for incoming connections.
   1047 		//
   1048 		ret = select(num_sock_fds, &sock_fds, NULL, NULL, NULL);
   1049 		if (ret == -1)
   1050 		{
   1051 			if (errno == EINTR)
   1052 			{
   1053 				//
   1054 				// If this is a "terminate the
   1055 				// server" signal, exit the loop,
   1056 				// otherwise just keep trying.
   1057 				//
   1058 				if (shutdown_server)
   1059 				{
   1060 					//
   1061 					// Time to quit.  Exit the loop.
   1062 					//
   1063 					break;
   1064 				}
   1065 				if (reread_config)
   1066 				{
   1067 					//
   1068 					// We should re-read the configuration
   1069 					// file.
   1070 					//
   1071 					reread_config = 0;	// clear the indicator
   1072 					fileconf_read();
   1073 				}
   1074 
   1075 				//
   1076 				// Go back and wait again.
   1077 				//
   1078 				continue;
   1079 			}
   1080 			else
   1081 			{
   1082 				rpcapd_log(LOGPRIO_ERROR, "select failed: %s",
   1083 				    strerror(errno));
   1084 				exit(2);
   1085 			}
   1086 		}
   1087 
   1088 		//
   1089 		// Check each socket.
   1090 		//
   1091 		for (sock_info = listen_socks; sock_info;
   1092 		    sock_info = sock_info->next)
   1093 		{
   1094 			if (FD_ISSET(sock_info->sock, &sock_fds))
   1095 			{
   1096 				//
   1097 				// Accept the connection.
   1098 				//
   1099 				accept_connection(sock_info->sock);
   1100 			}
   1101 		}
   1102 	}
   1103 #endif
   1104 
   1105 	//
   1106 	// Close all the listen sockets.
   1107 	//
   1108 	for (sock_info = listen_socks; sock_info; sock_info = sock_info->next)
   1109 	{
   1110 		closesocket(sock_info->sock);
   1111 	}
   1112 	sock_cleanup();
   1113 }
   1114 
   1115 #ifdef _WIN32
   1116 //
   1117 // A structure to hold the parameters to the daemon service loop
   1118 // thread on Windows.
   1119 //
   1120 // (On UN*X, there is no need for this explicit copy since the
   1121 // fork "inherits" the parent stack.)
   1122 //
   1123 struct params_copy {
   1124 	SOCKET sockctrl;
   1125 	char *hostlist;
   1126 };
   1127 #endif
   1128 
   1129 //
   1130 // Accept a connection and start a worker thread, on Windows, or a
   1131 // worker process, on UN*X, to handle the connection.
   1132 //
   1133 static void
   1134 accept_connection(SOCKET listen_sock)
   1135 {
   1136 	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
   1137 	SOCKET sockctrl;			// keeps the socket ID for this control connection
   1138 	struct sockaddr_storage from;		// generic sockaddr_storage variable
   1139 	socklen_t fromlen;			// keeps the length of the sockaddr_storage variable
   1140 
   1141 #ifdef _WIN32
   1142 	HANDLE threadId;			// handle for the subthread
   1143 	u_long off = 0;
   1144 	struct params_copy *params_copy = NULL;
   1145 #else
   1146 	pid_t pid;
   1147 #endif
   1148 
   1149 	// Initialize errbuf
   1150 	memset(errbuf, 0, sizeof(errbuf));
   1151 
   1152 	for (;;)
   1153 	{
   1154 		// Accept the connection
   1155 		fromlen = sizeof(struct sockaddr_storage);
   1156 
   1157 		sockctrl = accept(listen_sock, (struct sockaddr *) &from, &fromlen);
   1158 
   1159 		if (sockctrl != INVALID_SOCKET)
   1160 		{
   1161 			// Success.
   1162 			break;
   1163 		}
   1164 
   1165 		// The accept() call can return this error when a signal is caught
   1166 		// In this case, we have simply to ignore this error code
   1167 		// Stevens, pg 124
   1168 #ifdef _WIN32
   1169 		if (WSAGetLastError() == WSAEINTR)
   1170 #else
   1171 		if (errno == EINTR)
   1172 #endif
   1173 			continue;
   1174 
   1175 		// Don't check for errors here, since the error can be due to the fact that the thread
   1176 		// has been killed
   1177 		sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, "accept() failed");
   1178 		rpcapd_log(LOGPRIO_ERROR, "Accept of control connection from client failed: %s",
   1179 		    errbuf);
   1180 		return;
   1181 	}
   1182 
   1183 #ifdef _WIN32
   1184 	//
   1185 	// Put the socket back into blocking mode; doing WSAEventSelect()
   1186 	// on the listen socket makes that socket non-blocking, and it
   1187 	// appears that sockets returned from an accept() on that socket
   1188 	// are also non-blocking.
   1189 	//
   1190 	// First, we have to un-WSAEventSelect() this socket, and then
   1191 	// we can turn non-blocking mode off.
   1192 	//
   1193 	// If this fails, we aren't guaranteed that, for example, any
   1194 	// of the error message will be sent - if it can't be put in
   1195 	// the socket queue, the send will just fail.
   1196 	//
   1197 	// So we just log the message and close the connection.
   1198 	//
   1199 	if (WSAEventSelect(sockctrl, NULL, 0) == SOCKET_ERROR)
   1200 	{
   1201 		sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
   1202 		    "WSAEventSelect() failed");
   1203 		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
   1204 		sock_close(sockctrl, NULL, 0);
   1205 		return;
   1206 	}
   1207 	if (ioctlsocket(sockctrl, FIONBIO, &off) == SOCKET_ERROR)
   1208 	{
   1209 		sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
   1210 		    "ioctlsocket(FIONBIO) failed");
   1211 		rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
   1212 		sock_close(sockctrl, NULL, 0);
   1213 		return;
   1214 	}
   1215 
   1216 	//
   1217 	// Make a copy of the host list to pass to the new thread, so that
   1218 	// if we update it in the main thread, it won't catch us in the
   1219 	// middle of updating it.
   1220 	//
   1221 	// daemon_serviceloop() will free it once it's done with it.
   1222 	//
   1223 	char *hostlist_copy = strdup(hostlist);
   1224 	if (hostlist_copy == NULL)
   1225 	{
   1226 		rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
   1227 		sock_close(sockctrl, NULL, 0);
   1228 		return;
   1229 	}
   1230 
   1231 	//
   1232 	// Allocate a location to hold the values of sockctrl.
   1233 	// It will be freed in the newly-created thread once it's
   1234 	// finished with it.
   1235 	//
   1236 	params_copy = malloc(sizeof(*params_copy));
   1237 	if (params_copy == NULL)
   1238 	{
   1239 		rpcapd_log(LOGPRIO_ERROR, "Out of memory allocating the parameter copy structure");
   1240 		free(hostlist_copy);
   1241 		sock_close(sockctrl, NULL, 0);
   1242 		return;
   1243 	}
   1244 	params_copy->sockctrl = sockctrl;
   1245 	params_copy->hostlist = hostlist_copy;
   1246 
   1247 	threadId = (HANDLE)_beginthreadex(NULL, 0,
   1248 	    main_passive_serviceloop_thread, (void *) params_copy, 0, NULL);
   1249 	if (threadId == 0)
   1250 	{
   1251 		rpcapd_log(LOGPRIO_ERROR, "Error creating the child thread");
   1252 		free(params_copy);
   1253 		free(hostlist_copy);
   1254 		sock_close(sockctrl, NULL, 0);
   1255 		return;
   1256 	}
   1257 	CloseHandle(threadId);
   1258 #else /* _WIN32 */
   1259 	pid = fork();
   1260 	if (pid == -1)
   1261 	{
   1262 		rpcapd_log(LOGPRIO_ERROR, "Error creating the child process: %s",
   1263 		    strerror(errno));
   1264 		sock_close(sockctrl, NULL, 0);
   1265 		return;
   1266 	}
   1267 	if (pid == 0)
   1268 	{
   1269 		//
   1270 		// Child process.
   1271 		//
   1272 		// Close the socket on which we're listening (must
   1273 		// be open only in the parent).
   1274 		//
   1275 		closesocket(listen_sock);
   1276 
   1277 #if 0
   1278 		//
   1279 		// Modify thread params so that it can be killed at any time
   1280 		// XXX - is this necessary?  This is the main and, currently,
   1281 		// only thread in the child process, and nobody tries to
   1282 		// cancel us, although *we* may cancel the thread that's
   1283 		// handling the capture loop.
   1284 		//
   1285 		if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL))
   1286 			goto end;
   1287 		if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL))
   1288 			goto end;
   1289 #endif
   1290 
   1291 		//
   1292 		// Run the service loop.
   1293 		// This is passive mode, so we don't care whether we were
   1294 		// told by the client to close.
   1295 		//
   1296 		char *hostlist_copy = strdup(hostlist);
   1297 		if (hostlist_copy == NULL)
   1298 		{
   1299 			rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
   1300 			exit(0);
   1301 		}
   1302 		(void)daemon_serviceloop(sockctrl, 0, hostlist_copy,
   1303 		    nullAuthAllowed, uses_ssl);
   1304 
   1305 		exit(0);
   1306 	}
   1307 
   1308 	// I am the parent
   1309 	// Close the socket for this session (must be open only in the child)
   1310 	closesocket(sockctrl);
   1311 #endif /* _WIN32 */
   1312 }
   1313 
   1314 /*!
   1315 	\brief 'true' main of the program in case the active mode is turned on.
   1316 
   1317 	This function loops forever trying to connect to the remote host, until the
   1318 	daemon is turned down.
   1319 
   1320 	\param ptr: it keeps the 'activepars' parameters.  It is a 'void *'
   1321 	just because the thread APIs want this format.
   1322 */
   1323 #ifdef _WIN32
   1324 static unsigned __stdcall
   1325 #else
   1326 static void *
   1327 #endif
   1328 main_active(void *ptr)
   1329 {
   1330 	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
   1331 	SOCKET sockctrl;			// keeps the socket ID for this control connection
   1332 	struct addrinfo hints;			// temporary struct to keep settings needed to open the new socket
   1333 	struct addrinfo *addrinfo;		// keeps the addrinfo chain; required to open a new socket
   1334 	struct active_pars *activepars;
   1335 
   1336 	activepars = (struct active_pars *) ptr;
   1337 
   1338 	// Prepare to open a new server socket
   1339 	memset(&hints, 0, sizeof(struct addrinfo));
   1340 						// WARNING Currently it supports only ONE socket family among IPv4 and IPv6
   1341 	hints.ai_family = AF_INET;		// PF_UNSPEC to have both IPv4 and IPv6 server
   1342 	hints.ai_socktype = SOCK_STREAM;
   1343 	hints.ai_family = activepars->ai_family;
   1344 
   1345 	rpcapd_log(LOGPRIO_DEBUG, "Connecting to host %s, port %s, using protocol %s",
   1346 	    activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4":
   1347 	    (hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified");
   1348 
   1349 	// Initialize errbuf
   1350 	memset(errbuf, 0, sizeof(errbuf));
   1351 
   1352 	// Do the work
   1353 	if (sock_initaddress(activepars->address, activepars->port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
   1354 	{
   1355 		rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
   1356 		return 0;
   1357 	}
   1358 
   1359 	for (;;)
   1360 	{
   1361 		int activeclose;
   1362 
   1363 		if ((sockctrl = sock_open(activepars->address, addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
   1364 		{
   1365 			rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
   1366 
   1367 			DIAG_OFF_FORMAT_TRUNCATION
   1368 			snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error connecting to host %s, port %s, using protocol %s",
   1369 					activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4":
   1370 					(hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified");
   1371 			DIAG_ON_FORMAT_TRUNCATION
   1372 
   1373 			rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
   1374 
   1375 			sleep_secs(RPCAP_ACTIVE_WAIT);
   1376 
   1377 			continue;
   1378 		}
   1379 
   1380 		char *hostlist_copy = strdup(hostlist);
   1381 		if (hostlist_copy == NULL)
   1382 		{
   1383 			rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
   1384 			activeclose = 0;
   1385 			sock_close(sockctrl, NULL, 0);
   1386 		}
   1387 		else
   1388 		{
   1389 			//
   1390 			// daemon_serviceloop() will free the copy.
   1391 			//
   1392 			activeclose = daemon_serviceloop(sockctrl, 1,
   1393 			    hostlist_copy, nullAuthAllowed, uses_ssl);
   1394 		}
   1395 
   1396 		// If the connection is closed by the user explicitly, don't try to connect to it again
   1397 		// just exit the program
   1398 		if (activeclose == 1)
   1399 			break;
   1400 	}
   1401 
   1402 	freeaddrinfo(addrinfo);
   1403 	return 0;
   1404 }
   1405 
   1406 #ifdef _WIN32
   1407 //
   1408 // Main routine of a passive-mode service thread.
   1409 //
   1410 unsigned __stdcall main_passive_serviceloop_thread(void *ptr)
   1411 {
   1412 	struct params_copy params = *(struct params_copy *)ptr;
   1413 	free(ptr);
   1414 
   1415 	//
   1416 	// Handle this client.
   1417 	// This is passive mode, so we don't care whether we were
   1418 	// told by the client to close.
   1419 	//
   1420 	(void)daemon_serviceloop(params.sockctrl, 0, params.hostlist,
   1421 	    nullAuthAllowed, uses_ssl);
   1422 
   1423 	return 0;
   1424 }
   1425 #endif
   1426