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