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