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