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