xref: /freebsd/contrib/libpcap/rpcapd/rpcapd.c (revision 9f23cbd6cae82fd77edfad7173432fa8dccd0a95)
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