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