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