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