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