2 * Copyright (c) 2002 - 2003
3 * NetGroup, Politecnico di Torino (Italy)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
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()
46 #include "sockutils.h" // for socket calls
47 #include "varattrs.h" // for _U_
48 #include "portability.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
57 #include <process.h> // for thread stuff
58 #include "win32-svc.h" // for Win32 service stuff
59 #include "getopt.h" // for getopt()-for-Windows
61 #include <fcntl.h> // for open()
62 #include <unistd.h> // for exit()
63 #include <sys/wait.h> // waitpid()
67 // Element in list of sockets on which we're listening for connections.
70 struct listen_sock *next;
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
85 static HANDLE state_change_event; //!< event to signal that a state change should take place
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
90 extern char *optarg; // for getopt()
92 // Function definition
94 static unsigned __stdcall main_active(void *ptr);
95 static BOOL WINAPI main_ctrl_event(DWORD);
97 static void *main_active(void *ptr);
98 static void main_terminate(int sign);
99 static void main_reread_config(int sign);
101 static void accept_connections(void);
102 static void accept_connection(SOCKET listen_sock);
104 static void main_reap_children(int sign);
107 static unsigned __stdcall main_passive_serviceloop_thread(void *ptr);
110 #define RPCAP_ACTIVE_WAIT 30 /* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */
113 \brief Prints the usage screen if it is launched in console mode.
115 static void printusage(void)
117 const char *usagetext =
119 " " PROGRAM_NAME " [-b <address>] [-p <port>] [-4] [-l <host_list>] [-a <host,port>]\n"
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"
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"
145 " -i run in inetd mode (UNIX only)\n\n"
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";
153 (void)fprintf(stderr, "RPCAPD, a remote packet capture daemon.\n"
154 "Compiled with %s\n\n", pcap_lib_version());
155 printf("%s", usagetext);
161 int main(int argc, char *argv[])
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
167 int isrunbyinetd = 0; // Non-zero if this is being run by inetd or something inetd-like
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
173 struct sigaction action;
181 memset(errbuf, 0, sizeof(errbuf));
183 strncpy(address, RPCAP_DEFAULT_NETADDR, MAX_LINE);
184 strncpy(port, RPCAP_DEFAULT_NETPORT, MAX_LINE);
186 // Prepare to open a new server socket
187 memset(&mainhints, 0, sizeof(struct addrinfo));
189 mainhints.ai_family = PF_UNSPEC;
190 mainhints.ai_flags = AI_PASSIVE; // Ready to a bind() socket
191 mainhints.ai_socktype = SOCK_STREAM;
193 // Getting the proper command line options
194 while ((retval = getopt(argc, argv, "b:dDhip:4l:na:s:f:v")) != -1)
199 log_debug_messages = 1;
200 rpcapd_log_set(log_to_systemlog, log_debug_messages);
203 strncpy(address, optarg, MAX_LINE);
206 strncpy(port, optarg, MAX_LINE);
209 mainhints.ai_family = PF_INET; // IPv4 server only
213 log_to_systemlog = 1;
214 rpcapd_log_set(log_to_systemlog, log_debug_messages);
222 log_to_systemlog = 1;
223 rpcapd_log_set(log_to_systemlog, log_debug_messages);
234 strncpy(hostlist, optarg, sizeof(hostlist));
239 char *tmpaddress, *tmpport;
243 tmpaddress = pcap_strtok_r(optarg, RPCAP_HOSTLIST_SEP, &lasts);
245 while ((tmpaddress != NULL) && (i < MAX_ACTIVE_LIST))
247 tmpport = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
249 pcap_strlcpy(activelist[i].address, tmpaddress, MAX_LINE);
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);
254 pcap_strlcpy(activelist[i].port, tmpport, MAX_LINE);
256 tmpaddress = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
261 if (i > MAX_ACTIVE_LIST)
262 rpcapd_log(LOGPRIO_ERROR, "Only MAX_ACTIVE_LIST active connections are currently supported.");
264 // I don't initialize the remaining part of the structure, since
265 // it is already zeroed (it is a global var)
269 pcap_strlcpy(loadfile, optarg, MAX_LINE);
272 pcap_strlcpy(savefile, optarg, MAX_LINE);
285 if (isdaemon && isrunbyinetd)
287 rpcapd_log(LOGPRIO_ERROR, "rpcapd: -d and -i can't be used together");
292 if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
294 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
298 if (savefile[0] && fileconf_save(savefile))
299 rpcapd_log(LOGPRIO_DEBUG, "Error when saving the configuration to file");
301 // If the file does not exist, it keeps the settings provided by the command line
307 // Create a handle to signal the main loop to tell it to do
310 state_change_event = CreateEvent(NULL, FALSE, FALSE, NULL);
311 if (state_change_event == NULL)
313 sock_geterror("Can't create state change event", errbuf,
315 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
320 // Catch control signals.
322 if (!SetConsoleCtrlHandler(main_ctrl_event, TRUE))
324 sock_geterror("Can't set control handler", errbuf,
326 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
330 memset(&action, 0, sizeof (action));
331 action.sa_handler = main_terminate;
333 sigemptyset(&action.sa_mask);
334 sigaction(SIGTERM, &action, NULL);
335 memset(&action, 0, sizeof (action));
336 action.sa_handler = main_reap_children;
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);
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.).
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
363 // Duplicate the standard input as the control socket.
368 sock_geterror("Can't dup standard input", errbuf,
370 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
375 // Try to set the standard input, output, and error
378 devnull_fd = open("/dev/null", O_RDWR);
379 if (devnull_fd != -1)
382 // If this fails, just drive on.
384 (void)dup2(devnull_fd, 0);
385 (void)dup2(devnull_fd, 1);
386 (void)dup2(devnull_fd, 2);
391 // Handle this client.
392 // This is passive mode, so we don't care whether we were
393 // told by the client to close.
395 char *hostlist_copy = strdup(hostlist);
396 if (hostlist_copy == NULL)
398 rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
401 (void)daemon_serviceloop(sockctrl, 0, hostlist_copy,
405 // Nothing more to do.
414 // This is being run as a daemon.
415 // On UN*X, it might be manually run, or run from an
422 // Daemonize ourselves.
424 // Unix Network Programming, pg 336
426 if ((pid = fork()) != 0)
427 exit(0); // Parent terminates
429 // First child continues
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;
437 sigemptyset(&action.sa_mask);
438 sigaction(SIGHUP, &action, NULL);
440 if ((pid = fork()) != 0)
441 exit(0); // First child terminates
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
448 // Second child continues
453 // This is being run as a service on Windows.
455 // If this call succeeds, it is blocking on Win32
457 if (svc_start() != 1)
458 rpcapd_log(LOGPRIO_DEBUG, "Unable to start the service");
460 // When the previous call returns, the entire application has to be stopped.
467 // Enable the catching of Ctrl+C
468 memset(&action, 0, sizeof (action));
469 action.sa_handler = main_terminate;
471 sigemptyset(&action.sa_mask);
472 sigaction(SIGINT, &action, NULL);
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;
479 sigemptyset(&action.sa_mask);
480 sigaction(SIGHUP, &action, NULL);
483 printf("Press CTRL + C to stop the server...\n");
486 // If we're a Win32 service, we have already called this function in the service_main
489 // The code should never arrive here (since the main_startup is blocking)
490 // however this avoids a compiler warning
494 void main_startup(void)
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
500 HANDLE threadId; // handle for the subthread
507 memset(errbuf, 0, sizeof(errbuf));
509 // Starts all the active threads
510 while ((i < MAX_ACTIVE_LIST) && (activelist[i].address[0] != 0))
512 activelist[i].ai_family = mainhints.ai_family;
515 threadId = (HANDLE)_beginthreadex(NULL, 0, main_active,
516 (void *)&activelist[i], 0, NULL);
519 rpcapd_log(LOGPRIO_DEBUG, "Error creating the active child threads");
522 CloseHandle(threadId);
524 if ((pid = fork()) == 0) // I am the child
526 main_active((void *) &activelist[i]);
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.
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.
547 struct addrinfo *tempaddrinfo;
550 // Get a list of sockets on which to listen.
552 if (sock_initaddress((address[0]) ? address : NULL, port, &mainhints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
554 rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
558 for (tempaddrinfo = addrinfo; tempaddrinfo;
559 tempaddrinfo = tempaddrinfo->ai_next)
562 struct listen_sock *sock_info;
564 if ((sock = sock_open(tempaddrinfo, SOCKOPEN_SERVER, SOCKET_MAXCONN, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
566 switch (tempaddrinfo->ai_family)
570 struct sockaddr_in *in;
571 char addrbuf[INET_ADDRSTRLEN];
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)),
584 struct sockaddr_in6 *in6;
585 char addrbuf[INET6_ADDRSTRLEN];
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),
597 rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for address family %u: %s",
598 tempaddrinfo->ai_family,
605 sock_info = (struct listen_sock *) malloc(sizeof (struct listen_sock));
606 if (sock_info == NULL)
608 rpcapd_log(LOGPRIO_ERROR, "Can't allocate structure for listen socket");
611 sock_info->sock = sock;
612 sock_info->next = listen_socks;
613 listen_socks = sock_info;
616 freeaddrinfo(addrinfo);
618 if (listen_socks == NULL)
620 rpcapd_log(LOGPRIO_ERROR, "Can't listen on any address");
625 // Now listen on all of them, waiting for connections.
627 accept_connections();
633 rpcapd_log(LOGPRIO_DEBUG, PROGRAM_NAME " is closing.\n");
637 // Sends a KILL signal to all the processes in this process's
638 // process group; i.e., it kills all the child processes
641 // XXX - that also includes us, so we will be killed as well;
642 // that may cause a message to be printed or logged.
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
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).
671 send_state_change_event(void)
673 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
675 if (!SetEvent(state_change_event))
677 sock_geterror("SetEvent on shutdown event failed", errbuf,
679 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
684 send_shutdown_notification(void)
687 // Indicate that the server should shut down.
692 // Send a state change event, to wake up WSAWaitForMultipleEvents().
694 send_state_change_event();
698 send_reread_configuration_notification(void)
701 // Indicate that the server should re-read its configuration file.
706 // Send a state change event, to wake up WSAWaitForMultipleEvents().
708 send_state_change_event();
711 static BOOL WINAPI main_ctrl_event(DWORD ctrltype)
714 // ctrltype is one of:
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
721 // CTRL_SHUTDOWN_EVENT - the systemis shutting down; this is
722 // received only by services
724 // For now, we treat all but CTRL_LOGOFF_EVENT as indications
725 // that we should shut down.
730 case CTRL_BREAK_EVENT:
731 case CTRL_CLOSE_EVENT:
732 case CTRL_SHUTDOWN_EVENT:
734 // Set a shutdown notification.
736 send_shutdown_notification();
749 static void main_terminate(int sign _U_)
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.
759 static void main_reread_config(int sign _U_)
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.
769 static void main_reap_children(int sign _U_)
774 // Reap all child processes that have exited.
775 // For reference, Stevens, pg 128
777 while ((pid = waitpid(-1, &exitstat, WNOHANG)) > 0)
778 rpcapd_log(LOGPRIO_DEBUG, "Child terminated");
785 // Loop waiting for incoming connections and accepting them.
788 accept_connections(void)
791 struct listen_sock *sock_info;
795 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
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.
802 num_events = 1; // shutdown event
803 for (sock_info = listen_socks; sock_info;
804 sock_info = sock_info->next)
806 if (num_events == WSA_MAXIMUM_WAIT_EVENTS)
809 // WSAWaitForMultipleEvents() doesn't support
810 // more than WSA_MAXIMUM_WAIT_EVENTS events
813 rpcapd_log(LOGPRIO_ERROR, "Too many sockets on which to listen");
820 // Allocate the array of events.
822 events = (WSAEVENT *) malloc(num_events * sizeof (WSAEVENT));
825 rpcapd_log(LOGPRIO_ERROR, "Can't allocate array of events which to listen");
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++)
839 // Create an event that is signaled if there's a connection
840 // to accept on the socket in question.
842 event = WSACreateEvent();
843 if (event == WSA_INVALID_EVENT)
845 sock_geterror("Can't create socket event", errbuf,
847 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
850 if (WSAEventSelect(sock_info->sock, event, FD_ACCEPT) == SOCKET_ERROR)
852 sock_geterror("Can't setup socket event", errbuf,
854 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
863 // Wait for incoming connections.
867 ret = WSAWaitForMultipleEvents(num_events, events, FALSE,
868 WSA_INFINITE, FALSE);
869 if (ret == WSA_WAIT_FAILED)
871 sock_geterror("WSAWaitForMultipleEvents failed", errbuf,
873 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
877 if (ret == WSA_WAIT_EVENT_0)
880 // The state change event was set.
885 // Time to quit. Exit the loop.
892 // We should re-read the configuration
895 reread_config = 0; // clear the indicator
901 // Check each socket.
903 for (sock_info = listen_socks, i = 1; sock_info;
904 sock_info = sock_info->next, i++)
906 WSANETWORKEVENTS network_events;
908 if (WSAEnumNetworkEvents(sock_info->sock,
909 events[i], &network_events) == SOCKET_ERROR)
911 sock_geterror("WSAEnumNetworkEvents failed",
912 errbuf, PCAP_ERRBUF_SIZE);
913 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
916 if (network_events.lNetworkEvents & FD_ACCEPT)
919 // Did an error occur?
921 if (network_events.iErrorCode[FD_ACCEPT_BIT] != 0)
924 // Yes - report it and keep going.
926 sock_fmterror("Socket error",
927 network_events.iErrorCode[FD_ACCEPT_BIT],
930 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
935 // Accept the connection.
937 accept_connection(sock_info->sock);
942 struct listen_sock *sock_info;
946 // How big does the bitset of sockets on which to select() have
950 for (sock_info = listen_socks; sock_info; sock_info = sock_info->next)
952 if (sock_info->sock + 1 > num_sock_fds)
954 if ((unsigned int)(sock_info->sock + 1) >
955 (unsigned int)FD_SETSIZE)
957 rpcapd_log(LOGPRIO_ERROR, "Socket FD is too bit for an fd_set");
960 num_sock_fds = sock_info->sock + 1;
970 // Set up an fd_set for all the sockets on which we're
973 // This set is modified by select(), so we have to
974 // construct it anew each time.
977 for (sock_info = listen_socks; sock_info;
978 sock_info = sock_info->next)
980 FD_SET(sock_info->sock, &sock_fds);
984 // Wait for incoming connections.
986 ret = select(num_sock_fds, &sock_fds, NULL, NULL, NULL);
992 // If this is a "terminate the
993 // server" signal, exit the loop,
994 // otherwise just keep trying.
999 // Time to quit. Exit the loop.
1006 // We should re-read the configuration
1009 reread_config = 0; // clear the indicator
1014 // Go back and wait again.
1020 rpcapd_log(LOGPRIO_ERROR, "select failed: %s",
1027 // Check each socket.
1029 for (sock_info = listen_socks; sock_info;
1030 sock_info = sock_info->next)
1032 if (FD_ISSET(sock_info->sock, &sock_fds))
1035 // Accept the connection.
1037 accept_connection(sock_info->sock);
1044 // Close all the listen sockets.
1046 for (sock_info = listen_socks; sock_info; sock_info = sock_info->next)
1048 closesocket(sock_info->sock);
1055 // A structure to hold the parameters to the daemon service loop
1056 // thread on Windows.
1058 // (On UN*X, there is no need for this explicit copy since the
1059 // fork "inherits" the parent stack.)
1061 struct params_copy {
1068 // Accept a connection and start a worker thread, on Windows, or a
1069 // worker process, on UN*X, to handle the connection.
1072 accept_connection(SOCKET listen_sock)
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
1080 HANDLE threadId; // handle for the subthread
1082 struct params_copy *params_copy = NULL;
1087 // Initialize errbuf
1088 memset(errbuf, 0, sizeof(errbuf));
1092 // Accept the connection
1093 fromlen = sizeof(struct sockaddr_storage);
1095 sockctrl = accept(listen_sock, (struct sockaddr *) &from, &fromlen);
1097 if (sockctrl != INVALID_SOCKET)
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
1107 if (WSAGetLastError() == WSAEINTR)
1113 // Don't check for errors here, since the error can be due to the fact that the thread
1115 sock_geterror("accept()", errbuf, PCAP_ERRBUF_SIZE);
1116 rpcapd_log(LOGPRIO_ERROR, "Accept of control connection from client failed: %s",
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.
1128 // First, we have to un-WSAEventSelect() this socket, and then
1129 // we can turn non-blocking mode off.
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.
1135 // So we just log the message and close the connection.
1137 if (WSAEventSelect(sockctrl, NULL, 0) == SOCKET_ERROR)
1139 sock_geterror("WSAEventSelect()", errbuf, PCAP_ERRBUF_SIZE);
1140 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
1141 sock_close(sockctrl, NULL, 0);
1144 if (ioctlsocket(sockctrl, FIONBIO, &off) == SOCKET_ERROR)
1146 sock_geterror("ioctlsocket(FIONBIO)", errbuf, PCAP_ERRBUF_SIZE);
1147 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
1148 sock_close(sockctrl, NULL, 0);
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.
1157 // daemon_serviceloop() will free it once it's done with it.
1159 char *hostlist_copy = strdup(hostlist);
1160 if (hostlist_copy == NULL)
1162 rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
1163 sock_close(sockctrl, NULL, 0);
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.
1172 params_copy = malloc(sizeof(*params_copy));
1173 if (params_copy == NULL)
1175 rpcapd_log(LOGPRIO_ERROR, "Out of memory allocating the parameter copy structure");
1176 free(hostlist_copy);
1177 sock_close(sockctrl, NULL, 0);
1180 params_copy->sockctrl = sockctrl;
1181 params_copy->hostlist = hostlist_copy;
1183 threadId = (HANDLE)_beginthreadex(NULL, 0,
1184 main_passive_serviceloop_thread, (void *) params_copy, 0, NULL);
1187 rpcapd_log(LOGPRIO_ERROR, "Error creating the child thread");
1189 free(hostlist_copy);
1190 sock_close(sockctrl, NULL, 0);
1193 CloseHandle(threadId);
1198 rpcapd_log(LOGPRIO_ERROR, "Error creating the child process: %s",
1200 sock_close(sockctrl, NULL, 0);
1208 // Close the socket on which we're listening (must
1209 // be open only in the parent).
1211 closesocket(listen_sock);
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.
1221 if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL))
1223 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL))
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.
1232 char *hostlist_copy = strdup(hostlist);
1233 if (hostlist_copy == NULL)
1235 rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
1238 (void)daemon_serviceloop(sockctrl, 0, hostlist_copy,
1245 // Close the socket for this session (must be open only in the child)
1246 closesocket(sockctrl);
1251 \brief 'true' main of the program in case the active mode is turned on.
1253 This function loops forever trying to connect to the remote host, until the
1254 daemon is turned down.
1256 \param ptr: it keeps the 'activepars' parameters. It is a 'void *'
1257 just because the thread APIs want this format.
1260 static unsigned __stdcall
1264 main_active(void *ptr)
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;
1272 activepars = (struct active_pars *) ptr;
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;
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");
1285 // Initialize errbuf
1286 memset(errbuf, 0, sizeof(errbuf));
1289 if (sock_initaddress(activepars->address, activepars->port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
1291 rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
1299 if ((sockctrl = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
1301 rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
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");
1307 rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
1309 sleep_secs(RPCAP_ACTIVE_WAIT);
1314 char *hostlist_copy = strdup(hostlist);
1315 if (hostlist_copy == NULL)
1317 rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
1319 sock_close(sockctrl, NULL, 0);
1324 // daemon_serviceloop() will free the copy.
1326 activeclose = daemon_serviceloop(sockctrl, 1,
1327 hostlist_copy, nullAuthAllowed);
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)
1336 freeaddrinfo(addrinfo);
1342 // Main routine of a passive-mode service thread.
1344 unsigned __stdcall main_passive_serviceloop_thread(void *ptr)
1346 struct params_copy params = *(struct params_copy *)ptr;
1350 // Handle this client.
1351 // This is passive mode, so we don't care whether we were
1352 // told by the client to close.
1354 (void)daemon_serviceloop(params.sockctrl, 0, params.hostlist,