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