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